1.1 --- a/src/cpu/x86/vm/assembler_x86_64.cpp Thu Jun 05 15:57:56 2008 -0700 1.2 +++ b/src/cpu/x86/vm/assembler_x86_64.cpp Thu Jun 12 13:50:55 2008 -0700 1.3 @@ -683,7 +683,8 @@ 1.4 1.5 case REP8(0xB8): // movl/q r, #32/#64(oop?) 1.6 if (which == end_pc_operand) return ip + (is_64bit ? 8 : 4); 1.7 - assert((which == call32_operand || which == imm64_operand) && is_64bit, ""); 1.8 + assert((which == call32_operand || which == imm64_operand) && is_64bit || 1.9 + which == narrow_oop_operand && !is_64bit, ""); 1.10 return ip; 1.11 1.12 case 0x69: // imul r, a, #32 1.13 @@ -909,7 +910,8 @@ 1.14 } else if (r->is_call() || format == call32_operand) { 1.15 opnd = locate_operand(inst, call32_operand); 1.16 } else if (r->is_data()) { 1.17 - assert(format == imm64_operand || format == disp32_operand, "format ok"); 1.18 + assert(format == imm64_operand || format == disp32_operand || 1.19 + format == narrow_oop_operand, "format ok"); 1.20 opnd = locate_operand(inst, (WhichOperand) format); 1.21 } else { 1.22 assert(format == 0, "cannot specify a format"); 1.23 @@ -5060,6 +5062,8 @@ 1.24 movq(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); 1.25 // set klass to intArrayKlass 1.26 movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr())); 1.27 + // store klass last. concurrent gcs assumes klass length is valid if 1.28 + // klass field is not null. 1.29 store_klass(top, t1); 1.30 1.31 // refill the tlab with an eden allocation 1.32 @@ -5130,8 +5134,7 @@ 1.33 jcc(Assembler::notEqual, cas_label); 1.34 // The bias pattern is present in the object's header. Need to check 1.35 // whether the bias owner and the epoch are both still current. 1.36 - load_klass(tmp_reg, obj_reg); 1.37 - movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); 1.38 + load_prototype_header(tmp_reg, obj_reg); 1.39 orq(tmp_reg, r15_thread); 1.40 xorq(tmp_reg, swap_reg); 1.41 andq(tmp_reg, ~((int) markOopDesc::age_mask_in_place)); 1.42 @@ -5205,8 +5208,7 @@ 1.43 // 1.44 // FIXME: due to a lack of registers we currently blow away the age 1.45 // bits in this situation. Should attempt to preserve them. 1.46 - load_klass(tmp_reg, obj_reg); 1.47 - movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); 1.48 + load_prototype_header(tmp_reg, obj_reg); 1.49 orq(tmp_reg, r15_thread); 1.50 if (os::is_MP()) { 1.51 lock(); 1.52 @@ -5236,8 +5238,7 @@ 1.53 // 1.54 // FIXME: due to a lack of registers we currently blow away the age 1.55 // bits in this situation. Should attempt to preserve them. 1.56 - load_klass(tmp_reg, obj_reg); 1.57 - movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); 1.58 + load_prototype_header(tmp_reg, obj_reg); 1.59 if (os::is_MP()) { 1.60 lock(); 1.61 } 1.62 @@ -5281,17 +5282,32 @@ 1.63 } 1.64 } 1.65 1.66 +void MacroAssembler::load_prototype_header(Register dst, Register src) { 1.67 + if (UseCompressedOops) { 1.68 + movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); 1.69 + movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); 1.70 + } else { 1.71 + movq(dst, Address(src, oopDesc::klass_offset_in_bytes())); 1.72 + movq(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); 1.73 + } 1.74 +} 1.75 + 1.76 void MacroAssembler::store_klass(Register dst, Register src) { 1.77 if (UseCompressedOops) { 1.78 encode_heap_oop_not_null(src); 1.79 - // zero the entire klass field first as the gap needs to be zeroed too. 1.80 - movptr(Address(dst, oopDesc::klass_offset_in_bytes()), NULL_WORD); 1.81 movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); 1.82 } else { 1.83 movq(Address(dst, oopDesc::klass_offset_in_bytes()), src); 1.84 } 1.85 } 1.86 1.87 +void MacroAssembler::store_klass_gap(Register dst, Register src) { 1.88 + if (UseCompressedOops) { 1.89 + // Store to klass gap in destination 1.90 + movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src); 1.91 + } 1.92 +} 1.93 + 1.94 void MacroAssembler::load_heap_oop(Register dst, Address src) { 1.95 if (UseCompressedOops) { 1.96 movl(dst, src); 1.97 @@ -5315,13 +5331,15 @@ 1.98 void MacroAssembler::encode_heap_oop(Register r) { 1.99 assert (UseCompressedOops, "should be compressed"); 1.100 #ifdef ASSERT 1.101 - Label ok; 1.102 - pushq(rscratch1); // cmpptr trashes rscratch1 1.103 - cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); 1.104 - jcc(Assembler::equal, ok); 1.105 - stop("MacroAssembler::encode_heap_oop: heap base corrupted?"); 1.106 - bind(ok); 1.107 - popq(rscratch1); 1.108 + if (CheckCompressedOops) { 1.109 + Label ok; 1.110 + pushq(rscratch1); // cmpptr trashes rscratch1 1.111 + cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); 1.112 + jcc(Assembler::equal, ok); 1.113 + stop("MacroAssembler::encode_heap_oop: heap base corrupted?"); 1.114 + bind(ok); 1.115 + popq(rscratch1); 1.116 + } 1.117 #endif 1.118 verify_oop(r, "broken oop in encode_heap_oop"); 1.119 testq(r, r); 1.120 @@ -5333,11 +5351,13 @@ 1.121 void MacroAssembler::encode_heap_oop_not_null(Register r) { 1.122 assert (UseCompressedOops, "should be compressed"); 1.123 #ifdef ASSERT 1.124 - Label ok; 1.125 - testq(r, r); 1.126 - jcc(Assembler::notEqual, ok); 1.127 - stop("null oop passed to encode_heap_oop_not_null"); 1.128 - bind(ok); 1.129 + if (CheckCompressedOops) { 1.130 + Label ok; 1.131 + testq(r, r); 1.132 + jcc(Assembler::notEqual, ok); 1.133 + stop("null oop passed to encode_heap_oop_not_null"); 1.134 + bind(ok); 1.135 + } 1.136 #endif 1.137 verify_oop(r, "broken oop in encode_heap_oop_not_null"); 1.138 subq(r, r12_heapbase); 1.139 @@ -5347,11 +5367,13 @@ 1.140 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) { 1.141 assert (UseCompressedOops, "should be compressed"); 1.142 #ifdef ASSERT 1.143 - Label ok; 1.144 - testq(src, src); 1.145 - jcc(Assembler::notEqual, ok); 1.146 - stop("null oop passed to encode_heap_oop_not_null2"); 1.147 - bind(ok); 1.148 + if (CheckCompressedOops) { 1.149 + Label ok; 1.150 + testq(src, src); 1.151 + jcc(Assembler::notEqual, ok); 1.152 + stop("null oop passed to encode_heap_oop_not_null2"); 1.153 + bind(ok); 1.154 + } 1.155 #endif 1.156 verify_oop(src, "broken oop in encode_heap_oop_not_null2"); 1.157 if (dst != src) { 1.158 @@ -5364,14 +5386,16 @@ 1.159 void MacroAssembler::decode_heap_oop(Register r) { 1.160 assert (UseCompressedOops, "should be compressed"); 1.161 #ifdef ASSERT 1.162 - Label ok; 1.163 - pushq(rscratch1); 1.164 - cmpptr(r12_heapbase, 1.165 - ExternalAddress((address)Universe::heap_base_addr())); 1.166 - jcc(Assembler::equal, ok); 1.167 - stop("MacroAssembler::decode_heap_oop: heap base corrupted?"); 1.168 - bind(ok); 1.169 - popq(rscratch1); 1.170 + if (CheckCompressedOops) { 1.171 + Label ok; 1.172 + pushq(rscratch1); 1.173 + cmpptr(r12_heapbase, 1.174 + ExternalAddress((address)Universe::heap_base_addr())); 1.175 + jcc(Assembler::equal, ok); 1.176 + stop("MacroAssembler::decode_heap_oop: heap base corrupted?"); 1.177 + bind(ok); 1.178 + popq(rscratch1); 1.179 + } 1.180 #endif 1.181 1.182 Label done; 1.183 @@ -5392,6 +5416,7 @@ 1.184 assert (UseCompressedOops, "should only be used for compressed headers"); 1.185 // Cannot assert, unverified entry point counts instructions (see .ad file) 1.186 // vtableStubs also counts instructions in pd_code_size_limit. 1.187 + // Also do not verify_oop as this is called by verify_oop. 1.188 assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong"); 1.189 leaq(r, Address(r12_heapbase, r, Address::times_8, 0)); 1.190 } 1.191 @@ -5400,10 +5425,24 @@ 1.192 assert (UseCompressedOops, "should only be used for compressed headers"); 1.193 // Cannot assert, unverified entry point counts instructions (see .ad file) 1.194 // vtableStubs also counts instructions in pd_code_size_limit. 1.195 + // Also do not verify_oop as this is called by verify_oop. 1.196 assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong"); 1.197 leaq(dst, Address(r12_heapbase, src, Address::times_8, 0)); 1.198 } 1.199 1.200 +void MacroAssembler::set_narrow_oop(Register dst, jobject obj) { 1.201 + assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); 1.202 + int oop_index = oop_recorder()->find_index(obj); 1.203 + RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.204 + 1.205 + // movl dst,obj 1.206 + InstructionMark im(this); 1.207 + int encode = prefix_and_encode(dst->encoding()); 1.208 + emit_byte(0xB8 | encode); 1.209 + emit_data(oop_index, rspec, narrow_oop_operand); 1.210 +} 1.211 + 1.212 + 1.213 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) { 1.214 switch (cond) { 1.215 // Note some conditions are synonyms for others