RFR: Improve C2 no-fwdptr codegen: assume object is forwarded, avoid long immediate

Roman Kennke rkennke at redhat.com
Mon May 13 14:51:12 UTC 2019


Yes that seems good.

However, what I'm really asking myself is if we shouldn't just generate
the same inversion-based path that we do in assembly. And optimize the
asm path too (see comments below):

  Label done;
  __ movptr(tmp, Address(dst, oopDesc::mark_offset_in_bytes()));
  // Is the an instruction that only inverts the lowest N bits while
leaving the upper alone?
  __ notptr(tmp);
  __ testb(tmp, markOopDesc::marked_value);
  __ jccb(Assembler::notZero, done);
  // Should also be possible via orb(..)
  __ orptr(tmp, markOopDesc::marked_value);
  // See above?
  __ notptr(tmp);
  __ mov(dst, tmp);
  __ bind(done);

It avoids the extra reg for the immediates altogether, and uses
byte-sized-ops in most/all cases.

What do you think?

Roman

> Continuing to meditate over no-fwdptr generated code. Two wrinkles are there: a) we better assume
> that the object is forwarded, this is likely because obj is evacuated once; b) avoid long immediate
> 0xfff...fc, instead use the already available bits. Both these things seem to cut out about 5..7
> bytes from LRB midpath.
> 
> diff -r 6041f00b663f src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
> --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp  Fri May 10 21:43:07 2019 +0200
> +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp  Mon May 13 16:30:38 2019 +0200
> @@ -1521,19 +1521,20 @@
> 
>      // Only branch to LRB stub if object is not forwarded; otherwise reply with fwd ptr
>      Node* bol = new BoolNode(cmp, BoolTest::eq); // Equals 3 means it's forwarded
>      phase->register_new_node(bol, ctrl);
> 
> -    IfNode* iff = new IfNode(ctrl, bol, PROB_UNLIKELY(0.999), COUNT_UNKNOWN);
> +    IfNode* iff = new IfNode(ctrl, bol, PROB_LIKELY(0.999), COUNT_UNKNOWN);
>      phase->register_control(iff, loop, ctrl);
>      Node* if_fwd = new IfTrueNode(iff);
>      phase->register_control(if_fwd, loop, iff);
>      Node* if_not_fwd = new IfFalseNode(iff);
>      phase->register_control(if_not_fwd, loop, iff);
> 
> -    // Decode forward pointer.
> -    Node* masked2 = new AndXNode(markword, phase->igvn().MakeConX(~markOopDesc::lock_mask_in_place));
> +    // Decode forward pointer: since we already have the lowest bits, we can just subtract them
> +    // from the mark word without the need for large immediate mask.
> +    Node* masked2 = new SubXNode(markword, masked);
>      phase->register_new_node(masked2, if_fwd);
>      Node* fwdraw = new CastX2PNode(masked2);
>      fwdraw->init_req(0, if_fwd);
>      phase->register_new_node(fwdraw, if_fwd);
>      Node* fwd = new CheckCastPPNode(NULL, fwdraw, val->bottom_type());
> 
> Testing: hotspot_gc_shenandoah x86_64
> 
> --
> Thanks,
> -Aleksey
> 



More information about the shenandoah-dev mailing list