1.1 --- a/src/cpu/x86/vm/assembler_x86.cpp Thu Sep 04 18:40:43 2008 -0700 1.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp Wed Sep 17 16:49:18 2008 +0400 1.3 @@ -5935,26 +5935,30 @@ 1.4 Label& slow_case) { 1.5 assert(obj == rax, "obj must be in rax, for cmpxchg"); 1.6 assert_different_registers(obj, var_size_in_bytes, t1); 1.7 - Register end = t1; 1.8 - Label retry; 1.9 - bind(retry); 1.10 - ExternalAddress heap_top((address) Universe::heap()->top_addr()); 1.11 - movptr(obj, heap_top); 1.12 - if (var_size_in_bytes == noreg) { 1.13 - lea(end, Address(obj, con_size_in_bytes)); 1.14 + if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) { 1.15 + jmp(slow_case); 1.16 } else { 1.17 - lea(end, Address(obj, var_size_in_bytes, Address::times_1)); 1.18 - } 1.19 - // if end < obj then we wrapped around => object too long => slow case 1.20 - cmpptr(end, obj); 1.21 - jcc(Assembler::below, slow_case); 1.22 - cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr())); 1.23 - jcc(Assembler::above, slow_case); 1.24 - // Compare obj with the top addr, and if still equal, store the new top addr in 1.25 - // end at the address of the top addr pointer. Sets ZF if was equal, and clears 1.26 - // it otherwise. Use lock prefix for atomicity on MPs. 1.27 - locked_cmpxchgptr(end, heap_top); 1.28 - jcc(Assembler::notEqual, retry); 1.29 + Register end = t1; 1.30 + Label retry; 1.31 + bind(retry); 1.32 + ExternalAddress heap_top((address) Universe::heap()->top_addr()); 1.33 + movptr(obj, heap_top); 1.34 + if (var_size_in_bytes == noreg) { 1.35 + lea(end, Address(obj, con_size_in_bytes)); 1.36 + } else { 1.37 + lea(end, Address(obj, var_size_in_bytes, Address::times_1)); 1.38 + } 1.39 + // if end < obj then we wrapped around => object too long => slow case 1.40 + cmpptr(end, obj); 1.41 + jcc(Assembler::below, slow_case); 1.42 + cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr())); 1.43 + jcc(Assembler::above, slow_case); 1.44 + // Compare obj with the top addr, and if still equal, store the new top addr in 1.45 + // end at the address of the top addr pointer. Sets ZF if was equal, and clears 1.46 + // it otherwise. Use lock prefix for atomicity on MPs. 1.47 + locked_cmpxchgptr(end, heap_top); 1.48 + jcc(Assembler::notEqual, retry); 1.49 + } 1.50 } 1.51 1.52 void MacroAssembler::enter() { 1.53 @@ -6491,6 +6495,179 @@ 1.54 } 1.55 } 1.56 1.57 +////////////////////////////////////////////////////////////////////////////////// 1.58 +#ifndef SERIALGC 1.59 + 1.60 +void MacroAssembler::g1_write_barrier_pre(Register obj, 1.61 +#ifndef _LP64 1.62 + Register thread, 1.63 +#endif 1.64 + Register tmp, 1.65 + Register tmp2, 1.66 + bool tosca_live) { 1.67 + LP64_ONLY(Register thread = r15_thread;) 1.68 + Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() + 1.69 + PtrQueue::byte_offset_of_active())); 1.70 + 1.71 + Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() + 1.72 + PtrQueue::byte_offset_of_index())); 1.73 + Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() + 1.74 + PtrQueue::byte_offset_of_buf())); 1.75 + 1.76 + 1.77 + Label done; 1.78 + Label runtime; 1.79 + 1.80 + // if (!marking_in_progress) goto done; 1.81 + if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { 1.82 + cmpl(in_progress, 0); 1.83 + } else { 1.84 + assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption"); 1.85 + cmpb(in_progress, 0); 1.86 + } 1.87 + jcc(Assembler::equal, done); 1.88 + 1.89 + // if (x.f == NULL) goto done; 1.90 + cmpptr(Address(obj, 0), NULL_WORD); 1.91 + jcc(Assembler::equal, done); 1.92 + 1.93 + // Can we store original value in the thread's buffer? 1.94 + 1.95 + LP64_ONLY(movslq(tmp, index);) 1.96 + movptr(tmp2, Address(obj, 0)); 1.97 +#ifdef _LP64 1.98 + cmpq(tmp, 0); 1.99 +#else 1.100 + cmpl(index, 0); 1.101 +#endif 1.102 + jcc(Assembler::equal, runtime); 1.103 +#ifdef _LP64 1.104 + subq(tmp, wordSize); 1.105 + movl(index, tmp); 1.106 + addq(tmp, buffer); 1.107 +#else 1.108 + subl(index, wordSize); 1.109 + movl(tmp, buffer); 1.110 + addl(tmp, index); 1.111 +#endif 1.112 + movptr(Address(tmp, 0), tmp2); 1.113 + jmp(done); 1.114 + bind(runtime); 1.115 + // save the live input values 1.116 + if(tosca_live) push(rax); 1.117 + push(obj); 1.118 +#ifdef _LP64 1.119 + movq(c_rarg0, Address(obj, 0)); 1.120 + call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), c_rarg0, r15_thread); 1.121 +#else 1.122 + push(thread); 1.123 + call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), tmp2, thread); 1.124 + pop(thread); 1.125 +#endif 1.126 + pop(obj); 1.127 + if(tosca_live) pop(rax); 1.128 + bind(done); 1.129 + 1.130 +} 1.131 + 1.132 +void MacroAssembler::g1_write_barrier_post(Register store_addr, 1.133 + Register new_val, 1.134 +#ifndef _LP64 1.135 + Register thread, 1.136 +#endif 1.137 + Register tmp, 1.138 + Register tmp2) { 1.139 + 1.140 + LP64_ONLY(Register thread = r15_thread;) 1.141 + Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() + 1.142 + PtrQueue::byte_offset_of_index())); 1.143 + Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() + 1.144 + PtrQueue::byte_offset_of_buf())); 1.145 + BarrierSet* bs = Universe::heap()->barrier_set(); 1.146 + CardTableModRefBS* ct = (CardTableModRefBS*)bs; 1.147 + Label done; 1.148 + Label runtime; 1.149 + 1.150 + // Does store cross heap regions? 1.151 + 1.152 + movptr(tmp, store_addr); 1.153 + xorptr(tmp, new_val); 1.154 + shrptr(tmp, HeapRegion::LogOfHRGrainBytes); 1.155 + jcc(Assembler::equal, done); 1.156 + 1.157 + // crosses regions, storing NULL? 1.158 + 1.159 + cmpptr(new_val, (int32_t) NULL_WORD); 1.160 + jcc(Assembler::equal, done); 1.161 + 1.162 + // storing region crossing non-NULL, is card already dirty? 1.163 + 1.164 + ExternalAddress cardtable((address) ct->byte_map_base); 1.165 + assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); 1.166 +#ifdef _LP64 1.167 + const Register card_addr = tmp; 1.168 + 1.169 + movq(card_addr, store_addr); 1.170 + shrq(card_addr, CardTableModRefBS::card_shift); 1.171 + 1.172 + lea(tmp2, cardtable); 1.173 + 1.174 + // get the address of the card 1.175 + addq(card_addr, tmp2); 1.176 +#else 1.177 + const Register card_index = tmp; 1.178 + 1.179 + movl(card_index, store_addr); 1.180 + shrl(card_index, CardTableModRefBS::card_shift); 1.181 + 1.182 + Address index(noreg, card_index, Address::times_1); 1.183 + const Register card_addr = tmp; 1.184 + lea(card_addr, as_Address(ArrayAddress(cardtable, index))); 1.185 +#endif 1.186 + cmpb(Address(card_addr, 0), 0); 1.187 + jcc(Assembler::equal, done); 1.188 + 1.189 + // storing a region crossing, non-NULL oop, card is clean. 1.190 + // dirty card and log. 1.191 + 1.192 + movb(Address(card_addr, 0), 0); 1.193 + 1.194 + cmpl(queue_index, 0); 1.195 + jcc(Assembler::equal, runtime); 1.196 + subl(queue_index, wordSize); 1.197 + movptr(tmp2, buffer); 1.198 +#ifdef _LP64 1.199 + movslq(rscratch1, queue_index); 1.200 + addq(tmp2, rscratch1); 1.201 + movq(Address(tmp2, 0), card_addr); 1.202 +#else 1.203 + addl(tmp2, queue_index); 1.204 + movl(Address(tmp2, 0), card_index); 1.205 +#endif 1.206 + jmp(done); 1.207 + 1.208 + bind(runtime); 1.209 + // save the live input values 1.210 + push(store_addr); 1.211 + push(new_val); 1.212 +#ifdef _LP64 1.213 + call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, r15_thread); 1.214 +#else 1.215 + push(thread); 1.216 + call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread); 1.217 + pop(thread); 1.218 +#endif 1.219 + pop(new_val); 1.220 + pop(store_addr); 1.221 + 1.222 + bind(done); 1.223 + 1.224 +} 1.225 + 1.226 +#endif // SERIALGC 1.227 +////////////////////////////////////////////////////////////////////////////////// 1.228 + 1.229 + 1.230 void MacroAssembler::store_check(Register obj) { 1.231 // Does a store check for the oop in register obj. The content of 1.232 // register obj is destroyed afterwards.