comparison src/cpu/x86/vm/templateTable_x86_32.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 93b6525e3b82
children 1ee8caae33af
comparison
equal deleted inserted replaced
189:0b27f3512f9e 342:37f87013dfd8
104 } 104 }
105 105
106 106
107 //---------------------------------------------------------------------------------------------------- 107 //----------------------------------------------------------------------------------------------------
108 // Miscelaneous helper routines 108 // Miscelaneous helper routines
109
110 // Store an oop (or NULL) at the address described by obj.
111 // If val == noreg this means store a NULL
112
113 static void do_oop_store(InterpreterMacroAssembler* _masm,
114 Address obj,
115 Register val,
116 BarrierSet::Name barrier,
117 bool precise) {
118 assert(val == noreg || val == rax, "parameter is just for looks");
119 switch (barrier) {
120 #ifndef SERIALGC
121 case BarrierSet::G1SATBCT:
122 case BarrierSet::G1SATBCTLogging:
123 {
124 // flatten object address if needed
125 // We do it regardless of precise because we need the registers
126 if (obj.index() == noreg && obj.disp() == 0) {
127 if (obj.base() != rdx) {
128 __ movl(rdx, obj.base());
129 }
130 } else {
131 __ leal(rdx, obj);
132 }
133 __ get_thread(rcx);
134 __ save_bcp();
135 __ g1_write_barrier_pre(rdx, rcx, rsi, rbx, val != noreg);
136
137 // Do the actual store
138 // noreg means NULL
139 if (val == noreg) {
140 __ movl(Address(rdx, 0), NULL_WORD);
141 // No post barrier for NULL
142 } else {
143 __ movl(Address(rdx, 0), val);
144 __ g1_write_barrier_post(rdx, rax, rcx, rbx, rsi);
145 }
146 __ restore_bcp();
147
148 }
149 break;
150 #endif // SERIALGC
151 case BarrierSet::CardTableModRef:
152 case BarrierSet::CardTableExtension:
153 {
154 if (val == noreg) {
155 __ movl(obj, NULL_WORD);
156 } else {
157 __ movl(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 __ leal(rdx, obj);
163 __ store_check(rdx);
164 }
165 }
166 }
167 break;
168 case BarrierSet::ModRef:
169 case BarrierSet::Other:
170 if (val == noreg) {
171 __ movl(obj, NULL_WORD);
172 } else {
173 __ movl(obj, val);
174 }
175 break;
176 default :
177 ShouldNotReachHere();
178
179 }
180 }
109 181
110 Address TemplateTable::at_bcp(int offset) { 182 Address TemplateTable::at_bcp(int offset) {
111 assert(_desc->uses_bcp(), "inconsistent uses_bcp information"); 183 assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
112 return Address(rsi, offset); 184 return Address(rsi, offset);
113 } 185 }
870 transition(vtos, vtos); 942 transition(vtos, vtos);
871 // stack: ..., array, index, value 943 // stack: ..., array, index, value
872 __ movl(rax, at_tos()); // Value 944 __ movl(rax, at_tos()); // Value
873 __ movl(rcx, at_tos_p1()); // Index 945 __ movl(rcx, at_tos_p1()); // Index
874 __ movl(rdx, at_tos_p2()); // Array 946 __ movl(rdx, at_tos_p2()); // Array
947
948 Address element_address(rdx, rcx, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
875 index_check_without_pop(rdx, rcx); // kills rbx, 949 index_check_without_pop(rdx, rcx); // kills rbx,
876 // do array store check - check for NULL value first 950 // do array store check - check for NULL value first
877 __ testl(rax, rax); 951 __ testl(rax, rax);
878 __ jcc(Assembler::zero, is_null); 952 __ jcc(Assembler::zero, is_null);
879 953
881 __ movl(rbx, Address(rax, oopDesc::klass_offset_in_bytes())); 955 __ movl(rbx, Address(rax, oopDesc::klass_offset_in_bytes()));
882 // Move superklass into EAX 956 // Move superklass into EAX
883 __ movl(rax, Address(rdx, oopDesc::klass_offset_in_bytes())); 957 __ movl(rax, Address(rdx, oopDesc::klass_offset_in_bytes()));
884 __ movl(rax, Address(rax, sizeof(oopDesc) + objArrayKlass::element_klass_offset_in_bytes())); 958 __ movl(rax, Address(rax, sizeof(oopDesc) + objArrayKlass::element_klass_offset_in_bytes()));
885 // Compress array+index*4+12 into a single register. Frees ECX. 959 // Compress array+index*4+12 into a single register. Frees ECX.
886 __ leal(rdx, Address(rdx, rcx, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); 960 __ leal(rdx, element_address);
887 961
888 // Generate subtype check. Blows ECX. Resets EDI to locals. 962 // Generate subtype check. Blows ECX. Resets EDI to locals.
889 // Superklass in EAX. Subklass in EBX. 963 // Superklass in EAX. Subklass in EBX.
890 __ gen_subtype_check( rbx, ok_is_subtype ); 964 __ gen_subtype_check( rbx, ok_is_subtype );
891 965
893 // object is at TOS 967 // object is at TOS
894 __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry)); 968 __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry));
895 969
896 // Come here on success 970 // Come here on success
897 __ bind(ok_is_subtype); 971 __ bind(ok_is_subtype);
898 __ movl(rax, at_rsp()); // Value 972
899 __ movl(Address(rdx, 0), rax); 973 // Get the value to store
900 __ store_check(rdx); 974 __ movl(rax, at_rsp());
901 __ jmpb(done); 975 // and store it with appropriate barrier
976 do_oop_store(_masm, Address(rdx, 0), rax, _bs->kind(), true);
977
978 __ jmp(done);
902 979
903 // Have a NULL in EAX, EDX=array, ECX=index. Store NULL at ary[idx] 980 // Have a NULL in EAX, EDX=array, ECX=index. Store NULL at ary[idx]
904 __ bind(is_null); 981 __ bind(is_null);
905 __ profile_null_seen(rbx); 982 __ profile_null_seen(rbx);
906 __ movl(Address(rdx, rcx, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), rax); 983
984 // Store NULL, (noreg means NULL to do_oop_store)
985 do_oop_store(_masm, element_address, noreg, _bs->kind(), true);
907 986
908 // Pop stack arguments 987 // Pop stack arguments
909 __ bind(done); 988 __ bind(done);
910 __ addl(rsp, 3 * Interpreter::stackElementSize()); 989 __ addl(rsp, 3 * Interpreter::stackElementSize());
911 } 990 }
1504 __ load_unsigned_byte(rbx, Address(rsi, rdx, Address::times_1, 0)); 1583 __ load_unsigned_byte(rbx, Address(rsi, rdx, Address::times_1, 0));
1505 1584
1506 // compute return address as bci in rax, 1585 // compute return address as bci in rax,
1507 __ leal(rax, at_bcp((is_wide ? 5 : 3) - in_bytes(constMethodOopDesc::codes_offset()))); 1586 __ leal(rax, at_bcp((is_wide ? 5 : 3) - in_bytes(constMethodOopDesc::codes_offset())));
1508 __ subl(rax, Address(rcx, methodOopDesc::const_offset())); 1587 __ subl(rax, Address(rcx, methodOopDesc::const_offset()));
1509 // Adjust the bcp in ESI by the displacement in EDX 1588 // Adjust the bcp in rsi by the displacement in EDX
1510 __ addl(rsi, rdx); 1589 __ addl(rsi, rdx);
1511 // Push return address 1590 // Push return address
1512 __ push_i(rax); 1591 __ push_i(rax);
1513 // jsr returns vtos 1592 // jsr returns vtos
1514 __ dispatch_only_noverify(vtos); 1593 __ dispatch_only_noverify(vtos);
1515 return; 1594 return;
1516 } 1595 }
1517 1596
1518 // Normal (non-jsr) branch handling 1597 // Normal (non-jsr) branch handling
1519 1598
1520 // Adjust the bcp in ESI by the displacement in EDX 1599 // Adjust the bcp in rsi by the displacement in EDX
1521 __ addl(rsi, rdx); 1600 __ addl(rsi, rdx);
1522 1601
1523 assert(UseLoopCounter || !UseOnStackReplacement, "on-stack-replacement requires loop counters"); 1602 assert(UseLoopCounter || !UseOnStackReplacement, "on-stack-replacement requires loop counters");
1524 Label backedge_counter_overflow; 1603 Label backedge_counter_overflow;
1525 Label profile_method; 1604 Label profile_method;
2424 __ jcc(Assembler::notEqual, notObj); 2503 __ jcc(Assembler::notEqual, notObj);
2425 2504
2426 __ pop(atos); 2505 __ pop(atos);
2427 if (!is_static) pop_and_check_object(obj); 2506 if (!is_static) pop_and_check_object(obj);
2428 2507
2429 __ movl(lo, rax ); 2508 do_oop_store(_masm, lo, rax, _bs->kind(), false);
2430 __ store_check(obj, lo); // Need to mark card 2509
2431 if (!is_static) { 2510 if (!is_static) {
2432 patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx); 2511 patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx);
2433 } 2512 }
2513
2434 __ jmp(Done); 2514 __ jmp(Done);
2435 2515
2436 __ bind(notObj); 2516 __ bind(notObj);
2437 // ctos 2517 // ctos
2438 __ cmpl(flags, ctos ); 2518 __ cmpl(flags, ctos );
2636 case Bytecodes::_fast_cputfield: __ movw(lo, rax); break; 2716 case Bytecodes::_fast_cputfield: __ movw(lo, rax); break;
2637 case Bytecodes::_fast_iputfield: __ movl(lo, rax); break; 2717 case Bytecodes::_fast_iputfield: __ movl(lo, rax); break;
2638 case Bytecodes::_fast_lputfield: __ movl(hi, rdx); __ movl(lo, rax); break; 2718 case Bytecodes::_fast_lputfield: __ movl(hi, rdx); __ movl(lo, rax); break;
2639 case Bytecodes::_fast_fputfield: __ fstp_s(lo); break; 2719 case Bytecodes::_fast_fputfield: __ fstp_s(lo); break;
2640 case Bytecodes::_fast_dputfield: __ fstp_d(lo); break; 2720 case Bytecodes::_fast_dputfield: __ fstp_d(lo); break;
2641 case Bytecodes::_fast_aputfield: __ movl(lo, rax); __ store_check(rcx, lo); break; 2721 case Bytecodes::_fast_aputfield: {
2722 do_oop_store(_masm, lo, rax, _bs->kind(), false);
2723 break;
2724 }
2642 default: 2725 default:
2643 ShouldNotReachHere(); 2726 ShouldNotReachHere();
2644 } 2727 }
2645 2728
2646 Label done; 2729 Label done;
2647 volatile_barrier( ); 2730 volatile_barrier( );
2648 __ jmpb(done); 2731 // Barriers are so large that short branch doesn't reach!
2732 __ jmp(done);
2649 2733
2650 // Same code as above, but don't need rdx to test for volatile. 2734 // Same code as above, but don't need rdx to test for volatile.
2651 __ bind(notVolatile); 2735 __ bind(notVolatile);
2652 2736
2653 if (bytecode() == Bytecodes::_fast_lputfield) __ popl(rdx); 2737 if (bytecode() == Bytecodes::_fast_lputfield) __ popl(rdx);
2662 case Bytecodes::_fast_cputfield: __ movw(lo, rax); break; 2746 case Bytecodes::_fast_cputfield: __ movw(lo, rax); break;
2663 case Bytecodes::_fast_iputfield: __ movl(lo, rax); break; 2747 case Bytecodes::_fast_iputfield: __ movl(lo, rax); break;
2664 case Bytecodes::_fast_lputfield: __ movl(hi, rdx); __ movl(lo, rax); break; 2748 case Bytecodes::_fast_lputfield: __ movl(hi, rdx); __ movl(lo, rax); break;
2665 case Bytecodes::_fast_fputfield: __ fstp_s(lo); break; 2749 case Bytecodes::_fast_fputfield: __ fstp_s(lo); break;
2666 case Bytecodes::_fast_dputfield: __ fstp_d(lo); break; 2750 case Bytecodes::_fast_dputfield: __ fstp_d(lo); break;
2667 case Bytecodes::_fast_aputfield: __ movl(lo, rax); __ store_check(rcx, lo); break; 2751 case Bytecodes::_fast_aputfield: {
2752 do_oop_store(_masm, lo, rax, _bs->kind(), false);
2753 break;
2754 }
2668 default: 2755 default:
2669 ShouldNotReachHere(); 2756 ShouldNotReachHere();
2670 } 2757 }
2671 __ bind(done); 2758 __ bind(done);
2672 } 2759 }
3017 Label done; 3104 Label done;
3018 Label initialize_header; 3105 Label initialize_header;
3019 Label initialize_object; // including clearing the fields 3106 Label initialize_object; // including clearing the fields
3020 Label allocate_shared; 3107 Label allocate_shared;
3021 3108
3022 ExternalAddress heap_top((address)Universe::heap()->top_addr());
3023
3024 __ get_cpool_and_tags(rcx, rax); 3109 __ get_cpool_and_tags(rcx, rax);
3025 // get instanceKlass 3110 // get instanceKlass
3026 __ movl(rcx, Address(rcx, rdx, Address::times_4, sizeof(constantPoolOopDesc))); 3111 __ movl(rcx, Address(rcx, rdx, Address::times_4, sizeof(constantPoolOopDesc)));
3027 __ pushl(rcx); // save the contexts of klass for initializing the header 3112 __ pushl(rcx); // save the contexts of klass for initializing the header
3028 3113
3074 // Allocation in the shared Eden, if allowed. 3159 // Allocation in the shared Eden, if allowed.
3075 // 3160 //
3076 // rdx: instance size in bytes 3161 // rdx: instance size in bytes
3077 if (allow_shared_alloc) { 3162 if (allow_shared_alloc) {
3078 __ bind(allocate_shared); 3163 __ bind(allocate_shared);
3164
3165 ExternalAddress heap_top((address)Universe::heap()->top_addr());
3079 3166
3080 Label retry; 3167 Label retry;
3081 __ bind(retry); 3168 __ bind(retry);
3082 __ mov32(rax, heap_top); 3169 __ mov32(rax, heap_top);
3083 __ leal(rbx, Address(rax, rdx, Address::times_1)); 3170 __ leal(rbx, Address(rax, rdx, Address::times_1));