Mercurial > hg > truffle
comparison src/share/vm/interpreter/interpreterRuntime.cpp @ 6275:957c266d8bc5
Merge with http://hg.openjdk.java.net/hsx/hsx24/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Tue, 21 Aug 2012 10:39:19 +0200 |
parents | 18a5539bf19b 1d7922586cf6 |
children | e522a00b91aa |
comparison
equal
deleted
inserted
replaced
5891:fd8832ae511d | 6275:957c266d8bc5 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
143 #ifdef ASSERT | 143 #ifdef ASSERT |
144 { | 144 { |
145 // The bytecode wrappers aren't GC-safe so construct a new one | 145 // The bytecode wrappers aren't GC-safe so construct a new one |
146 Bytecode_loadconstant ldc2(m, bci(thread)); | 146 Bytecode_loadconstant ldc2(m, bci(thread)); |
147 ConstantPoolCacheEntry* cpce = m->constants()->cache()->entry_at(ldc2.cache_index()); | 147 ConstantPoolCacheEntry* cpce = m->constants()->cache()->entry_at(ldc2.cache_index()); |
148 assert(result == cpce->f1(), "expected result for assembly code"); | 148 assert(result == cpce->f1_as_instance(), "expected result for assembly code"); |
149 } | 149 } |
150 #endif | 150 #endif |
151 } | 151 } |
152 IRT_END | 152 IRT_END |
153 | 153 |
373 IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThread* thread, oopDesc* exception)) | 373 IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThread* thread, oopDesc* exception)) |
374 | 374 |
375 Handle h_exception(thread, exception); | 375 Handle h_exception(thread, exception); |
376 methodHandle h_method (thread, method(thread)); | 376 methodHandle h_method (thread, method(thread)); |
377 constantPoolHandle h_constants(thread, h_method->constants()); | 377 constantPoolHandle h_constants(thread, h_method->constants()); |
378 typeArrayHandle h_extable (thread, h_method->exception_table()); | |
379 bool should_repeat; | 378 bool should_repeat; |
380 int handler_bci; | 379 int handler_bci; |
381 int current_bci = bci(thread); | 380 int current_bci = bci(thread); |
382 | 381 |
383 // Need to do this check first since when _do_not_unlock_if_synchronized | 382 // Need to do this check first since when _do_not_unlock_if_synchronized |
559 if (is_put || !info.access_flags().is_final()) { | 558 if (is_put || !info.access_flags().is_final()) { |
560 put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield); | 559 put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield); |
561 } | 560 } |
562 } | 561 } |
563 | 562 |
564 if (is_put && !is_static && klass->is_subclass_of(SystemDictionary::CallSite_klass()) && (info.name() == vmSymbols::target_name())) { | |
565 const jint direction = frame::interpreter_frame_expression_stack_direction(); | |
566 Handle call_site (THREAD, *((oop*) thread->last_frame().interpreter_frame_tos_at(-1 * direction))); | |
567 Handle method_handle(THREAD, *((oop*) thread->last_frame().interpreter_frame_tos_at( 0 * direction))); | |
568 assert(call_site ->is_a(SystemDictionary::CallSite_klass()), "must be"); | |
569 assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be"); | |
570 | |
571 { | |
572 // Walk all nmethods depending on this call site. | |
573 MutexLocker mu(Compile_lock, thread); | |
574 Universe::flush_dependents_on(call_site, method_handle); | |
575 } | |
576 | |
577 // Don't allow fast path for setting CallSite.target and sub-classes. | |
578 put_code = (Bytecodes::Code) 0; | |
579 } | |
580 | |
581 cache_entry(thread)->set_field( | 563 cache_entry(thread)->set_field( |
582 get_code, | 564 get_code, |
583 put_code, | 565 put_code, |
584 info.klass(), | 566 info.klass(), |
585 info.field_index(), | 567 info.field_index(), |
686 | 668 |
687 IRT_ENTRY(void, InterpreterRuntime::_breakpoint(JavaThread* thread, methodOopDesc* method, address bcp)) | 669 IRT_ENTRY(void, InterpreterRuntime::_breakpoint(JavaThread* thread, methodOopDesc* method, address bcp)) |
688 JvmtiExport::post_raw_breakpoint(thread, method, bcp); | 670 JvmtiExport::post_raw_breakpoint(thread, method, bcp); |
689 IRT_END | 671 IRT_END |
690 | 672 |
691 IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) | 673 IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) { |
692 // extract receiver from the outgoing argument list if necessary | 674 // extract receiver from the outgoing argument list if necessary |
693 Handle receiver(thread, NULL); | 675 Handle receiver(thread, NULL); |
694 if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) { | 676 if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) { |
695 ResourceMark rm(thread); | 677 ResourceMark rm(thread); |
696 methodHandle m (thread, method(thread)); | 678 methodHandle m (thread, method(thread)); |
754 cache_entry(thread)->set_method( | 736 cache_entry(thread)->set_method( |
755 bytecode, | 737 bytecode, |
756 info.resolved_method(), | 738 info.resolved_method(), |
757 info.vtable_index()); | 739 info.vtable_index()); |
758 } | 740 } |
741 } | |
742 IRT_END | |
743 | |
744 | |
745 // First time execution: Resolve symbols, create a permanent MethodType object. | |
746 IRT_ENTRY(void, InterpreterRuntime::resolve_invokehandle(JavaThread* thread)) { | |
747 assert(EnableInvokeDynamic, ""); | |
748 const Bytecodes::Code bytecode = Bytecodes::_invokehandle; | |
749 | |
750 // resolve method | |
751 CallInfo info; | |
752 constantPoolHandle pool(thread, method(thread)->constants()); | |
753 | |
754 { | |
755 JvmtiHideSingleStepping jhss(thread); | |
756 LinkResolver::resolve_invoke(info, Handle(), pool, | |
757 get_index_u2_cpcache(thread, bytecode), bytecode, CHECK); | |
758 } // end JvmtiHideSingleStepping | |
759 | |
760 cache_entry(thread)->set_method_handle( | |
761 info.resolved_method(), | |
762 info.resolved_appendix()); | |
763 } | |
759 IRT_END | 764 IRT_END |
760 | 765 |
761 | 766 |
762 // First time execution: Resolve symbols, create a permanent CallSite object. | 767 // First time execution: Resolve symbols, create a permanent CallSite object. |
763 IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) { | 768 IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) { |
764 ResourceMark rm(thread); | |
765 | |
766 assert(EnableInvokeDynamic, ""); | 769 assert(EnableInvokeDynamic, ""); |
767 | |
768 const Bytecodes::Code bytecode = Bytecodes::_invokedynamic; | 770 const Bytecodes::Code bytecode = Bytecodes::_invokedynamic; |
769 | 771 |
770 methodHandle caller_method(thread, method(thread)); | 772 //TO DO: consider passing BCI to Java. |
771 | 773 // int caller_bci = method(thread)->bci_from(bcp(thread)); |
772 constantPoolHandle pool(thread, caller_method->constants()); | 774 |
773 pool->set_invokedynamic(); // mark header to flag active call sites | 775 // resolve method |
774 | 776 CallInfo info; |
775 int caller_bci = 0; | 777 constantPoolHandle pool(thread, method(thread)->constants()); |
776 int site_index = 0; | 778 int index = get_index_u4(thread, bytecode); |
777 { address caller_bcp = bcp(thread); | 779 |
778 caller_bci = caller_method->bci_from(caller_bcp); | 780 { |
779 site_index = Bytes::get_native_u4(caller_bcp+1); | |
780 } | |
781 assert(site_index == InterpreterRuntime::bytecode(thread).get_index_u4(bytecode), ""); | |
782 assert(constantPoolCacheOopDesc::is_secondary_index(site_index), "proper format"); | |
783 // there is a second CPC entries that is of interest; it caches signature info: | |
784 int main_index = pool->cache()->secondary_entry_at(site_index)->main_entry_index(); | |
785 int pool_index = pool->cache()->entry_at(main_index)->constant_pool_index(); | |
786 | |
787 // first resolve the signature to a MH.invoke methodOop | |
788 if (!pool->cache()->entry_at(main_index)->is_resolved(bytecode)) { | |
789 JvmtiHideSingleStepping jhss(thread); | 781 JvmtiHideSingleStepping jhss(thread); |
790 CallInfo callinfo; | 782 LinkResolver::resolve_invoke(info, Handle(), pool, |
791 LinkResolver::resolve_invoke(callinfo, Handle(), pool, | 783 index, bytecode, CHECK); |
792 site_index, bytecode, CHECK); | 784 } // end JvmtiHideSingleStepping |
793 // The main entry corresponds to a JVM_CONSTANT_InvokeDynamic, and serves | 785 |
794 // as a common reference point for all invokedynamic call sites with | 786 pool->cache()->secondary_entry_at(index)->set_dynamic_call( |
795 // that exact call descriptor. We will link it in the CP cache exactly | 787 info.resolved_method(), |
796 // as if it were an invokevirtual of MethodHandle.invoke. | 788 info.resolved_appendix()); |
797 pool->cache()->entry_at(main_index)->set_method( | |
798 bytecode, | |
799 callinfo.resolved_method(), | |
800 callinfo.vtable_index()); | |
801 } | |
802 | |
803 // The method (f2 entry) of the main entry is the MH.invoke for the | |
804 // invokedynamic target call signature. | |
805 oop f1_value = pool->cache()->entry_at(main_index)->f1(); | |
806 methodHandle signature_invoker(THREAD, (methodOop) f1_value); | |
807 assert(signature_invoker.not_null() && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(), | |
808 "correct result from LinkResolver::resolve_invokedynamic"); | |
809 | |
810 Handle info; // optional argument(s) in JVM_CONSTANT_InvokeDynamic | |
811 Handle bootm = SystemDictionary::find_bootstrap_method(caller_method, caller_bci, | |
812 main_index, info, CHECK); | |
813 if (!java_lang_invoke_MethodHandle::is_instance(bootm())) { | |
814 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), | |
815 "no bootstrap method found for invokedynamic"); | |
816 } | |
817 | |
818 // Short circuit if CallSite has been bound already: | |
819 if (!pool->cache()->secondary_entry_at(site_index)->is_f1_null()) | |
820 return; | |
821 | |
822 Symbol* call_site_name = pool->name_ref_at(site_index); | |
823 | |
824 Handle call_site | |
825 = SystemDictionary::make_dynamic_call_site(bootm, | |
826 // Callee information: | |
827 call_site_name, | |
828 signature_invoker, | |
829 info, | |
830 // Caller information: | |
831 caller_method, | |
832 caller_bci, | |
833 CHECK); | |
834 | |
835 // In the secondary entry, the f1 field is the call site, and the f2 (index) | |
836 // field is some data about the invoke site. Currently, it is just the BCI. | |
837 // Later, it might be changed to help manage inlining dependencies. | |
838 pool->cache()->secondary_entry_at(site_index)->set_dynamic_call(call_site, signature_invoker); | |
839 } | 789 } |
840 IRT_END | 790 IRT_END |
841 | 791 |
842 | 792 |
843 //------------------------------------------------------------------------------------------------------------------------ | 793 //------------------------------------------------------------------------------------------------------------------------ |
856 frame fr = thread->last_frame(); | 806 frame fr = thread->last_frame(); |
857 methodOop method = fr.interpreter_frame_method(); | 807 methodOop method = fr.interpreter_frame_method(); |
858 int bci = method->bci_from(fr.interpreter_frame_bcp()); | 808 int bci = method->bci_from(fr.interpreter_frame_bcp()); |
859 nm = method->lookup_osr_nmethod_for(bci, CompLevel_none, false); | 809 nm = method->lookup_osr_nmethod_for(bci, CompLevel_none, false); |
860 } | 810 } |
811 #ifndef PRODUCT | |
812 if (TraceOnStackReplacement) { | |
813 if (nm != NULL) { | |
814 tty->print("OSR entry @ pc: " INTPTR_FORMAT ": ", nm->osr_entry()); | |
815 nm->print(); | |
816 } | |
817 } | |
818 #endif | |
861 return nm; | 819 return nm; |
862 } | 820 } |
863 | 821 |
864 IRT_ENTRY(nmethod*, | 822 IRT_ENTRY(nmethod*, |
865 InterpreterRuntime::frequency_counter_overflow_inner(JavaThread* thread, address branch_bcp)) | 823 InterpreterRuntime::frequency_counter_overflow_inner(JavaThread* thread, address branch_bcp)) |
997 IRT_ENTRY(void, InterpreterRuntime::post_field_access(JavaThread *thread, oopDesc* obj, | 955 IRT_ENTRY(void, InterpreterRuntime::post_field_access(JavaThread *thread, oopDesc* obj, |
998 ConstantPoolCacheEntry *cp_entry)) | 956 ConstantPoolCacheEntry *cp_entry)) |
999 | 957 |
1000 // check the access_flags for the field in the klass | 958 // check the access_flags for the field in the klass |
1001 | 959 |
1002 instanceKlass* ik = instanceKlass::cast(java_lang_Class::as_klassOop(cp_entry->f1())); | 960 instanceKlass* ik = instanceKlass::cast(java_lang_Class::as_klassOop(cp_entry->f1_as_klass_mirror())); |
1003 int index = cp_entry->field_index(); | 961 int index = cp_entry->field_index(); |
1004 if ((ik->field_access_flags(index) & JVM_ACC_FIELD_ACCESS_WATCHED) == 0) return; | 962 if ((ik->field_access_flags(index) & JVM_ACC_FIELD_ACCESS_WATCHED) == 0) return; |
1005 | 963 |
1006 switch(cp_entry->flag_state()) { | 964 switch(cp_entry->flag_state()) { |
1007 case btos: // fall through | 965 case btos: // fall through |
1020 Handle h_obj; | 978 Handle h_obj; |
1021 if (!is_static) { | 979 if (!is_static) { |
1022 // non-static field accessors have an object, but we need a handle | 980 // non-static field accessors have an object, but we need a handle |
1023 h_obj = Handle(thread, obj); | 981 h_obj = Handle(thread, obj); |
1024 } | 982 } |
1025 instanceKlassHandle h_cp_entry_f1(thread, java_lang_Class::as_klassOop(cp_entry->f1())); | 983 instanceKlassHandle h_cp_entry_f1(thread, java_lang_Class::as_klassOop(cp_entry->f1_as_klass_mirror())); |
1026 jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_cp_entry_f1, cp_entry->f2(), is_static); | 984 jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_cp_entry_f1, cp_entry->f2_as_index(), is_static); |
1027 JvmtiExport::post_field_access(thread, method(thread), bcp(thread), h_cp_entry_f1, h_obj, fid); | 985 JvmtiExport::post_field_access(thread, method(thread), bcp(thread), h_cp_entry_f1, h_obj, fid); |
1028 IRT_END | 986 IRT_END |
1029 | 987 |
1030 IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread, | 988 IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread, |
1031 oopDesc* obj, ConstantPoolCacheEntry *cp_entry, jvalue *value)) | 989 oopDesc* obj, ConstantPoolCacheEntry *cp_entry, jvalue *value)) |
1032 | 990 |
1033 klassOop k = java_lang_Class::as_klassOop(cp_entry->f1()); | 991 klassOop k = java_lang_Class::as_klassOop(cp_entry->f1_as_klass_mirror()); |
1034 | 992 |
1035 // check the access_flags for the field in the klass | 993 // check the access_flags for the field in the klass |
1036 instanceKlass* ik = instanceKlass::cast(k); | 994 instanceKlass* ik = instanceKlass::cast(k); |
1037 int index = cp_entry->field_index(); | 995 int index = cp_entry->field_index(); |
1038 // bail out if field modifications are not watched | 996 // bail out if field modifications are not watched |
1053 } | 1011 } |
1054 bool is_static = (obj == NULL); | 1012 bool is_static = (obj == NULL); |
1055 | 1013 |
1056 HandleMark hm(thread); | 1014 HandleMark hm(thread); |
1057 instanceKlassHandle h_klass(thread, k); | 1015 instanceKlassHandle h_klass(thread, k); |
1058 jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_klass, cp_entry->f2(), is_static); | 1016 jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_klass, cp_entry->f2_as_index(), is_static); |
1059 jvalue fvalue; | 1017 jvalue fvalue; |
1060 #ifdef _LP64 | 1018 #ifdef _LP64 |
1061 fvalue = *value; | 1019 fvalue = *value; |
1062 #else | 1020 #else |
1063 // Long/double values are stored unaligned and also noncontiguously with | 1021 // Long/double values are stored unaligned and also noncontiguously with |
1122 | 1080 |
1123 BufferBlob* bb = BufferBlob::create("Signature Handler Temp Buffer", | 1081 BufferBlob* bb = BufferBlob::create("Signature Handler Temp Buffer", |
1124 SignatureHandlerLibrary::buffer_size); | 1082 SignatureHandlerLibrary::buffer_size); |
1125 _buffer = bb->code_begin(); | 1083 _buffer = bb->code_begin(); |
1126 | 1084 |
1127 _fingerprints = new(ResourceObj::C_HEAP)GrowableArray<uint64_t>(32, true); | 1085 _fingerprints = new(ResourceObj::C_HEAP, mtCode)GrowableArray<uint64_t>(32, true); |
1128 _handlers = new(ResourceObj::C_HEAP)GrowableArray<address>(32, true); | 1086 _handlers = new(ResourceObj::C_HEAP, mtCode)GrowableArray<address>(32, true); |
1129 } | 1087 } |
1130 | 1088 |
1131 address SignatureHandlerLibrary::set_handler(CodeBuffer* buffer) { | 1089 address SignatureHandlerLibrary::set_handler(CodeBuffer* buffer) { |
1132 address handler = _handler; | 1090 address handler = _handler; |
1133 int insts_size = buffer->pure_insts_size(); | 1091 int insts_size = buffer->pure_insts_size(); |