RFR: Eliminate extra forwarding pointer per object
Roman Kennke
rkennke at redhat.com
Wed May 8 14:28:41 UTC 2019
Hi Aleksey,
>>> I actually think that we can keep ShenandoahBrooksPointer and put all that util code there. It would
>>> still be doing its job: abstracting away the forwarding data handling.
>>
>> I reinstated the ShenandoahForwarding utility class. However, it is hard to abstract the protocol
>> because the two parts strictly belong together. However, this seems all the more reason to abstract
>> it properly. The only thing that happens in between the two blocks is actually allocating and
>> copying the object. So we could call into, say, ShenandoahForwarding::evacuate() which would do the
>> prefix and suffix, and call back to say copy = ShHeap::allocate_and_copy(obj); or such for the
>> payload. What do you think?
>
> I don't understand off-hand why the protocol is different. For example, why do you need to drag
> old_mark in SH:evacuate_object? You can still have try_update_forwardee to check that "old" mark is
> not forwarded yet, and use that?
>
> Pseudocode for try_update_forwardee:
>
> // returns "true" on success
> bool try_update_forwardee(p, copy_val):
> markOop old = p->mark_raw();
> if (old->is_marked()):
> return false;
> markOop new_mark = markOopDesc::encode_pointer_as_mark(copy_val);
> markOop prev_mark = p->cas_set_mark_raw(new_mark, old_mark);
> return prev_mark == old_mark;
>
> ...then:
>
> if (try_update_forwardee(p, copy_val)):
> shenandoah_assert_correct(NULL, copy_val);
> return copy_val;
> } else {
> return ShenandoahForwarding::get_forwardee(p);
> }
Ok right, I got it. I moved all forwarding related code to
ShenandoahForwarding.
I also added ShenandoahForwarding::is_forwarded(oop obj) which can be
used in the GC threads evac path where we don't care about actually
decoding and comparing the oops. Should be slightly more efficient.
>>> *) In ShenandoahMarkCompact, do these need to be public?
>>>
>>> 76 public:
>>> 77 void preserve_mark(oop obj);
>>> 78 void restore_marks();
>>> 79 void adjust_marks();
>>
>> I forgot to mention ShenandoahMarkCompact. This completely overhauls how ShMarkCompact stores
>> forwarding information. It's changed to basically work like other GCs and stores the forwarding in
>> the mark-word. However, the mark word must sometimes be preserved. Therefore we store it to the
>> side. The 3 methods above handle that. They are public because they are called from closures.
>> Alternatively, we could make the closures friends of ShMarkCompact. ?
>
> Yes, befriending closures would look cleaner, I think.
Done.
>> Updated patch:
>> http://cr.openjdk.java.net/~rkennke/eliminate-fwdptr/webrev.01/
>
> Other nits:
>
> *) The dance like that needs some rationale/pseudo-code?
>
> 326 Label done;
> 327 __ movptr(tmp, Address(dst, oopDesc::mark_offset_in_bytes()));
> 328 __ notptr(tmp);
> 329 __ testb(tmp, markOopDesc::marked_value);
> 330 __ jccb(Assembler::notZero, done);
> 331 __ orptr(tmp, markOopDesc::marked_value);
> 332 __ notptr(tmp);
> 333 __ mov(dst, tmp);
> 334 __ bind(done);
I added comments.
> *) In here, you can call get_forwardee_raw_unchecked to have only one shenandoah_assert_correct assert:
>
> 45 inline oop ShenandoahForwarding::get_forwardee(oop obj) {
> 46 shenandoah_assert_correct(NULL, obj);
> 47 return oop(get_forwardee_raw(obj));
> 48 }
Done.
New webrev:
http://cr.openjdk.java.net/~rkennke/eliminate-fwdptr/webrev.02/
Better?
Roman
More information about the shenandoah-dev
mailing list