Mercurial > hg > truffle
comparison src/share/vm/graal/graalCompilerToVM.cpp @ 15063:36e1a11a72b3
new StackIntrospection interface to allow access to stack contents
author | Lukas Stadler <lukas.stadler@oracle.com> |
---|---|
date | Fri, 11 Apr 2014 11:52:19 +0200 |
parents | 4df6d7c966a2 |
children | d3add9b82b71 |
comparison
equal
deleted
inserted
replaced
15062:10b0b01a4a61 | 15063:36e1a11a72b3 |
---|---|
20 * or visit www.oracle.com if you need additional information or have any | 20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. | 21 * questions. |
22 */ | 22 */ |
23 | 23 |
24 #include "precompiled.hpp" | 24 #include "precompiled.hpp" |
25 #include "code/scopeDesc.hpp" | |
25 #include "memory/oopFactory.hpp" | 26 #include "memory/oopFactory.hpp" |
26 #include "oops/generateOopMap.hpp" | 27 #include "oops/generateOopMap.hpp" |
27 #include "oops/fieldStreams.hpp" | 28 #include "oops/fieldStreams.hpp" |
28 #include "runtime/fieldDescriptor.hpp" | 29 #include "runtime/fieldDescriptor.hpp" |
29 #include "runtime/javaCalls.hpp" | 30 #include "runtime/javaCalls.hpp" |
37 #include "graal/graalJavaAccess.hpp" | 38 #include "graal/graalJavaAccess.hpp" |
38 #include "graal/graalCodeInstaller.hpp" | 39 #include "graal/graalCodeInstaller.hpp" |
39 #include "graal/graalVMToCompiler.hpp" | 40 #include "graal/graalVMToCompiler.hpp" |
40 #include "gc_implementation/g1/heapRegion.hpp" | 41 #include "gc_implementation/g1/heapRegion.hpp" |
41 #include "runtime/javaCalls.hpp" | 42 #include "runtime/javaCalls.hpp" |
43 #include "runtime/deoptimization.hpp" | |
44 #include "runtime/vframe.hpp" | |
45 #include "runtime/vframe_hp.hpp" | |
42 #include "runtime/vmStructs.hpp" | 46 #include "runtime/vmStructs.hpp" |
43 #include "runtime/gpu.hpp" | 47 #include "runtime/gpu.hpp" |
44 | 48 |
45 | 49 |
46 // Entry to native method implementation that transitions current thread to '_thread_in_vm'. | 50 // Entry to native method implementation that transitions current thread to '_thread_in_vm'. |
780 // tty->time_stamp is the time since VM start which should be used | 784 // tty->time_stamp is the time since VM start which should be used |
781 // for all HotSpot log output when a timestamp is required. | 785 // for all HotSpot log output when a timestamp is required. |
782 return tty->time_stamp().milliseconds(); | 786 return tty->time_stamp().milliseconds(); |
783 C2V_END | 787 C2V_END |
784 | 788 |
789 // public native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, ResolvedJavaMethod method); | |
790 C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv *env, jobject compilerToVM, jobject hs_frame, jobject hs_method)) | |
791 ResourceMark rm; | |
792 | |
793 if (!thread->has_last_Java_frame()) return NULL; | |
794 methodHandle method = hs_method == NULL ? NULL : asMethod(HotSpotResolvedJavaMethod::metaspaceMethod(hs_method)); | |
795 Handle result = InstanceKlass::cast(HotSpotStackFrameReference::klass())->allocate_instance(thread); | |
796 HotSpotStackFrameReference::klass()->initialize(thread); | |
797 | |
798 StackFrameStream fst(thread); | |
799 if (hs_frame != NULL) { | |
800 // look for the correct stack frame if one is given | |
801 intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(hs_frame); | |
802 while (fst.current()->sp() != stack_pointer && !fst.is_done()) { | |
803 fst.next(); | |
804 } | |
805 if (fst.current()->sp() != stack_pointer) { | |
806 THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "stack frame not found") | |
807 } | |
808 } | |
809 | |
810 int frame_number = 0; | |
811 vframe* vf = vframe::new_vframe(fst.current(), fst.register_map(), thread); | |
812 if (hs_frame != NULL) { | |
813 // look for the correct vframe within the stack frame if one is given | |
814 int last_frame_number = HotSpotStackFrameReference::frameNumber(hs_frame); | |
815 while (frame_number < last_frame_number) { | |
816 if (vf->is_top()) { | |
817 THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "invalid frame number") | |
818 } | |
819 vf = vf->sender(); | |
820 frame_number ++; | |
821 } | |
822 // move one frame forward | |
823 if (vf->is_top()) { | |
824 if (fst.is_done()) { | |
825 return NULL; | |
826 } | |
827 fst.next(); | |
828 vf = vframe::new_vframe(fst.current(), fst.register_map(), thread); | |
829 frame_number = 0; | |
830 } else { | |
831 vf = vf->sender(); | |
832 frame_number++; | |
833 } | |
834 } | |
835 | |
836 while (true) { | |
837 // look for the given method | |
838 while (true) { | |
839 StackValueCollection* locals = NULL; | |
840 if (vf->is_compiled_frame()) { | |
841 // compiled method frame | |
842 compiledVFrame* cvf = compiledVFrame::cast(vf); | |
843 if (method == NULL || cvf->method() == method()) { | |
844 GrowableArray<ScopeValue*>* objects = cvf->scope()->objects(); | |
845 bool reallocated = false; | |
846 if (objects != NULL) { | |
847 reallocated = Deoptimization::realloc_objects(thread, fst.current(), objects, THREAD); | |
848 if (reallocated) { | |
849 Deoptimization::reassign_fields(fst.current(), fst.register_map(), objects); | |
850 } | |
851 | |
852 GrowableArray<ScopeValue*>* local_values = cvf->scope()->locals(); | |
853 typeArrayHandle array = oopFactory::new_boolArray(local_values->length(), thread); | |
854 for (int i = 0; i < local_values->length(); i++) { | |
855 ScopeValue* value = local_values->at(i); | |
856 if (value->is_object()) { | |
857 array->bool_at_put(i, true); | |
858 } | |
859 } | |
860 HotSpotStackFrameReference::set_localIsVirtual(result, array()); | |
861 } else { | |
862 HotSpotStackFrameReference::set_localIsVirtual(result, NULL); | |
863 } | |
864 | |
865 locals = cvf->locals(); | |
866 HotSpotStackFrameReference::set_bci(result, cvf->bci()); | |
867 if (hs_method == NULL) { | |
868 HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) cvf->method()); | |
869 } else { | |
870 HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) method()); | |
871 } | |
872 } | |
873 } else if (vf->is_interpreted_frame()) { | |
874 // interpreted method frame | |
875 interpretedVFrame* ivf = interpretedVFrame::cast(vf); | |
876 if (method == NULL || ivf->method() == method()) { | |
877 locals = ivf->locals(); | |
878 HotSpotStackFrameReference::set_bci(result, ivf->bci()); | |
879 if (hs_method == NULL) { | |
880 HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) ivf->method()); | |
881 } else { | |
882 HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) method()); | |
883 } | |
884 HotSpotStackFrameReference::set_localIsVirtual(result, NULL); | |
885 } | |
886 } | |
887 | |
888 // locals != NULL means that we found a matching frame and result is already partially initialized | |
889 if (locals != NULL) { | |
890 HotSpotStackFrameReference::set_compilerToVM(result, JNIHandles::resolve(compilerToVM)); | |
891 HotSpotStackFrameReference::set_stackPointer(result, (jlong) fst.current()->sp()); | |
892 HotSpotStackFrameReference::set_frameNumber(result, frame_number); | |
893 | |
894 // initialize the locals array | |
895 objArrayHandle array = oopFactory::new_objectArray(locals->size(), thread); | |
896 for (int i = 0; i < locals->size(); i++) { | |
897 StackValue* var = locals->at(i); | |
898 if (var->type() == T_OBJECT) { | |
899 array->obj_at_put(i, locals->at(i)->get_obj()()); | |
900 } | |
901 } | |
902 HotSpotStackFrameReference::set_locals(result, array()); | |
903 | |
904 return JNIHandles::make_local(thread, result()); | |
905 } | |
906 | |
907 if (vf->is_top()) { | |
908 break; | |
909 } | |
910 frame_number++; | |
911 vf = vf->sender(); | |
912 } // end of vframe loop | |
913 | |
914 if (fst.is_done()) { | |
915 break; | |
916 } | |
917 fst.next(); | |
918 vf = vframe::new_vframe(fst.current(), fst.register_map(), thread); | |
919 frame_number = 0; | |
920 } // end of frame loop | |
921 | |
922 // the end was reached without finding a matching method | |
923 return NULL; | |
924 C2V_END | |
925 | |
926 | |
927 | |
928 // public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate); | |
929 C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv *env, jobject, jobject hs_frame, bool invalidate)) | |
930 ResourceMark rm; | |
931 | |
932 if (hs_frame == NULL) { | |
933 THROW_MSG(vmSymbols::java_lang_NullPointerException(), "stack frame is null") | |
934 } | |
935 | |
936 HotSpotStackFrameReference::klass()->initialize(thread); | |
937 | |
938 // look for the given stack frame | |
939 StackFrameStream fst(thread); | |
940 intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(hs_frame); | |
941 while (fst.current()->sp() != stack_pointer && !fst.is_done()) { | |
942 fst.next(); | |
943 } | |
944 if (fst.current()->sp() != stack_pointer) { | |
945 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "stack frame not found") | |
946 } | |
947 | |
948 if (invalidate) { | |
949 assert(fst.current()->cb()->is_nmethod(), "nmethod expected"); | |
950 ((nmethod*) fst.current()->cb())->make_not_entrant(); | |
951 } | |
952 Deoptimization::deoptimize(thread, *fst.current(), fst.register_map(), Deoptimization::Reason_none); | |
953 | |
954 vframe* vf = vframe::new_vframe(fst.current(), fst.register_map(), thread); | |
955 if (!vf->is_compiled_frame()) { | |
956 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "compiled stack frame expected") | |
957 } | |
958 | |
959 GrowableArray<compiledVFrame*>* virtualFrames = new GrowableArray<compiledVFrame*>(10); | |
960 while (true) { | |
961 assert(vf->is_compiled_frame(), "Wrong frame type"); | |
962 virtualFrames->push(compiledVFrame::cast(vf)); | |
963 if (vf->is_top()) { | |
964 break; | |
965 } | |
966 vf = vf->sender(); | |
967 } | |
968 | |
969 int last_frame_number = HotSpotStackFrameReference::frameNumber(hs_frame); | |
970 if (last_frame_number >= virtualFrames->length()) { | |
971 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "invalid frame number") | |
972 } | |
973 | |
974 // Reallocate the non-escaping objects and restore their fields. | |
975 assert (virtualFrames->at(last_frame_number)->scope() != NULL,"invalid scope"); | |
976 GrowableArray<ScopeValue*>* objects = virtualFrames->at(last_frame_number)->scope()->objects(); | |
977 | |
978 if (objects == NULL) { | |
979 // no objects to materialize | |
980 return; | |
981 } | |
982 | |
983 bool reallocated = Deoptimization::realloc_objects(thread, fst.current(), objects, THREAD); | |
984 if (reallocated) { | |
985 Deoptimization::reassign_fields(fst.current(), fst.register_map(), objects); | |
986 | |
987 for (int frame_index = 0; frame_index < virtualFrames->length(); frame_index++) { | |
988 compiledVFrame* cvf = virtualFrames->at(frame_index); | |
989 | |
990 GrowableArray<ScopeValue*>* scopeLocals = cvf->scope()->locals(); | |
991 StackValueCollection* locals = cvf->locals(); | |
992 | |
993 if (locals != NULL) { | |
994 for (int i2 = 0; i2 < locals->size(); i2++) { | |
995 StackValue* var = locals->at(i2); | |
996 if (var->type() == T_OBJECT && scopeLocals->at(i2)->is_object()) { | |
997 jvalue val; | |
998 val.l = (jobject) locals->at(i2)->get_obj()(); | |
999 cvf->update_local(T_OBJECT, i2, val); | |
1000 } | |
1001 } | |
1002 } | |
1003 } | |
1004 | |
1005 // all locals are materialized by now | |
1006 HotSpotStackFrameReference::set_localIsVirtual(hs_frame, NULL); | |
1007 | |
1008 // update the locals array | |
1009 objArrayHandle array = (objArrayOop) HotSpotStackFrameReference::locals(hs_frame); | |
1010 StackValueCollection* locals = virtualFrames->at(last_frame_number)->locals(); | |
1011 for (int i = 0; i < locals->size(); i++) { | |
1012 StackValue* var = locals->at(i); | |
1013 if (var->type() == T_OBJECT) { | |
1014 array->obj_at_put(i, locals->at(i)->get_obj()()); | |
1015 } | |
1016 } | |
1017 } | |
1018 C2V_END | |
1019 | |
1020 | |
1021 | |
785 #define CC (char*) /*cast a literal from (const char*)*/ | 1022 #define CC (char*) /*cast a literal from (const char*)*/ |
786 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) | 1023 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) |
787 | 1024 |
788 #define TYPE "Lcom/oracle/graal/api/meta/JavaType;" | 1025 #define TYPE "Lcom/oracle/graal/api/meta/JavaType;" |
789 #define METHOD "Lcom/oracle/graal/api/meta/JavaMethod;" | 1026 #define METHOD "Lcom/oracle/graal/api/meta/JavaMethod;" |
796 #define HS_RESOLVED_METHOD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;" | 1033 #define HS_RESOLVED_METHOD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;" |
797 #define HS_COMPILED_CODE "Lcom/oracle/graal/hotspot/HotSpotCompiledCode;" | 1034 #define HS_COMPILED_CODE "Lcom/oracle/graal/hotspot/HotSpotCompiledCode;" |
798 #define HS_CONFIG "Lcom/oracle/graal/hotspot/HotSpotVMConfig;" | 1035 #define HS_CONFIG "Lcom/oracle/graal/hotspot/HotSpotVMConfig;" |
799 #define HS_INSTALLED_CODE "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;" | 1036 #define HS_INSTALLED_CODE "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;" |
800 #define NODE_CLASS "Lcom/oracle/graal/graph/NodeClass;" | 1037 #define NODE_CLASS "Lcom/oracle/graal/graph/NodeClass;" |
1038 #define HS_STACK_FRAME_REF "Lcom/oracle/graal/hotspot/HotSpotStackFrameReference;" | |
801 #define METASPACE_KLASS "J" | 1039 #define METASPACE_KLASS "J" |
802 #define METASPACE_METHOD "J" | 1040 #define METASPACE_METHOD "J" |
803 #define METASPACE_METHOD_DATA "J" | 1041 #define METASPACE_METHOD_DATA "J" |
804 #define METASPACE_CONSTANT_POOL "J" | 1042 #define METASPACE_CONSTANT_POOL "J" |
805 #define METASPACE_SYMBOL "J" | 1043 #define METASPACE_SYMBOL "J" |
853 {CC"getGPUs", CC"()"STRING, FN_PTR(getGPUs)}, | 1091 {CC"getGPUs", CC"()"STRING, FN_PTR(getGPUs)}, |
854 {CC"allocateCompileId", CC"("METASPACE_METHOD"I)I", FN_PTR(allocateCompileId)}, | 1092 {CC"allocateCompileId", CC"("METASPACE_METHOD"I)I", FN_PTR(allocateCompileId)}, |
855 {CC"isMature", CC"("METASPACE_METHOD_DATA")Z", FN_PTR(isMature)}, | 1093 {CC"isMature", CC"("METASPACE_METHOD_DATA")Z", FN_PTR(isMature)}, |
856 {CC"hasCompiledCodeForOSR", CC"("METASPACE_METHOD"II)Z", FN_PTR(hasCompiledCodeForOSR)}, | 1094 {CC"hasCompiledCodeForOSR", CC"("METASPACE_METHOD"II)Z", FN_PTR(hasCompiledCodeForOSR)}, |
857 {CC"getTimeStamp", CC"()J", FN_PTR(getTimeStamp)}, | 1095 {CC"getTimeStamp", CC"()J", FN_PTR(getTimeStamp)}, |
1096 {CC"getNextStackFrame", CC"("HS_STACK_FRAME_REF HS_RESOLVED_METHOD")"HS_STACK_FRAME_REF, FN_PTR(getNextStackFrame)}, | |
1097 {CC"materializeVirtualObjects", CC"("HS_STACK_FRAME_REF"Z)V", FN_PTR(materializeVirtualObjects)}, | |
858 }; | 1098 }; |
859 | 1099 |
860 int CompilerToVM_methods_count() { | 1100 int CompilerToVM_methods_count() { |
861 return sizeof(CompilerToVM_methods) / sizeof(JNINativeMethod); | 1101 return sizeof(CompilerToVM_methods) / sizeof(JNINativeMethod); |
862 } | 1102 } |