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
|