< prev index next >

src/hotspot/cpu/x86/macroAssembler_x86.cpp

Print this page
rev 58099 : 8239492: [x86] Turn MacroAssembler::verify_oop into macro recording file and line


2430   MacroAssembler::call_VM_leaf_base(entry_point, 3);
2431 }
2432 
2433 void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Register arg_1, Register arg_2, Register arg_3) {
2434   LP64_ONLY(assert(arg_0 != c_rarg3, "smashed arg"));
2435   LP64_ONLY(assert(arg_1 != c_rarg3, "smashed arg"));
2436   LP64_ONLY(assert(arg_2 != c_rarg3, "smashed arg"));
2437   pass_arg3(this, arg_3);
2438   LP64_ONLY(assert(arg_0 != c_rarg2, "smashed arg"));
2439   LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg"));
2440   pass_arg2(this, arg_2);
2441   LP64_ONLY(assert(arg_0 != c_rarg1, "smashed arg"));
2442   pass_arg1(this, arg_1);
2443   pass_arg0(this, arg_0);
2444   MacroAssembler::call_VM_leaf_base(entry_point, 4);
2445 }
2446 
2447 void MacroAssembler::get_vm_result(Register oop_result, Register java_thread) {
2448   movptr(oop_result, Address(java_thread, JavaThread::vm_result_offset()));
2449   movptr(Address(java_thread, JavaThread::vm_result_offset()), NULL_WORD);
2450   verify_oop(oop_result, "broken oop in call_VM_base");
2451 }
2452 
2453 void MacroAssembler::get_vm_result_2(Register metadata_result, Register java_thread) {
2454   movptr(metadata_result, Address(java_thread, JavaThread::vm_result_2_offset()));
2455   movptr(Address(java_thread, JavaThread::vm_result_2_offset()), NULL_WORD);
2456 }
2457 
2458 void MacroAssembler::check_and_handle_earlyret(Register java_thread) {
2459 }
2460 
2461 void MacroAssembler::check_and_handle_popframe(Register java_thread) {
2462 }
2463 
2464 void MacroAssembler::cmp32(AddressLiteral src1, int32_t imm) {
2465   if (reachable(src1)) {
2466     cmpl(as_Address(src1), imm);
2467   } else {
2468     lea(rscratch1, src1);
2469     cmpl(Address(rscratch1, 0), imm);
2470   }


4621     cmovl(cc, dst, src);
4622   } else {
4623     Label L;
4624     jccb(negate_condition(cc), L);
4625     movl(dst, src);
4626     bind(L);
4627   }
4628 }
4629 
4630 void MacroAssembler::cmov32(Condition cc, Register dst, Register src) {
4631   if (VM_Version::supports_cmov()) {
4632     cmovl(cc, dst, src);
4633   } else {
4634     Label L;
4635     jccb(negate_condition(cc), L);
4636     movl(dst, src);
4637     bind(L);
4638   }
4639 }
4640 
4641 void MacroAssembler::verify_oop(Register reg, const char* s) {
4642   if (!VerifyOops) return;
4643 
4644   // Pass register number to verify_oop_subroutine
4645   const char* b = NULL;
4646   {
4647     ResourceMark rm;
4648     stringStream ss;
4649     ss.print("verify_oop: %s: %s", reg->name(), s);
4650     b = code_string(ss.as_string());
4651   }
4652   BLOCK_COMMENT("verify_oop {");
4653 #ifdef _LP64
4654   push(rscratch1);                    // save r10, trashed by movptr()
4655 #endif
4656   push(rax);                          // save rax,
4657   push(reg);                          // pass register argument
4658   ExternalAddress buffer((address) b);
4659   // avoid using pushptr, as it modifies scratch registers
4660   // and our contract is not to modify anything
4661   movptr(rax, buffer.addr());
4662   push(rax);
4663   // call indirectly to solve generation ordering problem
4664   movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
4665   call(rax);
4666   // Caller pops the arguments (oop, message) and restores rax, r10
4667   BLOCK_COMMENT("} verify_oop");
4668 }
4669 


4711   // cf. TemplateTable::prepare_invoke(), if (load_receiver).
4712   int stackElementSize = Interpreter::stackElementSize;
4713   int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0);
4714 #ifdef ASSERT
4715   int offset1 = Interpreter::expr_offset_in_bytes(extra_slot_offset+1);
4716   assert(offset1 - offset == stackElementSize, "correct arithmetic");
4717 #endif
4718   Register             scale_reg    = noreg;
4719   Address::ScaleFactor scale_factor = Address::no_scale;
4720   if (arg_slot.is_constant()) {
4721     offset += arg_slot.as_constant() * stackElementSize;
4722   } else {
4723     scale_reg    = arg_slot.as_register();
4724     scale_factor = Address::times(stackElementSize);
4725   }
4726   offset += wordSize;           // return PC is on stack
4727   return Address(rsp, scale_reg, scale_factor, offset);
4728 }
4729 
4730 
4731 void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
4732   if (!VerifyOops) return;
4733 
4734   // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord);
4735   // Pass register number to verify_oop_subroutine
4736   const char* b = NULL;
4737   {
4738     ResourceMark rm;
4739     stringStream ss;
4740     ss.print("verify_oop_addr: %s", s);
4741     b = code_string(ss.as_string());
4742   }
4743 #ifdef _LP64
4744   push(rscratch1);                    // save r10, trashed by movptr()
4745 #endif
4746   push(rax);                          // save rax,
4747   // addr may contain rsp so we will have to adjust it based on the push
4748   // we just did (and on 64 bit we do two pushes)
4749   // NOTE: 64bit seemed to have had a bug in that it did movq(addr, rax); which
4750   // stores rax into addr which is backwards of what was intended.
4751   if (addr.uses(rsp)) {
4752     lea(rax, addr);
4753     pushptr(Address(rax, LP64_ONLY(2 *) BytesPerWord));
4754   } else {
4755     pushptr(addr);
4756   }
4757 
4758   ExternalAddress buffer((address) b);
4759   // pass msg argument
4760   // avoid using pushptr, as it modifies scratch registers


5316 void MacroAssembler::verify_heapbase(const char* msg) {
5317   assert (UseCompressedOops, "should be compressed");
5318   assert (Universe::heap() != NULL, "java heap should be initialized");
5319   if (CheckCompressedOops) {
5320     Label ok;
5321     push(rscratch1); // cmpptr trashes rscratch1
5322     cmpptr(r12_heapbase, ExternalAddress((address)CompressedOops::ptrs_base_addr()));
5323     jcc(Assembler::equal, ok);
5324     STOP(msg);
5325     bind(ok);
5326     pop(rscratch1);
5327   }
5328 }
5329 #endif
5330 
5331 // Algorithm must match oop.inline.hpp encode_heap_oop.
5332 void MacroAssembler::encode_heap_oop(Register r) {
5333 #ifdef ASSERT
5334   verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
5335 #endif
5336   verify_oop(r, "broken oop in encode_heap_oop");
5337   if (CompressedOops::base() == NULL) {
5338     if (CompressedOops::shift() != 0) {
5339       assert (LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong");
5340       shrq(r, LogMinObjAlignmentInBytes);
5341     }
5342     return;
5343   }
5344   testq(r, r);
5345   cmovq(Assembler::equal, r, r12_heapbase);
5346   subq(r, r12_heapbase);
5347   shrq(r, LogMinObjAlignmentInBytes);
5348 }
5349 
5350 void MacroAssembler::encode_heap_oop_not_null(Register r) {
5351 #ifdef ASSERT
5352   verify_heapbase("MacroAssembler::encode_heap_oop_not_null: heap base corrupted?");
5353   if (CheckCompressedOops) {
5354     Label ok;
5355     testq(r, r);
5356     jcc(Assembler::notEqual, ok);
5357     STOP("null oop passed to encode_heap_oop_not_null");
5358     bind(ok);
5359   }
5360 #endif
5361   verify_oop(r, "broken oop in encode_heap_oop_not_null");
5362   if (CompressedOops::base() != NULL) {
5363     subq(r, r12_heapbase);
5364   }
5365   if (CompressedOops::shift() != 0) {
5366     assert (LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong");
5367     shrq(r, LogMinObjAlignmentInBytes);
5368   }
5369 }
5370 
5371 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
5372 #ifdef ASSERT
5373   verify_heapbase("MacroAssembler::encode_heap_oop_not_null2: heap base corrupted?");
5374   if (CheckCompressedOops) {
5375     Label ok;
5376     testq(src, src);
5377     jcc(Assembler::notEqual, ok);
5378     STOP("null oop passed to encode_heap_oop_not_null2");
5379     bind(ok);
5380   }
5381 #endif
5382   verify_oop(src, "broken oop in encode_heap_oop_not_null2");
5383   if (dst != src) {
5384     movq(dst, src);
5385   }
5386   if (CompressedOops::base() != NULL) {
5387     subq(dst, r12_heapbase);
5388   }
5389   if (CompressedOops::shift() != 0) {
5390     assert (LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong");
5391     shrq(dst, LogMinObjAlignmentInBytes);
5392   }
5393 }
5394 
5395 void  MacroAssembler::decode_heap_oop(Register r) {
5396 #ifdef ASSERT
5397   verify_heapbase("MacroAssembler::decode_heap_oop: heap base corrupted?");
5398 #endif
5399   if (CompressedOops::base() == NULL) {
5400     if (CompressedOops::shift() != 0) {
5401       assert (LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong");
5402       shlq(r, LogMinObjAlignmentInBytes);
5403     }
5404   } else {
5405     Label done;
5406     shlq(r, LogMinObjAlignmentInBytes);
5407     jccb(Assembler::equal, done);
5408     addq(r, r12_heapbase);
5409     bind(done);
5410   }
5411   verify_oop(r, "broken oop in decode_heap_oop");
5412 }
5413 
5414 void  MacroAssembler::decode_heap_oop_not_null(Register r) {
5415   // Note: it will change flags
5416   assert (UseCompressedOops, "should only be used for compressed headers");
5417   assert (Universe::heap() != NULL, "java heap should be initialized");
5418   // Cannot assert, unverified entry point counts instructions (see .ad file)
5419   // vtableStubs also counts instructions in pd_code_size_limit.
5420   // Also do not verify_oop as this is called by verify_oop.
5421   if (CompressedOops::shift() != 0) {
5422     assert(LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong");
5423     shlq(r, LogMinObjAlignmentInBytes);
5424     if (CompressedOops::base() != NULL) {
5425       addq(r, r12_heapbase);
5426     }
5427   } else {
5428     assert (CompressedOops::base() == NULL, "sanity");
5429   }
5430 }
5431 




2430   MacroAssembler::call_VM_leaf_base(entry_point, 3);
2431 }
2432 
2433 void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Register arg_1, Register arg_2, Register arg_3) {
2434   LP64_ONLY(assert(arg_0 != c_rarg3, "smashed arg"));
2435   LP64_ONLY(assert(arg_1 != c_rarg3, "smashed arg"));
2436   LP64_ONLY(assert(arg_2 != c_rarg3, "smashed arg"));
2437   pass_arg3(this, arg_3);
2438   LP64_ONLY(assert(arg_0 != c_rarg2, "smashed arg"));
2439   LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg"));
2440   pass_arg2(this, arg_2);
2441   LP64_ONLY(assert(arg_0 != c_rarg1, "smashed arg"));
2442   pass_arg1(this, arg_1);
2443   pass_arg0(this, arg_0);
2444   MacroAssembler::call_VM_leaf_base(entry_point, 4);
2445 }
2446 
2447 void MacroAssembler::get_vm_result(Register oop_result, Register java_thread) {
2448   movptr(oop_result, Address(java_thread, JavaThread::vm_result_offset()));
2449   movptr(Address(java_thread, JavaThread::vm_result_offset()), NULL_WORD);
2450   verify_oop(oop_result);
2451 }
2452 
2453 void MacroAssembler::get_vm_result_2(Register metadata_result, Register java_thread) {
2454   movptr(metadata_result, Address(java_thread, JavaThread::vm_result_2_offset()));
2455   movptr(Address(java_thread, JavaThread::vm_result_2_offset()), NULL_WORD);
2456 }
2457 
2458 void MacroAssembler::check_and_handle_earlyret(Register java_thread) {
2459 }
2460 
2461 void MacroAssembler::check_and_handle_popframe(Register java_thread) {
2462 }
2463 
2464 void MacroAssembler::cmp32(AddressLiteral src1, int32_t imm) {
2465   if (reachable(src1)) {
2466     cmpl(as_Address(src1), imm);
2467   } else {
2468     lea(rscratch1, src1);
2469     cmpl(Address(rscratch1, 0), imm);
2470   }


4621     cmovl(cc, dst, src);
4622   } else {
4623     Label L;
4624     jccb(negate_condition(cc), L);
4625     movl(dst, src);
4626     bind(L);
4627   }
4628 }
4629 
4630 void MacroAssembler::cmov32(Condition cc, Register dst, Register src) {
4631   if (VM_Version::supports_cmov()) {
4632     cmovl(cc, dst, src);
4633   } else {
4634     Label L;
4635     jccb(negate_condition(cc), L);
4636     movl(dst, src);
4637     bind(L);
4638   }
4639 }
4640 
4641 void MacroAssembler::_verify_oop(Register reg, const char* s, const char* file, int line) {
4642   if (!VerifyOops) return;
4643 
4644   // Pass register number to verify_oop_subroutine
4645   const char* b = NULL;
4646   {
4647     ResourceMark rm;
4648     stringStream ss;
4649     ss.print("verify_oop: %s: %s (%s:%d)", reg->name(), s, file, line);
4650     b = code_string(ss.as_string());
4651   }
4652   BLOCK_COMMENT("verify_oop {");
4653 #ifdef _LP64
4654   push(rscratch1);                    // save r10, trashed by movptr()
4655 #endif
4656   push(rax);                          // save rax,
4657   push(reg);                          // pass register argument
4658   ExternalAddress buffer((address) b);
4659   // avoid using pushptr, as it modifies scratch registers
4660   // and our contract is not to modify anything
4661   movptr(rax, buffer.addr());
4662   push(rax);
4663   // call indirectly to solve generation ordering problem
4664   movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
4665   call(rax);
4666   // Caller pops the arguments (oop, message) and restores rax, r10
4667   BLOCK_COMMENT("} verify_oop");
4668 }
4669 


4711   // cf. TemplateTable::prepare_invoke(), if (load_receiver).
4712   int stackElementSize = Interpreter::stackElementSize;
4713   int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0);
4714 #ifdef ASSERT
4715   int offset1 = Interpreter::expr_offset_in_bytes(extra_slot_offset+1);
4716   assert(offset1 - offset == stackElementSize, "correct arithmetic");
4717 #endif
4718   Register             scale_reg    = noreg;
4719   Address::ScaleFactor scale_factor = Address::no_scale;
4720   if (arg_slot.is_constant()) {
4721     offset += arg_slot.as_constant() * stackElementSize;
4722   } else {
4723     scale_reg    = arg_slot.as_register();
4724     scale_factor = Address::times(stackElementSize);
4725   }
4726   offset += wordSize;           // return PC is on stack
4727   return Address(rsp, scale_reg, scale_factor, offset);
4728 }
4729 
4730 
4731 void MacroAssembler::_verify_oop_addr(Address addr, const char* s, const char* file, int line) {
4732   if (!VerifyOops) return;
4733 
4734   // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord);
4735   // Pass register number to verify_oop_subroutine
4736   const char* b = NULL;
4737   {
4738     ResourceMark rm;
4739     stringStream ss;
4740     ss.print("verify_oop_addr: %s (%s:%d)", s, file, line);
4741     b = code_string(ss.as_string());
4742   }
4743 #ifdef _LP64
4744   push(rscratch1);                    // save r10, trashed by movptr()
4745 #endif
4746   push(rax);                          // save rax,
4747   // addr may contain rsp so we will have to adjust it based on the push
4748   // we just did (and on 64 bit we do two pushes)
4749   // NOTE: 64bit seemed to have had a bug in that it did movq(addr, rax); which
4750   // stores rax into addr which is backwards of what was intended.
4751   if (addr.uses(rsp)) {
4752     lea(rax, addr);
4753     pushptr(Address(rax, LP64_ONLY(2 *) BytesPerWord));
4754   } else {
4755     pushptr(addr);
4756   }
4757 
4758   ExternalAddress buffer((address) b);
4759   // pass msg argument
4760   // avoid using pushptr, as it modifies scratch registers


5316 void MacroAssembler::verify_heapbase(const char* msg) {
5317   assert (UseCompressedOops, "should be compressed");
5318   assert (Universe::heap() != NULL, "java heap should be initialized");
5319   if (CheckCompressedOops) {
5320     Label ok;
5321     push(rscratch1); // cmpptr trashes rscratch1
5322     cmpptr(r12_heapbase, ExternalAddress((address)CompressedOops::ptrs_base_addr()));
5323     jcc(Assembler::equal, ok);
5324     STOP(msg);
5325     bind(ok);
5326     pop(rscratch1);
5327   }
5328 }
5329 #endif
5330 
5331 // Algorithm must match oop.inline.hpp encode_heap_oop.
5332 void MacroAssembler::encode_heap_oop(Register r) {
5333 #ifdef ASSERT
5334   verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
5335 #endif
5336   verify_oop(r);
5337   if (CompressedOops::base() == NULL) {
5338     if (CompressedOops::shift() != 0) {
5339       assert (LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong");
5340       shrq(r, LogMinObjAlignmentInBytes);
5341     }
5342     return;
5343   }
5344   testq(r, r);
5345   cmovq(Assembler::equal, r, r12_heapbase);
5346   subq(r, r12_heapbase);
5347   shrq(r, LogMinObjAlignmentInBytes);
5348 }
5349 
5350 void MacroAssembler::encode_heap_oop_not_null(Register r) {
5351 #ifdef ASSERT
5352   verify_heapbase("MacroAssembler::encode_heap_oop_not_null: heap base corrupted?");
5353   if (CheckCompressedOops) {
5354     Label ok;
5355     testq(r, r);
5356     jcc(Assembler::notEqual, ok);
5357     STOP("null oop passed to encode_heap_oop_not_null");
5358     bind(ok);
5359   }
5360 #endif
5361   verify_oop(r);
5362   if (CompressedOops::base() != NULL) {
5363     subq(r, r12_heapbase);
5364   }
5365   if (CompressedOops::shift() != 0) {
5366     assert (LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong");
5367     shrq(r, LogMinObjAlignmentInBytes);
5368   }
5369 }
5370 
5371 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
5372 #ifdef ASSERT
5373   verify_heapbase("MacroAssembler::encode_heap_oop_not_null2: heap base corrupted?");
5374   if (CheckCompressedOops) {
5375     Label ok;
5376     testq(src, src);
5377     jcc(Assembler::notEqual, ok);
5378     STOP("null oop passed to encode_heap_oop_not_null2");
5379     bind(ok);
5380   }
5381 #endif
5382   verify_oop(src);
5383   if (dst != src) {
5384     movq(dst, src);
5385   }
5386   if (CompressedOops::base() != NULL) {
5387     subq(dst, r12_heapbase);
5388   }
5389   if (CompressedOops::shift() != 0) {
5390     assert (LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong");
5391     shrq(dst, LogMinObjAlignmentInBytes);
5392   }
5393 }
5394 
5395 void  MacroAssembler::decode_heap_oop(Register r) {
5396 #ifdef ASSERT
5397   verify_heapbase("MacroAssembler::decode_heap_oop: heap base corrupted?");
5398 #endif
5399   if (CompressedOops::base() == NULL) {
5400     if (CompressedOops::shift() != 0) {
5401       assert (LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong");
5402       shlq(r, LogMinObjAlignmentInBytes);
5403     }
5404   } else {
5405     Label done;
5406     shlq(r, LogMinObjAlignmentInBytes);
5407     jccb(Assembler::equal, done);
5408     addq(r, r12_heapbase);
5409     bind(done);
5410   }
5411   verify_oop(r);
5412 }
5413 
5414 void  MacroAssembler::decode_heap_oop_not_null(Register r) {
5415   // Note: it will change flags
5416   assert (UseCompressedOops, "should only be used for compressed headers");
5417   assert (Universe::heap() != NULL, "java heap should be initialized");
5418   // Cannot assert, unverified entry point counts instructions (see .ad file)
5419   // vtableStubs also counts instructions in pd_code_size_limit.
5420   // Also do not verify_oop as this is called by verify_oop.
5421   if (CompressedOops::shift() != 0) {
5422     assert(LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong");
5423     shlq(r, LogMinObjAlignmentInBytes);
5424     if (CompressedOops::base() != NULL) {
5425       addq(r, r12_heapbase);
5426     }
5427   } else {
5428     assert (CompressedOops::base() == NULL, "sanity");
5429   }
5430 }
5431 


< prev index next >