--- old/src/share/vm/opto/graphKit.cpp 2016-05-23 12:17:53.995404573 +0200 +++ new/src/share/vm/opto/graphKit.cpp 2016-05-23 12:17:53.919404577 +0200 @@ -4198,8 +4198,16 @@ Node* val, BasicType bt, bool use_precise) { - // If we are writing a NULL then we need no post barrier + if (val == NULL) { + // The Object.clone() intrinsic uses this path if !ReduceInitialCardMarks. + // We don't need a barrier here because the destination is a newly allocated object + // in Eden. Otherwise, GC verification breaks because we assume that cards in Eden + // are set to 'g1_young_gen' (see G1SATBCardTableModRefBS::verify_g1_young_region()). + assert(!use_ReduceInitialCardMarks(), "can only happen with card marking"); + return; + } + // If we are writing a NULL then we need no post barrier if (val != NULL && val->is_Con() && val->bottom_type() == TypePtr::NULL_PTR) { // Must be NULL const Type* t = val->bottom_type(); @@ -4274,41 +4282,34 @@ // If we know the value being stored does it cross regions? - if (val != NULL) { - // Does the store cause us to cross regions? - - // Should be able to do an unsigned compare of region_size instead of - // and extra shift. Do we have an unsigned compare?? - // Node* region_size = __ ConI(1 << HeapRegion::LogOfHRGrainBytes); - Node* xor_res = __ URShiftX ( __ XorX( cast, __ CastPX(__ ctrl(), val)), __ ConI(HeapRegion::LogOfHRGrainBytes)); - - // if (xor_res == 0) same region so skip - __ if_then(xor_res, BoolTest::ne, zeroX); { - - // No barrier if we are storing a NULL - __ if_then(val, BoolTest::ne, null(), unlikely); { - - // Ok must mark the card if not already dirty - - // load the original value of the card - Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw); - - __ if_then(card_val, BoolTest::ne, young_card); { - sync_kit(ideal); - insert_store_load_for_barrier(); - __ sync_kit(this); - - Node* card_val_reload = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw); - __ if_then(card_val_reload, BoolTest::ne, dirty_card); { - g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf); - } __ end_if(); + // Should be able to do an unsigned compare of region_size instead of + // and extra shift. Do we have an unsigned compare?? + // Node* region_size = __ ConI(1 << HeapRegion::LogOfHRGrainBytes); + Node* xor_res = __ URShiftX ( __ XorX( cast, __ CastPX(__ ctrl(), val)), __ ConI(HeapRegion::LogOfHRGrainBytes)); + + // if (xor_res == 0) same region so skip + __ if_then(xor_res, BoolTest::ne, zeroX); { + + // No barrier if we are storing a NULL + __ if_then(val, BoolTest::ne, null(), unlikely); { + + // Ok must mark the card if not already dirty + + // load the original value of the card + Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw); + + __ if_then(card_val, BoolTest::ne, young_card); { + sync_kit(ideal); + insert_store_load_for_barrier(); + __ sync_kit(this); + + Node* card_val_reload = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw); + __ if_then(card_val_reload, BoolTest::ne, dirty_card); { + g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf); } __ end_if(); } __ end_if(); } __ end_if(); - } else { - // Object.clone() instrinsic uses this path. - g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf); - } + } __ end_if(); // Final sync IdealKit and GraphKit. final_sync(ideal);