Mercurial > hg > graal-compiler
comparison src/cpu/x86/vm/cppInterpreter_x86.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | 1d7922586cf6 |
children | 75f33eecc1b3 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
28 #include "interpreter/cppInterpreter.hpp" | 28 #include "interpreter/cppInterpreter.hpp" |
29 #include "interpreter/interpreter.hpp" | 29 #include "interpreter/interpreter.hpp" |
30 #include "interpreter/interpreterGenerator.hpp" | 30 #include "interpreter/interpreterGenerator.hpp" |
31 #include "interpreter/interpreterRuntime.hpp" | 31 #include "interpreter/interpreterRuntime.hpp" |
32 #include "oops/arrayOop.hpp" | 32 #include "oops/arrayOop.hpp" |
33 #include "oops/methodDataOop.hpp" | 33 #include "oops/methodData.hpp" |
34 #include "oops/methodOop.hpp" | 34 #include "oops/method.hpp" |
35 #include "oops/oop.inline.hpp" | 35 #include "oops/oop.inline.hpp" |
36 #include "prims/jvmtiExport.hpp" | 36 #include "prims/jvmtiExport.hpp" |
37 #include "prims/jvmtiThreadState.hpp" | 37 #include "prims/jvmtiThreadState.hpp" |
38 #include "runtime/arguments.hpp" | 38 #include "runtime/arguments.hpp" |
39 #include "runtime/deoptimization.hpp" | 39 #include "runtime/deoptimization.hpp" |
419 // Modifies rcx, rdx, rax | 419 // Modifies rcx, rdx, rax |
420 // Returns: | 420 // Returns: |
421 // state == address of new interpreterState | 421 // state == address of new interpreterState |
422 // rsp == bottom of method's expression stack. | 422 // rsp == bottom of method's expression stack. |
423 | 423 |
424 const Address const_offset (rbx, methodOopDesc::const_offset()); | 424 const Address const_offset (rbx, Method::const_offset()); |
425 | 425 |
426 | 426 |
427 // On entry sp is the sender's sp. This includes the space for the arguments | 427 // On entry sp is the sender's sp. This includes the space for the arguments |
428 // that the sender pushed. If the sender pushed no args (a static) and the | 428 // that the sender pushed. If the sender pushed no args (a static) and the |
429 // caller returns a long then we need two words on the sender's stack which | 429 // caller returns a long then we need two words on the sender's stack which |
469 __ movptr(STATE(_thread), r15_thread); // state->_bcp = codes() | 469 __ movptr(STATE(_thread), r15_thread); // state->_bcp = codes() |
470 #else | 470 #else |
471 __ get_thread(rax); // get vm's javathread* | 471 __ get_thread(rax); // get vm's javathread* |
472 __ movptr(STATE(_thread), rax); // state->_bcp = codes() | 472 __ movptr(STATE(_thread), rax); // state->_bcp = codes() |
473 #endif // _LP64 | 473 #endif // _LP64 |
474 __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); // get constantMethodOop | 474 __ movptr(rdx, Address(rbx, Method::const_offset())); // get constantMethodOop |
475 __ lea(rdx, Address(rdx, constMethodOopDesc::codes_offset())); // get code base | 475 __ lea(rdx, Address(rdx, ConstMethod::codes_offset())); // get code base |
476 if (native) { | 476 if (native) { |
477 __ movptr(STATE(_bcp), (int32_t)NULL_WORD); // state->_bcp = NULL | 477 __ movptr(STATE(_bcp), (int32_t)NULL_WORD); // state->_bcp = NULL |
478 } else { | 478 } else { |
479 __ movptr(STATE(_bcp), rdx); // state->_bcp = codes() | 479 __ movptr(STATE(_bcp), rdx); // state->_bcp = codes() |
480 } | 480 } |
481 __ xorptr(rdx, rdx); | 481 __ xorptr(rdx, rdx); |
482 __ movptr(STATE(_oop_temp), rdx); // state->_oop_temp = NULL (only really needed for native) | 482 __ movptr(STATE(_oop_temp), rdx); // state->_oop_temp = NULL (only really needed for native) |
483 __ movptr(STATE(_mdx), rdx); // state->_mdx = NULL | 483 __ movptr(STATE(_mdx), rdx); // state->_mdx = NULL |
484 __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); | 484 __ movptr(rdx, Address(rbx, Method::const_offset())); |
485 __ movptr(rdx, Address(rdx, constMethodOopDesc::constants_offset())); | 485 __ movptr(rdx, Address(rdx, ConstMethod::constants_offset())); |
486 __ movptr(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes())); | 486 __ movptr(rdx, Address(rdx, ConstantPool::cache_offset_in_bytes())); |
487 __ movptr(STATE(_constants), rdx); // state->_constants = constants() | 487 __ movptr(STATE(_constants), rdx); // state->_constants = constants() |
488 | 488 |
489 __ movptr(STATE(_method), rbx); // state->_method = method() | 489 __ movptr(STATE(_method), rbx); // state->_method = method() |
490 __ movl(STATE(_msg), (int32_t) BytecodeInterpreter::method_entry); // state->_msg = initial method entry | 490 __ movl(STATE(_msg), (int32_t) BytecodeInterpreter::method_entry); // state->_msg = initial method entry |
491 __ movptr(STATE(_result._to_call._callee), (int32_t) NULL_WORD); // state->_result._to_call._callee_callee = NULL | 491 __ movptr(STATE(_result._to_call._callee), (int32_t) NULL_WORD); // state->_result._to_call._callee_callee = NULL |
498 // Must not attempt to lock method until we enter interpreter as gc won't be able to find the | 498 // Must not attempt to lock method until we enter interpreter as gc won't be able to find the |
499 // initial frame. However we allocate a free monitor so we don't have to shuffle the expression stack | 499 // initial frame. However we allocate a free monitor so we don't have to shuffle the expression stack |
500 // immediately. | 500 // immediately. |
501 | 501 |
502 // synchronize method | 502 // synchronize method |
503 const Address access_flags (rbx, methodOopDesc::access_flags_offset()); | 503 const Address access_flags (rbx, Method::access_flags_offset()); |
504 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; | 504 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; |
505 Label not_synced; | 505 Label not_synced; |
506 | 506 |
507 __ movl(rax, access_flags); | 507 __ movl(rax, access_flags); |
508 __ testl(rax, JVM_ACC_SYNCHRONIZED); | 508 __ testl(rax, JVM_ACC_SYNCHRONIZED); |
515 const int mirror_offset = in_bytes(Klass::java_mirror_offset()); | 515 const int mirror_offset = in_bytes(Klass::java_mirror_offset()); |
516 __ movl(rax, access_flags); | 516 __ movl(rax, access_flags); |
517 __ testl(rax, JVM_ACC_STATIC); | 517 __ testl(rax, JVM_ACC_STATIC); |
518 __ movptr(rax, Address(locals, 0)); // get receiver (assume this is frequent case) | 518 __ movptr(rax, Address(locals, 0)); // get receiver (assume this is frequent case) |
519 __ jcc(Assembler::zero, done); | 519 __ jcc(Assembler::zero, done); |
520 __ movptr(rax, Address(rbx, methodOopDesc::const_offset())); | 520 __ movptr(rax, Address(rbx, Method::const_offset())); |
521 __ movptr(rax, Address(rax, constMethodOopDesc::constants_offset())); | 521 __ movptr(rax, Address(rax, ConstMethod::constants_offset())); |
522 __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); | 522 __ movptr(rax, Address(rax, ConstantPool::pool_holder_offset_in_bytes())); |
523 __ movptr(rax, Address(rax, mirror_offset)); | 523 __ movptr(rax, Address(rax, mirror_offset)); |
524 __ bind(done); | 524 __ bind(done); |
525 // add space for monitor & lock | 525 // add space for monitor & lock |
526 __ subptr(rsp, entry_size); // add space for a monitor entry | 526 __ subptr(rsp, entry_size); // add space for a monitor entry |
527 __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); // store object | 527 __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); // store object |
536 __ subptr(rsp, wordSize); // pre-push stack | 536 __ subptr(rsp, wordSize); // pre-push stack |
537 __ movptr(STATE(_stack), rsp); // set current expression stack tos | 537 __ movptr(STATE(_stack), rsp); // set current expression stack tos |
538 | 538 |
539 // compute full expression stack limit | 539 // compute full expression stack limit |
540 | 540 |
541 const Address size_of_stack (rbx, methodOopDesc::max_stack_offset()); | 541 const Address size_of_stack (rbx, Method::max_stack_offset()); |
542 const int extra_stack = 0; //6815692//methodOopDesc::extra_stack_words(); | 542 const int extra_stack = 0; //6815692//Method::extra_stack_words(); |
543 __ load_unsigned_short(rdx, size_of_stack); // get size of expression stack in words | 543 __ load_unsigned_short(rdx, size_of_stack); // get size of expression stack in words |
544 __ negptr(rdx); // so we can subtract in next step | 544 __ negptr(rdx); // so we can subtract in next step |
545 // Allocate expression stack | 545 // Allocate expression stack |
546 __ lea(rsp, Address(rsp, rdx, Address::times_ptr, -extra_stack)); | 546 __ lea(rsp, Address(rsp, rdx, Address::times_ptr, -extra_stack)); |
547 __ movptr(STATE(_stack_limit), rsp); | 547 __ movptr(STATE(_stack_limit), rsp); |
568 // rbx,: method | 568 // rbx,: method |
569 // rcx: invocation counter | 569 // rcx: invocation counter |
570 // | 570 // |
571 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { | 571 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { |
572 | 572 |
573 const Address invocation_counter(rbx, methodOopDesc::invocation_counter_offset() + InvocationCounter::counter_offset()); | 573 const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset()); |
574 const Address backedge_counter (rbx, methodOopDesc::backedge_counter_offset() + InvocationCounter::counter_offset()); | 574 const Address backedge_counter (rbx, Method::backedge_counter_offset() + InvocationCounter::counter_offset()); |
575 | 575 |
576 if (ProfileInterpreter) { // %%% Merge this into methodDataOop | 576 if (ProfileInterpreter) { // %%% Merge this into MethodData* |
577 __ incrementl(Address(rbx,methodOopDesc::interpreter_invocation_counter_offset())); | 577 __ incrementl(Address(rbx,Method::interpreter_invocation_counter_offset())); |
578 } | 578 } |
579 // Update standard invocation counters | 579 // Update standard invocation counters |
580 __ movl(rax, backedge_counter); // load backedge counter | 580 __ movl(rax, backedge_counter); // load backedge counter |
581 | 581 |
582 __ increment(rcx, InvocationCounter::count_increment); | 582 __ increment(rcx, InvocationCounter::count_increment); |
609 // rsp - sender_sp | 609 // rsp - sender_sp |
610 | 610 |
611 // C++ interpreter only | 611 // C++ interpreter only |
612 // rsi/r13 - previous interpreter state pointer | 612 // rsi/r13 - previous interpreter state pointer |
613 | 613 |
614 const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset()); | 614 const Address size_of_parameters(rbx, Method::size_of_parameters_offset()); |
615 | 615 |
616 // InterpreterRuntime::frequency_counter_overflow takes one argument | 616 // InterpreterRuntime::frequency_counter_overflow takes one argument |
617 // indicating if the counter overflow occurs at a backwards branch (non-NULL bcp). | 617 // indicating if the counter overflow occurs at a backwards branch (non-NULL bcp). |
618 // The call returns the address of the verified entry point for the method or NULL | 618 // The call returns the address of the verified entry point for the method or NULL |
619 // if the compilation did not complete (either went background or bailed out). | 619 // if the compilation did not complete (either went background or bailed out). |
636 // | 636 // |
637 // Registers live on entry: | 637 // Registers live on entry: |
638 // | 638 // |
639 // Asm interpreter | 639 // Asm interpreter |
640 // rdx: number of additional locals this frame needs (what we must check) | 640 // rdx: number of additional locals this frame needs (what we must check) |
641 // rbx,: methodOop | 641 // rbx,: Method* |
642 | 642 |
643 // C++ Interpreter | 643 // C++ Interpreter |
644 // rsi/r13: previous interpreter frame state object | 644 // rsi/r13: previous interpreter frame state object |
645 // rdi: &locals[0] | 645 // rdi: &locals[0] |
646 // rcx: # of locals | 646 // rcx: # of locals |
647 // rdx: number of additional locals this frame needs (what we must check) | 647 // rdx: number of additional locals this frame needs (what we must check) |
648 // rbx: methodOop | 648 // rbx: Method* |
649 | 649 |
650 // destroyed on exit | 650 // destroyed on exit |
651 // rax, | 651 // rax, |
652 | 652 |
653 // NOTE: since the additional locals are also always pushed (wasn't obvious in | 653 // NOTE: since the additional locals are also always pushed (wasn't obvious in |
680 | 680 |
681 const Address stack_base(thread, Thread::stack_base_offset()); | 681 const Address stack_base(thread, Thread::stack_base_offset()); |
682 const Address stack_size(thread, Thread::stack_size_offset()); | 682 const Address stack_size(thread, Thread::stack_size_offset()); |
683 | 683 |
684 // locals + overhead, in bytes | 684 // locals + overhead, in bytes |
685 const Address size_of_stack (rbx, methodOopDesc::max_stack_offset()); | 685 const Address size_of_stack (rbx, Method::max_stack_offset()); |
686 // Always give one monitor to allow us to start interp if sync method. | 686 // Always give one monitor to allow us to start interp if sync method. |
687 // Any additional monitors need a check when moving the expression stack | 687 // Any additional monitors need a check when moving the expression stack |
688 const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize; | 688 const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize; |
689 const int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); | 689 const int extra_stack = 0; //6815692//Method::extra_stack_entries(); |
690 __ load_unsigned_short(rax, size_of_stack); // get size of expression stack in words | 690 __ load_unsigned_short(rax, size_of_stack); // get size of expression stack in words |
691 __ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), extra_stack + one_monitor)); | 691 __ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), extra_stack + one_monitor)); |
692 __ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size)); | 692 __ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size)); |
693 | 693 |
694 #ifdef ASSERT | 694 #ifdef ASSERT |
736 | 736 |
737 __ bind(after_frame_check); | 737 __ bind(after_frame_check); |
738 } | 738 } |
739 | 739 |
740 // Find preallocated monitor and lock method (C++ interpreter) | 740 // Find preallocated monitor and lock method (C++ interpreter) |
741 // rbx - methodOop | 741 // rbx - Method* |
742 // | 742 // |
743 void InterpreterGenerator::lock_method(void) { | 743 void InterpreterGenerator::lock_method(void) { |
744 // assumes state == rsi/r13 == pointer to current interpreterState | 744 // assumes state == rsi/r13 == pointer to current interpreterState |
745 // minimally destroys rax, rdx|c_rarg1, rdi | 745 // minimally destroys rax, rdx|c_rarg1, rdi |
746 // | 746 // |
747 // synchronize method | 747 // synchronize method |
748 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; | 748 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; |
749 const Address access_flags (rbx, methodOopDesc::access_flags_offset()); | 749 const Address access_flags (rbx, Method::access_flags_offset()); |
750 | 750 |
751 const Register monitor = NOT_LP64(rdx) LP64_ONLY(c_rarg1); | 751 const Register monitor = NOT_LP64(rdx) LP64_ONLY(c_rarg1); |
752 | 752 |
753 // find initial monitor i.e. monitors[-1] | 753 // find initial monitor i.e. monitors[-1] |
754 __ movptr(monitor, STATE(_monitor_base)); // get monitor bottom limit | 754 __ movptr(monitor, STATE(_monitor_base)); // get monitor bottom limit |
769 __ movl(rax, access_flags); | 769 __ movl(rax, access_flags); |
770 __ movptr(rdi, STATE(_locals)); // prepare to get receiver (assume common case) | 770 __ movptr(rdi, STATE(_locals)); // prepare to get receiver (assume common case) |
771 __ testl(rax, JVM_ACC_STATIC); | 771 __ testl(rax, JVM_ACC_STATIC); |
772 __ movptr(rax, Address(rdi, 0)); // get receiver (assume this is frequent case) | 772 __ movptr(rax, Address(rdi, 0)); // get receiver (assume this is frequent case) |
773 __ jcc(Assembler::zero, done); | 773 __ jcc(Assembler::zero, done); |
774 __ movptr(rax, Address(rbx, methodOopDesc::const_offset())); | 774 __ movptr(rax, Address(rbx, Method::const_offset())); |
775 __ movptr(rax, Address(rax, constMethodOopDesc::constants_offset())); | 775 __ movptr(rax, Address(rax, ConstMethod::constants_offset())); |
776 __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes())); | 776 __ movptr(rax, Address(rax, ConstantPool::pool_holder_offset_in_bytes())); |
777 __ movptr(rax, Address(rax, mirror_offset)); | 777 __ movptr(rax, Address(rax, mirror_offset)); |
778 __ bind(done); | 778 __ bind(done); |
779 } | 779 } |
780 #ifdef ASSERT | 780 #ifdef ASSERT |
781 { Label L; | 781 { Label L; |
791 | 791 |
792 // Call an accessor method (assuming it is resolved, otherwise drop into vanilla (slow path) entry | 792 // Call an accessor method (assuming it is resolved, otherwise drop into vanilla (slow path) entry |
793 | 793 |
794 address InterpreterGenerator::generate_accessor_entry(void) { | 794 address InterpreterGenerator::generate_accessor_entry(void) { |
795 | 795 |
796 // rbx: methodOop | 796 // rbx: Method* |
797 | 797 |
798 // rsi/r13: senderSP must preserved for slow path, set SP to it on fast path | 798 // rsi/r13: senderSP must preserved for slow path, set SP to it on fast path |
799 | 799 |
800 Label xreturn_path; | 800 Label xreturn_path; |
801 | 801 |
823 // check if local 0 != NULL and read field | 823 // check if local 0 != NULL and read field |
824 __ testptr(rax, rax); | 824 __ testptr(rax, rax); |
825 __ jcc(Assembler::zero, slow_path); | 825 __ jcc(Assembler::zero, slow_path); |
826 | 826 |
827 // read first instruction word and extract bytecode @ 1 and index @ 2 | 827 // read first instruction word and extract bytecode @ 1 and index @ 2 |
828 __ movptr(rdx, Address(rbx, methodOopDesc::const_offset())); | 828 __ movptr(rdx, Address(rbx, Method::const_offset())); |
829 __ movptr(rdi, Address(rdx, constMethodOopDesc::constants_offset())); | 829 __ movptr(rdi, Address(rdx, ConstMethod::constants_offset())); |
830 __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset())); | 830 __ movl(rdx, Address(rdx, ConstMethod::codes_offset())); |
831 // Shift codes right to get the index on the right. | 831 // Shift codes right to get the index on the right. |
832 // The bytecode fetched looks like <index><0xb4><0x2a> | 832 // The bytecode fetched looks like <index><0xb4><0x2a> |
833 __ shrl(rdx, 2*BitsPerByte); | 833 __ shrl(rdx, 2*BitsPerByte); |
834 __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); | 834 __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); |
835 __ movptr(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); | 835 __ movptr(rdi, Address(rdi, ConstantPool::cache_offset_in_bytes())); |
836 | 836 |
837 // rax,: local 0 | 837 // rax,: local 0 |
838 // rbx,: method | 838 // rbx,: method |
839 // rcx: receiver - do not destroy since it is needed for slow path! | 839 // rcx: receiver - do not destroy since it is needed for slow path! |
840 // rcx: scratch | 840 // rcx: scratch |
847 // contains Bytecode::_getfield in b1 byte. | 847 // contains Bytecode::_getfield in b1 byte. |
848 assert(in_words(ConstantPoolCacheEntry::size()) == 4, "adjust shift below"); | 848 assert(in_words(ConstantPoolCacheEntry::size()) == 4, "adjust shift below"); |
849 __ movl(rcx, | 849 __ movl(rcx, |
850 Address(rdi, | 850 Address(rdi, |
851 rdx, | 851 rdx, |
852 Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); | 852 Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset())); |
853 __ shrl(rcx, 2*BitsPerByte); | 853 __ shrl(rcx, 2*BitsPerByte); |
854 __ andl(rcx, 0xFF); | 854 __ andl(rcx, 0xFF); |
855 __ cmpl(rcx, Bytecodes::_getfield); | 855 __ cmpl(rcx, Bytecodes::_getfield); |
856 __ jcc(Assembler::notEqual, slow_path); | 856 __ jcc(Assembler::notEqual, slow_path); |
857 | 857 |
858 // Note: constant pool entry is not valid before bytecode is resolved | 858 // Note: constant pool entry is not valid before bytecode is resolved |
859 __ movptr(rcx, | 859 __ movptr(rcx, |
860 Address(rdi, | 860 Address(rdi, |
861 rdx, | 861 rdx, |
862 Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f2_offset())); | 862 Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset())); |
863 __ movl(rdx, | 863 __ movl(rdx, |
864 Address(rdi, | 864 Address(rdi, |
865 rdx, | 865 rdx, |
866 Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); | 866 Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset())); |
867 | 867 |
868 Label notByte, notShort, notChar; | 868 Label notByte, notShort, notChar; |
869 const Address field_address (rax, rcx, Address::times_1); | 869 const Address field_address (rax, rcx, Address::times_1); |
870 | 870 |
871 // Need to differentiate between igetfield, agetfield, bgetfield etc. | 871 // Need to differentiate between igetfield, agetfield, bgetfield etc. |
968 | 968 |
969 address InterpreterGenerator::generate_native_entry(bool synchronized) { | 969 address InterpreterGenerator::generate_native_entry(bool synchronized) { |
970 // determine code generation flags | 970 // determine code generation flags |
971 bool inc_counter = UseCompiler || CountCompiledCalls; | 971 bool inc_counter = UseCompiler || CountCompiledCalls; |
972 | 972 |
973 // rbx: methodOop | 973 // rbx: Method* |
974 // rcx: receiver (unused) | 974 // rcx: receiver (unused) |
975 // rsi/r13: previous interpreter state (if called from C++ interpreter) must preserve | 975 // rsi/r13: previous interpreter state (if called from C++ interpreter) must preserve |
976 // in any case. If called via c1/c2/call_stub rsi/r13 is junk (to use) but harmless | 976 // in any case. If called via c1/c2/call_stub rsi/r13 is junk (to use) but harmless |
977 // to save/restore. | 977 // to save/restore. |
978 address entry_point = __ pc(); | 978 address entry_point = __ pc(); |
979 | 979 |
980 const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset()); | 980 const Address size_of_parameters(rbx, Method::size_of_parameters_offset()); |
981 const Address size_of_locals (rbx, methodOopDesc::size_of_locals_offset()); | 981 const Address size_of_locals (rbx, Method::size_of_locals_offset()); |
982 const Address invocation_counter(rbx, methodOopDesc::invocation_counter_offset() + InvocationCounter::counter_offset()); | 982 const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset()); |
983 const Address access_flags (rbx, methodOopDesc::access_flags_offset()); | 983 const Address access_flags (rbx, Method::access_flags_offset()); |
984 | 984 |
985 // rsi/r13 == state/locals rdi == prevstate | 985 // rsi/r13 == state/locals rdi == prevstate |
986 const Register locals = rdi; | 986 const Register locals = rdi; |
987 | 987 |
988 // get parameter size (always needed) | 988 // get parameter size (always needed) |
989 __ load_unsigned_short(rcx, size_of_parameters); | 989 __ load_unsigned_short(rcx, size_of_parameters); |
990 | 990 |
991 // rbx: methodOop | 991 // rbx: Method* |
992 // rcx: size of parameters | 992 // rcx: size of parameters |
993 __ pop(rax); // get return address | 993 __ pop(rax); // get return address |
994 // for natives the size of locals is zero | 994 // for natives the size of locals is zero |
995 | 995 |
996 // compute beginning of parameters /locals | 996 // compute beginning of parameters /locals |
1109 const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); // rcx|rscratch1 | 1109 const Register t = InterpreterRuntime::SignatureHandlerGenerator::temp(); // rcx|rscratch1 |
1110 | 1110 |
1111 // allocate space for parameters | 1111 // allocate space for parameters |
1112 __ movptr(method, STATE(_method)); | 1112 __ movptr(method, STATE(_method)); |
1113 __ verify_oop(method); | 1113 __ verify_oop(method); |
1114 __ load_unsigned_short(t, Address(method, methodOopDesc::size_of_parameters_offset())); | 1114 __ load_unsigned_short(t, Address(method, Method::size_of_parameters_offset())); |
1115 __ shll(t, 2); | 1115 __ shll(t, 2); |
1116 #ifdef _LP64 | 1116 #ifdef _LP64 |
1117 __ subptr(rsp, t); | 1117 __ subptr(rsp, t); |
1118 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows | 1118 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows |
1119 __ andptr(rsp, -16); // must be 16 byte boundary (see amd64 ABI) | 1119 __ andptr(rsp, -16); // must be 16 byte boundary (see amd64 ABI) |
1125 | 1125 |
1126 // get signature handler | 1126 // get signature handler |
1127 Label pending_exception_present; | 1127 Label pending_exception_present; |
1128 | 1128 |
1129 { Label L; | 1129 { Label L; |
1130 __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); | 1130 __ movptr(t, Address(method, Method::signature_handler_offset())); |
1131 __ testptr(t, t); | 1131 __ testptr(t, t); |
1132 __ jcc(Assembler::notZero, L); | 1132 __ jcc(Assembler::notZero, L); |
1133 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method, false); | 1133 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method, false); |
1134 __ movptr(method, STATE(_method)); | 1134 __ movptr(method, STATE(_method)); |
1135 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); | 1135 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); |
1136 __ jcc(Assembler::notEqual, pending_exception_present); | 1136 __ jcc(Assembler::notEqual, pending_exception_present); |
1137 __ verify_oop(method); | 1137 __ verify_oop(method); |
1138 __ movptr(t, Address(method, methodOopDesc::signature_handler_offset())); | 1138 __ movptr(t, Address(method, Method::signature_handler_offset())); |
1139 __ bind(L); | 1139 __ bind(L); |
1140 } | 1140 } |
1141 #ifdef ASSERT | 1141 #ifdef ASSERT |
1142 { | 1142 { |
1143 Label L; | 1143 Label L; |
1169 __ movptr(STATE(_result_handler), rax); | 1169 __ movptr(STATE(_result_handler), rax); |
1170 | 1170 |
1171 | 1171 |
1172 // get native function entry point | 1172 // get native function entry point |
1173 { Label L; | 1173 { Label L; |
1174 __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); | 1174 __ movptr(rax, Address(method, Method::native_function_offset())); |
1175 __ testptr(rax, rax); | 1175 __ testptr(rax, rax); |
1176 __ jcc(Assembler::notZero, L); | 1176 __ jcc(Assembler::notZero, L); |
1177 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method); | 1177 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), method); |
1178 __ movptr(method, STATE(_method)); | 1178 __ movptr(method, STATE(_method)); |
1179 __ verify_oop(method); | 1179 __ verify_oop(method); |
1180 __ movptr(rax, Address(method, methodOopDesc::native_function_offset())); | 1180 __ movptr(rax, Address(method, Method::native_function_offset())); |
1181 __ bind(L); | 1181 __ bind(L); |
1182 } | 1182 } |
1183 | 1183 |
1184 // pass mirror handle if static call | 1184 // pass mirror handle if static call |
1185 { Label L; | 1185 { Label L; |
1186 const int mirror_offset = in_bytes(Klass::java_mirror_offset()); | 1186 const int mirror_offset = in_bytes(Klass::java_mirror_offset()); |
1187 __ movl(t, Address(method, methodOopDesc::access_flags_offset())); | 1187 __ movl(t, Address(method, Method::access_flags_offset())); |
1188 __ testl(t, JVM_ACC_STATIC); | 1188 __ testl(t, JVM_ACC_STATIC); |
1189 __ jcc(Assembler::zero, L); | 1189 __ jcc(Assembler::zero, L); |
1190 // get mirror | 1190 // get mirror |
1191 __ movptr(t, Address(method, methodOopDesc:: const_offset())); | 1191 __ movptr(t, Address(method, Method:: const_offset())); |
1192 __ movptr(t, Address(t, constMethodOopDesc::constants_offset())); | 1192 __ movptr(t, Address(t, ConstMethod::constants_offset())); |
1193 __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes())); | 1193 __ movptr(t, Address(t, ConstantPool::pool_holder_offset_in_bytes())); |
1194 __ movptr(t, Address(t, mirror_offset)); | 1194 __ movptr(t, Address(t, mirror_offset)); |
1195 // copy mirror into activation object | 1195 // copy mirror into activation object |
1196 __ movptr(STATE(_oop_temp), t); | 1196 __ movptr(STATE(_oop_temp), t); |
1197 // pass handle to mirror | 1197 // pass handle to mirror |
1198 #ifdef _LP64 | 1198 #ifdef _LP64 |
1436 __ bind(L); | 1436 __ bind(L); |
1437 } | 1437 } |
1438 | 1438 |
1439 // do unlocking if necessary | 1439 // do unlocking if necessary |
1440 { Label L; | 1440 { Label L; |
1441 __ movl(t, Address(method, methodOopDesc::access_flags_offset())); | 1441 __ movl(t, Address(method, Method::access_flags_offset())); |
1442 __ testl(t, JVM_ACC_SYNCHRONIZED); | 1442 __ testl(t, JVM_ACC_SYNCHRONIZED); |
1443 __ jcc(Assembler::zero, L); | 1443 __ jcc(Assembler::zero, L); |
1444 // the code below should be shared with interpreter macro assembler implementation | 1444 // the code below should be shared with interpreter macro assembler implementation |
1445 { Label unlock; | 1445 { Label unlock; |
1446 const Register monitor = NOT_LP64(rdx) LP64_ONLY(c_rarg1); | 1446 const Register monitor = NOT_LP64(rdx) LP64_ONLY(c_rarg1); |
1632 // happens during entry during the entry via the call stub. | 1632 // happens during entry during the entry via the call stub. |
1633 // RETURN_FROM_METHOD - remove an activation. Return to interpreter or call stub. | 1633 // RETURN_FROM_METHOD - remove an activation. Return to interpreter or call stub. |
1634 // | 1634 // |
1635 // Arguments: | 1635 // Arguments: |
1636 // | 1636 // |
1637 // rbx: methodOop | 1637 // rbx: Method* |
1638 // rcx: receiver - unused (retrieved from stack as needed) | 1638 // rcx: receiver - unused (retrieved from stack as needed) |
1639 // rsi/r13: previous frame manager state (NULL from the call_stub/c1/c2) | 1639 // rsi/r13: previous frame manager state (NULL from the call_stub/c1/c2) |
1640 // | 1640 // |
1641 // | 1641 // |
1642 // Stack layout at entry | 1642 // Stack layout at entry |
1655 | 1655 |
1656 static address interpreter_frame_manager = NULL; | 1656 static address interpreter_frame_manager = NULL; |
1657 | 1657 |
1658 address InterpreterGenerator::generate_normal_entry(bool synchronized) { | 1658 address InterpreterGenerator::generate_normal_entry(bool synchronized) { |
1659 | 1659 |
1660 // rbx: methodOop | 1660 // rbx: Method* |
1661 // rsi/r13: sender sp | 1661 // rsi/r13: sender sp |
1662 | 1662 |
1663 // Because we redispatch "recursive" interpreter entries thru this same entry point | 1663 // Because we redispatch "recursive" interpreter entries thru this same entry point |
1664 // the "input" register usage is a little strange and not what you expect coming | 1664 // the "input" register usage is a little strange and not what you expect coming |
1665 // from the call_stub. From the call stub rsi/rdi (current/previous) interpreter | 1665 // from the call_stub. From the call stub rsi/rdi (current/previous) interpreter |
1698 __ bind(dispatch_entry_2); | 1698 __ bind(dispatch_entry_2); |
1699 | 1699 |
1700 // save sender sp | 1700 // save sender sp |
1701 __ push(rcx); | 1701 __ push(rcx); |
1702 | 1702 |
1703 const Address size_of_parameters(rbx, methodOopDesc::size_of_parameters_offset()); | 1703 const Address size_of_parameters(rbx, Method::size_of_parameters_offset()); |
1704 const Address size_of_locals (rbx, methodOopDesc::size_of_locals_offset()); | 1704 const Address size_of_locals (rbx, Method::size_of_locals_offset()); |
1705 const Address access_flags (rbx, methodOopDesc::access_flags_offset()); | 1705 const Address access_flags (rbx, Method::access_flags_offset()); |
1706 | 1706 |
1707 // const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); | 1707 // const Address monitor_block_top (rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize); |
1708 // const Address monitor_block_bot (rbp, frame::interpreter_frame_initial_sp_offset * wordSize); | 1708 // const Address monitor_block_bot (rbp, frame::interpreter_frame_initial_sp_offset * wordSize); |
1709 // const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock)); | 1709 // const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock)); |
1710 | 1710 |
1711 // get parameter size (always needed) | 1711 // get parameter size (always needed) |
1712 __ load_unsigned_short(rcx, size_of_parameters); | 1712 __ load_unsigned_short(rcx, size_of_parameters); |
1713 | 1713 |
1714 // rbx: methodOop | 1714 // rbx: Method* |
1715 // rcx: size of parameters | 1715 // rcx: size of parameters |
1716 __ load_unsigned_short(rdx, size_of_locals); // get size of locals in words | 1716 __ load_unsigned_short(rdx, size_of_locals); // get size of locals in words |
1717 | 1717 |
1718 __ subptr(rdx, rcx); // rdx = no. of additional locals | 1718 __ subptr(rdx, rcx); // rdx = no. of additional locals |
1719 | 1719 |
1925 | 1925 |
1926 // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases | 1926 // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases |
1927 if (UseSSE < 2) { | 1927 if (UseSSE < 2) { |
1928 __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); | 1928 __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); |
1929 __ movptr(rbx, STATE(_result._to_call._callee)); // get method just executed | 1929 __ movptr(rbx, STATE(_result._to_call._callee)); // get method just executed |
1930 __ movl(rcx, Address(rbx, methodOopDesc::result_index_offset())); | 1930 __ movl(rcx, Address(rbx, Method::result_index_offset())); |
1931 __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_FLOAT)); // Result stub address array index | 1931 __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_FLOAT)); // Result stub address array index |
1932 __ jcc(Assembler::equal, do_float); | 1932 __ jcc(Assembler::equal, do_float); |
1933 __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_DOUBLE)); // Result stub address array index | 1933 __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_DOUBLE)); // Result stub address array index |
1934 __ jcc(Assembler::equal, do_double); | 1934 __ jcc(Assembler::equal, do_double); |
1935 #if !defined(_LP64) || defined(COMPILER1) || !defined(COMPILER2) | 1935 #if !defined(_LP64) || defined(COMPILER1) || !defined(COMPILER2) |
1987 | 1987 |
1988 // get method just executed | 1988 // get method just executed |
1989 __ movptr(rbx, STATE(_result._to_call._callee)); | 1989 __ movptr(rbx, STATE(_result._to_call._callee)); |
1990 | 1990 |
1991 // callee left args on top of expression stack, remove them | 1991 // callee left args on top of expression stack, remove them |
1992 __ load_unsigned_short(rcx, Address(rbx, methodOopDesc::size_of_parameters_offset())); | 1992 __ load_unsigned_short(rcx, Address(rbx, Method::size_of_parameters_offset())); |
1993 __ lea(rsp, Address(rsp, rcx, Address::times_ptr)); | 1993 __ lea(rsp, Address(rsp, rcx, Address::times_ptr)); |
1994 | 1994 |
1995 __ movl(rcx, Address(rbx, methodOopDesc::result_index_offset())); | 1995 __ movl(rcx, Address(rbx, Method::result_index_offset())); |
1996 ExternalAddress tosca_to_stack((address)CppInterpreter::_tosca_to_stack); | 1996 ExternalAddress tosca_to_stack((address)CppInterpreter::_tosca_to_stack); |
1997 // Address index(noreg, rax, Address::times_ptr); | 1997 // Address index(noreg, rax, Address::times_ptr); |
1998 __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_ptr))); | 1998 __ movptr(rcx, ArrayAddress(tosca_to_stack, Address(noreg, rcx, Address::times_ptr))); |
1999 // __ movl(rcx, Address(noreg, rcx, Address::times_ptr, int(AbstractInterpreter::_tosca_to_stack))); | 1999 // __ movl(rcx, Address(noreg, rcx, Address::times_ptr, int(AbstractInterpreter::_tosca_to_stack))); |
2000 __ call(rcx); // call result converter | 2000 __ call(rcx); // call result converter |
2017 | 2017 |
2018 Label return_to_initial_caller; | 2018 Label return_to_initial_caller; |
2019 | 2019 |
2020 __ movptr(rbx, STATE(_method)); // get method just executed | 2020 __ movptr(rbx, STATE(_method)); // get method just executed |
2021 __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from "recursive" interpreter call? | 2021 __ cmpptr(STATE(_prev_link), (int32_t)NULL_WORD); // returning from "recursive" interpreter call? |
2022 __ movl(rax, Address(rbx, methodOopDesc::result_index_offset())); // get result type index | 2022 __ movl(rax, Address(rbx, Method::result_index_offset())); // get result type index |
2023 __ jcc(Assembler::equal, return_to_initial_caller); // back to native code (call_stub/c1/c2) | 2023 __ jcc(Assembler::equal, return_to_initial_caller); // back to native code (call_stub/c1/c2) |
2024 | 2024 |
2025 // Copy result to callers java stack | 2025 // Copy result to callers java stack |
2026 ExternalAddress stack_to_stack((address)CppInterpreter::_stack_to_stack); | 2026 ExternalAddress stack_to_stack((address)CppInterpreter::_stack_to_stack); |
2027 // Address index(noreg, rax, Address::times_ptr); | 2027 // Address index(noreg, rax, Address::times_ptr); |
2251 } | 2251 } |
2252 | 2252 |
2253 // Deoptimization helpers for C++ interpreter | 2253 // Deoptimization helpers for C++ interpreter |
2254 | 2254 |
2255 // How much stack a method activation needs in words. | 2255 // How much stack a method activation needs in words. |
2256 int AbstractInterpreter::size_top_interpreter_activation(methodOop method) { | 2256 int AbstractInterpreter::size_top_interpreter_activation(Method* method) { |
2257 | 2257 |
2258 const int stub_code = 4; // see generate_call_stub | 2258 const int stub_code = 4; // see generate_call_stub |
2259 // Save space for one monitor to get into the interpreted method in case | 2259 // Save space for one monitor to get into the interpreted method in case |
2260 // the method is synchronized | 2260 // the method is synchronized |
2261 int monitor_size = method->is_synchronized() ? | 2261 int monitor_size = method->is_synchronized() ? |
2265 // address, saved rbp and 2 words for a "static long no_params() method" issue. | 2265 // address, saved rbp and 2 words for a "static long no_params() method" issue. |
2266 | 2266 |
2267 const int overhead_size = sizeof(BytecodeInterpreter)/wordSize + | 2267 const int overhead_size = sizeof(BytecodeInterpreter)/wordSize + |
2268 ( frame::sender_sp_offset - frame::link_offset) + 2; | 2268 ( frame::sender_sp_offset - frame::link_offset) + 2; |
2269 | 2269 |
2270 const int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); | 2270 const int extra_stack = 0; //6815692//Method::extra_stack_entries(); |
2271 const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) * | 2271 const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) * |
2272 Interpreter::stackElementWords(); | 2272 Interpreter::stackElementWords; |
2273 return overhead_size + method_stack + stub_code; | 2273 return overhead_size + method_stack + stub_code; |
2274 } | 2274 } |
2275 | 2275 |
2276 // returns the activation size. | 2276 // returns the activation size. |
2277 static int size_activation_helper(int extra_locals_size, int monitor_size) { | 2277 static int size_activation_helper(int extra_locals_size, int monitor_size) { |
2283 } | 2283 } |
2284 | 2284 |
2285 void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill, | 2285 void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill, |
2286 frame* caller, | 2286 frame* caller, |
2287 frame* current, | 2287 frame* current, |
2288 methodOop method, | 2288 Method* method, |
2289 intptr_t* locals, | 2289 intptr_t* locals, |
2290 intptr_t* stack, | 2290 intptr_t* stack, |
2291 intptr_t* stack_base, | 2291 intptr_t* stack_base, |
2292 intptr_t* monitor_base, | 2292 intptr_t* monitor_base, |
2293 intptr_t* frame_bottom, | 2293 intptr_t* frame_bottom, |
2331 to_fill->_oop_temp = NULL; | 2331 to_fill->_oop_temp = NULL; |
2332 to_fill->_stack_base = stack_base; | 2332 to_fill->_stack_base = stack_base; |
2333 // Need +1 here because stack_base points to the word just above the first expr stack entry | 2333 // Need +1 here because stack_base points to the word just above the first expr stack entry |
2334 // and stack_limit is supposed to point to the word just below the last expr stack entry. | 2334 // and stack_limit is supposed to point to the word just below the last expr stack entry. |
2335 // See generate_compute_interpreter_state. | 2335 // See generate_compute_interpreter_state. |
2336 int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); | 2336 int extra_stack = 0; //6815692//Method::extra_stack_entries(); |
2337 to_fill->_stack_limit = stack_base - (method->max_stack() + extra_stack + 1); | 2337 to_fill->_stack_limit = stack_base - (method->max_stack() + extra_stack + 1); |
2338 to_fill->_monitor_base = (BasicObjectLock*) monitor_base; | 2338 to_fill->_monitor_base = (BasicObjectLock*) monitor_base; |
2339 | 2339 |
2340 to_fill->_self_link = to_fill; | 2340 to_fill->_self_link = to_fill; |
2341 assert(stack >= to_fill->_stack_limit && stack < to_fill->_stack_base, | 2341 assert(stack >= to_fill->_stack_limit && stack < to_fill->_stack_base, |
2342 "Stack top out of range"); | 2342 "Stack top out of range"); |
2343 } | 2343 } |
2344 | 2344 |
2345 int AbstractInterpreter::layout_activation(methodOop method, | 2345 int AbstractInterpreter::layout_activation(Method* method, |
2346 int tempcount, // | 2346 int tempcount, // |
2347 int popframe_extra_args, | 2347 int popframe_extra_args, |
2348 int moncount, | 2348 int moncount, |
2349 int caller_actual_parameters, | 2349 int caller_actual_parameters, |
2350 int callee_param_count, | 2350 int callee_param_count, |
2379 // First calculate the frame size without any java expression stack | 2379 // First calculate the frame size without any java expression stack |
2380 int short_frame_size = size_activation_helper(extra_locals_size, | 2380 int short_frame_size = size_activation_helper(extra_locals_size, |
2381 monitor_size); | 2381 monitor_size); |
2382 | 2382 |
2383 // Now with full size expression stack | 2383 // Now with full size expression stack |
2384 int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); | 2384 int extra_stack = 0; //6815692//Method::extra_stack_entries(); |
2385 int full_frame_size = short_frame_size + (method->max_stack() + extra_stack) * BytesPerWord; | 2385 int full_frame_size = short_frame_size + (method->max_stack() + extra_stack) * BytesPerWord; |
2386 | 2386 |
2387 // and now with only live portion of the expression stack | 2387 // and now with only live portion of the expression stack |
2388 short_frame_size = short_frame_size + tempcount * BytesPerWord; | 2388 short_frame_size = short_frame_size + tempcount * BytesPerWord; |
2389 | 2389 |