Mercurial > hg > truffle
diff src/cpu/x86/vm/assembler_x86_64.cpp @ 344:6aae2f9d0294
Merge
author | ysr |
---|---|
date | Thu, 12 Jun 2008 13:50:55 -0700 |
parents | 37f87013dfd8 cf1821c649d9 |
children | 1ee8caae33af |
line wrap: on
line diff
--- a/src/cpu/x86/vm/assembler_x86_64.cpp Thu Jun 05 15:57:56 2008 -0700 +++ b/src/cpu/x86/vm/assembler_x86_64.cpp Thu Jun 12 13:50:55 2008 -0700 @@ -683,7 +683,8 @@ case REP8(0xB8): // movl/q r, #32/#64(oop?) if (which == end_pc_operand) return ip + (is_64bit ? 8 : 4); - assert((which == call32_operand || which == imm64_operand) && is_64bit, ""); + assert((which == call32_operand || which == imm64_operand) && is_64bit || + which == narrow_oop_operand && !is_64bit, ""); return ip; case 0x69: // imul r, a, #32 @@ -909,7 +910,8 @@ } else if (r->is_call() || format == call32_operand) { opnd = locate_operand(inst, call32_operand); } else if (r->is_data()) { - assert(format == imm64_operand || format == disp32_operand, "format ok"); + assert(format == imm64_operand || format == disp32_operand || + format == narrow_oop_operand, "format ok"); opnd = locate_operand(inst, (WhichOperand) format); } else { assert(format == 0, "cannot specify a format"); @@ -5060,6 +5062,8 @@ movq(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); // set klass to intArrayKlass movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr())); + // store klass last. concurrent gcs assumes klass length is valid if + // klass field is not null. store_klass(top, t1); // refill the tlab with an eden allocation @@ -5130,8 +5134,7 @@ jcc(Assembler::notEqual, cas_label); // The bias pattern is present in the object's header. Need to check // whether the bias owner and the epoch are both still current. - load_klass(tmp_reg, obj_reg); - movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + load_prototype_header(tmp_reg, obj_reg); orq(tmp_reg, r15_thread); xorq(tmp_reg, swap_reg); andq(tmp_reg, ~((int) markOopDesc::age_mask_in_place)); @@ -5205,8 +5208,7 @@ // // FIXME: due to a lack of registers we currently blow away the age // bits in this situation. Should attempt to preserve them. - load_klass(tmp_reg, obj_reg); - movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + load_prototype_header(tmp_reg, obj_reg); orq(tmp_reg, r15_thread); if (os::is_MP()) { lock(); @@ -5236,8 +5238,7 @@ // // FIXME: due to a lack of registers we currently blow away the age // bits in this situation. Should attempt to preserve them. - load_klass(tmp_reg, obj_reg); - movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + load_prototype_header(tmp_reg, obj_reg); if (os::is_MP()) { lock(); } @@ -5281,17 +5282,32 @@ } } +void MacroAssembler::load_prototype_header(Register dst, Register src) { + if (UseCompressedOops) { + movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); + movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + } else { + movq(dst, Address(src, oopDesc::klass_offset_in_bytes())); + movq(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + } +} + void MacroAssembler::store_klass(Register dst, Register src) { if (UseCompressedOops) { encode_heap_oop_not_null(src); - // zero the entire klass field first as the gap needs to be zeroed too. - movptr(Address(dst, oopDesc::klass_offset_in_bytes()), NULL_WORD); movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); } else { movq(Address(dst, oopDesc::klass_offset_in_bytes()), src); } } +void MacroAssembler::store_klass_gap(Register dst, Register src) { + if (UseCompressedOops) { + // Store to klass gap in destination + movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src); + } +} + void MacroAssembler::load_heap_oop(Register dst, Address src) { if (UseCompressedOops) { movl(dst, src); @@ -5315,13 +5331,15 @@ void MacroAssembler::encode_heap_oop(Register r) { assert (UseCompressedOops, "should be compressed"); #ifdef ASSERT - Label ok; - pushq(rscratch1); // cmpptr trashes rscratch1 - cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); - jcc(Assembler::equal, ok); - stop("MacroAssembler::encode_heap_oop: heap base corrupted?"); - bind(ok); - popq(rscratch1); + if (CheckCompressedOops) { + Label ok; + pushq(rscratch1); // cmpptr trashes rscratch1 + cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); + jcc(Assembler::equal, ok); + stop("MacroAssembler::encode_heap_oop: heap base corrupted?"); + bind(ok); + popq(rscratch1); + } #endif verify_oop(r, "broken oop in encode_heap_oop"); testq(r, r); @@ -5333,11 +5351,13 @@ void MacroAssembler::encode_heap_oop_not_null(Register r) { assert (UseCompressedOops, "should be compressed"); #ifdef ASSERT - Label ok; - testq(r, r); - jcc(Assembler::notEqual, ok); - stop("null oop passed to encode_heap_oop_not_null"); - bind(ok); + if (CheckCompressedOops) { + Label ok; + testq(r, r); + jcc(Assembler::notEqual, ok); + stop("null oop passed to encode_heap_oop_not_null"); + bind(ok); + } #endif verify_oop(r, "broken oop in encode_heap_oop_not_null"); subq(r, r12_heapbase); @@ -5347,11 +5367,13 @@ void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) { assert (UseCompressedOops, "should be compressed"); #ifdef ASSERT - Label ok; - testq(src, src); - jcc(Assembler::notEqual, ok); - stop("null oop passed to encode_heap_oop_not_null2"); - bind(ok); + if (CheckCompressedOops) { + Label ok; + testq(src, src); + jcc(Assembler::notEqual, ok); + stop("null oop passed to encode_heap_oop_not_null2"); + bind(ok); + } #endif verify_oop(src, "broken oop in encode_heap_oop_not_null2"); if (dst != src) { @@ -5364,14 +5386,16 @@ void MacroAssembler::decode_heap_oop(Register r) { assert (UseCompressedOops, "should be compressed"); #ifdef ASSERT - Label ok; - pushq(rscratch1); - cmpptr(r12_heapbase, - ExternalAddress((address)Universe::heap_base_addr())); - jcc(Assembler::equal, ok); - stop("MacroAssembler::decode_heap_oop: heap base corrupted?"); - bind(ok); - popq(rscratch1); + if (CheckCompressedOops) { + Label ok; + pushq(rscratch1); + cmpptr(r12_heapbase, + ExternalAddress((address)Universe::heap_base_addr())); + jcc(Assembler::equal, ok); + stop("MacroAssembler::decode_heap_oop: heap base corrupted?"); + bind(ok); + popq(rscratch1); + } #endif Label done; @@ -5392,6 +5416,7 @@ assert (UseCompressedOops, "should only be used for compressed headers"); // Cannot assert, unverified entry point counts instructions (see .ad file) // vtableStubs also counts instructions in pd_code_size_limit. + // Also do not verify_oop as this is called by verify_oop. assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong"); leaq(r, Address(r12_heapbase, r, Address::times_8, 0)); } @@ -5400,10 +5425,24 @@ assert (UseCompressedOops, "should only be used for compressed headers"); // Cannot assert, unverified entry point counts instructions (see .ad file) // vtableStubs also counts instructions in pd_code_size_limit. + // Also do not verify_oop as this is called by verify_oop. assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong"); leaq(dst, Address(r12_heapbase, src, Address::times_8, 0)); } +void MacroAssembler::set_narrow_oop(Register dst, jobject obj) { + assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); + int oop_index = oop_recorder()->find_index(obj); + RelocationHolder rspec = oop_Relocation::spec(oop_index); + + // movl dst,obj + InstructionMark im(this); + int encode = prefix_and_encode(dst->encoding()); + emit_byte(0xB8 | encode); + emit_data(oop_index, rspec, narrow_oop_operand); +} + + Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) { switch (cond) { // Note some conditions are synonyms for others