24 */ |
24 */ |
25 |
25 |
26 #include "precompiled.hpp" |
26 #include "precompiled.hpp" |
27 #include "asm/macroAssembler.inline.hpp" |
27 #include "asm/macroAssembler.inline.hpp" |
28 #include "compiler/disassembler.hpp" |
28 #include "compiler/disassembler.hpp" |
|
29 #include "gc/shared/cardTable.hpp" |
29 #include "gc/shared/cardTableModRefBS.hpp" |
30 #include "gc/shared/cardTableModRefBS.hpp" |
30 #include "gc/shared/collectedHeap.inline.hpp" |
31 #include "gc/shared/collectedHeap.inline.hpp" |
31 #include "interpreter/interpreter.hpp" |
32 #include "interpreter/interpreter.hpp" |
32 #include "memory/resourceArea.hpp" |
33 #include "memory/resourceArea.hpp" |
33 #include "nativeInst_ppc.hpp" |
34 #include "nativeInst_ppc.hpp" |
41 #include "runtime/safepointMechanism.hpp" |
42 #include "runtime/safepointMechanism.hpp" |
42 #include "runtime/sharedRuntime.hpp" |
43 #include "runtime/sharedRuntime.hpp" |
43 #include "runtime/stubRoutines.hpp" |
44 #include "runtime/stubRoutines.hpp" |
44 #include "utilities/macros.hpp" |
45 #include "utilities/macros.hpp" |
45 #if INCLUDE_ALL_GCS |
46 #if INCLUDE_ALL_GCS |
|
47 #include "gc/g1/g1CardTable.hpp" |
46 #include "gc/g1/g1CollectedHeap.inline.hpp" |
48 #include "gc/g1/g1CollectedHeap.inline.hpp" |
47 #include "gc/g1/g1SATBCardTableModRefBS.hpp" |
49 #include "gc/g1/g1SATBCardTableModRefBS.hpp" |
48 #include "gc/g1/heapRegion.hpp" |
50 #include "gc/g1/heapRegion.hpp" |
49 #endif // INCLUDE_ALL_GCS |
51 #endif // INCLUDE_ALL_GCS |
50 #ifdef COMPILER2 |
52 #ifdef COMPILER2 |
3034 |
3036 |
3035 // Write the card table byte if needed. |
3037 // Write the card table byte if needed. |
3036 void MacroAssembler::card_write_barrier_post(Register Rstore_addr, Register Rnew_val, Register Rtmp) { |
3038 void MacroAssembler::card_write_barrier_post(Register Rstore_addr, Register Rnew_val, Register Rtmp) { |
3037 CardTableModRefBS* bs = |
3039 CardTableModRefBS* bs = |
3038 barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set()); |
3040 barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set()); |
3039 assert(bs->kind() == BarrierSet::CardTableForRS || |
3041 assert(bs->kind() == BarrierSet::CardTableModRef, "wrong barrier"); |
3040 bs->kind() == BarrierSet::CardTableExtension, "wrong barrier"); |
3042 CardTable* ct = bs->card_table(); |
3041 #ifdef ASSERT |
3043 #ifdef ASSERT |
3042 cmpdi(CCR0, Rnew_val, 0); |
3044 cmpdi(CCR0, Rnew_val, 0); |
3043 asm_assert_ne("null oop not allowed", 0x321); |
3045 asm_assert_ne("null oop not allowed", 0x321); |
3044 #endif |
3046 #endif |
3045 card_table_write(bs->byte_map_base, Rtmp, Rstore_addr); |
3047 card_table_write(ct->byte_map_base(), Rtmp, Rstore_addr); |
3046 } |
3048 } |
3047 |
3049 |
3048 // Write the card table byte. |
3050 // Write the card table byte. |
3049 void MacroAssembler::card_table_write(jbyte* byte_map_base, Register Rtmp, Register Robj) { |
3051 void MacroAssembler::card_table_write(jbyte* byte_map_base, Register Rtmp, Register Robj) { |
3050 assert_different_registers(Robj, Rtmp, R0); |
3052 assert_different_registers(Robj, Rtmp, R0); |
3051 load_const_optimized(Rtmp, (address)byte_map_base, R0); |
3053 load_const_optimized(Rtmp, (address)byte_map_base, R0); |
3052 srdi(Robj, Robj, CardTableModRefBS::card_shift); |
3054 srdi(Robj, Robj, CardTable::card_shift); |
3053 li(R0, 0); // dirty |
3055 li(R0, 0); // dirty |
3054 if (UseConcMarkSweepGC) membar(Assembler::StoreStore); |
3056 if (UseConcMarkSweepGC) membar(Assembler::StoreStore); |
3055 stbx(R0, Rtmp, Robj); |
3057 stbx(R0, Rtmp, Robj); |
3056 } |
3058 } |
3057 |
3059 |
3169 Label& filtered = (filtered_ext != NULL) ? *filtered_ext : filtered_int; |
3171 Label& filtered = (filtered_ext != NULL) ? *filtered_ext : filtered_int; |
3170 assert_different_registers(Rstore_addr, Rnew_val, Rtmp1, Rtmp2); |
3172 assert_different_registers(Rstore_addr, Rnew_val, Rtmp1, Rtmp2); |
3171 |
3173 |
3172 G1SATBCardTableLoggingModRefBS* bs = |
3174 G1SATBCardTableLoggingModRefBS* bs = |
3173 barrier_set_cast<G1SATBCardTableLoggingModRefBS>(Universe::heap()->barrier_set()); |
3175 barrier_set_cast<G1SATBCardTableLoggingModRefBS>(Universe::heap()->barrier_set()); |
|
3176 CardTable* ct = bs->card_table(); |
3174 |
3177 |
3175 // Does store cross heap regions? |
3178 // Does store cross heap regions? |
3176 if (G1RSBarrierRegionFilter) { |
3179 if (G1RSBarrierRegionFilter) { |
3177 xorr(Rtmp1, Rstore_addr, Rnew_val); |
3180 xorr(Rtmp1, Rstore_addr, Rnew_val); |
3178 srdi_(Rtmp1, Rtmp1, HeapRegion::LogOfHRGrainBytes); |
3181 srdi_(Rtmp1, Rtmp1, HeapRegion::LogOfHRGrainBytes); |
3185 asm_assert_ne("null oop not allowed (G1)", 0x322); // Checked by caller on PPC64, so following branch is obsolete: |
3188 asm_assert_ne("null oop not allowed (G1)", 0x322); // Checked by caller on PPC64, so following branch is obsolete: |
3186 //beq(CCR0, filtered); |
3189 //beq(CCR0, filtered); |
3187 #endif |
3190 #endif |
3188 |
3191 |
3189 // Storing region crossing non-NULL, is card already dirty? |
3192 // Storing region crossing non-NULL, is card already dirty? |
3190 assert(sizeof(*bs->byte_map_base) == sizeof(jbyte), "adjust this code"); |
3193 assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code"); |
3191 const Register Rcard_addr = Rtmp1; |
3194 const Register Rcard_addr = Rtmp1; |
3192 Register Rbase = Rtmp2; |
3195 Register Rbase = Rtmp2; |
3193 load_const_optimized(Rbase, (address)bs->byte_map_base, /*temp*/ Rtmp3); |
3196 load_const_optimized(Rbase, (address)ct->byte_map_base(), /*temp*/ Rtmp3); |
3194 |
3197 |
3195 srdi(Rcard_addr, Rstore_addr, CardTableModRefBS::card_shift); |
3198 srdi(Rcard_addr, Rstore_addr, CardTable::card_shift); |
3196 |
3199 |
3197 // Get the address of the card. |
3200 // Get the address of the card. |
3198 lbzx(/*card value*/ Rtmp3, Rbase, Rcard_addr); |
3201 lbzx(/*card value*/ Rtmp3, Rbase, Rcard_addr); |
3199 cmpwi(CCR0, Rtmp3, (int)G1SATBCardTableModRefBS::g1_young_card_val()); |
3202 cmpwi(CCR0, Rtmp3, (int)G1CardTable::g1_young_card_val()); |
3200 beq(CCR0, filtered); |
3203 beq(CCR0, filtered); |
3201 |
3204 |
3202 membar(Assembler::StoreLoad); |
3205 membar(Assembler::StoreLoad); |
3203 lbzx(/*card value*/ Rtmp3, Rbase, Rcard_addr); // Reload after membar. |
3206 lbzx(/*card value*/ Rtmp3, Rbase, Rcard_addr); // Reload after membar. |
3204 cmpwi(CCR0, Rtmp3 /* card value */, CardTableModRefBS::dirty_card_val()); |
3207 cmpwi(CCR0, Rtmp3 /* card value */, CardTable::dirty_card_val()); |
3205 beq(CCR0, filtered); |
3208 beq(CCR0, filtered); |
3206 |
3209 |
3207 // Storing a region crossing, non-NULL oop, card is clean. |
3210 // Storing a region crossing, non-NULL oop, card is clean. |
3208 // Dirty card and log. |
3211 // Dirty card and log. |
3209 li(Rtmp3, CardTableModRefBS::dirty_card_val()); |
3212 li(Rtmp3, CardTable::dirty_card_val()); |
3210 //release(); // G1: oops are allowed to get visible after dirty marking. |
3213 //release(); // G1: oops are allowed to get visible after dirty marking. |
3211 stbx(Rtmp3, Rbase, Rcard_addr); |
3214 stbx(Rtmp3, Rbase, Rcard_addr); |
3212 |
3215 |
3213 add(Rcard_addr, Rbase, Rcard_addr); // This is the address which needs to get enqueued. |
3216 add(Rcard_addr, Rbase, Rcard_addr); // This is the address which needs to get enqueued. |
3214 Rbase = noreg; // end of lifetime |
3217 Rbase = noreg; // end of lifetime |