< prev index next > src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
Print this page
// Preform needed unlocking
MonitorExitStub* stub = NULL;
if (method()->is_synchronized()) {
monitor_address(0, FrameMap::r0_opr);
stub = new MonitorExitStub(FrameMap::r0_opr, true, 0);
! __ unlock_object(r5, r4, r0, *stub->entry());
__ bind(*stub->continuation());
}
if (compilation()->env()->dtrace_method_probes()) {
__ mov(c_rarg0, rthread);
// Preform needed unlocking
MonitorExitStub* stub = NULL;
if (method()->is_synchronized()) {
monitor_address(0, FrameMap::r0_opr);
stub = new MonitorExitStub(FrameMap::r0_opr, true, 0);
! __ unlock_object(r5, r4, r0, r6, *stub->entry());
__ bind(*stub->continuation());
}
if (compilation()->env()->dtrace_method_probes()) {
__ mov(c_rarg0, rthread);
}
__ allocate_array(op->obj()->as_register(),
len,
tmp1,
tmp2,
! arrayOopDesc::header_size(op->type()),
array_element_size(op->type()),
op->klass()->as_register(),
*op->stub()->entry());
}
__ bind(*op->stub()->continuation());
}
__ allocate_array(op->obj()->as_register(),
len,
tmp1,
tmp2,
! arrayOopDesc::base_offset_in_bytes(op->type()),
array_element_size(op->type()),
op->klass()->as_register(),
*op->stub()->entry());
}
__ bind(*op->stub()->continuation());
if (flags & LIR_OpArrayCopy::type_check) {
// We don't know the array types are compatible
if (basic_type != T_OBJECT) {
// Simple test for basic type arrays
if (UseCompressedClassPointers) {
! __ ldrw(tmp, src_klass_addr);
! __ ldrw(rscratch1, dst_klass_addr);
__ cmpw(tmp, rscratch1);
} else {
! __ ldr(tmp, src_klass_addr);
! __ ldr(rscratch1, dst_klass_addr);
__ cmp(tmp, rscratch1);
}
__ br(Assembler::NE, *stub->entry());
} else {
// For object arrays, if src is a sub class of dst then we can
if (flags & LIR_OpArrayCopy::type_check) {
// We don't know the array types are compatible
if (basic_type != T_OBJECT) {
// Simple test for basic type arrays
if (UseCompressedClassPointers) {
! __ load_nklass(tmp, src);
! __ load_nklass(rscratch1, dst);
__ cmpw(tmp, rscratch1);
} else {
! __ ldr(tmp, Address(src, oopDesc::klass_offset_in_bytes()));
! __ ldr(rscratch1, Address(dst, oopDesc::klass_offset_in_bytes()));
__ cmp(tmp, rscratch1);
}
__ br(Assembler::NE, *stub->entry());
} else {
// For object arrays, if src is a sub class of dst then we can
// dst type is exactly the expected type and the src type is a
// subtype which we can't check or src is the same array as dst
// but not necessarily exactly of type default_type.
Label known_ok, halt;
__ mov_metadata(tmp, default_type->constant_encoding());
- if (UseCompressedClassPointers) {
- __ encode_klass_not_null(tmp);
- }
if (basic_type != T_OBJECT) {
!
- if (UseCompressedClassPointers) {
- __ ldrw(rscratch1, dst_klass_addr);
- __ cmpw(tmp, rscratch1);
- } else {
- __ ldr(rscratch1, dst_klass_addr);
- __ cmp(tmp, rscratch1);
- }
__ br(Assembler::NE, halt);
! if (UseCompressedClassPointers) {
- __ ldrw(rscratch1, src_klass_addr);
- __ cmpw(tmp, rscratch1);
- } else {
- __ ldr(rscratch1, src_klass_addr);
- __ cmp(tmp, rscratch1);
- }
__ br(Assembler::EQ, known_ok);
} else {
! if (UseCompressedClassPointers) {
- __ ldrw(rscratch1, dst_klass_addr);
- __ cmpw(tmp, rscratch1);
- } else {
- __ ldr(rscratch1, dst_klass_addr);
- __ cmp(tmp, rscratch1);
- }
__ br(Assembler::EQ, known_ok);
__ cmp(src, dst);
__ br(Assembler::EQ, known_ok);
}
__ bind(halt);
// dst type is exactly the expected type and the src type is a
// subtype which we can't check or src is the same array as dst
// but not necessarily exactly of type default_type.
Label known_ok, halt;
__ mov_metadata(tmp, default_type->constant_encoding());
if (basic_type != T_OBJECT) {
! __ cmp_klass(dst, tmp, rscratch1);
__ br(Assembler::NE, halt);
! __ cmp_klass(src, tmp, rscratch1);
__ br(Assembler::EQ, known_ok);
} else {
! __ cmp_klass(dst, tmp, rscratch1);
__ br(Assembler::EQ, known_ok);
__ cmp(src, dst);
__ br(Assembler::EQ, known_ok);
}
__ bind(halt);
void LIR_Assembler::emit_lock(LIR_OpLock* op) {
Register obj = op->obj_opr()->as_register(); // may not be an oop
Register hdr = op->hdr_opr()->as_register();
Register lock = op->lock_opr()->as_register();
! if (!UseFastLocking) {
__ b(*op->stub()->entry());
} else if (op->code() == lir_lock) {
- Register scratch = noreg;
- if (UseBiasedLocking) {
- scratch = op->scratch_opr()->as_register();
- }
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
// add debug info for NullPointerException only if one is possible
! int null_check_offset = __ lock_object(hdr, obj, lock, scratch, *op->stub()->entry());
if (op->info() != NULL) {
add_debug_info_for_null_check(null_check_offset, op->info());
}
// done
} else if (op->code() == lir_unlock) {
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
! __ unlock_object(hdr, obj, lock, *op->stub()->entry());
} else {
Unimplemented();
}
__ bind(*op->stub()->continuation());
}
void LIR_Assembler::emit_lock(LIR_OpLock* op) {
Register obj = op->obj_opr()->as_register(); // may not be an oop
Register hdr = op->hdr_opr()->as_register();
Register lock = op->lock_opr()->as_register();
! Register temp = op->scratch_opr()->as_register();
+ if (LockingMode == LM_MONITOR) {
+ if (op->info() != NULL) {
+ add_debug_info_for_null_check_here(op->info());
+ __ null_check(obj, -1);
+ }
__ b(*op->stub()->entry());
} else if (op->code() == lir_lock) {
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
// add debug info for NullPointerException only if one is possible
! int null_check_offset = __ lock_object(hdr, obj, lock, temp, *op->stub()->entry());
if (op->info() != NULL) {
add_debug_info_for_null_check(null_check_offset, op->info());
}
// done
} else if (op->code() == lir_unlock) {
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
! __ unlock_object(hdr, obj, lock, temp, *op->stub()->entry());
} else {
Unimplemented();
}
__ bind(*op->stub()->continuation());
}
if (info != NULL) {
add_debug_info_for_null_check_here(info);
}
if (UseCompressedClassPointers) {
! __ ldrw(result, Address (obj, oopDesc::klass_offset_in_bytes()));
__ decode_klass_not_null(result);
} else {
__ ldr(result, Address (obj, oopDesc::klass_offset_in_bytes()));
}
}
if (info != NULL) {
add_debug_info_for_null_check_here(info);
}
if (UseCompressedClassPointers) {
! if (UseCompactObjectHeaders) {
+ // Check if we can take the (common) fast path, if obj is unlocked.
+ __ ldr(result, Address(obj, oopDesc::mark_offset_in_bytes()));
+ __ tst(result, markWord::monitor_value);
+ __ br(Assembler::NE, *op->stub()->entry());
+ __ bind(*op->stub()->continuation());
+
+ // Shift to get proper narrow Klass*.
+ __ lsr(result, result, markWord::klass_shift);
+ } else {
+ __ ldrw(result, Address (obj, oopDesc::klass_offset_in_bytes()));
+ }
__ decode_klass_not_null(result);
} else {
__ ldr(result, Address (obj, oopDesc::klass_offset_in_bytes()));
}
}
< prev index next >