1.1 --- a/src/cpu/sparc/vm/assembler_sparc.cpp Tue Apr 05 19:14:03 2011 -0700 1.2 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp Thu Apr 07 09:53:20 2011 -0700 1.3 @@ -4257,34 +4257,14 @@ 1.4 /////////////////////////////////////////////////////////////////////////////////// 1.5 #ifndef SERIALGC 1.6 1.7 -static uint num_stores = 0; 1.8 -static uint num_null_pre_stores = 0; 1.9 - 1.10 -static void count_null_pre_vals(void* pre_val) { 1.11 - num_stores++; 1.12 - if (pre_val == NULL) num_null_pre_stores++; 1.13 - if ((num_stores % 1000000) == 0) { 1.14 - tty->print_cr(UINT32_FORMAT " stores, " UINT32_FORMAT " (%5.2f%%) with null pre-vals.", 1.15 - num_stores, num_null_pre_stores, 1.16 - 100.0*(float)num_null_pre_stores/(float)num_stores); 1.17 - } 1.18 -} 1.19 - 1.20 -static address satb_log_enqueue_with_frame = 0; 1.21 -static u_char* satb_log_enqueue_with_frame_end = 0; 1.22 - 1.23 -static address satb_log_enqueue_frameless = 0; 1.24 -static u_char* satb_log_enqueue_frameless_end = 0; 1.25 +static address satb_log_enqueue_with_frame = NULL; 1.26 +static u_char* satb_log_enqueue_with_frame_end = NULL; 1.27 + 1.28 +static address satb_log_enqueue_frameless = NULL; 1.29 +static u_char* satb_log_enqueue_frameless_end = NULL; 1.30 1.31 static int EnqueueCodeSize = 128 DEBUG_ONLY( + 256); // Instructions? 1.32 1.33 -// The calls to this don't work. We'd need to do a fair amount of work to 1.34 -// make it work. 1.35 -static void check_index(int ind) { 1.36 - assert(0 <= ind && ind <= 64*K && ((ind % oopSize) == 0), 1.37 - "Invariants."); 1.38 -} 1.39 - 1.40 static void generate_satb_log_enqueue(bool with_frame) { 1.41 BufferBlob* bb = BufferBlob::create("enqueue_with_frame", EnqueueCodeSize); 1.42 CodeBuffer buf(bb); 1.43 @@ -4388,13 +4368,27 @@ 1.44 } 1.45 } 1.46 1.47 -void MacroAssembler::g1_write_barrier_pre(Register obj, Register index, int offset, Register tmp, bool preserve_o_regs) { 1.48 - assert(offset == 0 || index == noreg, "choose one"); 1.49 - 1.50 - if (G1DisablePreBarrier) return; 1.51 - // satb_log_barrier(tmp, obj, offset, preserve_o_regs); 1.52 +void MacroAssembler::g1_write_barrier_pre(Register obj, 1.53 + Register index, 1.54 + int offset, 1.55 + Register pre_val, 1.56 + Register tmp, 1.57 + bool preserve_o_regs) { 1.58 Label filtered; 1.59 - // satb_log_barrier_work0(tmp, filtered); 1.60 + 1.61 + if (obj == noreg) { 1.62 + // We are not loading the previous value so make 1.63 + // sure that we don't trash the value in pre_val 1.64 + // with the code below. 1.65 + assert_different_registers(pre_val, tmp); 1.66 + } else { 1.67 + // We will be loading the previous value 1.68 + // in this code so... 1.69 + assert(offset == 0 || index == noreg, "choose one"); 1.70 + assert(pre_val == noreg, "check this code"); 1.71 + } 1.72 + 1.73 + // Is marking active? 1.74 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { 1.75 ld(G2, 1.76 in_bytes(JavaThread::satb_mark_queue_offset() + 1.77 @@ -4413,61 +4407,46 @@ 1.78 br_on_reg_cond(rc_z, /*annul*/false, Assembler::pt, tmp, filtered); 1.79 delayed() -> nop(); 1.80 1.81 - // satb_log_barrier_work1(tmp, offset); 1.82 - if (index == noreg) { 1.83 - if (Assembler::is_simm13(offset)) { 1.84 - load_heap_oop(obj, offset, tmp); 1.85 + // Do we need to load the previous value? 1.86 + if (obj != noreg) { 1.87 + // Load the previous value... 1.88 + if (index == noreg) { 1.89 + if (Assembler::is_simm13(offset)) { 1.90 + load_heap_oop(obj, offset, tmp); 1.91 + } else { 1.92 + set(offset, tmp); 1.93 + load_heap_oop(obj, tmp, tmp); 1.94 + } 1.95 } else { 1.96 - set(offset, tmp); 1.97 - load_heap_oop(obj, tmp, tmp); 1.98 + load_heap_oop(obj, index, tmp); 1.99 } 1.100 - } else { 1.101 - load_heap_oop(obj, index, tmp); 1.102 + // Previous value has been loaded into tmp 1.103 + pre_val = tmp; 1.104 } 1.105 1.106 - // satb_log_barrier_work2(obj, tmp, offset); 1.107 - 1.108 - // satb_log_barrier_work3(tmp, filtered, preserve_o_regs); 1.109 - 1.110 - const Register pre_val = tmp; 1.111 - 1.112 - if (G1SATBBarrierPrintNullPreVals) { 1.113 - save_frame(0); 1.114 - mov(pre_val, O0); 1.115 - // Save G-regs that target may use. 1.116 - mov(G1, L1); 1.117 - mov(G2, L2); 1.118 - mov(G3, L3); 1.119 - mov(G4, L4); 1.120 - mov(G5, L5); 1.121 - call(CAST_FROM_FN_PTR(address, &count_null_pre_vals)); 1.122 - delayed()->nop(); 1.123 - // Restore G-regs that target may have used. 1.124 - mov(L1, G1); 1.125 - mov(L2, G2); 1.126 - mov(L3, G3); 1.127 - mov(L4, G4); 1.128 - mov(L5, G5); 1.129 - restore(G0, G0, G0); 1.130 - } 1.131 - 1.132 + assert(pre_val != noreg, "must have a real register"); 1.133 + 1.134 + // Is the previous value null? 1.135 // Check on whether to annul. 1.136 br_on_reg_cond(rc_z, /*annul*/false, Assembler::pt, pre_val, filtered); 1.137 delayed() -> nop(); 1.138 1.139 // OK, it's not filtered, so we'll need to call enqueue. In the normal 1.140 - // case, pre_val will be a scratch G-reg, but there's some cases in which 1.141 - // it's an O-reg. In the first case, do a normal call. In the latter, 1.142 - // do a save here and call the frameless version. 1.143 + // case, pre_val will be a scratch G-reg, but there are some cases in 1.144 + // which it's an O-reg. In the first case, do a normal call. In the 1.145 + // latter, do a save here and call the frameless version. 1.146 1.147 guarantee(pre_val->is_global() || pre_val->is_out(), 1.148 "Or we need to think harder."); 1.149 + 1.150 if (pre_val->is_global() && !preserve_o_regs) { 1.151 - generate_satb_log_enqueue_if_necessary(true); // with frame. 1.152 + generate_satb_log_enqueue_if_necessary(true); // with frame 1.153 + 1.154 call(satb_log_enqueue_with_frame); 1.155 delayed()->mov(pre_val, O0); 1.156 } else { 1.157 - generate_satb_log_enqueue_if_necessary(false); // with frameless. 1.158 + generate_satb_log_enqueue_if_necessary(false); // frameless 1.159 + 1.160 save_frame(0); 1.161 call(satb_log_enqueue_frameless); 1.162 delayed()->mov(pre_val->after_save(), O0); 1.163 @@ -4614,7 +4593,6 @@ 1.164 MacroAssembler* post_filter_masm = this; 1.165 1.166 if (new_val == G0) return; 1.167 - if (G1DisablePostBarrier) return; 1.168 1.169 G1SATBCardTableModRefBS* bs = (G1SATBCardTableModRefBS*) Universe::heap()->barrier_set(); 1.170 assert(bs->kind() == BarrierSet::G1SATBCT || 1.171 @@ -4626,6 +4604,7 @@ 1.172 #else 1.173 srl(tmp, HeapRegion::LogOfHRGrainBytes, tmp); 1.174 #endif 1.175 + 1.176 if (G1PrintCTFilterStats) { 1.177 guarantee(tmp->is_global(), "Or stats won't work..."); 1.178 // This is a sleazy hack: I'm temporarily hijacking G2, which I