Mercurial > hg > graal-jvmci-8
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); |