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);