Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/templateTable_x86_64.cpp @ 342:37f87013dfd8
6711316: Open source the Garbage-First garbage collector
Summary: First mercurial integration of the code for the Garbage-First garbage collector.
Reviewed-by: apetrusenko, iveresov, jmasa, sgoldman, tonyp, ysr
author | ysr |
---|---|
date | Thu, 05 Jun 2008 15:57:56 -0700 |
parents | ba764ed4b6f2 |
children | 6aae2f9d0294 |
comparison
equal
deleted
inserted
replaced
189:0b27f3512f9e | 342:37f87013dfd8 |
---|---|
111 return Assembler::zero; | 111 return Assembler::zero; |
112 } | 112 } |
113 | 113 |
114 | 114 |
115 // Miscelaneous helper routines | 115 // Miscelaneous helper routines |
116 // Store an oop (or NULL) at the address described by obj. | |
117 // If val == noreg this means store a NULL | |
118 | |
119 static void do_oop_store(InterpreterMacroAssembler* _masm, | |
120 Address obj, | |
121 Register val, | |
122 BarrierSet::Name barrier, | |
123 bool precise) { | |
124 assert(val == noreg || val == rax, "parameter is just for looks"); | |
125 switch (barrier) { | |
126 #ifndef SERIALGC | |
127 case BarrierSet::G1SATBCT: | |
128 case BarrierSet::G1SATBCTLogging: | |
129 { | |
130 // flatten object address if needed | |
131 if (obj.index() == noreg && obj.disp() == 0) { | |
132 if (obj.base() != rdx) { | |
133 __ movq(rdx, obj.base()); | |
134 } | |
135 } else { | |
136 __ leaq(rdx, obj); | |
137 } | |
138 __ g1_write_barrier_pre(rdx, r8, rbx, val != noreg); | |
139 if (val == noreg) { | |
140 __ store_heap_oop(Address(rdx, 0), NULL_WORD); | |
141 } else { | |
142 __ store_heap_oop(Address(rdx, 0), val); | |
143 __ g1_write_barrier_post(rdx, val, r8, rbx); | |
144 } | |
145 | |
146 } | |
147 break; | |
148 #endif // SERIALGC | |
149 case BarrierSet::CardTableModRef: | |
150 case BarrierSet::CardTableExtension: | |
151 { | |
152 if (val == noreg) { | |
153 __ store_heap_oop(obj, NULL_WORD); | |
154 } else { | |
155 __ store_heap_oop(obj, val); | |
156 // flatten object address if needed | |
157 if (!precise || (obj.index() == noreg && obj.disp() == 0)) { | |
158 __ store_check(obj.base()); | |
159 } else { | |
160 __ leaq(rdx, obj); | |
161 __ store_check(rdx); | |
162 } | |
163 } | |
164 } | |
165 break; | |
166 case BarrierSet::ModRef: | |
167 case BarrierSet::Other: | |
168 if (val == noreg) { | |
169 __ store_heap_oop(obj, NULL_WORD); | |
170 } else { | |
171 __ store_heap_oop(obj, val); | |
172 } | |
173 break; | |
174 default : | |
175 ShouldNotReachHere(); | |
176 | |
177 } | |
178 } | |
116 | 179 |
117 Address TemplateTable::at_bcp(int offset) { | 180 Address TemplateTable::at_bcp(int offset) { |
118 assert(_desc->uses_bcp(), "inconsistent uses_bcp information"); | 181 assert(_desc->uses_bcp(), "inconsistent uses_bcp information"); |
119 return Address(r13, offset); | 182 return Address(r13, offset); |
120 } | 183 } |
556 __ pop_ptr(rdx); | 619 __ pop_ptr(rdx); |
557 // eax: index | 620 // eax: index |
558 // rdx: array | 621 // rdx: array |
559 index_check(rdx, rax); // kills rbx | 622 index_check(rdx, rax); // kills rbx |
560 __ load_heap_oop(rax, Address(rdx, rax, | 623 __ load_heap_oop(rax, Address(rdx, rax, |
561 UseCompressedOops ? Address::times_4 : Address::times_8, | 624 UseCompressedOops ? Address::times_4 : Address::times_8, |
562 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); | 625 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); |
563 } | 626 } |
564 | 627 |
565 void TemplateTable::baload() { | 628 void TemplateTable::baload() { |
566 transition(itos, itos); | 629 transition(itos, itos); |
567 __ pop_ptr(rdx); | 630 __ pop_ptr(rdx); |
862 transition(vtos, vtos); | 925 transition(vtos, vtos); |
863 // stack: ..., array, index, value | 926 // stack: ..., array, index, value |
864 __ movq(rax, at_tos()); // value | 927 __ movq(rax, at_tos()); // value |
865 __ movl(rcx, at_tos_p1()); // index | 928 __ movl(rcx, at_tos_p1()); // index |
866 __ movq(rdx, at_tos_p2()); // array | 929 __ movq(rdx, at_tos_p2()); // array |
930 | |
931 Address element_address(rdx, rcx, | |
932 UseCompressedOops? Address::times_4 : Address::times_8, | |
933 arrayOopDesc::base_offset_in_bytes(T_OBJECT)); | |
934 | |
867 index_check(rdx, rcx); // kills rbx | 935 index_check(rdx, rcx); // kills rbx |
868 // do array store check - check for NULL value first | 936 // do array store check - check for NULL value first |
869 __ testq(rax, rax); | 937 __ testq(rax, rax); |
870 __ jcc(Assembler::zero, is_null); | 938 __ jcc(Assembler::zero, is_null); |
871 | 939 |
875 __ load_klass(rax, rdx); | 943 __ load_klass(rax, rdx); |
876 __ movq(rax, Address(rax, | 944 __ movq(rax, Address(rax, |
877 sizeof(oopDesc) + | 945 sizeof(oopDesc) + |
878 objArrayKlass::element_klass_offset_in_bytes())); | 946 objArrayKlass::element_klass_offset_in_bytes())); |
879 // Compress array + index*oopSize + 12 into a single register. Frees rcx. | 947 // Compress array + index*oopSize + 12 into a single register. Frees rcx. |
880 __ leaq(rdx, Address(rdx, rcx, | 948 __ leaq(rdx, element_address); |
881 UseCompressedOops ? Address::times_4 : Address::times_8, | |
882 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); | |
883 | 949 |
884 // Generate subtype check. Blows rcx, rdi | 950 // Generate subtype check. Blows rcx, rdi |
885 // Superklass in rax. Subklass in rbx. | 951 // Superklass in rax. Subklass in rbx. |
886 __ gen_subtype_check(rbx, ok_is_subtype); | 952 __ gen_subtype_check(rbx, ok_is_subtype); |
887 | 953 |
889 // object is at TOS | 955 // object is at TOS |
890 __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry)); | 956 __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry)); |
891 | 957 |
892 // Come here on success | 958 // Come here on success |
893 __ bind(ok_is_subtype); | 959 __ bind(ok_is_subtype); |
894 __ movq(rax, at_tos()); // Value | 960 |
895 __ store_heap_oop(Address(rdx, 0), rax); | 961 // Get the value we will store |
896 __ store_check(rdx); | 962 __ movq(rax, at_tos()); |
963 | |
964 // Now store using the appropriate barrier | |
965 do_oop_store(_masm, Address(rdx, 0), rax, _bs->kind(), true); | |
897 __ jmp(done); | 966 __ jmp(done); |
898 | 967 |
899 // Have a NULL in rax, rdx=array, ecx=index. Store NULL at ary[idx] | 968 // Have a NULL in rax, rdx=array, ecx=index. Store NULL at ary[idx] |
900 __ bind(is_null); | 969 __ bind(is_null); |
901 __ profile_null_seen(rbx); | 970 __ profile_null_seen(rbx); |
902 __ store_heap_oop(Address(rdx, rcx, | 971 |
903 UseCompressedOops ? Address::times_4 : Address::times_8, | 972 // Store a NULL |
904 arrayOopDesc::base_offset_in_bytes(T_OBJECT)), | 973 do_oop_store(_masm, element_address, noreg, _bs->kind(), true); |
905 rax); | |
906 | 974 |
907 // Pop stack arguments | 975 // Pop stack arguments |
908 __ bind(done); | 976 __ bind(done); |
909 __ addq(rsp, 3 * Interpreter::stackElementSize()); | 977 __ addq(rsp, 3 * Interpreter::stackElementSize()); |
910 } | 978 } |
2392 __ cmpl(flags, atos); | 2460 __ cmpl(flags, atos); |
2393 __ jcc(Assembler::notEqual, notObj); | 2461 __ jcc(Assembler::notEqual, notObj); |
2394 // atos | 2462 // atos |
2395 __ pop(atos); | 2463 __ pop(atos); |
2396 if (!is_static) pop_and_check_object(obj); | 2464 if (!is_static) pop_and_check_object(obj); |
2397 __ store_heap_oop(field, rax); | 2465 |
2398 __ store_check(obj, field); // Need to mark card | 2466 // Store into the field |
2467 do_oop_store(_masm, field, rax, _bs->kind(), false); | |
2468 | |
2399 if (!is_static) { | 2469 if (!is_static) { |
2400 patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx); | 2470 patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx); |
2401 } | 2471 } |
2402 __ jmp(Done); | 2472 __ jmp(Done); |
2403 | 2473 |
2580 const Address field(rcx, rbx, Address::times_1); | 2650 const Address field(rcx, rbx, Address::times_1); |
2581 | 2651 |
2582 // access field | 2652 // access field |
2583 switch (bytecode()) { | 2653 switch (bytecode()) { |
2584 case Bytecodes::_fast_aputfield: | 2654 case Bytecodes::_fast_aputfield: |
2585 __ store_heap_oop(field, rax); | 2655 do_oop_store(_masm, field, rax, _bs->kind(), false); |
2586 __ store_check(rcx, field); | |
2587 break; | 2656 break; |
2588 case Bytecodes::_fast_lputfield: | 2657 case Bytecodes::_fast_lputfield: |
2589 __ movq(field, rax); | 2658 __ movq(field, rax); |
2590 break; | 2659 break; |
2591 case Bytecodes::_fast_iputfield: | 2660 case Bytecodes::_fast_iputfield: |
2787 if (load_receiver) { | 2856 if (load_receiver) { |
2788 __ movl(recv, flags); | 2857 __ movl(recv, flags); |
2789 __ andl(recv, 0xFF); | 2858 __ andl(recv, 0xFF); |
2790 if (TaggedStackInterpreter) __ shll(recv, 1); // index*2 | 2859 if (TaggedStackInterpreter) __ shll(recv, 1); // index*2 |
2791 __ movq(recv, Address(rsp, recv, Address::times_8, | 2860 __ movq(recv, Address(rsp, recv, Address::times_8, |
2792 -Interpreter::expr_offset_in_bytes(1))); | 2861 -Interpreter::expr_offset_in_bytes(1))); |
2793 __ verify_oop(recv); | 2862 __ verify_oop(recv); |
2794 } | 2863 } |
2795 | 2864 |
2796 // do null check if needed | 2865 // do null check if needed |
2797 if (receiver_null_check) { | 2866 if (receiver_null_check) { |
3040 Label slow_case; | 3109 Label slow_case; |
3041 Label done; | 3110 Label done; |
3042 Label initialize_header; | 3111 Label initialize_header; |
3043 Label initialize_object; // including clearing the fields | 3112 Label initialize_object; // including clearing the fields |
3044 Label allocate_shared; | 3113 Label allocate_shared; |
3045 ExternalAddress top((address)Universe::heap()->top_addr()); | |
3046 ExternalAddress end((address)Universe::heap()->end_addr()); | |
3047 | 3114 |
3048 __ get_cpool_and_tags(rsi, rax); | 3115 __ get_cpool_and_tags(rsi, rax); |
3049 // get instanceKlass | 3116 // get instanceKlass |
3050 __ movq(rsi, Address(rsi, rdx, | 3117 __ movq(rsi, Address(rsi, rdx, |
3051 Address::times_8, sizeof(constantPoolOopDesc))); | 3118 Address::times_8, sizeof(constantPoolOopDesc))); |
3101 // Allocation in the shared Eden, if allowed. | 3168 // Allocation in the shared Eden, if allowed. |
3102 // | 3169 // |
3103 // rdx: instance size in bytes | 3170 // rdx: instance size in bytes |
3104 if (allow_shared_alloc) { | 3171 if (allow_shared_alloc) { |
3105 __ bind(allocate_shared); | 3172 __ bind(allocate_shared); |
3173 | |
3174 ExternalAddress top((address)Universe::heap()->top_addr()); | |
3175 ExternalAddress end((address)Universe::heap()->end_addr()); | |
3106 | 3176 |
3107 const Register RtopAddr = rscratch1; | 3177 const Register RtopAddr = rscratch1; |
3108 const Register RendAddr = rscratch2; | 3178 const Register RendAddr = rscratch2; |
3109 | 3179 |
3110 __ lea(RtopAddr, top); | 3180 __ lea(RtopAddr, top); |