RFR Backport 8165808: Add release barriers when allocating objects with concurrent collection

Yangfei (Felix) felix.yang at huawei.com
Thu Aug 27 03:20:43 UTC 2020


Hi,

> -----Original Message-----
> From: Andrew Haley [mailto:aph at redhat.com]
> Sent: Thursday, August 27, 2020 12:12 AM
> To: Yangfei (Felix) <felix.yang at huawei.com>; jdk8u-dev at openjdk.java.net
> Subject: Re: RFR Backport 8165808: Add release barriers when allocating
> objects with concurrent collection

Cut ...

> >>
> >> By the way, there are many places where arrays are allocated. Do you
> >> know why only this particular one needs a release barrier?
> >
> > Not sure if I understand the question correctly.
> > I think the common entry points are CollectedHeap::obj_allocate &
> CollectedHeap::array_allocate.  These functions finally calls
> CollectedHeap::post_allocation_setup_common.
> > Many places will call these functions to create objects.  For example,
> > InstanceKlass::allocate_objArray -> CollectedHeap::array_allocate ->
> > CollectedHeap::post_allocation_setup_array ->
> > CollectedHeap::post_allocation_setup_common
> > Since we do a release store in
> CollectedHeap::post_allocation_setup_common, so all the places where
> objects are created will benefit.
> 
> There is code at MacroAssembler::eden_allocate and
> PhaseMacroExpand::expand_allocate_common which does object allocation.
> If CollectedHeap::obj_allocate needs release barriers, why don't those places
> need them too? Is there another patch which adds such release barriers that
> also needs to be backported?

That's a good question.
I checked the latest jdk/jdk repo and looks like the barrier is not there too. 
One of the code path looks like: TemplateTable::_new -> MacroAssembler::eden_allocate

Consider the fast path in TemplateTable::_new, we do a plain store for klass:

3622     // initialize object header only.
3623     __ bind(initialize_header);
3624     if (UseBiasedLocking) {
3625       __ ldr(rscratch1, Address(r4, Klass::prototype_header_offset()));
3626     } else {
3627       __ mov(rscratch1, (intptr_t)markWord::prototype().value());
3628     }
3629     __ str(rscratch1, Address(r0, oopDesc::mark_offset_in_bytes()));
3630     __ store_klass_gap(r0, zr);  // zero klass gap for compressed oops
3631     __ store_klass(r0, r4);      // store klass last                <==============

Looking at MacroAssembler::store_klass, the same question has been raised early before.

3780 void MacroAssembler::store_klass(Register dst, Register src) {
3781   // FIXME: Should this be a store release?  concurrent gcs assumes
3782   // klass length is valid if klass field is not null.
3783   if (UseCompressedClassPointers) {
3784     encode_klass_not_null(src);
3785     strw(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3786   } else {
3787     str(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3788   }
3789 }

But the slow path in TemplateTable::_new is different.  The call chain looks like:
    InterpreterRuntime::_new -> InstanceKlass::allocate_instance -> CollectedHeap::obj_allocate -> MemAllocator::allocate -> ObjAllocator::initialize -> MemAllocator::finish -> oopDesc::release_set_klass

I don't see a reason why the barrier is not necessary for the fast path.
There is a similar issue for PhaseMacroExpand::expand_allocate_common: fast path and slow path are different on the storing of klass.
Also C1 uses a plain store for klass too in C1_MacroAssembler::initialize_header.
I'm more inclined to think these code paths are missed by the original patch, but that need confirmation.

Thanks,
Felix




More information about the jdk8u-dev mailing list