--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Jul 05 16:41:01 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Sep 17 16:49:18 2008 +0400
@@ -107,6 +107,78 @@
//----------------------------------------------------------------------------------------------------
// Miscelaneous helper routines
+// Store an oop (or NULL) at the address described by obj.
+// If val == noreg this means store a NULL
+
+static void do_oop_store(InterpreterMacroAssembler* _masm,
+ Address obj,
+ Register val,
+ BarrierSet::Name barrier,
+ bool precise) {
+ assert(val == noreg || val == rax, "parameter is just for looks");
+ switch (barrier) {
+#ifndef SERIALGC
+ case BarrierSet::G1SATBCT:
+ case BarrierSet::G1SATBCTLogging:
+ {
+ // flatten object address if needed
+ // We do it regardless of precise because we need the registers
+ if (obj.index() == noreg && obj.disp() == 0) {
+ if (obj.base() != rdx) {
+ __ movl(rdx, obj.base());
+ }
+ } else {
+ __ leal(rdx, obj);
+ }
+ __ get_thread(rcx);
+ __ save_bcp();
+ __ g1_write_barrier_pre(rdx, rcx, rsi, rbx, val != noreg);
+
+ // Do the actual store
+ // noreg means NULL
+ if (val == noreg) {
+ __ movl(Address(rdx, 0), NULL_WORD);
+ // No post barrier for NULL
+ } else {
+ __ movl(Address(rdx, 0), val);
+ __ g1_write_barrier_post(rdx, rax, rcx, rbx, rsi);
+ }
+ __ restore_bcp();
+
+ }
+ break;
+#endif // SERIALGC
+ case BarrierSet::CardTableModRef:
+ case BarrierSet::CardTableExtension:
+ {
+ if (val == noreg) {
+ __ movl(obj, NULL_WORD);
+ } else {
+ __ movl(obj, val);
+ // flatten object address if needed
+ if (!precise || (obj.index() == noreg && obj.disp() == 0)) {
+ __ store_check(obj.base());
+ } else {
+ __ leal(rdx, obj);
+ __ store_check(rdx);
+ }
+ }
+ }
+ break;
+ case BarrierSet::ModRef:
+ case BarrierSet::Other:
+ if (val == noreg) {
+ __ movl(obj, NULL_WORD);
+ } else {
+ __ movl(obj, val);
+ }
+ break;
+ default :
+ ShouldNotReachHere();
+
+ }
+}
+
Address TemplateTable::at_bcp(int offset) {
assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
return Address(rsi, offset);
@@ -876,6 +948,8 @@
__ movptr(rax, at_tos()); // Value
__ movl(rcx, at_tos_p1()); // Index
__ movptr(rdx, at_tos_p2()); // Array
+
+ Address element_address(rdx, rcx, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
index_check_without_pop(rdx, rcx); // kills rbx,
// do array store check - check for NULL value first
__ testptr(rax, rax);
@@ -887,7 +961,7 @@
__ movptr(rax, Address(rdx, oopDesc::klass_offset_in_bytes()));
__ movptr(rax, Address(rax, sizeof(oopDesc) + objArrayKlass::element_klass_offset_in_bytes()));
// Compress array+index*wordSize+12 into a single register. Frees ECX.
- __ lea(rdx, Address(rdx, rcx, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
+ __ lea(rdx, element_address);
// Generate subtype check. Blows ECX. Resets EDI to locals.
// Superklass in EAX. Subklass in EBX.
@@ -899,15 +973,20 @@
// Come here on success
__ bind(ok_is_subtype);
- __ movptr(rax, at_rsp()); // Value
- __ movptr(Address(rdx, 0), rax);
- __ store_check(rdx);
- __ jmpb(done);
+
+ // Get the value to store
+ __ movptr(rax, at_rsp());
+ // and store it with appropriate barrier
+ do_oop_store(_masm, Address(rdx, 0), rax, _bs->kind(), true);
+
+ __ jmp(done);
// Have a NULL in EAX, EDX=array, ECX=index. Store NULL at ary[idx]
__ bind(is_null);
__ profile_null_seen(rbx);
- __ movptr(Address(rdx, rcx, Address::times_ptr, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), rax);
+
+ // Store NULL, (noreg means NULL to do_oop_store)
+ do_oop_store(_masm, element_address, noreg, _bs->kind(), true);
// Pop stack arguments
__ bind(done);
@@ -1515,7 +1594,7 @@
// compute return address as bci in rax,
__ lea(rax, at_bcp((is_wide ? 5 : 3) - in_bytes(constMethodOopDesc::codes_offset())));
__ subptr(rax, Address(rcx, methodOopDesc::const_offset()));
- // Adjust the bcp in ESI by the displacement in EDX
+ // Adjust the bcp in RSI by the displacement in EDX
__ addptr(rsi, rdx);
// Push return address
__ push_i(rax);
@@ -1526,7 +1605,7 @@
// Normal (non-jsr) branch handling
- // Adjust the bcp in ESI by the displacement in EDX
+ // Adjust the bcp in RSI by the displacement in EDX
__ addptr(rsi, rdx);
assert(UseLoopCounter || !UseOnStackReplacement, "on-stack-replacement requires loop counters");
@@ -2439,11 +2518,12 @@
__ pop(atos);
if (!is_static) pop_and_check_object(obj);
- __ movptr(lo, rax );
- __ store_check(obj, lo); // Need to mark card
+ do_oop_store(_masm, lo, rax, _bs->kind(), false);
+
if (!is_static) {
patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx);
}
+
__ jmp(Done);
__ bind(notObj);
@@ -2664,7 +2744,10 @@
break;
case Bytecodes::_fast_fputfield: __ fstp_s(lo); break;
case Bytecodes::_fast_dputfield: __ fstp_d(lo); break;
- case Bytecodes::_fast_aputfield: __ movptr(lo, rax); __ store_check(rcx, lo); break;
+ case Bytecodes::_fast_aputfield: {
+ do_oop_store(_masm, lo, rax, _bs->kind(), false);
+ break;
+ }
default:
ShouldNotReachHere();
}
@@ -2672,7 +2755,8 @@
Label done;
volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
Assembler::StoreStore));
- __ jmpb(done);
+ // Barriers are so large that short branch doesn't reach!
+ __ jmp(done);
// Same code as above, but don't need rdx to test for volatile.
__ bind(notVolatile);
@@ -2694,7 +2778,10 @@
break;
case Bytecodes::_fast_fputfield: __ fstp_s(lo); break;
case Bytecodes::_fast_dputfield: __ fstp_d(lo); break;
- case Bytecodes::_fast_aputfield: __ movptr(lo, rax); __ store_check(rcx, lo); break;
+ case Bytecodes::_fast_aputfield: {
+ do_oop_store(_masm, lo, rax, _bs->kind(), false);
+ break;
+ }
default:
ShouldNotReachHere();
}
@@ -3054,8 +3141,6 @@
Label initialize_object; // including clearing the fields
Label allocate_shared;
- ExternalAddress heap_top((address)Universe::heap()->top_addr());
-
__ get_cpool_and_tags(rcx, rax);
// get instanceKlass
__ movptr(rcx, Address(rcx, rdx, Address::times_ptr, sizeof(constantPoolOopDesc)));
@@ -3112,6 +3197,8 @@
if (allow_shared_alloc) {
__ bind(allocate_shared);
+ ExternalAddress heap_top((address)Universe::heap()->top_addr());
+
Label retry;
__ bind(retry);
__ movptr(rax, heap_top);