comparison 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
comparison
equal deleted inserted replaced
342:37f87013dfd8 344:6aae2f9d0294
681 } 681 }
682 break; 682 break;
683 683
684 case REP8(0xB8): // movl/q r, #32/#64(oop?) 684 case REP8(0xB8): // movl/q r, #32/#64(oop?)
685 if (which == end_pc_operand) return ip + (is_64bit ? 8 : 4); 685 if (which == end_pc_operand) return ip + (is_64bit ? 8 : 4);
686 assert((which == call32_operand || which == imm64_operand) && is_64bit, ""); 686 assert((which == call32_operand || which == imm64_operand) && is_64bit ||
687 which == narrow_oop_operand && !is_64bit, "");
687 return ip; 688 return ip;
688 689
689 case 0x69: // imul r, a, #32 690 case 0x69: // imul r, a, #32
690 case 0xC7: // movl a, #32(oop?) 691 case 0xC7: // movl a, #32(oop?)
691 tail_size = 4; 692 tail_size = 4;
907 if (r->type() == relocInfo::none) { 908 if (r->type() == relocInfo::none) {
908 return; 909 return;
909 } else if (r->is_call() || format == call32_operand) { 910 } else if (r->is_call() || format == call32_operand) {
910 opnd = locate_operand(inst, call32_operand); 911 opnd = locate_operand(inst, call32_operand);
911 } else if (r->is_data()) { 912 } else if (r->is_data()) {
912 assert(format == imm64_operand || format == disp32_operand, "format ok"); 913 assert(format == imm64_operand || format == disp32_operand ||
914 format == narrow_oop_operand, "format ok");
913 opnd = locate_operand(inst, (WhichOperand) format); 915 opnd = locate_operand(inst, (WhichOperand) format);
914 } else { 916 } else {
915 assert(format == 0, "cannot specify a format"); 917 assert(format == 0, "cannot specify a format");
916 return; 918 return;
917 } 919 }
5058 addq(t1, (int)ThreadLocalAllocBuffer::alignment_reserve()); 5060 addq(t1, (int)ThreadLocalAllocBuffer::alignment_reserve());
5059 shlq(t1, log2_intptr(HeapWordSize / sizeof(jint))); 5061 shlq(t1, log2_intptr(HeapWordSize / sizeof(jint)));
5060 movq(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); 5062 movq(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);
5061 // set klass to intArrayKlass 5063 // set klass to intArrayKlass
5062 movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr())); 5064 movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr()));
5065 // store klass last. concurrent gcs assumes klass length is valid if
5066 // klass field is not null.
5063 store_klass(top, t1); 5067 store_klass(top, t1);
5064 5068
5065 // refill the tlab with an eden allocation 5069 // refill the tlab with an eden allocation
5066 bind(do_refill); 5070 bind(do_refill);
5067 movq(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); 5071 movq(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset())));
5128 andq(tmp_reg, markOopDesc::biased_lock_mask_in_place); 5132 andq(tmp_reg, markOopDesc::biased_lock_mask_in_place);
5129 cmpq(tmp_reg, markOopDesc::biased_lock_pattern); 5133 cmpq(tmp_reg, markOopDesc::biased_lock_pattern);
5130 jcc(Assembler::notEqual, cas_label); 5134 jcc(Assembler::notEqual, cas_label);
5131 // The bias pattern is present in the object's header. Need to check 5135 // The bias pattern is present in the object's header. Need to check
5132 // whether the bias owner and the epoch are both still current. 5136 // whether the bias owner and the epoch are both still current.
5133 load_klass(tmp_reg, obj_reg); 5137 load_prototype_header(tmp_reg, obj_reg);
5134 movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
5135 orq(tmp_reg, r15_thread); 5138 orq(tmp_reg, r15_thread);
5136 xorq(tmp_reg, swap_reg); 5139 xorq(tmp_reg, swap_reg);
5137 andq(tmp_reg, ~((int) markOopDesc::age_mask_in_place)); 5140 andq(tmp_reg, ~((int) markOopDesc::age_mask_in_place));
5138 if (counters != NULL) { 5141 if (counters != NULL) {
5139 cond_inc32(Assembler::zero, 5142 cond_inc32(Assembler::zero,
5203 // bias in the current epoch. In other words, we allow transfer of 5206 // bias in the current epoch. In other words, we allow transfer of
5204 // the bias from one thread to another directly in this situation. 5207 // the bias from one thread to another directly in this situation.
5205 // 5208 //
5206 // FIXME: due to a lack of registers we currently blow away the age 5209 // FIXME: due to a lack of registers we currently blow away the age
5207 // bits in this situation. Should attempt to preserve them. 5210 // bits in this situation. Should attempt to preserve them.
5208 load_klass(tmp_reg, obj_reg); 5211 load_prototype_header(tmp_reg, obj_reg);
5209 movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
5210 orq(tmp_reg, r15_thread); 5212 orq(tmp_reg, r15_thread);
5211 if (os::is_MP()) { 5213 if (os::is_MP()) {
5212 lock(); 5214 lock();
5213 } 5215 }
5214 cmpxchgq(tmp_reg, Address(obj_reg, 0)); 5216 cmpxchgq(tmp_reg, Address(obj_reg, 0));
5234 // bias of this particular object, so it's okay to continue in the 5236 // bias of this particular object, so it's okay to continue in the
5235 // normal locking code. 5237 // normal locking code.
5236 // 5238 //
5237 // FIXME: due to a lack of registers we currently blow away the age 5239 // FIXME: due to a lack of registers we currently blow away the age
5238 // bits in this situation. Should attempt to preserve them. 5240 // bits in this situation. Should attempt to preserve them.
5239 load_klass(tmp_reg, obj_reg); 5241 load_prototype_header(tmp_reg, obj_reg);
5240 movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
5241 if (os::is_MP()) { 5242 if (os::is_MP()) {
5242 lock(); 5243 lock();
5243 } 5244 }
5244 cmpxchgq(tmp_reg, Address(obj_reg, 0)); 5245 cmpxchgq(tmp_reg, Address(obj_reg, 0));
5245 // Fall through to the normal CAS-based lock, because no matter what 5246 // Fall through to the normal CAS-based lock, because no matter what
5279 } else { 5280 } else {
5280 movq(dst, Address(src, oopDesc::klass_offset_in_bytes())); 5281 movq(dst, Address(src, oopDesc::klass_offset_in_bytes()));
5281 } 5282 }
5282 } 5283 }
5283 5284
5285 void MacroAssembler::load_prototype_header(Register dst, Register src) {
5286 if (UseCompressedOops) {
5287 movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
5288 movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
5289 } else {
5290 movq(dst, Address(src, oopDesc::klass_offset_in_bytes()));
5291 movq(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
5292 }
5293 }
5294
5284 void MacroAssembler::store_klass(Register dst, Register src) { 5295 void MacroAssembler::store_klass(Register dst, Register src) {
5285 if (UseCompressedOops) { 5296 if (UseCompressedOops) {
5286 encode_heap_oop_not_null(src); 5297 encode_heap_oop_not_null(src);
5287 // zero the entire klass field first as the gap needs to be zeroed too.
5288 movptr(Address(dst, oopDesc::klass_offset_in_bytes()), NULL_WORD);
5289 movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); 5298 movl(Address(dst, oopDesc::klass_offset_in_bytes()), src);
5290 } else { 5299 } else {
5291 movq(Address(dst, oopDesc::klass_offset_in_bytes()), src); 5300 movq(Address(dst, oopDesc::klass_offset_in_bytes()), src);
5301 }
5302 }
5303
5304 void MacroAssembler::store_klass_gap(Register dst, Register src) {
5305 if (UseCompressedOops) {
5306 // Store to klass gap in destination
5307 movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src);
5292 } 5308 }
5293 } 5309 }
5294 5310
5295 void MacroAssembler::load_heap_oop(Register dst, Address src) { 5311 void MacroAssembler::load_heap_oop(Register dst, Address src) {
5296 if (UseCompressedOops) { 5312 if (UseCompressedOops) {
5313 5329
5314 // Algorithm must match oop.inline.hpp encode_heap_oop. 5330 // Algorithm must match oop.inline.hpp encode_heap_oop.
5315 void MacroAssembler::encode_heap_oop(Register r) { 5331 void MacroAssembler::encode_heap_oop(Register r) {
5316 assert (UseCompressedOops, "should be compressed"); 5332 assert (UseCompressedOops, "should be compressed");
5317 #ifdef ASSERT 5333 #ifdef ASSERT
5318 Label ok; 5334 if (CheckCompressedOops) {
5319 pushq(rscratch1); // cmpptr trashes rscratch1 5335 Label ok;
5320 cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); 5336 pushq(rscratch1); // cmpptr trashes rscratch1
5321 jcc(Assembler::equal, ok); 5337 cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr()));
5322 stop("MacroAssembler::encode_heap_oop: heap base corrupted?"); 5338 jcc(Assembler::equal, ok);
5323 bind(ok); 5339 stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
5324 popq(rscratch1); 5340 bind(ok);
5341 popq(rscratch1);
5342 }
5325 #endif 5343 #endif
5326 verify_oop(r, "broken oop in encode_heap_oop"); 5344 verify_oop(r, "broken oop in encode_heap_oop");
5327 testq(r, r); 5345 testq(r, r);
5328 cmovq(Assembler::equal, r, r12_heapbase); 5346 cmovq(Assembler::equal, r, r12_heapbase);
5329 subq(r, r12_heapbase); 5347 subq(r, r12_heapbase);
5331 } 5349 }
5332 5350
5333 void MacroAssembler::encode_heap_oop_not_null(Register r) { 5351 void MacroAssembler::encode_heap_oop_not_null(Register r) {
5334 assert (UseCompressedOops, "should be compressed"); 5352 assert (UseCompressedOops, "should be compressed");
5335 #ifdef ASSERT 5353 #ifdef ASSERT
5336 Label ok; 5354 if (CheckCompressedOops) {
5337 testq(r, r); 5355 Label ok;
5338 jcc(Assembler::notEqual, ok); 5356 testq(r, r);
5339 stop("null oop passed to encode_heap_oop_not_null"); 5357 jcc(Assembler::notEqual, ok);
5340 bind(ok); 5358 stop("null oop passed to encode_heap_oop_not_null");
5359 bind(ok);
5360 }
5341 #endif 5361 #endif
5342 verify_oop(r, "broken oop in encode_heap_oop_not_null"); 5362 verify_oop(r, "broken oop in encode_heap_oop_not_null");
5343 subq(r, r12_heapbase); 5363 subq(r, r12_heapbase);
5344 shrq(r, LogMinObjAlignmentInBytes); 5364 shrq(r, LogMinObjAlignmentInBytes);
5345 } 5365 }
5346 5366
5347 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) { 5367 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
5348 assert (UseCompressedOops, "should be compressed"); 5368 assert (UseCompressedOops, "should be compressed");
5349 #ifdef ASSERT 5369 #ifdef ASSERT
5350 Label ok; 5370 if (CheckCompressedOops) {
5351 testq(src, src); 5371 Label ok;
5352 jcc(Assembler::notEqual, ok); 5372 testq(src, src);
5353 stop("null oop passed to encode_heap_oop_not_null2"); 5373 jcc(Assembler::notEqual, ok);
5354 bind(ok); 5374 stop("null oop passed to encode_heap_oop_not_null2");
5375 bind(ok);
5376 }
5355 #endif 5377 #endif
5356 verify_oop(src, "broken oop in encode_heap_oop_not_null2"); 5378 verify_oop(src, "broken oop in encode_heap_oop_not_null2");
5357 if (dst != src) { 5379 if (dst != src) {
5358 movq(dst, src); 5380 movq(dst, src);
5359 } 5381 }
5362 } 5384 }
5363 5385
5364 void MacroAssembler::decode_heap_oop(Register r) { 5386 void MacroAssembler::decode_heap_oop(Register r) {
5365 assert (UseCompressedOops, "should be compressed"); 5387 assert (UseCompressedOops, "should be compressed");
5366 #ifdef ASSERT 5388 #ifdef ASSERT
5367 Label ok; 5389 if (CheckCompressedOops) {
5368 pushq(rscratch1); 5390 Label ok;
5369 cmpptr(r12_heapbase, 5391 pushq(rscratch1);
5370 ExternalAddress((address)Universe::heap_base_addr())); 5392 cmpptr(r12_heapbase,
5371 jcc(Assembler::equal, ok); 5393 ExternalAddress((address)Universe::heap_base_addr()));
5372 stop("MacroAssembler::decode_heap_oop: heap base corrupted?"); 5394 jcc(Assembler::equal, ok);
5373 bind(ok); 5395 stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
5374 popq(rscratch1); 5396 bind(ok);
5397 popq(rscratch1);
5398 }
5375 #endif 5399 #endif
5376 5400
5377 Label done; 5401 Label done;
5378 shlq(r, LogMinObjAlignmentInBytes); 5402 shlq(r, LogMinObjAlignmentInBytes);
5379 jccb(Assembler::equal, done); 5403 jccb(Assembler::equal, done);
5390 5414
5391 void MacroAssembler::decode_heap_oop_not_null(Register r) { 5415 void MacroAssembler::decode_heap_oop_not_null(Register r) {
5392 assert (UseCompressedOops, "should only be used for compressed headers"); 5416 assert (UseCompressedOops, "should only be used for compressed headers");
5393 // Cannot assert, unverified entry point counts instructions (see .ad file) 5417 // Cannot assert, unverified entry point counts instructions (see .ad file)
5394 // vtableStubs also counts instructions in pd_code_size_limit. 5418 // vtableStubs also counts instructions in pd_code_size_limit.
5419 // Also do not verify_oop as this is called by verify_oop.
5395 assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong"); 5420 assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
5396 leaq(r, Address(r12_heapbase, r, Address::times_8, 0)); 5421 leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
5397 } 5422 }
5398 5423
5399 void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) { 5424 void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) {
5400 assert (UseCompressedOops, "should only be used for compressed headers"); 5425 assert (UseCompressedOops, "should only be used for compressed headers");
5401 // Cannot assert, unverified entry point counts instructions (see .ad file) 5426 // Cannot assert, unverified entry point counts instructions (see .ad file)
5402 // vtableStubs also counts instructions in pd_code_size_limit. 5427 // vtableStubs also counts instructions in pd_code_size_limit.
5428 // Also do not verify_oop as this is called by verify_oop.
5403 assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong"); 5429 assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
5404 leaq(dst, Address(r12_heapbase, src, Address::times_8, 0)); 5430 leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
5405 } 5431 }
5432
5433 void MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
5434 assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
5435 int oop_index = oop_recorder()->find_index(obj);
5436 RelocationHolder rspec = oop_Relocation::spec(oop_index);
5437
5438 // movl dst,obj
5439 InstructionMark im(this);
5440 int encode = prefix_and_encode(dst->encoding());
5441 emit_byte(0xB8 | encode);
5442 emit_data(oop_index, rspec, narrow_oop_operand);
5443 }
5444
5406 5445
5407 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) { 5446 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
5408 switch (cond) { 5447 switch (cond) {
5409 // Note some conditions are synonyms for others 5448 // Note some conditions are synonyms for others
5410 case Assembler::zero: return Assembler::notZero; 5449 case Assembler::zero: return Assembler::notZero;