< prev index next > src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
Print this page
// rcx: osr buffer
//
// build frame
ciMethod* m = compilation()->method();
- __ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes());
+ __ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes(), compilation()->max_monitors());
// OSR buffer is
//
// locals[nlocals-1..0]
// monitors[0..number_of_locks]
}
__ allocate_array(op->obj()->as_register(),
len,
tmp1,
tmp2,
- arrayOopDesc::header_size(op->type()),
+ arrayOopDesc::base_offset_in_bytes(op->type()),
array_element_size(op->type()),
op->klass()->as_register(),
*op->stub()->entry());
}
__ bind(*op->stub()->continuation());
Register src_pos = op->src_pos()->as_register();
Register dst_pos = op->dst_pos()->as_register();
Register length = op->length()->as_register();
Register tmp = op->tmp()->as_register();
Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
+ Register tmp2 = LP64_ONLY(rscratch2) NOT_LP64(noreg);
CodeStub* stub = op->stub();
int flags = op->flags();
BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL;
if (is_reference_type(basic_type)) basic_type = T_OBJECT;
ShouldNotReachHere();
}
Address src_length_addr = Address(src, arrayOopDesc::length_offset_in_bytes());
Address dst_length_addr = Address(dst, arrayOopDesc::length_offset_in_bytes());
+ #ifndef _LP64
Address src_klass_addr = Address(src, oopDesc::klass_offset_in_bytes());
Address dst_klass_addr = Address(dst, oopDesc::klass_offset_in_bytes());
-
+ #endif
// length and pos's are all sign extended at this point on 64bit
// test for NULL
if (flags & LIR_OpArrayCopy::src_null_check) {
__ testptr(src, src);
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) {
- __ movl(tmp, src_klass_addr);
- __ cmpl(tmp, dst_klass_addr);
- } else {
- __ movptr(tmp, src_klass_addr);
- __ cmpptr(tmp, dst_klass_addr);
- }
+ #ifdef _LP64
+ __ load_nklass(tmp, src);
+ __ load_nklass(tmp2, dst);
+ __ cmpl(tmp, tmp2);
+ #else
+ __ movptr(tmp, src_klass_addr);
+ __ cmpptr(tmp, dst_klass_addr);
+ #endif
__ jcc(Assembler::notEqual, *stub->entry());
} else {
// For object arrays, if src is a sub class of dst then we can
// safely do the copy.
Label cont, slow;
// 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());
#ifdef _LP64
- if (UseCompressedClassPointers) {
- __ encode_klass_not_null(tmp, rscratch1);
- }
- #endif
-
+ assert(UseCompressedClassPointers, "Lilliput");
+ __ encode_klass_not_null(tmp, rscratch1);
if (basic_type != T_OBJECT) {
-
- if (UseCompressedClassPointers) __ cmpl(tmp, dst_klass_addr);
- else __ cmpptr(tmp, dst_klass_addr);
+ __ load_nklass(tmp2, dst);
+ __ cmpl(tmp, tmp2);
__ jcc(Assembler::notEqual, halt);
- if (UseCompressedClassPointers) __ cmpl(tmp, src_klass_addr);
- else __ cmpptr(tmp, src_klass_addr);
+ __ load_nklass(tmp2, src);
+ __ cmpl(tmp, tmp2);
__ jcc(Assembler::equal, known_ok);
} else {
- if (UseCompressedClassPointers) __ cmpl(tmp, dst_klass_addr);
- else __ cmpptr(tmp, dst_klass_addr);
+ __ load_nklass(tmp2, dst);
+ __ cmpl(tmp, tmp2);
+ #else
+ if (basic_type != T_OBJECT) {
+ __ cmpptr(tmp, dst_klass_addr);
+ __ jcc(Assembler::notEqual, halt);
+ __ cmpptr(tmp, src_klass_addr);
+ __ jcc(Assembler::equal, known_ok);
+ } else {
+ __ cmpptr(tmp, dst_klass_addr);
+ #endif
__ jcc(Assembler::equal, known_ok);
__ cmpptr(src, dst);
__ jcc(Assembler::equal, known_ok);
}
__ bind(halt);
__ null_check(obj);
}
__ jmp(*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");
+ Register tmp = UseFastLocking ? op->scratch_opr()->as_register() : noreg;
// add debug info for NullPointerException only if one is possible
- int null_check_offset = __ lock_object(hdr, obj, lock, *op->stub()->entry());
+ int null_check_offset = __ lock_object(hdr, obj, lock, tmp, *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) {
void LIR_Assembler::emit_load_klass(LIR_OpLoadKlass* op) {
Register obj = op->obj()->as_pointer_register();
Register result = op->result_opr()->as_pointer_register();
- CodeEmitInfo* info = op->info();
- if (info != NULL) {
- add_debug_info_for_null_check_here(info);
+ if (op->info() != NULL) {
+ add_debug_info_for_null_check_here(op->info());
}
-
#ifdef _LP64
- if (UseCompressedClassPointers) {
- __ movl(result, Address(obj, oopDesc::klass_offset_in_bytes()));
- __ decode_klass_not_null(result, rscratch1);
- } else
+ Register tmp = rscratch1;
+ assert_different_registers(tmp, obj);
+ assert_different_registers(tmp, result);
+
+ // Check if we can take the (common) fast path, if obj is unlocked.
+ __ movq(result, Address(obj, oopDesc::mark_offset_in_bytes()));
+ __ testb(result, markWord::monitor_value);
+ __ jcc(Assembler::notZero, *op->stub()->entry());
+ __ bind(*op->stub()->continuation());
+ // Fast-path: shift and decode Klass*.
+ __ shrq(result, markWord::klass_shift);
+ __ decode_klass_not_null(result, tmp);
+ #else
+ __ movptr(result, Address(obj, oopDesc::klass_offset_in_bytes()));
+ // Not really needed, but bind the label anyway to make compiler happy.
+ __ bind(*op->stub()->continuation());
#endif
- __ movptr(result, Address(obj, oopDesc::klass_offset_in_bytes()));
}
void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
ciMethod* method = op->profiled_method();
int bci = op->profiled_bci();
__ jccb(Assembler::notZero, update);
if (!TypeEntries::was_null_seen(current_klass)) {
__ orptr(mdo_addr, TypeEntries::null_seen);
}
if (do_update) {
- #ifndef ASSERT
- __ jmpb(next);
- }
- #else
__ jmp(next);
}
+ #ifdef ASSERT
} else {
__ testptr(tmp, tmp);
__ jcc(Assembler::notZero, update);
__ stop("unexpected null obj");
#endif
< prev index next >