Mercurial > hg > truffle
comparison src/cpu/x86/vm/sharedRuntime_x86_32.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 | 8a02ca5e5576 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
27 #include "assembler_x86.inline.hpp" | 27 #include "assembler_x86.inline.hpp" |
28 #include "code/debugInfoRec.hpp" | 28 #include "code/debugInfoRec.hpp" |
29 #include "code/icBuffer.hpp" | 29 #include "code/icBuffer.hpp" |
30 #include "code/vtableStubs.hpp" | 30 #include "code/vtableStubs.hpp" |
31 #include "interpreter/interpreter.hpp" | 31 #include "interpreter/interpreter.hpp" |
32 #include "oops/compiledICHolderOop.hpp" | 32 #include "oops/compiledICHolder.hpp" |
33 #include "prims/jvmtiRedefineClassesTrace.hpp" | 33 #include "prims/jvmtiRedefineClassesTrace.hpp" |
34 #include "runtime/sharedRuntime.hpp" | 34 #include "runtime/sharedRuntime.hpp" |
35 #include "runtime/vframeArray.hpp" | 35 #include "runtime/vframeArray.hpp" |
36 #include "vmreg_x86.inline.hpp" | 36 #include "vmreg_x86.inline.hpp" |
37 #ifdef COMPILER1 | 37 #ifdef COMPILER1 |
451 } | 451 } |
452 | 452 |
453 // Patch the callers callsite with entry to compiled code if it exists. | 453 // Patch the callers callsite with entry to compiled code if it exists. |
454 static void patch_callers_callsite(MacroAssembler *masm) { | 454 static void patch_callers_callsite(MacroAssembler *masm) { |
455 Label L; | 455 Label L; |
456 __ verify_oop(rbx); | 456 __ cmpptr(Address(rbx, in_bytes(Method::code_offset())), (int32_t)NULL_WORD); |
457 __ cmpptr(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int32_t)NULL_WORD); | |
458 __ jcc(Assembler::equal, L); | 457 __ jcc(Assembler::equal, L); |
459 // Schedule the branch target address early. | 458 // Schedule the branch target address early. |
460 // Call into the VM to patch the caller, then jump to compiled callee | 459 // Call into the VM to patch the caller, then jump to compiled callee |
461 // rax, isn't live so capture return address while we easily can | 460 // rax, isn't live so capture return address while we easily can |
462 __ movptr(rax, Address(rsp, 0)); | 461 __ movptr(rax, Address(rsp, 0)); |
484 | 483 |
485 // VM needs caller's callsite | 484 // VM needs caller's callsite |
486 __ push(rax); | 485 __ push(rax); |
487 // VM needs target method | 486 // VM needs target method |
488 __ push(rbx); | 487 __ push(rbx); |
489 __ verify_oop(rbx); | |
490 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite))); | 488 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite))); |
491 __ addptr(rsp, 2*wordSize); | 489 __ addptr(rsp, 2*wordSize); |
492 | 490 |
493 if (UseSSE == 1) { | 491 if (UseSSE == 1) { |
494 __ movflt(xmm0, Address(rsp, 0)); | 492 __ movflt(xmm0, Address(rsp, 0)); |
629 } | 627 } |
630 } | 628 } |
631 } | 629 } |
632 | 630 |
633 // Schedule the branch target address early. | 631 // Schedule the branch target address early. |
634 __ movptr(rcx, Address(rbx, in_bytes(methodOopDesc::interpreter_entry_offset()))); | 632 __ movptr(rcx, Address(rbx, in_bytes(Method::interpreter_entry_offset()))); |
635 // And repush original return address | 633 // And repush original return address |
636 __ push(rax); | 634 __ push(rax); |
637 __ jmp(rcx); | 635 __ jmp(rcx); |
638 } | 636 } |
639 | 637 |
744 __ movptr(saved_sp, rdi); | 742 __ movptr(saved_sp, rdi); |
745 | 743 |
746 | 744 |
747 // Will jump to the compiled code just as if compiled code was doing it. | 745 // Will jump to the compiled code just as if compiled code was doing it. |
748 // Pre-load the register-jump target early, to schedule it better. | 746 // Pre-load the register-jump target early, to schedule it better. |
749 __ movptr(rdi, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset()))); | 747 __ movptr(rdi, Address(rbx, in_bytes(Method::from_compiled_offset()))); |
750 | 748 |
751 // Now generate the shuffle code. Pick up all register args and move the | 749 // Now generate the shuffle code. Pick up all register args and move the |
752 // rest through the floating point stack top. | 750 // rest through the floating point stack top. |
753 for (int i = 0; i < total_args_passed; i++) { | 751 for (int i = 0; i < total_args_passed; i++) { |
754 if (sig_bt[i] == T_VOID) { | 752 if (sig_bt[i] == T_VOID) { |
857 // and the vm will find there should this case occur. | 855 // and the vm will find there should this case occur. |
858 | 856 |
859 __ get_thread(rax); | 857 __ get_thread(rax); |
860 __ movptr(Address(rax, JavaThread::callee_target_offset()), rbx); | 858 __ movptr(Address(rax, JavaThread::callee_target_offset()), rbx); |
861 | 859 |
862 // move methodOop to rax, in case we end up in an c2i adapter. | 860 // move Method* to rax, in case we end up in an c2i adapter. |
863 // the c2i adapters expect methodOop in rax, (c2) because c2's | 861 // the c2i adapters expect Method* in rax, (c2) because c2's |
864 // resolve stubs return the result (the method) in rax,. | 862 // resolve stubs return the result (the method) in rax,. |
865 // I'd love to fix this. | 863 // I'd love to fix this. |
866 __ mov(rax, rbx); | 864 __ mov(rax, rbx); |
867 | 865 |
868 __ jmp(rdi); | 866 __ jmp(rdi); |
878 address i2c_entry = __ pc(); | 876 address i2c_entry = __ pc(); |
879 | 877 |
880 gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs); | 878 gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs); |
881 | 879 |
882 // ------------------------------------------------------------------------- | 880 // ------------------------------------------------------------------------- |
883 // Generate a C2I adapter. On entry we know rbx, holds the methodOop during calls | 881 // Generate a C2I adapter. On entry we know rbx, holds the Method* during calls |
884 // to the interpreter. The args start out packed in the compiled layout. They | 882 // to the interpreter. The args start out packed in the compiled layout. They |
885 // need to be unpacked into the interpreter layout. This will almost always | 883 // need to be unpacked into the interpreter layout. This will almost always |
886 // require some stack space. We grow the current (compiled) stack, then repack | 884 // require some stack space. We grow the current (compiled) stack, then repack |
887 // the args. We finally end in a jump to the generic interpreter entry point. | 885 // the args. We finally end in a jump to the generic interpreter entry point. |
888 // On exit from the interpreter, the interpreter will restore our SP (lest the | 886 // On exit from the interpreter, the interpreter will restore our SP (lest the |
896 Register temp = rbx; | 894 Register temp = rbx; |
897 | 895 |
898 { | 896 { |
899 | 897 |
900 Label missed; | 898 Label missed; |
901 | |
902 __ verify_oop(holder); | |
903 __ movptr(temp, Address(receiver, oopDesc::klass_offset_in_bytes())); | 899 __ movptr(temp, Address(receiver, oopDesc::klass_offset_in_bytes())); |
904 __ verify_oop(temp); | 900 __ cmpptr(temp, Address(holder, CompiledICHolder::holder_klass_offset())); |
905 | 901 __ movptr(rbx, Address(holder, CompiledICHolder::holder_method_offset())); |
906 __ cmpptr(temp, Address(holder, compiledICHolderOopDesc::holder_klass_offset())); | |
907 __ movptr(rbx, Address(holder, compiledICHolderOopDesc::holder_method_offset())); | |
908 __ jcc(Assembler::notEqual, missed); | 902 __ jcc(Assembler::notEqual, missed); |
909 // Method might have been compiled since the call site was patched to | 903 // Method might have been compiled since the call site was patched to |
910 // interpreted if that is the case treat it as a miss so we can get | 904 // interpreted if that is the case treat it as a miss so we can get |
911 // the call site corrected. | 905 // the call site corrected. |
912 __ cmpptr(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int32_t)NULL_WORD); | 906 __ cmpptr(Address(rbx, in_bytes(Method::code_offset())), (int32_t)NULL_WORD); |
913 __ jcc(Assembler::equal, skip_fixup); | 907 __ jcc(Assembler::equal, skip_fixup); |
914 | 908 |
915 __ bind(missed); | 909 __ bind(missed); |
916 __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); | 910 __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); |
917 } | 911 } |
1916 // We have all of the arguments setup at this point. We must not touch any register | 1910 // We have all of the arguments setup at this point. We must not touch any register |
1917 // argument registers at this point (what if we save/restore them there are no oop? | 1911 // argument registers at this point (what if we save/restore them there are no oop? |
1918 | 1912 |
1919 { | 1913 { |
1920 SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0); | 1914 SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0); |
1921 __ movoop(rax, JNIHandles::make_local(method())); | 1915 __ mov_metadata(rax, method()); |
1922 __ call_VM_leaf( | 1916 __ call_VM_leaf( |
1923 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), | 1917 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), |
1924 thread, rax); | 1918 thread, rax); |
1925 } | 1919 } |
1926 | 1920 |
1927 // RedefineClasses() tracing support for obsolete method entry | 1921 // RedefineClasses() tracing support for obsolete method entry |
1928 if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) { | 1922 if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) { |
1929 __ movoop(rax, JNIHandles::make_local(method())); | 1923 __ mov_metadata(rax, method()); |
1930 __ call_VM_leaf( | 1924 __ call_VM_leaf( |
1931 CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry), | 1925 CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry), |
1932 thread, rax); | 1926 thread, rax); |
1933 } | 1927 } |
1934 | 1928 |
2182 | 2176 |
2183 { | 2177 { |
2184 SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0); | 2178 SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0); |
2185 // Tell dtrace about this method exit | 2179 // Tell dtrace about this method exit |
2186 save_native_result(masm, ret_type, stack_slots); | 2180 save_native_result(masm, ret_type, stack_slots); |
2187 __ movoop(rax, JNIHandles::make_local(method())); | 2181 __ mov_metadata(rax, method()); |
2188 __ call_VM_leaf( | 2182 __ call_VM_leaf( |
2189 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), | 2183 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), |
2190 thread, rax); | 2184 thread, rax); |
2191 restore_native_result(masm, ret_type, stack_slots); | 2185 restore_native_result(masm, ret_type, stack_slots); |
2192 } | 2186 } |
3425 // check for pending exceptions | 3419 // check for pending exceptions |
3426 Label pending; | 3420 Label pending; |
3427 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); | 3421 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); |
3428 __ jcc(Assembler::notEqual, pending); | 3422 __ jcc(Assembler::notEqual, pending); |
3429 | 3423 |
3430 // get the returned methodOop | 3424 // get the returned Method* |
3431 __ movptr(rbx, Address(thread, JavaThread::vm_result_offset())); | 3425 __ get_vm_result_2(rbx, thread); |
3432 __ movptr(Address(rsp, RegisterSaver::rbx_offset() * wordSize), rbx); | 3426 __ movptr(Address(rsp, RegisterSaver::rbx_offset() * wordSize), rbx); |
3433 | 3427 |
3434 __ movptr(Address(rsp, RegisterSaver::rax_offset() * wordSize), rax); | 3428 __ movptr(Address(rsp, RegisterSaver::rax_offset() * wordSize), rax); |
3435 | 3429 |
3436 RegisterSaver::restore_live_registers(masm); | 3430 RegisterSaver::restore_live_registers(masm); |