Mercurial > hg > graal-compiler
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; |