8205523: Explicit barriers for interpreter
Reviewed-by: eosterlund, coleenp
This commit is contained in:
parent
f62fa67625
commit
cbcc690048
@ -48,6 +48,10 @@ public:
|
|||||||
virtual void obj_equals(MacroAssembler* masm,
|
virtual void obj_equals(MacroAssembler* masm,
|
||||||
Register obj1, Register obj2);
|
Register obj1, Register obj2);
|
||||||
|
|
||||||
|
virtual void resolve(MacroAssembler* masm, DecoratorSet decorators, Register obj) {
|
||||||
|
// Default implementation does not need to do anything.
|
||||||
|
}
|
||||||
|
|
||||||
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
|
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
|
||||||
Register obj, Register tmp, Label& slowpath);
|
Register obj, Register tmp, Label& slowpath);
|
||||||
|
|
||||||
|
@ -3990,6 +3990,15 @@ void MacroAssembler::access_store_at(BasicType type, DecoratorSet decorators,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::resolve(DecoratorSet decorators, Register obj) {
|
||||||
|
// Use stronger ACCESS_WRITE|ACCESS_READ by default.
|
||||||
|
if ((decorators & (ACCESS_READ | ACCESS_WRITE)) == 0) {
|
||||||
|
decorators |= ACCESS_READ | ACCESS_WRITE;
|
||||||
|
}
|
||||||
|
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||||
|
return bs->resolve(this, decorators, obj);
|
||||||
|
}
|
||||||
|
|
||||||
void MacroAssembler::load_heap_oop(Register dst, Address src, Register tmp1,
|
void MacroAssembler::load_heap_oop(Register dst, Address src, Register tmp1,
|
||||||
Register thread_tmp, DecoratorSet decorators) {
|
Register thread_tmp, DecoratorSet decorators) {
|
||||||
access_load_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1, thread_tmp);
|
access_load_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1, thread_tmp);
|
||||||
|
@ -795,6 +795,10 @@ public:
|
|||||||
void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register src,
|
void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register src,
|
||||||
Register tmp1, Register tmp_thread);
|
Register tmp1, Register tmp_thread);
|
||||||
|
|
||||||
|
// Resolves obj for access. Result is placed in the same register.
|
||||||
|
// All other registers are preserved.
|
||||||
|
void resolve(DecoratorSet decorators, Register obj);
|
||||||
|
|
||||||
void load_heap_oop(Register dst, Address src, Register tmp1 = noreg,
|
void load_heap_oop(Register dst, Address src, Register tmp1 = noreg,
|
||||||
Register thread_tmp = noreg, DecoratorSet decorators = 0);
|
Register thread_tmp = noreg, DecoratorSet decorators = 0);
|
||||||
|
|
||||||
|
@ -1839,6 +1839,8 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||||||
// Load the oop from the handle
|
// Load the oop from the handle
|
||||||
__ ldr(obj_reg, Address(oop_handle_reg, 0));
|
__ ldr(obj_reg, Address(oop_handle_reg, 0));
|
||||||
|
|
||||||
|
__ resolve(IS_NOT_NULL, obj_reg);
|
||||||
|
|
||||||
if (UseBiasedLocking) {
|
if (UseBiasedLocking) {
|
||||||
__ biased_locking_enter(lock_reg, obj_reg, swap_reg, tmp, false, lock_done, &slow_path_lock);
|
__ biased_locking_enter(lock_reg, obj_reg, swap_reg, tmp, false, lock_done, &slow_path_lock);
|
||||||
}
|
}
|
||||||
@ -2001,6 +2003,8 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||||||
// Get locked oop from the handle we passed to jni
|
// Get locked oop from the handle we passed to jni
|
||||||
__ ldr(obj_reg, Address(oop_handle_reg, 0));
|
__ ldr(obj_reg, Address(oop_handle_reg, 0));
|
||||||
|
|
||||||
|
__ resolve(IS_NOT_NULL, obj_reg);
|
||||||
|
|
||||||
Label done;
|
Label done;
|
||||||
|
|
||||||
if (UseBiasedLocking) {
|
if (UseBiasedLocking) {
|
||||||
|
@ -836,6 +836,7 @@ void TemplateInterpreterGenerator::lock_method() {
|
|||||||
#endif // ASSERT
|
#endif // ASSERT
|
||||||
|
|
||||||
__ bind(done);
|
__ bind(done);
|
||||||
|
__ resolve(IS_NOT_NULL, r0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add space for monitor & lock
|
// add space for monitor & lock
|
||||||
@ -1062,6 +1063,7 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
|
|||||||
__ ldrw(crc, Address(esp, 4*wordSize)); // Initial CRC
|
__ ldrw(crc, Address(esp, 4*wordSize)); // Initial CRC
|
||||||
} else {
|
} else {
|
||||||
__ ldr(buf, Address(esp, 2*wordSize)); // byte[] array
|
__ ldr(buf, Address(esp, 2*wordSize)); // byte[] array
|
||||||
|
__ resolve(IS_NOT_NULL | ACCESS_READ, buf);
|
||||||
__ add(buf, buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
__ add(buf, buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||||
__ ldrw(off, Address(esp, wordSize)); // offset
|
__ ldrw(off, Address(esp, wordSize)); // offset
|
||||||
__ add(buf, buf, off); // + offset
|
__ add(buf, buf, off); // + offset
|
||||||
@ -1106,6 +1108,9 @@ address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(Abstract
|
|||||||
__ ldrw(off, Address(esp, wordSize)); // int offset
|
__ ldrw(off, Address(esp, wordSize)); // int offset
|
||||||
__ sub(len, end, off);
|
__ sub(len, end, off);
|
||||||
__ ldr(buf, Address(esp, 2*wordSize)); // byte[] buf | long buf
|
__ ldr(buf, Address(esp, 2*wordSize)); // byte[] buf | long buf
|
||||||
|
if (kind == Interpreter::java_util_zip_CRC32C_updateBytes) {
|
||||||
|
__ resolve(IS_NOT_NULL | ACCESS_READ, buf);
|
||||||
|
}
|
||||||
__ add(buf, buf, off); // + offset
|
__ add(buf, buf, off); // + offset
|
||||||
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
|
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
|
||||||
__ ldrw(crc, Address(esp, 4*wordSize)); // long crc
|
__ ldrw(crc, Address(esp, 4*wordSize)); // long crc
|
||||||
|
@ -3840,6 +3840,8 @@ void TemplateTable::monitorenter()
|
|||||||
// check for NULL object
|
// check for NULL object
|
||||||
__ null_check(r0);
|
__ null_check(r0);
|
||||||
|
|
||||||
|
__ resolve(IS_NOT_NULL, r0);
|
||||||
|
|
||||||
const Address monitor_block_top(
|
const Address monitor_block_top(
|
||||||
rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
|
rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
|
||||||
const Address monitor_block_bot(
|
const Address monitor_block_bot(
|
||||||
@ -3939,6 +3941,8 @@ void TemplateTable::monitorexit()
|
|||||||
// check for NULL object
|
// check for NULL object
|
||||||
__ null_check(r0);
|
__ null_check(r0);
|
||||||
|
|
||||||
|
__ resolve(IS_NOT_NULL, r0);
|
||||||
|
|
||||||
const Address monitor_block_top(
|
const Address monitor_block_top(
|
||||||
rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
|
rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
|
||||||
const Address monitor_block_bot(
|
const Address monitor_block_bot(
|
||||||
|
@ -61,6 +61,10 @@ public:
|
|||||||
virtual void obj_equals(MacroAssembler* masm,
|
virtual void obj_equals(MacroAssembler* masm,
|
||||||
Register obj1, Address obj2);
|
Register obj1, Address obj2);
|
||||||
|
|
||||||
|
virtual void resolve(MacroAssembler* masm, DecoratorSet decorators, Register obj) {
|
||||||
|
// Default implementation does not need to do anything.
|
||||||
|
}
|
||||||
|
|
||||||
// Support for jniFastGetField to try resolving a jobject/jweak in native
|
// Support for jniFastGetField to try resolving a jobject/jweak in native
|
||||||
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
|
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
|
||||||
Register obj, Register tmp, Label& slowpath);
|
Register obj, Register tmp, Label& slowpath);
|
||||||
|
@ -6287,6 +6287,15 @@ void MacroAssembler::access_store_at(BasicType type, DecoratorSet decorators, Ad
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::resolve(DecoratorSet decorators, Register obj) {
|
||||||
|
// Use stronger ACCESS_WRITE|ACCESS_READ by default.
|
||||||
|
if ((decorators & (ACCESS_READ | ACCESS_WRITE)) == 0) {
|
||||||
|
decorators |= ACCESS_READ | ACCESS_WRITE;
|
||||||
|
}
|
||||||
|
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||||
|
return bs->resolve(this, decorators, obj);
|
||||||
|
}
|
||||||
|
|
||||||
void MacroAssembler::load_heap_oop(Register dst, Address src, Register tmp1,
|
void MacroAssembler::load_heap_oop(Register dst, Address src, Register tmp1,
|
||||||
Register thread_tmp, DecoratorSet decorators) {
|
Register thread_tmp, DecoratorSet decorators) {
|
||||||
access_load_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1, thread_tmp);
|
access_load_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1, thread_tmp);
|
||||||
|
@ -319,6 +319,10 @@ class MacroAssembler: public Assembler {
|
|||||||
void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register src,
|
void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register src,
|
||||||
Register tmp1, Register tmp2);
|
Register tmp1, Register tmp2);
|
||||||
|
|
||||||
|
// Resolves obj access. Result is placed in the same register.
|
||||||
|
// All other registers are preserved.
|
||||||
|
void resolve(DecoratorSet decorators, Register obj);
|
||||||
|
|
||||||
void load_heap_oop(Register dst, Address src, Register tmp1 = noreg,
|
void load_heap_oop(Register dst, Address src, Register tmp1 = noreg,
|
||||||
Register thread_tmp = noreg, DecoratorSet decorators = 0);
|
Register thread_tmp = noreg, DecoratorSet decorators = 0);
|
||||||
void load_heap_oop_not_null(Register dst, Address src, Register tmp1 = noreg,
|
void load_heap_oop_not_null(Register dst, Address src, Register tmp1 = noreg,
|
||||||
|
@ -2450,6 +2450,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||||||
// Load the oop from the handle
|
// Load the oop from the handle
|
||||||
__ movptr(obj_reg, Address(oop_handle_reg, 0));
|
__ movptr(obj_reg, Address(oop_handle_reg, 0));
|
||||||
|
|
||||||
|
__ resolve(IS_NOT_NULL, obj_reg);
|
||||||
if (UseBiasedLocking) {
|
if (UseBiasedLocking) {
|
||||||
__ biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, lock_done, &slow_path_lock);
|
__ biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, lock_done, &slow_path_lock);
|
||||||
}
|
}
|
||||||
@ -2635,6 +2636,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||||||
|
|
||||||
// Get locked oop from the handle we passed to jni
|
// Get locked oop from the handle we passed to jni
|
||||||
__ movptr(obj_reg, Address(oop_handle_reg, 0));
|
__ movptr(obj_reg, Address(oop_handle_reg, 0));
|
||||||
|
__ resolve(IS_NOT_NULL, obj_reg);
|
||||||
|
|
||||||
Label done;
|
Label done;
|
||||||
|
|
||||||
|
@ -635,6 +635,7 @@ void TemplateInterpreterGenerator::lock_method() {
|
|||||||
#endif // ASSERT
|
#endif // ASSERT
|
||||||
|
|
||||||
__ bind(done);
|
__ bind(done);
|
||||||
|
__ resolve(IS_NOT_NULL, rax);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add space for monitor & lock
|
// add space for monitor & lock
|
||||||
|
@ -257,6 +257,7 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
|
|||||||
__ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC
|
__ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC
|
||||||
} else {
|
} else {
|
||||||
__ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array
|
__ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array
|
||||||
|
__ resolve(IS_NOT_NULL | ACCESS_READ, buf);
|
||||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||||
__ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
|
__ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
|
||||||
__ addq(buf, off); // + offset
|
__ addq(buf, off); // + offset
|
||||||
@ -312,6 +313,7 @@ address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(Abstract
|
|||||||
// "When calculating operand stack length, values of type long and double have length two."
|
// "When calculating operand stack length, values of type long and double have length two."
|
||||||
} else {
|
} else {
|
||||||
__ movptr(buf, Address(rsp, 3 * wordSize)); // byte[] array
|
__ movptr(buf, Address(rsp, 3 * wordSize)); // byte[] array
|
||||||
|
__ resolve(IS_NOT_NULL | ACCESS_READ, buf);
|
||||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||||
__ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset
|
__ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset
|
||||||
__ addq(buf, off); // + offset
|
__ addq(buf, off); // + offset
|
||||||
|
@ -4357,6 +4357,8 @@ void TemplateTable::monitorenter() {
|
|||||||
// check for NULL object
|
// check for NULL object
|
||||||
__ null_check(rax);
|
__ null_check(rax);
|
||||||
|
|
||||||
|
__ resolve(IS_NOT_NULL, rax);
|
||||||
|
|
||||||
const Address monitor_block_top(
|
const Address monitor_block_top(
|
||||||
rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
|
rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
|
||||||
const Address monitor_block_bot(
|
const Address monitor_block_bot(
|
||||||
@ -4454,6 +4456,8 @@ void TemplateTable::monitorexit() {
|
|||||||
// check for NULL object
|
// check for NULL object
|
||||||
__ null_check(rax);
|
__ null_check(rax);
|
||||||
|
|
||||||
|
__ resolve(IS_NOT_NULL, rax);
|
||||||
|
|
||||||
const Address monitor_block_top(
|
const Address monitor_block_top(
|
||||||
rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
|
rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
|
||||||
const Address monitor_block_bot(
|
const Address monitor_block_bot(
|
||||||
|
@ -212,8 +212,15 @@ const DecoratorSet ARRAYCOPY_DECORATOR_MASK = ARRAYCOPY_CHECKCAST | ARRAYC
|
|||||||
ARRAYCOPY_DISJOINT | ARRAYCOPY_ARRAYOF |
|
ARRAYCOPY_DISJOINT | ARRAYCOPY_ARRAYOF |
|
||||||
ARRAYCOPY_ATOMIC | ARRAYCOPY_ALIGNED;
|
ARRAYCOPY_ATOMIC | ARRAYCOPY_ALIGNED;
|
||||||
|
|
||||||
|
// == Resolve barrier decorators ==
|
||||||
|
// * ACCESS_READ: Indicate that the resolved object is accessed read-only. This allows the GC
|
||||||
|
// backend to use weaker and more efficient barriers.
|
||||||
|
// * ACCESS_WRITE: Indicate that the resolved object is used for write access.
|
||||||
|
const DecoratorSet ACCESS_READ = UCONST64(1) << 29;
|
||||||
|
const DecoratorSet ACCESS_WRITE = UCONST64(1) << 30;
|
||||||
|
|
||||||
// Keep track of the last decorator.
|
// Keep track of the last decorator.
|
||||||
const DecoratorSet DECORATOR_LAST = UCONST64(1) << 28;
|
const DecoratorSet DECORATOR_LAST = UCONST64(1) << 30;
|
||||||
|
|
||||||
namespace AccessInternal {
|
namespace AccessInternal {
|
||||||
// This class adds implied decorators that follow according to decorator rules.
|
// This class adds implied decorators that follow according to decorator rules.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user