comparison src/cpu/x86/vm/templateTable_x86_64.cpp @ 362:f8199438385b

Merge
author apetrusenko
date Wed, 17 Sep 2008 16:49:18 +0400
parents dc7f315e41f7 1ee8caae33af
children 98cb887364d3
comparison
equal deleted inserted replaced
316:5fa96a5a7e76 362:f8199438385b
113 return Assembler::zero; 113 return Assembler::zero;
114 } 114 }
115 115
116 116
117 // Miscelaneous helper routines 117 // Miscelaneous helper routines
118 // Store an oop (or NULL) at the address described by obj.
119 // If val == noreg this means store a NULL
120
121 static void do_oop_store(InterpreterMacroAssembler* _masm,
122 Address obj,
123 Register val,
124 BarrierSet::Name barrier,
125 bool precise) {
126 assert(val == noreg || val == rax, "parameter is just for looks");
127 switch (barrier) {
128 #ifndef SERIALGC
129 case BarrierSet::G1SATBCT:
130 case BarrierSet::G1SATBCTLogging:
131 {
132 // flatten object address if needed
133 if (obj.index() == noreg && obj.disp() == 0) {
134 if (obj.base() != rdx) {
135 __ movq(rdx, obj.base());
136 }
137 } else {
138 __ leaq(rdx, obj);
139 }
140 __ g1_write_barrier_pre(rdx, r8, rbx, val != noreg);
141 if (val == noreg) {
142 __ store_heap_oop(Address(rdx, 0), NULL_WORD);
143 } else {
144 __ store_heap_oop(Address(rdx, 0), val);
145 __ g1_write_barrier_post(rdx, val, r8, rbx);
146 }
147
148 }
149 break;
150 #endif // SERIALGC
151 case BarrierSet::CardTableModRef:
152 case BarrierSet::CardTableExtension:
153 {
154 if (val == noreg) {
155 __ store_heap_oop(obj, NULL_WORD);
156 } else {
157 __ store_heap_oop(obj, val);
158 // flatten object address if needed
159 if (!precise || (obj.index() == noreg && obj.disp() == 0)) {
160 __ store_check(obj.base());
161 } else {
162 __ leaq(rdx, obj);
163 __ store_check(rdx);
164 }
165 }
166 }
167 break;
168 case BarrierSet::ModRef:
169 case BarrierSet::Other:
170 if (val == noreg) {
171 __ store_heap_oop(obj, NULL_WORD);
172 } else {
173 __ store_heap_oop(obj, val);
174 }
175 break;
176 default :
177 ShouldNotReachHere();
178
179 }
180 }
118 181
119 Address TemplateTable::at_bcp(int offset) { 182 Address TemplateTable::at_bcp(int offset) {
120 assert(_desc->uses_bcp(), "inconsistent uses_bcp information"); 183 assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
121 return Address(r13, offset); 184 return Address(r13, offset);
122 } 185 }
558 __ pop_ptr(rdx); 621 __ pop_ptr(rdx);
559 // eax: index 622 // eax: index
560 // rdx: array 623 // rdx: array
561 index_check(rdx, rax); // kills rbx 624 index_check(rdx, rax); // kills rbx
562 __ load_heap_oop(rax, Address(rdx, rax, 625 __ load_heap_oop(rax, Address(rdx, rax,
563 UseCompressedOops ? Address::times_4 : Address::times_8, 626 UseCompressedOops ? Address::times_4 : Address::times_8,
564 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); 627 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
565 } 628 }
566 629
567 void TemplateTable::baload() { 630 void TemplateTable::baload() {
568 transition(itos, itos); 631 transition(itos, itos);
569 __ pop_ptr(rdx); 632 __ pop_ptr(rdx);
864 transition(vtos, vtos); 927 transition(vtos, vtos);
865 // stack: ..., array, index, value 928 // stack: ..., array, index, value
866 __ movptr(rax, at_tos()); // value 929 __ movptr(rax, at_tos()); // value
867 __ movl(rcx, at_tos_p1()); // index 930 __ movl(rcx, at_tos_p1()); // index
868 __ movptr(rdx, at_tos_p2()); // array 931 __ movptr(rdx, at_tos_p2()); // array
932
933 Address element_address(rdx, rcx,
934 UseCompressedOops? Address::times_4 : Address::times_8,
935 arrayOopDesc::base_offset_in_bytes(T_OBJECT));
936
869 index_check(rdx, rcx); // kills rbx 937 index_check(rdx, rcx); // kills rbx
870 // do array store check - check for NULL value first 938 // do array store check - check for NULL value first
871 __ testptr(rax, rax); 939 __ testptr(rax, rax);
872 __ jcc(Assembler::zero, is_null); 940 __ jcc(Assembler::zero, is_null);
873 941
877 __ load_klass(rax, rdx); 945 __ load_klass(rax, rdx);
878 __ movptr(rax, Address(rax, 946 __ movptr(rax, Address(rax,
879 sizeof(oopDesc) + 947 sizeof(oopDesc) +
880 objArrayKlass::element_klass_offset_in_bytes())); 948 objArrayKlass::element_klass_offset_in_bytes()));
881 // Compress array + index*oopSize + 12 into a single register. Frees rcx. 949 // Compress array + index*oopSize + 12 into a single register. Frees rcx.
882 __ lea(rdx, Address(rdx, rcx, 950 __ lea(rdx, element_address);
883 UseCompressedOops ? Address::times_4 : Address::times_8,
884 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
885 951
886 // Generate subtype check. Blows rcx, rdi 952 // Generate subtype check. Blows rcx, rdi
887 // Superklass in rax. Subklass in rbx. 953 // Superklass in rax. Subklass in rbx.
888 __ gen_subtype_check(rbx, ok_is_subtype); 954 __ gen_subtype_check(rbx, ok_is_subtype);
889 955
891 // object is at TOS 957 // object is at TOS
892 __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry)); 958 __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry));
893 959
894 // Come here on success 960 // Come here on success
895 __ bind(ok_is_subtype); 961 __ bind(ok_is_subtype);
896 __ movptr(rax, at_tos()); // Value 962
897 __ store_heap_oop(Address(rdx, 0), rax); 963 // Get the value we will store
898 __ store_check(rdx); 964 __ movptr(rax, at_tos());
965 // Now store using the appropriate barrier
966 do_oop_store(_masm, Address(rdx, 0), rax, _bs->kind(), true);
899 __ jmp(done); 967 __ jmp(done);
900 968
901 // Have a NULL in rax, rdx=array, ecx=index. Store NULL at ary[idx] 969 // Have a NULL in rax, rdx=array, ecx=index. Store NULL at ary[idx]
902 __ bind(is_null); 970 __ bind(is_null);
903 __ profile_null_seen(rbx); 971 __ profile_null_seen(rbx);
904 __ store_heap_oop(Address(rdx, rcx, 972
905 UseCompressedOops ? Address::times_4 : Address::times_8, 973 // Store a NULL
906 arrayOopDesc::base_offset_in_bytes(T_OBJECT)), 974 do_oop_store(_masm, element_address, noreg, _bs->kind(), true);
907 rax);
908 975
909 // Pop stack arguments 976 // Pop stack arguments
910 __ bind(done); 977 __ bind(done);
911 __ addptr(rsp, 3 * Interpreter::stackElementSize()); 978 __ addptr(rsp, 3 * Interpreter::stackElementSize());
912 } 979 }
2394 __ cmpl(flags, atos); 2461 __ cmpl(flags, atos);
2395 __ jcc(Assembler::notEqual, notObj); 2462 __ jcc(Assembler::notEqual, notObj);
2396 // atos 2463 // atos
2397 __ pop(atos); 2464 __ pop(atos);
2398 if (!is_static) pop_and_check_object(obj); 2465 if (!is_static) pop_and_check_object(obj);
2399 __ store_heap_oop(field, rax); 2466
2400 __ store_check(obj, field); // Need to mark card 2467 // Store into the field
2468 do_oop_store(_masm, field, rax, _bs->kind(), false);
2469
2401 if (!is_static) { 2470 if (!is_static) {
2402 patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx); 2471 patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx);
2403 } 2472 }
2404 __ jmp(Done); 2473 __ jmp(Done);
2405 2474
2582 const Address field(rcx, rbx, Address::times_1); 2651 const Address field(rcx, rbx, Address::times_1);
2583 2652
2584 // access field 2653 // access field
2585 switch (bytecode()) { 2654 switch (bytecode()) {
2586 case Bytecodes::_fast_aputfield: 2655 case Bytecodes::_fast_aputfield:
2587 __ store_heap_oop(field, rax); 2656 do_oop_store(_masm, field, rax, _bs->kind(), false);
2588 __ store_check(rcx, field);
2589 break; 2657 break;
2590 case Bytecodes::_fast_lputfield: 2658 case Bytecodes::_fast_lputfield:
2591 __ movq(field, rax); 2659 __ movq(field, rax);
2592 break; 2660 break;
2593 case Bytecodes::_fast_iputfield: 2661 case Bytecodes::_fast_iputfield:
3042 Label slow_case; 3110 Label slow_case;
3043 Label done; 3111 Label done;
3044 Label initialize_header; 3112 Label initialize_header;
3045 Label initialize_object; // including clearing the fields 3113 Label initialize_object; // including clearing the fields
3046 Label allocate_shared; 3114 Label allocate_shared;
3047 ExternalAddress top((address)Universe::heap()->top_addr());
3048 ExternalAddress end((address)Universe::heap()->end_addr());
3049 3115
3050 __ get_cpool_and_tags(rsi, rax); 3116 __ get_cpool_and_tags(rsi, rax);
3051 // get instanceKlass 3117 // get instanceKlass
3052 __ movptr(rsi, Address(rsi, rdx, 3118 __ movptr(rsi, Address(rsi, rdx,
3053 Address::times_8, sizeof(constantPoolOopDesc))); 3119 Address::times_8, sizeof(constantPoolOopDesc)));
3103 // Allocation in the shared Eden, if allowed. 3169 // Allocation in the shared Eden, if allowed.
3104 // 3170 //
3105 // rdx: instance size in bytes 3171 // rdx: instance size in bytes
3106 if (allow_shared_alloc) { 3172 if (allow_shared_alloc) {
3107 __ bind(allocate_shared); 3173 __ bind(allocate_shared);
3174
3175 ExternalAddress top((address)Universe::heap()->top_addr());
3176 ExternalAddress end((address)Universe::heap()->end_addr());
3108 3177
3109 const Register RtopAddr = rscratch1; 3178 const Register RtopAddr = rscratch1;
3110 const Register RendAddr = rscratch2; 3179 const Register RendAddr = rscratch2;
3111 3180
3112 __ lea(RtopAddr, top); 3181 __ lea(RtopAddr, top);