151 // here and the specialized cleanup code is not needed here. |
153 // here and the specialized cleanup code is not needed here. |
152 |
154 |
153 address entry = __ pc(); |
155 address entry = __ pc(); |
154 |
156 |
155 // Restore stack bottom in case i2c adjusted stack |
157 // Restore stack bottom in case i2c adjusted stack |
156 __ movq(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); |
158 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); |
157 // and NULL it as marker that esp is now tos until next java call |
159 // and NULL it as marker that esp is now tos until next java call |
158 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); |
160 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); |
159 |
161 |
160 __ restore_bcp(); |
162 __ restore_bcp(); |
161 __ restore_locals(); |
163 __ restore_locals(); |
|
164 |
162 __ get_cache_and_index_at_bcp(rbx, rcx, 1); |
165 __ get_cache_and_index_at_bcp(rbx, rcx, 1); |
163 __ movl(rbx, Address(rbx, rcx, |
166 __ movl(rbx, Address(rbx, rcx, |
164 Address::times_8, |
167 Address::times_8, |
165 in_bytes(constantPoolCacheOopDesc::base_offset()) + |
168 in_bytes(constantPoolCacheOopDesc::base_offset()) + |
166 3 * wordSize)); |
169 3 * wordSize)); |
167 __ andl(rbx, 0xFF); |
170 __ andl(rbx, 0xFF); |
168 if (TaggedStackInterpreter) __ shll(rbx, 1); // 2 slots per parameter. |
171 if (TaggedStackInterpreter) __ shll(rbx, 1); // 2 slots per parameter. |
169 __ leaq(rsp, Address(rsp, rbx, Address::times_8)); |
172 __ lea(rsp, Address(rsp, rbx, Address::times_8)); |
170 __ dispatch_next(state, step); |
173 __ dispatch_next(state, step); |
171 return entry; |
174 return entry; |
172 } |
175 } |
173 |
176 |
174 |
177 |
175 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, |
178 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, |
176 int step) { |
179 int step) { |
177 address entry = __ pc(); |
180 address entry = __ pc(); |
178 // NULL last_sp until next java call |
181 // NULL last_sp until next java call |
179 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); |
182 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); |
180 __ restore_bcp(); |
183 __ restore_bcp(); |
181 __ restore_locals(); |
184 __ restore_locals(); |
182 // handle exceptions |
185 // handle exceptions |
183 { |
186 { |
184 Label L; |
187 Label L; |
185 __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int) NULL); |
188 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD); |
186 __ jcc(Assembler::zero, L); |
189 __ jcc(Assembler::zero, L); |
187 __ call_VM(noreg, |
190 __ call_VM(noreg, |
188 CAST_FROM_FN_PTR(address, |
191 CAST_FROM_FN_PTR(address, |
189 InterpreterRuntime::throw_pending_exception)); |
192 InterpreterRuntime::throw_pending_exception)); |
190 __ should_not_reach_here(); |
193 __ should_not_reach_here(); |
383 |
386 |
384 const Address stack_base(r15_thread, Thread::stack_base_offset()); |
387 const Address stack_base(r15_thread, Thread::stack_base_offset()); |
385 const Address stack_size(r15_thread, Thread::stack_size_offset()); |
388 const Address stack_size(r15_thread, Thread::stack_size_offset()); |
386 |
389 |
387 // locals + overhead, in bytes |
390 // locals + overhead, in bytes |
388 __ movq(rax, rdx); |
391 __ mov(rax, rdx); |
389 __ shll(rax, Interpreter::logStackElementSize()); // 2 slots per parameter. |
392 __ shlptr(rax, Interpreter::logStackElementSize()); // 2 slots per parameter. |
390 __ addq(rax, overhead_size); |
393 __ addptr(rax, overhead_size); |
391 |
394 |
392 #ifdef ASSERT |
395 #ifdef ASSERT |
393 Label stack_base_okay, stack_size_okay; |
396 Label stack_base_okay, stack_size_okay; |
394 // verify that thread stack base is non-zero |
397 // verify that thread stack base is non-zero |
395 __ cmpq(stack_base, 0); |
398 __ cmpptr(stack_base, (int32_t)NULL_WORD); |
396 __ jcc(Assembler::notEqual, stack_base_okay); |
399 __ jcc(Assembler::notEqual, stack_base_okay); |
397 __ stop("stack base is zero"); |
400 __ stop("stack base is zero"); |
398 __ bind(stack_base_okay); |
401 __ bind(stack_base_okay); |
399 // verify that thread stack size is non-zero |
402 // verify that thread stack size is non-zero |
400 __ cmpq(stack_size, 0); |
403 __ cmpptr(stack_size, 0); |
401 __ jcc(Assembler::notEqual, stack_size_okay); |
404 __ jcc(Assembler::notEqual, stack_size_okay); |
402 __ stop("stack size is zero"); |
405 __ stop("stack size is zero"); |
403 __ bind(stack_size_okay); |
406 __ bind(stack_size_okay); |
404 #endif |
407 #endif |
405 |
408 |
406 // Add stack base to locals and subtract stack size |
409 // Add stack base to locals and subtract stack size |
407 __ addq(rax, stack_base); |
410 __ addptr(rax, stack_base); |
408 __ subq(rax, stack_size); |
411 __ subptr(rax, stack_size); |
409 |
412 |
410 // add in the red and yellow zone sizes |
413 // add in the red and yellow zone sizes |
411 __ addq(rax, (StackRedPages + StackYellowPages) * page_size); |
414 __ addptr(rax, (StackRedPages + StackYellowPages) * page_size); |
412 |
415 |
413 // check against the current stack bottom |
416 // check against the current stack bottom |
414 __ cmpq(rsp, rax); |
417 __ cmpptr(rsp, rax); |
415 __ jcc(Assembler::above, after_frame_check); |
418 __ jcc(Assembler::above, after_frame_check); |
416 |
419 |
417 __ popq(rax); // get return address |
420 __ pop(rax); // get return address |
418 __ jump(ExternalAddress(Interpreter::throw_StackOverflowError_entry())); |
421 __ jump(ExternalAddress(Interpreter::throw_StackOverflowError_entry())); |
419 |
422 |
420 // all done with frame size check |
423 // all done with frame size check |
421 __ bind(after_frame_check); |
424 __ bind(after_frame_check); |
422 } |
425 } |
456 Klass::java_mirror_offset_in_bytes(); |
459 Klass::java_mirror_offset_in_bytes(); |
457 Label done; |
460 Label done; |
458 __ movl(rax, access_flags); |
461 __ movl(rax, access_flags); |
459 __ testl(rax, JVM_ACC_STATIC); |
462 __ testl(rax, JVM_ACC_STATIC); |
460 // get receiver (assume this is frequent case) |
463 // get receiver (assume this is frequent case) |
461 __ movq(rax, Address(r14, Interpreter::local_offset_in_bytes(0))); |
464 __ movptr(rax, Address(r14, Interpreter::local_offset_in_bytes(0))); |
462 __ jcc(Assembler::zero, done); |
465 __ jcc(Assembler::zero, done); |
463 __ movq(rax, Address(rbx, methodOopDesc::constants_offset())); |
466 __ movptr(rax, Address(rbx, methodOopDesc::constants_offset())); |
464 __ movq(rax, Address(rax, |
467 __ movptr(rax, Address(rax, |
465 constantPoolOopDesc::pool_holder_offset_in_bytes())); |
468 constantPoolOopDesc::pool_holder_offset_in_bytes())); |
466 __ movq(rax, Address(rax, mirror_offset)); |
469 __ movptr(rax, Address(rax, mirror_offset)); |
467 |
470 |
468 #ifdef ASSERT |
471 #ifdef ASSERT |
469 { |
472 { |
470 Label L; |
473 Label L; |
471 __ testq(rax, rax); |
474 __ testptr(rax, rax); |
472 __ jcc(Assembler::notZero, L); |
475 __ jcc(Assembler::notZero, L); |
473 __ stop("synchronization object is NULL"); |
476 __ stop("synchronization object is NULL"); |
474 __ bind(L); |
477 __ bind(L); |
475 } |
478 } |
476 #endif // ASSERT |
479 #endif // ASSERT |
477 |
480 |
478 __ bind(done); |
481 __ bind(done); |
479 } |
482 } |
480 |
483 |
481 // add space for monitor & lock |
484 // add space for monitor & lock |
482 __ subq(rsp, entry_size); // add space for a monitor entry |
485 __ subptr(rsp, entry_size); // add space for a monitor entry |
483 __ movq(monitor_block_top, rsp); // set new monitor block top |
486 __ movptr(monitor_block_top, rsp); // set new monitor block top |
484 // store object |
487 // store object |
485 __ movq(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); |
488 __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); |
486 __ movq(c_rarg1, rsp); // object address |
489 __ movptr(c_rarg1, rsp); // object address |
487 __ lock_object(c_rarg1); |
490 __ lock_object(c_rarg1); |
488 } |
491 } |
489 |
492 |
490 // Generate a fixed interpreter frame. This is identical setup for |
493 // Generate a fixed interpreter frame. This is identical setup for |
491 // interpreted methods and for native methods hence the shared code. |
494 // interpreted methods and for native methods hence the shared code. |
496 // r14: pointer to locals |
499 // r14: pointer to locals |
497 // r13: sender sp |
500 // r13: sender sp |
498 // rdx: cp cache |
501 // rdx: cp cache |
499 void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { |
502 void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { |
500 // initialize fixed part of activation frame |
503 // initialize fixed part of activation frame |
501 __ pushq(rax); // save return address |
504 __ push(rax); // save return address |
502 __ enter(); // save old & set new rbp |
505 __ enter(); // save old & set new rbp |
503 __ pushq(r13); // set sender sp |
506 __ push(r13); // set sender sp |
504 __ pushq((int)NULL_WORD); // leave last_sp as null |
507 __ push((int)NULL_WORD); // leave last_sp as null |
505 __ movq(r13, Address(rbx, methodOopDesc::const_offset())); // get constMethodOop |
508 __ movptr(r13, Address(rbx, methodOopDesc::const_offset())); // get constMethodOop |
506 __ leaq(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase |
509 __ lea(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase |
507 __ pushq(rbx); // save methodOop |
510 __ push(rbx); // save methodOop |
508 if (ProfileInterpreter) { |
511 if (ProfileInterpreter) { |
509 Label method_data_continue; |
512 Label method_data_continue; |
510 __ movq(rdx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); |
513 __ movptr(rdx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); |
511 __ testq(rdx, rdx); |
514 __ testptr(rdx, rdx); |
512 __ jcc(Assembler::zero, method_data_continue); |
515 __ jcc(Assembler::zero, method_data_continue); |
513 __ addq(rdx, in_bytes(methodDataOopDesc::data_offset())); |
516 __ addptr(rdx, in_bytes(methodDataOopDesc::data_offset())); |
514 __ bind(method_data_continue); |
517 __ bind(method_data_continue); |
515 __ pushq(rdx); // set the mdp (method data pointer) |
518 __ push(rdx); // set the mdp (method data pointer) |
516 } else { |
519 } else { |
517 __ pushq(0); |
520 __ push(0); |
518 } |
521 } |
519 |
522 |
520 __ movq(rdx, Address(rbx, methodOopDesc::constants_offset())); |
523 __ movptr(rdx, Address(rbx, methodOopDesc::constants_offset())); |
521 __ movq(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); |
524 __ movptr(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); |
522 __ pushq(rdx); // set constant pool cache |
525 __ push(rdx); // set constant pool cache |
523 __ pushq(r14); // set locals pointer |
526 __ push(r14); // set locals pointer |
524 if (native_call) { |
527 if (native_call) { |
525 __ pushq(0); // no bcp |
528 __ push(0); // no bcp |
526 } else { |
529 } else { |
527 __ pushq(r13); // set bcp |
530 __ push(r13); // set bcp |
528 } |
531 } |
529 __ pushq(0); // reserve word for pointer to expression stack bottom |
532 __ push(0); // reserve word for pointer to expression stack bottom |
530 __ movq(Address(rsp, 0), rsp); // set expression stack bottom |
533 __ movptr(Address(rsp, 0), rsp); // set expression stack bottom |
531 } |
534 } |
532 |
535 |
533 // End of helpers |
536 // End of helpers |
|
537 |
|
538 // Various method entries |
|
539 //------------------------------------------------------------------------------------------------------------------------ |
|
540 // |
|
541 // |
|
542 |
|
543 // Call an accessor method (assuming it is resolved, otherwise drop |
|
544 // into vanilla (slow path) entry |
|
545 address InterpreterGenerator::generate_accessor_entry(void) { |
|
546 // rbx: methodOop |
|
547 |
|
548 // r13: senderSP must preserver for slow path, set SP to it on fast path |
|
549 |
|
550 address entry_point = __ pc(); |
|
551 Label xreturn_path; |
|
552 |
|
553 // do fastpath for resolved accessor methods |
|
554 if (UseFastAccessorMethods) { |
|
555 // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites |
|
556 // thereof; parameter size = 1 |
|
557 // Note: We can only use this code if the getfield has been resolved |
|
558 // and if we don't have a null-pointer exception => check for |
|
559 // these conditions first and use slow path if necessary. |
|
560 Label slow_path; |
|
561 // If we need a safepoint check, generate full interpreter entry. |
|
562 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), |
|
563 SafepointSynchronize::_not_synchronized); |
|
564 |
|
565 __ jcc(Assembler::notEqual, slow_path); |
|
566 // rbx: method |
|
567 __ movptr(rax, Address(rsp, wordSize)); |
|
568 |
|
569 // check if local 0 != NULL and read field |
|
570 __ testptr(rax, rax); |
|
571 __ jcc(Assembler::zero, slow_path); |
|
572 |
|
573 __ movptr(rdi, Address(rbx, methodOopDesc::constants_offset())); |
|
574 // read first instruction word and extract bytecode @ 1 and index @ 2 |
|
575 __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); |
|
576 __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset())); |
|
577 // Shift codes right to get the index on the right. |
|
578 // The bytecode fetched looks like <index><0xb4><0x2a> |
|
579 __ shrl(rdx, 2 * BitsPerByte); |
|
580 __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); |
|
581 __ movptr(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); |
|
582 |
|
583 // rax: local 0 |
|
584 // rbx: method |
|
585 // rdx: constant pool cache index |
|
586 // rdi: constant pool cache |
|
587 |
|
588 // check if getfield has been resolved and read constant pool cache entry |
|
589 // check the validity of the cache entry by testing whether _indices field |
|
590 // contains Bytecode::_getfield in b1 byte. |
|
591 assert(in_words(ConstantPoolCacheEntry::size()) == 4, |
|
592 "adjust shift below"); |
|
593 __ movl(rcx, |
|
594 Address(rdi, |
|
595 rdx, |
|
596 Address::times_8, |
|
597 constantPoolCacheOopDesc::base_offset() + |
|
598 ConstantPoolCacheEntry::indices_offset())); |
|
599 __ shrl(rcx, 2 * BitsPerByte); |
|
600 __ andl(rcx, 0xFF); |
|
601 __ cmpl(rcx, Bytecodes::_getfield); |
|
602 __ jcc(Assembler::notEqual, slow_path); |
|
603 |
|
604 // Note: constant pool entry is not valid before bytecode is resolved |
|
605 __ movptr(rcx, |
|
606 Address(rdi, |
|
607 rdx, |
|
608 Address::times_8, |
|
609 constantPoolCacheOopDesc::base_offset() + |
|
610 ConstantPoolCacheEntry::f2_offset())); |
|
611 // edx: flags |
|
612 __ movl(rdx, |
|
613 Address(rdi, |
|
614 rdx, |
|
615 Address::times_8, |
|
616 constantPoolCacheOopDesc::base_offset() + |
|
617 ConstantPoolCacheEntry::flags_offset())); |
|
618 |
|
619 Label notObj, notInt, notByte, notShort; |
|
620 const Address field_address(rax, rcx, Address::times_1); |
|
621 |
|
622 // Need to differentiate between igetfield, agetfield, bgetfield etc. |
|
623 // because they are different sizes. |
|
624 // Use the type from the constant pool cache |
|
625 __ shrl(rdx, ConstantPoolCacheEntry::tosBits); |
|
626 // Make sure we don't need to mask edx for tosBits after the above shift |
|
627 ConstantPoolCacheEntry::verify_tosBits(); |
|
628 |
|
629 __ cmpl(rdx, atos); |
|
630 __ jcc(Assembler::notEqual, notObj); |
|
631 // atos |
|
632 __ load_heap_oop(rax, field_address); |
|
633 __ jmp(xreturn_path); |
|
634 |
|
635 __ bind(notObj); |
|
636 __ cmpl(rdx, itos); |
|
637 __ jcc(Assembler::notEqual, notInt); |
|
638 // itos |
|
639 __ movl(rax, field_address); |
|
640 __ jmp(xreturn_path); |
|
641 |
|
642 __ bind(notInt); |
|
643 __ cmpl(rdx, btos); |
|
644 __ jcc(Assembler::notEqual, notByte); |
|
645 // btos |
|
646 __ load_signed_byte(rax, field_address); |
|
647 __ jmp(xreturn_path); |
|
648 |
|
649 __ bind(notByte); |
|
650 __ cmpl(rdx, stos); |
|
651 __ jcc(Assembler::notEqual, notShort); |
|
652 // stos |
|
653 __ load_signed_word(rax, field_address); |
|
654 __ jmp(xreturn_path); |
|
655 |
|
656 __ bind(notShort); |
|
657 #ifdef ASSERT |
|
658 Label okay; |
|
659 __ cmpl(rdx, ctos); |
|
660 __ jcc(Assembler::equal, okay); |
|
661 __ stop("what type is this?"); |
|
662 __ bind(okay); |
|
663 #endif |
|
664 // ctos |
|
665 __ load_unsigned_word(rax, field_address); |
|
666 |
|
667 __ bind(xreturn_path); |
|
668 |
|
669 // _ireturn/_areturn |
|
670 __ pop(rdi); |
|
671 __ mov(rsp, r13); |
|
672 __ jmp(rdi); |
|
673 __ ret(0); |
|
674 |
|
675 // generate a vanilla interpreter entry as the slow path |
|
676 __ bind(slow_path); |
|
677 (void) generate_normal_entry(false); |
|
678 } else { |
|
679 (void) generate_normal_entry(false); |
|
680 } |
|
681 |
|
682 return entry_point; |
|
683 } |
534 |
684 |
535 // Interpreter stub for calling a native method. (asm interpreter) |
685 // Interpreter stub for calling a native method. (asm interpreter) |
536 // This sets up a somewhat different looking stack for calling the |
686 // This sets up a somewhat different looking stack for calling the |
537 // native method than the typical interpreter frame setup. |
687 // native method than the typical interpreter frame setup. |
538 address InterpreterGenerator::generate_native_entry(bool synchronized) { |
688 address InterpreterGenerator::generate_native_entry(bool synchronized) { |
672 __ load_unsigned_word(t, |
822 __ load_unsigned_word(t, |
673 Address(method, |
823 Address(method, |
674 methodOopDesc::size_of_parameters_offset())); |
824 methodOopDesc::size_of_parameters_offset())); |
675 __ shll(t, Interpreter::logStackElementSize()); |
825 __ shll(t, Interpreter::logStackElementSize()); |
676 |
826 |
677 __ subq(rsp, t); |
827 __ subptr(rsp, t); |
678 __ subq(rsp, frame::arg_reg_save_area_bytes); // windows |
828 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows |
679 __ andq(rsp, -16); // must be 16 byte boundry (see amd64 ABI) |
829 __ andptr(rsp, -16); // must be 16 byte boundry (see amd64 ABI) |
680 |
830 |
681 // get signature handler |
831 // get signature handler |
682 { |
832 { |
683 Label L; |
833 Label L; |
684 __ movq(t, Address(method, methodOopDesc::signature_handler_offset())); |
834 __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); |
685 __ testq(t, t); |
835 __ testptr(t, t); |
686 __ jcc(Assembler::notZero, L); |
836 __ jcc(Assembler::notZero, L); |
687 __ call_VM(noreg, |
837 __ call_VM(noreg, |
688 CAST_FROM_FN_PTR(address, |
838 CAST_FROM_FN_PTR(address, |
689 InterpreterRuntime::prepare_native_call), |
839 InterpreterRuntime::prepare_native_call), |
690 method); |
840 method); |
691 __ get_method(method); |
841 __ get_method(method); |
692 __ movq(t, Address(method, methodOopDesc::signature_handler_offset())); |
842 __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); |
693 __ bind(L); |
843 __ bind(L); |
694 } |
844 } |
695 |
845 |
696 // call signature handler |
846 // call signature handler |
697 assert(InterpreterRuntime::SignatureHandlerGenerator::from() == r14, |
847 assert(InterpreterRuntime::SignatureHandlerGenerator::from() == r14, |
709 __ get_method(method); // slow path can do a GC, reload RBX |
859 __ get_method(method); // slow path can do a GC, reload RBX |
710 |
860 |
711 |
861 |
712 // result handler is in rax |
862 // result handler is in rax |
713 // set result handler |
863 // set result handler |
714 __ movq(Address(rbp, |
864 __ movptr(Address(rbp, |
715 (frame::interpreter_frame_result_handler_offset) * wordSize), |
865 (frame::interpreter_frame_result_handler_offset) * wordSize), |
716 rax); |
866 rax); |
717 |
867 |
718 // pass mirror handle if static call |
868 // pass mirror handle if static call |
719 { |
869 { |
720 Label L; |
870 Label L; |
721 const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + |
871 const int mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + |
722 Klass::java_mirror_offset_in_bytes(); |
872 Klass::java_mirror_offset_in_bytes(); |
723 __ movl(t, Address(method, methodOopDesc::access_flags_offset())); |
873 __ movl(t, Address(method, methodOopDesc::access_flags_offset())); |
724 __ testl(t, JVM_ACC_STATIC); |
874 __ testl(t, JVM_ACC_STATIC); |
725 __ jcc(Assembler::zero, L); |
875 __ jcc(Assembler::zero, L); |
726 // get mirror |
876 // get mirror |
727 __ movq(t, Address(method, methodOopDesc::constants_offset())); |
877 __ movptr(t, Address(method, methodOopDesc::constants_offset())); |
728 __ movq(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); |
878 __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); |
729 __ movq(t, Address(t, mirror_offset)); |
879 __ movptr(t, Address(t, mirror_offset)); |
730 // copy mirror into activation frame |
880 // copy mirror into activation frame |
731 __ movq(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize), |
881 __ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize), |
732 t); |
882 t); |
733 // pass handle to mirror |
883 // pass handle to mirror |
734 __ leaq(c_rarg1, |
884 __ lea(c_rarg1, |
735 Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize)); |
885 Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize)); |
736 __ bind(L); |
886 __ bind(L); |
737 } |
887 } |
738 |
888 |
739 // get native function entry point |
889 // get native function entry point |
740 { |
890 { |
741 Label L; |
891 Label L; |
742 __ movq(rax, Address(method, methodOopDesc::native_function_offset())); |
892 __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); |
743 ExternalAddress unsatisfied(SharedRuntime::native_method_throw_unsatisfied_link_error_entry()); |
893 ExternalAddress unsatisfied(SharedRuntime::native_method_throw_unsatisfied_link_error_entry()); |
744 __ movptr(rscratch2, unsatisfied.addr()); |
894 __ movptr(rscratch2, unsatisfied.addr()); |
745 __ cmpq(rax, rscratch2); |
895 __ cmpptr(rax, rscratch2); |
746 __ jcc(Assembler::notEqual, L); |
896 __ jcc(Assembler::notEqual, L); |
747 __ call_VM(noreg, |
897 __ call_VM(noreg, |
748 CAST_FROM_FN_PTR(address, |
898 CAST_FROM_FN_PTR(address, |
749 InterpreterRuntime::prepare_native_call), |
899 InterpreterRuntime::prepare_native_call), |
750 method); |
900 method); |
751 __ get_method(method); |
901 __ get_method(method); |
752 __ verify_oop(method); |
902 __ verify_oop(method); |
753 __ movq(rax, Address(method, methodOopDesc::native_function_offset())); |
903 __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); |
754 __ bind(L); |
904 __ bind(L); |
755 } |
905 } |
756 |
906 |
757 // pass JNIEnv |
907 // pass JNIEnv |
758 __ leaq(c_rarg0, Address(r15_thread, JavaThread::jni_environment_offset())); |
908 __ lea(c_rarg0, Address(r15_thread, JavaThread::jni_environment_offset())); |
759 |
909 |
760 // It is enough that the pc() points into the right code |
910 // It is enough that the pc() points into the right code |
761 // segment. It does not have to be the correct return pc. |
911 // segment. It does not have to be the correct return pc. |
762 __ set_last_Java_frame(rsp, rbp, (address) __ pc()); |
912 __ set_last_Java_frame(rsp, rbp, (address) __ pc()); |
763 |
913 |
853 |
1003 |
854 // reset_last_Java_frame |
1004 // reset_last_Java_frame |
855 __ reset_last_Java_frame(true, true); |
1005 __ reset_last_Java_frame(true, true); |
856 |
1006 |
857 // reset handle block |
1007 // reset handle block |
858 __ movq(t, Address(r15_thread, JavaThread::active_handles_offset())); |
1008 __ movptr(t, Address(r15_thread, JavaThread::active_handles_offset())); |
859 __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); |
1009 __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); |
860 |
1010 |
861 // If result is an oop unbox and store it in frame where gc will see it |
1011 // If result is an oop unbox and store it in frame where gc will see it |
862 // and result handler will pick it up |
1012 // and result handler will pick it up |
863 |
1013 |
864 { |
1014 { |
865 Label no_oop, store_result; |
1015 Label no_oop, store_result; |
866 __ lea(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT))); |
1016 __ lea(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT))); |
867 __ cmpq(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize)); |
1017 __ cmpptr(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize)); |
868 __ jcc(Assembler::notEqual, no_oop); |
1018 __ jcc(Assembler::notEqual, no_oop); |
869 // retrieve result |
1019 // retrieve result |
870 __ pop(ltos); |
1020 __ pop(ltos); |
871 __ testq(rax, rax); |
1021 __ testptr(rax, rax); |
872 __ jcc(Assembler::zero, store_result); |
1022 __ jcc(Assembler::zero, store_result); |
873 __ movq(rax, Address(rax, 0)); |
1023 __ movptr(rax, Address(rax, 0)); |
874 __ bind(store_result); |
1024 __ bind(store_result); |
875 __ movq(Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize), rax); |
1025 __ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize), rax); |
876 // keep stack depth as expected by pushing oop which will eventually be discarde |
1026 // keep stack depth as expected by pushing oop which will eventually be discarde |
877 __ push(ltos); |
1027 __ push(ltos); |
878 __ bind(no_oop); |
1028 __ bind(no_oop); |
879 } |
1029 } |
880 |
1030 |
904 __ get_method(method); |
1054 __ get_method(method); |
905 __ verify_oop(method); |
1055 __ verify_oop(method); |
906 |
1056 |
907 // restore r13 to have legal interpreter frame, i.e., bci == 0 <=> |
1057 // restore r13 to have legal interpreter frame, i.e., bci == 0 <=> |
908 // r13 == code_base() |
1058 // r13 == code_base() |
909 __ movq(r13, Address(method, methodOopDesc::const_offset())); // get constMethodOop |
1059 __ movptr(r13, Address(method, methodOopDesc::const_offset())); // get constMethodOop |
910 __ leaq(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase |
1060 __ lea(r13, Address(r13, constMethodOopDesc::codes_offset())); // get codebase |
911 // handle exceptions (exception handling will handle unlocking!) |
1061 // handle exceptions (exception handling will handle unlocking!) |
912 { |
1062 { |
913 Label L; |
1063 Label L; |
914 __ cmpq(Address(r15_thread, Thread::pending_exception_offset()), (int) NULL); |
1064 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD); |
915 __ jcc(Assembler::zero, L); |
1065 __ jcc(Assembler::zero, L); |
916 // Note: At some point we may want to unify this with the code |
1066 // Note: At some point we may want to unify this with the code |
917 // used in call_VM_base(); i.e., we should use the |
1067 // used in call_VM_base(); i.e., we should use the |
918 // StubRoutines::forward_exception code. For now this doesn't work |
1068 // StubRoutines::forward_exception code. For now this doesn't work |
919 // here because the rsp is not correctly set at this point. |
1069 // here because the rsp is not correctly set at this point. |
1475 // no space between the top of the expression stack (current |
1625 // no space between the top of the expression stack (current |
1476 // last_sp) and the top of stack. Rather than force deopt to |
1626 // last_sp) and the top of stack. Rather than force deopt to |
1477 // maintain this kind of invariant all the time we call a small |
1627 // maintain this kind of invariant all the time we call a small |
1478 // fixup routine to move the mutated arguments onto the top of our |
1628 // fixup routine to move the mutated arguments onto the top of our |
1479 // expression stack if necessary. |
1629 // expression stack if necessary. |
1480 __ movq(c_rarg1, rsp); |
1630 __ mov(c_rarg1, rsp); |
1481 __ movq(c_rarg2, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); |
1631 __ movptr(c_rarg2, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); |
1482 // PC must point into interpreter here |
1632 // PC must point into interpreter here |
1483 __ set_last_Java_frame(noreg, rbp, __ pc()); |
1633 __ set_last_Java_frame(noreg, rbp, __ pc()); |
1484 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), r15_thread, c_rarg1, c_rarg2); |
1634 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), r15_thread, c_rarg1, c_rarg2); |
1485 __ reset_last_Java_frame(true, true); |
1635 __ reset_last_Java_frame(true, true); |
1486 // Restore the last_sp and null it out |
1636 // Restore the last_sp and null it out |
1487 __ movq(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); |
1637 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); |
1488 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); |
1638 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); |
1489 |
1639 |
1490 __ restore_bcp(); // XXX do we need this? |
1640 __ restore_bcp(); // XXX do we need this? |
1491 __ restore_locals(); // XXX do we need this? |
1641 __ restore_locals(); // XXX do we need this? |
1492 // The method data pointer was incremented already during |
1642 // The method data pointer was incremented already during |
1493 // call profiling. We have to restore the mdp for the current bcp. |
1643 // call profiling. We have to restore the mdp for the current bcp. |
1504 |
1654 |
1505 Interpreter::_remove_activation_entry = __ pc(); |
1655 Interpreter::_remove_activation_entry = __ pc(); |
1506 |
1656 |
1507 // preserve exception over this code sequence |
1657 // preserve exception over this code sequence |
1508 __ pop_ptr(rax); |
1658 __ pop_ptr(rax); |
1509 __ movq(Address(r15_thread, JavaThread::vm_result_offset()), rax); |
1659 __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), rax); |
1510 // remove the activation (without doing throws on illegalMonitorExceptions) |
1660 // remove the activation (without doing throws on illegalMonitorExceptions) |
1511 __ remove_activation(vtos, rdx, false, true, false); |
1661 __ remove_activation(vtos, rdx, false, true, false); |
1512 // restore exception |
1662 // restore exception |
1513 __ movq(rax, Address(r15_thread, JavaThread::vm_result_offset())); |
1663 __ movptr(rax, Address(r15_thread, JavaThread::vm_result_offset())); |
1514 __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), NULL_WORD); |
1664 __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); |
1515 __ verify_oop(rax); |
1665 __ verify_oop(rax); |
1516 |
1666 |
1517 // In between activations - previous activation type unknown yet |
1667 // In between activations - previous activation type unknown yet |
1518 // compute continuation point - the continuation point expects the |
1668 // compute continuation point - the continuation point expects the |
1519 // following registers set up: |
1669 // following registers set up: |
1520 // |
1670 // |
1521 // rax: exception |
1671 // rax: exception |
1522 // rdx: return address/pc that threw exception |
1672 // rdx: return address/pc that threw exception |
1523 // rsp: expression stack of caller |
1673 // rsp: expression stack of caller |
1524 // rbp: ebp of caller |
1674 // rbp: ebp of caller |
1525 __ pushq(rax); // save exception |
1675 __ push(rax); // save exception |
1526 __ pushq(rdx); // save return address |
1676 __ push(rdx); // save return address |
1527 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, |
1677 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, |
1528 SharedRuntime::exception_handler_for_return_address), |
1678 SharedRuntime::exception_handler_for_return_address), |
1529 rdx); |
1679 rdx); |
1530 __ movq(rbx, rax); // save exception handler |
1680 __ mov(rbx, rax); // save exception handler |
1531 __ popq(rdx); // restore return address |
1681 __ pop(rdx); // restore return address |
1532 __ popq(rax); // restore exception |
1682 __ pop(rax); // restore exception |
1533 // Note that an "issuing PC" is actually the next PC after the call |
1683 // Note that an "issuing PC" is actually the next PC after the call |
1534 __ jmp(rbx); // jump to exception |
1684 __ jmp(rbx); // jump to exception |
1535 // handler of caller |
1685 // handler of caller |
1536 } |
1686 } |
1537 |
1687 |