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 }