# HG changeset patch # User Thomas Wuerthinger # Date 1356011456 -3600 # Node ID 79a7b761755ce68ca3c6ca42f5f50d9c225a71f5 # Parent 75c18356504da58526ce851fa3849faf1085ba60 Added getLineNumberTable and getFileName capabilities. diff -r 75c18356504d -r 79a7b761755c graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Thu Dec 20 14:43:37 2012 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Thu Dec 20 14:50:56 2012 +0100 @@ -24,6 +24,7 @@ import java.lang.annotation.*; import java.lang.reflect.*; +import java.lang.reflect.Method; import java.util.*; /** @@ -159,4 +160,10 @@ * Returns {@code true} if this method can be inlined. */ boolean canBeInlined(); + + + /** + * Returns the LineNumberTable of this method. + */ + LineNumberTable getLineNumberTable(); } diff -r 75c18356504d -r 79a7b761755c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Thu Dec 20 14:43:37 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Thu Dec 20 14:50:56 2012 +0100 @@ -34,6 +34,7 @@ import com.oracle.graal.api.meta.ProfilingInfo.ExceptionSeen; import com.oracle.graal.bytecode.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.debug.*; import com.oracle.graal.phases.*; /** @@ -290,6 +291,21 @@ return HotSpotGraalRuntime.getInstance().getCompilerToVM().isMethodCompilable(metaspaceMethod); } + @Override + public LineNumberTable getLineNumberTable() { + long[] values = HotSpotGraalRuntime.getInstance().getCompilerToVM().getLineNumberTable(this); + assert values.length % 2 == 0; + int[] bci = new int[values.length / 2]; + int[] line = new int[values.length / 2]; + + for (int i = 0; i < values.length / 2; i++) { + bci[i] = (int) values[i * 2]; + line[i] = (int) values[i * 2 + 1]; + } + + return new LineNumberTableImpl(line, bci); + } + /** * Returns the offset of this method into the v-table. * If the holder is not initialized, returns -1 @@ -309,4 +325,5 @@ public CompilationTask currentTask() { return currentTask; } + } diff -r 75c18356504d -r 79a7b761755c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Thu Dec 20 14:43:37 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Thu Dec 20 14:50:56 2012 +0100 @@ -181,7 +181,12 @@ } @Override - public Class mirror() { + public String getSourceFileName() { + throw GraalInternalError.shouldNotReachHere(); + } + + @Override + public Class< ? > mirror() { return javaMirror; } } diff -r 75c18356504d -r 79a7b761755c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Thu Dec 20 14:43:37 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Thu Dec 20 14:50:56 2012 +0100 @@ -148,4 +148,13 @@ } return targetMethod().getName(); } + + public static MethodCallTargetNode find(StructuredGraph graph, ResolvedJavaMethod method) { + for (MethodCallTargetNode target : graph.getNodes(MethodCallTargetNode.class)) { + if (target.targetMethod == method) { + return target; + } + } + return null; + } } diff -r 75c18356504d -r 79a7b761755c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Thu Dec 20 14:43:37 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Thu Dec 20 14:50:56 2012 +0100 @@ -186,30 +186,67 @@ /** * Gets an approximate source code location for a node if possible. * - * @return a file name and source line number in stack trace format (e.g. "String.java:32") - * if an approximate source location is found, null otherwise + * @return the StackTraceElements if an approximate source location is found, null otherwise */ - public static String approxSourceLocation(Node node) { + public static StackTraceElement[] approxSourceStackTraceElement(Node node) { + ArrayList elements = new ArrayList<>(); Node n = node; while (n != null) { if (n instanceof MethodCallTargetNode) { + elements.add(((MethodCallTargetNode) n).targetMethod().asStackTraceElement(-1)); n = ((MethodCallTargetNode) n).invoke().node(); } if (n instanceof StateSplit) { - FrameState stateAfter = ((StateSplit) n).stateAfter(); - if (stateAfter != null) { - ResolvedJavaMethod method = stateAfter.method(); + FrameState state = ((StateSplit) n).stateAfter(); + while (state != null) { + ResolvedJavaMethod method = state.method(); if (method != null) { - StackTraceElement stackTraceElement = method.asStackTraceElement(stateAfter.bci); - if (stackTraceElement.getFileName() != null && stackTraceElement.getLineNumber() >= 0) { - return stackTraceElement.getFileName() + ":" + stackTraceElement.getLineNumber(); - } + elements.add(method.asStackTraceElement(state.bci - 1)); } + state = state.outerFrameState(); } + break; } n = n.predecessor(); } + return elements.toArray(new StackTraceElement[elements.size()]); + } + + + /** + * Gets an approximate source code location for a node, encoded as an exception, if possible. + * + * @return the exception with the location + */ + public static RuntimeException approxSourceException(Node node, Throwable cause) { + final StackTraceElement[] elements = approxSourceStackTraceElement(node); + @SuppressWarnings("serial") + RuntimeException exception = new RuntimeException(cause.getMessage(), cause) { + + @Override + public synchronized Throwable fillInStackTrace() { + setStackTrace(elements); + return this; + } + }; + return exception; + } + + /** + * Gets an approximate source code location for a node if possible. + * + * @return a file name and source line number in stack trace format (e.g. "String.java:32") if an approximate source + * location is found, null otherwise + */ + public static String approxSourceLocation(Node node) { + StackTraceElement[] stackTraceElements = approxSourceStackTraceElement(node); + if (stackTraceElements != null && stackTraceElements.length > 0) { + StackTraceElement top = stackTraceElements[0]; + if (top.getFileName() != null && top.getLineNumber() >= 0) { + return top.getFileName() + ":" + top.getLineNumber(); + } + } return null; } diff -r 75c18356504d -r 79a7b761755c src/cpu/x86/vm/jniTypes_x86.hpp --- a/src/cpu/x86/vm/jniTypes_x86.hpp Thu Dec 20 14:43:37 2012 +0100 +++ b/src/cpu/x86/vm/jniTypes_x86.hpp Thu Dec 20 14:50:56 2012 +0100 @@ -128,11 +128,25 @@ static inline jfloat get_float (intptr_t *from) { return *(jfloat *) from; } static inline jdouble get_double(intptr_t *from) { return *(jdouble *)(from + _JNI_SLOT_OFFSET); } - static inline jint get_int (intptr_t *from, int& pos) { return get_int(from + pos++); } - static inline jlong get_long (intptr_t *from, int& pos) { return get_long(from + pos); pos += 2; } - static inline oop get_obj (intptr_t *from, int& pos) { return get_obj(from + pos++); } - static inline jfloat get_float (intptr_t *from, int& pos) { return get_float(from + pos++); } - static inline jdouble get_double(intptr_t *from, int& pos) { return get_double(from + pos); pos += 2; } + static inline jint get_int (intptr_t *from, int& pos) { + return get_int(from + pos++); + } + static inline jlong get_long (intptr_t *from, int& pos) { + jlong result = get_long(from + pos); + pos += 2; + return result; + } + static inline oop get_obj (intptr_t *from, int& pos) { + return get_obj(from + pos++); + } + static inline jfloat get_float (intptr_t *from, int& pos) { + return get_float(from + pos++); + } + static inline jdouble get_double(intptr_t *from, int& pos) { + jdouble result = get_double(from + pos); + pos += 2; + return result; + } #undef _JNI_SLOT_OFFSET }; diff -r 75c18356504d -r 79a7b761755c src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Thu Dec 20 14:43:37 2012 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Thu Dec 20 14:50:56 2012 +0100 @@ -938,6 +938,47 @@ return JNIHandles::make_local(result()); C2V_END +C2V_ENTRY(jlongArray, getLineNumberTable, (JNIEnv *env, jobject, jobject hotspot_method)) +// XXX: Attention: it seEms that the line number table of a method just contains lines that are important, means that +// empty lines are left out or lines that can't have a breakpoint on it; eg int a; or try { + Method* method = getMethodFromHotSpotMethod(JNIHandles::resolve(hotspot_method)); + if(!method->has_linenumber_table()) { + return NULL; + } + u2 num_entries = 0; + CompressedLineNumberReadStream streamForSize(method->compressed_linenumber_table()); + while (streamForSize.read_pair()) { + num_entries++; + } + + CompressedLineNumberReadStream stream(method->compressed_linenumber_table()); + jlongArray result = env->NewLongArray(2 * num_entries); + + int i = 0; + jlong value; + while (stream.read_pair()) { + value = ((long) stream.bci()); + env->SetLongArrayRegion(result,i,1,&value); + value = ((long) stream.line()); + env->SetLongArrayRegion(result,i + 1,1,&value); + i += 2; + } + + return result; +C2V_END + + +C2V_VMENTRY(jobject, getFileName, (JNIEnv *, jobject, jobject klass)) + ResourceMark rm; + InstanceKlass* k = (InstanceKlass*) asKlass(HotSpotResolvedObjectType::metaspaceKlass(klass)); + Symbol *s = k->source_file_name(); + int length; + jchar *name = s->as_unicode(length); + + Handle result = java_lang_String::create_from_unicode(name, length, CHECK_NULL); + return JNIHandles::make_local(result()); + +C2V_END #define CC (char*) /*cast a literal from (const char*)*/ #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) @@ -960,6 +1001,7 @@ #define CLASS "Ljava/lang/Class;" #define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;" #define HS_RESOLVED_TYPE "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;" +#define HS_RESOLVED_JAVA_TYPE "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaType;" #define HS_RESOLVED_METHOD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;" #define HS_RESOLVED_FIELD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;" #define HS_COMP_RESULT "Lcom/oracle/graal/hotspot/HotSpotCompilationResult;" @@ -1008,6 +1050,8 @@ {CC"executeCompiledMethodVarargs", CC"("METASPACE_METHOD NMETHOD "["OBJECT")"OBJECT, FN_PTR(executeCompiledMethodVarargs)}, {CC"getDeoptedLeafGraphIds", CC"()[J", FN_PTR(getDeoptedLeafGraphIds)}, {CC"decodePC", CC"(J)"STRING, FN_PTR(decodePC)}, + {CC"getLineNumberTable", CC"("HS_RESOLVED_METHOD")[J", FN_PTR(getLineNumberTable)}, + {CC"getFileName", CC"("HS_RESOLVED_JAVA_TYPE")"STRING, FN_PTR(getFileName)}, }; int CompilerToVM_methods_count() {