1.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Sep 04 18:40:43 2008 -0700 1.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Sep 17 16:49:18 2008 +0400 1.3 @@ -115,6 +115,69 @@ 1.4 1.5 1.6 // Miscelaneous helper routines 1.7 +// Store an oop (or NULL) at the address described by obj. 1.8 +// If val == noreg this means store a NULL 1.9 + 1.10 +static void do_oop_store(InterpreterMacroAssembler* _masm, 1.11 + Address obj, 1.12 + Register val, 1.13 + BarrierSet::Name barrier, 1.14 + bool precise) { 1.15 + assert(val == noreg || val == rax, "parameter is just for looks"); 1.16 + switch (barrier) { 1.17 +#ifndef SERIALGC 1.18 + case BarrierSet::G1SATBCT: 1.19 + case BarrierSet::G1SATBCTLogging: 1.20 + { 1.21 + // flatten object address if needed 1.22 + if (obj.index() == noreg && obj.disp() == 0) { 1.23 + if (obj.base() != rdx) { 1.24 + __ movq(rdx, obj.base()); 1.25 + } 1.26 + } else { 1.27 + __ leaq(rdx, obj); 1.28 + } 1.29 + __ g1_write_barrier_pre(rdx, r8, rbx, val != noreg); 1.30 + if (val == noreg) { 1.31 + __ store_heap_oop(Address(rdx, 0), NULL_WORD); 1.32 + } else { 1.33 + __ store_heap_oop(Address(rdx, 0), val); 1.34 + __ g1_write_barrier_post(rdx, val, r8, rbx); 1.35 + } 1.36 + 1.37 + } 1.38 + break; 1.39 +#endif // SERIALGC 1.40 + case BarrierSet::CardTableModRef: 1.41 + case BarrierSet::CardTableExtension: 1.42 + { 1.43 + if (val == noreg) { 1.44 + __ store_heap_oop(obj, NULL_WORD); 1.45 + } else { 1.46 + __ store_heap_oop(obj, val); 1.47 + // flatten object address if needed 1.48 + if (!precise || (obj.index() == noreg && obj.disp() == 0)) { 1.49 + __ store_check(obj.base()); 1.50 + } else { 1.51 + __ leaq(rdx, obj); 1.52 + __ store_check(rdx); 1.53 + } 1.54 + } 1.55 + } 1.56 + break; 1.57 + case BarrierSet::ModRef: 1.58 + case BarrierSet::Other: 1.59 + if (val == noreg) { 1.60 + __ store_heap_oop(obj, NULL_WORD); 1.61 + } else { 1.62 + __ store_heap_oop(obj, val); 1.63 + } 1.64 + break; 1.65 + default : 1.66 + ShouldNotReachHere(); 1.67 + 1.68 + } 1.69 +} 1.70 1.71 Address TemplateTable::at_bcp(int offset) { 1.72 assert(_desc->uses_bcp(), "inconsistent uses_bcp information"); 1.73 @@ -560,8 +623,8 @@ 1.74 // rdx: array 1.75 index_check(rdx, rax); // kills rbx 1.76 __ load_heap_oop(rax, Address(rdx, rax, 1.77 - UseCompressedOops ? Address::times_4 : Address::times_8, 1.78 - arrayOopDesc::base_offset_in_bytes(T_OBJECT))); 1.79 + UseCompressedOops ? Address::times_4 : Address::times_8, 1.80 + arrayOopDesc::base_offset_in_bytes(T_OBJECT))); 1.81 } 1.82 1.83 void TemplateTable::baload() { 1.84 @@ -866,6 +929,11 @@ 1.85 __ movptr(rax, at_tos()); // value 1.86 __ movl(rcx, at_tos_p1()); // index 1.87 __ movptr(rdx, at_tos_p2()); // array 1.88 + 1.89 + Address element_address(rdx, rcx, 1.90 + UseCompressedOops? Address::times_4 : Address::times_8, 1.91 + arrayOopDesc::base_offset_in_bytes(T_OBJECT)); 1.92 + 1.93 index_check(rdx, rcx); // kills rbx 1.94 // do array store check - check for NULL value first 1.95 __ testptr(rax, rax); 1.96 @@ -879,9 +947,7 @@ 1.97 sizeof(oopDesc) + 1.98 objArrayKlass::element_klass_offset_in_bytes())); 1.99 // Compress array + index*oopSize + 12 into a single register. Frees rcx. 1.100 - __ lea(rdx, Address(rdx, rcx, 1.101 - UseCompressedOops ? Address::times_4 : Address::times_8, 1.102 - arrayOopDesc::base_offset_in_bytes(T_OBJECT))); 1.103 + __ lea(rdx, element_address); 1.104 1.105 // Generate subtype check. Blows rcx, rdi 1.106 // Superklass in rax. Subklass in rbx. 1.107 @@ -893,18 +959,19 @@ 1.108 1.109 // Come here on success 1.110 __ bind(ok_is_subtype); 1.111 - __ movptr(rax, at_tos()); // Value 1.112 - __ store_heap_oop(Address(rdx, 0), rax); 1.113 - __ store_check(rdx); 1.114 + 1.115 + // Get the value we will store 1.116 + __ movptr(rax, at_tos()); 1.117 + // Now store using the appropriate barrier 1.118 + do_oop_store(_masm, Address(rdx, 0), rax, _bs->kind(), true); 1.119 __ jmp(done); 1.120 1.121 // Have a NULL in rax, rdx=array, ecx=index. Store NULL at ary[idx] 1.122 __ bind(is_null); 1.123 __ profile_null_seen(rbx); 1.124 - __ store_heap_oop(Address(rdx, rcx, 1.125 - UseCompressedOops ? Address::times_4 : Address::times_8, 1.126 - arrayOopDesc::base_offset_in_bytes(T_OBJECT)), 1.127 - rax); 1.128 + 1.129 + // Store a NULL 1.130 + do_oop_store(_masm, element_address, noreg, _bs->kind(), true); 1.131 1.132 // Pop stack arguments 1.133 __ bind(done); 1.134 @@ -2396,8 +2463,10 @@ 1.135 // atos 1.136 __ pop(atos); 1.137 if (!is_static) pop_and_check_object(obj); 1.138 - __ store_heap_oop(field, rax); 1.139 - __ store_check(obj, field); // Need to mark card 1.140 + 1.141 + // Store into the field 1.142 + do_oop_store(_masm, field, rax, _bs->kind(), false); 1.143 + 1.144 if (!is_static) { 1.145 patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx); 1.146 } 1.147 @@ -2584,8 +2653,7 @@ 1.148 // access field 1.149 switch (bytecode()) { 1.150 case Bytecodes::_fast_aputfield: 1.151 - __ store_heap_oop(field, rax); 1.152 - __ store_check(rcx, field); 1.153 + do_oop_store(_masm, field, rax, _bs->kind(), false); 1.154 break; 1.155 case Bytecodes::_fast_lputfield: 1.156 __ movq(field, rax); 1.157 @@ -3044,8 +3112,6 @@ 1.158 Label initialize_header; 1.159 Label initialize_object; // including clearing the fields 1.160 Label allocate_shared; 1.161 - ExternalAddress top((address)Universe::heap()->top_addr()); 1.162 - ExternalAddress end((address)Universe::heap()->end_addr()); 1.163 1.164 __ get_cpool_and_tags(rsi, rax); 1.165 // get instanceKlass 1.166 @@ -3106,6 +3172,9 @@ 1.167 if (allow_shared_alloc) { 1.168 __ bind(allocate_shared); 1.169 1.170 + ExternalAddress top((address)Universe::heap()->top_addr()); 1.171 + ExternalAddress end((address)Universe::heap()->end_addr()); 1.172 + 1.173 const Register RtopAddr = rscratch1; 1.174 const Register RendAddr = rscratch2; 1.175