Write barrier for G1GC SATB wasn't atomic?
Tony Printezis
tony.printezis at oracle.com
Wed Mar 23 14:41:53 UTC 2011
What Igor said!
Narihiro,
Nice hobby you have. :-) The SATB barrier was first proposed by Yuasa in
this paper (IIRC):
Taichi Yuasa. *Real-time garbage collection on general-purpose
machines*. / Journal of Systems and Software/, 11(3):181-198, 1990.
Tony
Igor Veresov wrote:
> That's ok. The goal of SATB is to snapshot the object graph and track
> the changes to it. So, in your example, obj0 was the contents of the
> field before the snapshot. It doesn't matter if we capture it multiple
> times or values that were stored to the field after the snapshot - all
> of this will be filtered later. The important part is that we captured
> the value that was before the snapshot at least once.
>
> On 3/22/11 11:11 PM, Narihiro Nakamura wrote:
>> Hi, all.
>>
>> I read G1GC by a hobby.
>> I have one question about write barrier for SATB.
>>
>> I think that satb write barrier is defined in the following points:
>> - cpu/sparc/vm/assembler_sparc.cpp:
>> MacroAssembler::g1_write_barrier_pre()
>> - cpu/x86/vm/assembler_x86.cpp: MacroAssembler::g1_write_barrier_pre()
>> - share/vm/opto/graphKit.cpp: GraphKit::g1_write_barrier_pre()
>>
>
> There are also C1 versions in c1_LIRGeneration.cpp,
> c1_CodeStubs_*.cpp, c1_Runtime_*.cpp.
>
>> I read their code.
>> I think that the pseudo-cord of "satb write barrier" is as follows:
>>
>> 1: def satb_write_barrier(field, newobj):
>> 2: oldobj = *field // (a)
>> 3: if $gc_phase == GC_CONCURRENT_MARK and oldobj != Null:
>> 4: enqueue($current_thread.stab_mark_queue, oldobj) // (b)
>> 5: *field = newobj // (c)
>>
>
> It actually checks if marking is in progress first, then loads the
> previous value. More importantly, the the marking flag can be set only
> during a safepoint, so from that point of view, barriers are "atomic"
> with respect to safepoints, a thread won't enter a safepoint while in
> the barrier.
>
>> This code doesn't look like in atomic operation from (a) to (b).
>> In that case, when mutator more than 2 try to write *field at the
>> same time, the reference that should record may leak out to satb
>> mark queue.
>>
>> For example.
>> 1. *field == obj0 address
>> 2. t1(Thread1) try to write obj1 address to *field.
>> 3. t2(Thread2) try to write obj2 address to *field.
>> 4. t1 at (a): oldobj = obj0
>> 5. t2 at (a): oldobj = obj0
>> 6. t1 at (b): enqueue obj0 to satb mark queue
>> 7. t2 at (b): enqueue obj0 to satb mark queue
>> 8. t1 at (c): *field = obj1
>> 9. t2 at (c): *field = obj2
>>
>> In this example, obj1 that should enqueue satb mark queue is leaked.
>>
>
> Yes, we're not interested in obj1 at all. We're only interested in the
> contents of the field that were there before the marking started.
>
>
> igor
>
>> Is this intended behavior? Or, Is it my misunderstanding?
>>
>> Thanks.
>
>
More information about the hotspot-gc-dev
mailing list