[9] RFR(S): 8156760: VM crashes if -XX:-ReduceInitialCardMarks is set

Tobias Hartmann tobias.hartmann at oracle.com
Tue May 24 08:54:42 UTC 2016

Hi Dean,

On 23.05.2016 20:09, dean.long at oracle.com wrote:
> Hi Tobias.  I was just wondering, how do we know that the destination object is in Eden, both now and in the future, and what would happen if it wasn't?  Would we get a nice assert somewhere, or would we end up with a hard-to-find bug?

Thanks for the feedback! From reading the G1 code, I assumed that a newly allocated object is always in Eden. Looking at the code again, I'm not sure what happens if the Eden space is full. If allocations may happen in the old generation as well, we need a runtime check for the card value. I don't think we have an assert/verification that checks this.

Could someone from GC please verify this? 


> dl
> On 5/23/16 2:25 AM, Tobias Hartmann wrote:
>> Hi,
>> please review the following patch:
>> https://bugs.openjdk.java.net/browse/JDK-8156760
>> http://cr.openjdk.java.net/~thartmann/8156760/webrev.00/
>> While working on JDK-8155643, I found several problems when running tests with -XX:-ReduceInitialCardMarks:
>> Problem 1:
>> C2 crashes with "missing G1 post barrier" while trying to eliminate the card mark emitted by the Object.clone() intrinsic (after removing the allocation of the destination object) [1]. The problem is that the shape of the card mark code is different for the Object.clone() intrinsic because we don't emit any checks (see [4]). However, PhaseMacroExpand::eliminate_card_mark() tries to find and collapse a region check. Usually, this is not a problem because with ReduceInitialCardMarks we don't emit a post barrier for Object.clone().
>> Problem 2:
>> The VM crashes during GC verification in G1SATBCardTableModRefBS::verify_g1_young_region() with "there should not have been any failures" because we expect cards for the young generation to be always set to 'g1_young_gen' [2]:
>> [1.478s][error][gc,verify] == CT verification failed: [0x00007f097c167800,0x00007f097c167fff]
>> [1.478s][error][gc,verify] == expecting value: 32
>> [1.478s][error][gc,verify] == card 0x00007f097c167800 [0x00000006d8900000,0x00000006d8900200], val: 0
>> [1.478s][error][gc,verify] == card 0x00007f097c167801 [0x00000006d8900200,0x00000006d8900400], val: 0
>> ...
>> With !ReduceInitialCardMarks, the Object.clone() intrinsic emits card marks that set the cards of the newly allocated destination object to 'dirty' (!= 'g1_young_gen') and thus causing the verification to fail.
>> I fixed problems 1 and 2 by removing the card marking code for the Object.clone() intrinsic with G1. This should be fine because the destination object is always in Eden and we therefore don't need to mark the cards.
>> Problem 3:
>> C2 crashes with SIGSEGV in ArrayCopyNode::prepare_array_copy() because we expect an array clone/copy and dereference 'src_type->isa_aryptr()' but actually have a non-array Object.clone() [3]. This is because with !ReduceInitialCardMarks, ArrayCopyNode::try_clone_instance() does not capture the Object.clone() intrinsic because we emit card marking code (we bail out in 'ArrayCopyNode::finish_transform()'). We continue assuming that the array copy is a non-instance copy. I added an additional check to bail out in this case.
>> I changed 'TestInstanceCloneAsLoadsStores' to be also executed with -XX:-ReduceInitialCardMarks. This triggers problem 1 and 2. Problem 3 can be reproduced by running the modified test with XX:+UseConcMarkSweepGC.
>> Tested with failing tests, JPRT and RBT (running).
>> Thanks,
>> Tobias
>> [1] https://bugs.openjdk.java.net/secure/attachment/59410/hs_err_pid28313.log
>> [2] https://bugs.openjdk.java.net/secure/attachment/59661/hs_err_pid30301.log
>> [3] https://bugs.openjdk.java.net/secure/attachment/59660/hs_err_pid22570.log
>> [4] https://bugs.openjdk.java.net/secure/attachment/59564/graph.png

More information about the hotspot-dev mailing list