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