# HG changeset patch # User Lukas Stadler # Date 1397492409 -7200 # Node ID d3add9b82b710c5d1539691dba376b2e978c659d # Parent f3e74d317e8383af2b54bcc8944fb78d47037f42 change to StackIntrospection and Truffle getStackTrace implementation diff -r f3e74d317e83 -r d3add9b82b71 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/stack/StackIntrospection.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/stack/StackIntrospection.java Mon Apr 14 15:38:19 2014 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/stack/StackIntrospection.java Mon Apr 14 18:20:09 2014 +0200 @@ -30,10 +30,10 @@ * Accesses the current stack, returning a collection of {@long InspectedFrame}s that can be * used to inspect the stack frames' contents. * - * @param initialMethod if this is non-{@code null}, then the stack trace will start at this - * method - * @param matchingMethod if this is non-{@code null}, then only matching stack frames are + * @param initialMethods if this is non-{@code null}, then the stack trace will start at these + * methods + * @param matchingMethods if this is non-{@code null}, then only matching stack frames are * returned */ - Iterable getStackTrace(ResolvedJavaMethod initialMethod, ResolvedJavaMethod matchingMethod); + Iterable getStackTrace(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods); } diff -r f3e74d317e83 -r d3add9b82b71 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon Apr 14 15:38:19 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon Apr 14 18:20:09 2014 +0200 @@ -445,10 +445,12 @@ } } - public Iterable getStackTrace(final ResolvedJavaMethod initialMethod, final ResolvedJavaMethod matchingMethod) { + public Iterable getStackTrace(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods) { + final long[] initialMetaMethods = toMeta(initialMethods); + final long[] matchingMetaMethods = toMeta(matchingMethods); class StackFrameIterator implements Iterator { - private HotSpotStackFrameReference current = compilerToVm.getNextStackFrame(null, (HotSpotResolvedJavaMethod) initialMethod); + private HotSpotStackFrameReference current = compilerToVm.getNextStackFrame(null, initialMetaMethods); // we don't want to read ahead if hasNext isn't called private boolean advanced = true; @@ -465,7 +467,7 @@ private void update() { if (!advanced) { - current = compilerToVm.getNextStackFrame(current, (HotSpotResolvedJavaMethod) matchingMethod); + current = compilerToVm.getNextStackFrame(current, matchingMetaMethods); advanced = true; } } @@ -476,4 +478,16 @@ } }; } + + private static long[] toMeta(ResolvedJavaMethod[] methods) { + if (methods == null) { + return null; + } else { + long[] result = new long[methods.length]; + for (int i = 0; i < result.length; i++) { + result[i] = ((HotSpotResolvedJavaMethod) methods[i]).getMetaspaceMethod(); + } + return result; + } + } } diff -r f3e74d317e83 -r d3add9b82b71 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Mon Apr 14 15:38:19 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Mon Apr 14 18:20:09 2014 +0200 @@ -339,10 +339,11 @@ * Looks for the next Java stack frame with the given method. * * @param frame the starting point of the search, where {@code null} refers to the topmost frame - * @param method the method to look for, where {@code null} means that any frame is returned + * @param methods the metaspace methods to look for, where {@code null} means that any frame is + * returned * @return the frame, or {@code null} if the end of the stack was reached during the search */ - HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, HotSpotResolvedJavaMethod method); + HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, long[] methods); /** * Materialized all virtual objects within the given stack frame and update the locals within diff -r f3e74d317e83 -r d3add9b82b71 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Mon Apr 14 15:38:19 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Mon Apr 14 18:20:09 2014 +0200 @@ -179,7 +179,7 @@ public native boolean hasCompiledCodeForOSR(long metaspaceMethod, int entryBCI, int level); - public native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, HotSpotResolvedJavaMethod method); + public native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, long[] methods); public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate); diff -r f3e74d317e83 -r d3add9b82b71 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 Mon Apr 14 15:38:19 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Apr 14 18:20:09 2014 +0200 @@ -162,6 +162,10 @@ return HotSpotMetaspaceConstant.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this); } + public long getMetaspaceMethod() { + return metaspaceMethod; + } + @Override public Constant getEncoding() { return getMetaspaceMethodConstant(); diff -r f3e74d317e83 -r d3add9b82b71 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotFrameInstance.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotFrameInstance.java Mon Apr 14 15:38:19 2014 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotFrameInstance.java Mon Apr 14 18:20:09 2014 +0200 @@ -34,7 +34,7 @@ public abstract class HotSpotFrameInstance implements FrameInstance { - private final InspectedFrame stackFrame; + protected final InspectedFrame stackFrame; public HotSpotFrameInstance(InspectedFrame stackFrame) { this.stackFrame = stackFrame; @@ -51,13 +51,15 @@ if (access == FrameAccess.NONE) { return null; } - if (!slowPath) { + if (!slowPath && getNotifyIndex() != -1) { MaterializedFrameNotify notify = (MaterializedFrameNotify) stackFrame.getLocal(getNotifyIndex()); - if (access.ordinal() > notify.getOutsideFrameAccess().ordinal()) { - notify.setOutsideFrameAccess(access); - } - if (stackFrame.isVirtual(getFrameIndex())) { - stackFrame.materializeVirtualObjects(true); + if (notify != null) { + if (access.ordinal() > notify.getOutsideFrameAccess().ordinal()) { + notify.setOutsideFrameAccess(access); + } + if (stackFrame.isVirtual(getFrameIndex())) { + stackFrame.materializeVirtualObjects(true); + } } } switch (access) { @@ -82,9 +84,9 @@ return stackFrame.isVirtual(getFrameIndex()); } - public CallTarget getCallTarget() { - return (CallTarget) stackFrame.getLocal(getCallTargetIndex()); - } + public abstract CallTarget getCallTarget(); + + public abstract CallTarget getTargetCallTarget(); public CallNode getCallNode() { Object receiver = stackFrame.getLocal(getNotifyIndex()); @@ -100,7 +102,7 @@ * {@link DefaultCallNode#callProxy(MaterializedFrameNotify, CallTarget, VirtualFrame, Object[])} * method. */ - public static final class NextFrame extends HotSpotFrameInstance { + public static final class CallNodeFrame extends HotSpotFrameInstance { public static final Method METHOD; static { try { @@ -113,7 +115,7 @@ private static final int CALL_TARGET_INDEX = 1; private static final int FRAME_INDEX = 2; - public NextFrame(InspectedFrame stackFrame) { + public CallNodeFrame(InspectedFrame stackFrame) { super(stackFrame); } @@ -131,6 +133,16 @@ protected int getFrameIndex() { return FRAME_INDEX; } + + @Override + public CallTarget getCallTarget() { + return getCallNode().getRootNode().getCallTarget(); + } + + @Override + public CallTarget getTargetCallTarget() { + return (CallTarget) stackFrame.getLocal(getCallTargetIndex()); + } } /** @@ -138,7 +150,7 @@ * {@link RootCallTarget#callProxy(VirtualFrame)} method. */ @SuppressWarnings("javadoc") - public static final class CurrentFrame extends HotSpotFrameInstance { + public static final class CallTargetFrame extends HotSpotFrameInstance { public static final Method METHOD; static { try { @@ -147,17 +159,19 @@ throw new GraalInternalError(e); } } - private static final int NOTIFY_INDEX = 0; + private static final int NOTIFY_INDEX = -1; private static final int CALL_TARGET_INDEX = 0; private static final int FRAME_INDEX = 1; + private final boolean currentFrame; - public CurrentFrame(InspectedFrame stackFrame) { + public CallTargetFrame(InspectedFrame stackFrame, boolean currentFrame) { super(stackFrame); + this.currentFrame = currentFrame; } @Override public Frame getFrame(FrameAccess access, boolean slowPath) { - if (!slowPath) { + if (!slowPath && currentFrame) { throw new UnsupportedOperationException("cannot access current frame as fast path"); } return super.getFrame(access, slowPath); @@ -177,5 +191,15 @@ protected int getFrameIndex() { return FRAME_INDEX; } + + @Override + public CallTarget getCallTarget() { + return (CallTarget) stackFrame.getLocal(getCallTargetIndex()); + } + + @Override + public CallTarget getTargetCallTarget() { + return null; + } } } diff -r f3e74d317e83 -r d3add9b82b71 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Mon Apr 14 15:38:19 2014 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Mon Apr 14 18:20:09 2014 +0200 @@ -69,8 +69,16 @@ private ArrayList includes; private ArrayList excludes; + private final ResolvedJavaMethod[] callNodeMethod; + private final ResolvedJavaMethod[] callTargetMethod; + private final ResolvedJavaMethod[] anyFrameMethod; + private HotSpotTruffleRuntime() { installOptimizedCallTargetCallMethod(); + + callNodeMethod = new ResolvedJavaMethod[]{getGraalProviders().getMetaAccess().lookupJavaMethod(HotSpotFrameInstance.CallNodeFrame.METHOD)}; + callTargetMethod = new ResolvedJavaMethod[]{getGraalProviders().getMetaAccess().lookupJavaMethod(HotSpotFrameInstance.CallTargetFrame.METHOD)}; + anyFrameMethod = new ResolvedJavaMethod[]{callNodeMethod[0], callTargetMethod[0]}; } public String getName() { @@ -221,16 +229,27 @@ if (stackIntrospection == null) { stackIntrospection = Graal.getRequiredCapability(StackIntrospection.class); } - ResolvedJavaMethod method = getGraalProviders().getMetaAccess().lookupJavaMethod(HotSpotFrameInstance.NextFrame.METHOD); - final Iterator frames = stackIntrospection.getStackTrace(method, method).iterator(); + final Iterator frames = stackIntrospection.getStackTrace(anyFrameMethod, anyFrameMethod).iterator(); + assert frames.hasNext(); + InspectedFrame calltarget = frames.next(); + assert calltarget.getMethod().equals(callTargetMethod[0]); class FrameIterator implements Iterator { + public boolean hasNext() { return frames.hasNext(); } public FrameInstance next() { InspectedFrame frame = frames.next(); - return new HotSpotFrameInstance.NextFrame(frame); + if (frame.getMethod().equals(callNodeMethod[0])) { + assert frames.hasNext(); + InspectedFrame calltarget2 = frames.next(); + assert calltarget2.getMethod().equals(callTargetMethod[0]); + return new HotSpotFrameInstance.CallNodeFrame(frame); + } else { + assert frame.getMethod().equals(callTargetMethod[0]); + return new HotSpotFrameInstance.CallTargetFrame(frame, false); + } } } return new Iterable() { @@ -244,10 +263,9 @@ if (stackIntrospection == null) { stackIntrospection = Graal.getRequiredCapability(StackIntrospection.class); } - ResolvedJavaMethod method = getGraalProviders().getMetaAccess().lookupJavaMethod(HotSpotFrameInstance.CurrentFrame.METHOD); - Iterator frames = stackIntrospection.getStackTrace(method, method).iterator(); + Iterator frames = stackIntrospection.getStackTrace(callTargetMethod, callTargetMethod).iterator(); if (frames.hasNext()) { - return new HotSpotFrameInstance.CurrentFrame(frames.next()); + return new HotSpotFrameInstance.CallTargetFrame(frames.next(), true); } else { System.out.println("no current frame found"); return null; diff -r f3e74d317e83 -r d3add9b82b71 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameInstance.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameInstance.java Mon Apr 14 15:38:19 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameInstance.java Mon Apr 14 18:20:09 2014 +0200 @@ -43,4 +43,6 @@ CallNode getCallNode(); CallTarget getCallTarget(); + + CallTarget getTargetCallTarget(); } diff -r f3e74d317e83 -r d3add9b82b71 graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.sl --- a/graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.sl Mon Apr 14 15:38:19 2014 +0200 +++ b/graal/com.oracle.truffle.sl.test/tests/HelloEqualsWorld.sl Mon Apr 14 18:20:09 2014 +0200 @@ -19,4 +19,4 @@ doIt(i); i = i + 1; } -} +} diff -r f3e74d317e83 -r d3add9b82b71 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java Mon Apr 14 15:38:19 2014 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java Mon Apr 14 18:20:09 2014 +0200 @@ -46,12 +46,12 @@ private static String createStackTrace() { StringBuilder str = new StringBuilder(); for (FrameInstance frame : Truffle.getRuntime().getStackTrace()) { - dumpFrame(str, frame.getCallNode().getRootNode(), frame.getFrame(FrameAccess.READ_ONLY, true), frame.isVirtualFrame()); + dumpFrame(str, frame.getCallTarget(), frame.getFrame(FrameAccess.READ_ONLY, true), frame.isVirtualFrame()); } return str.toString(); } - private static void dumpFrame(StringBuilder str, RootNode rootNode, Frame frame, boolean isVirtual) { + private static void dumpFrame(StringBuilder str, CallTarget rootNode, Frame frame, boolean isVirtual) { if (str.length() > 0) { str.append("\n"); } diff -r f3e74d317e83 -r d3add9b82b71 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLGenericDispatchNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLGenericDispatchNode.java Mon Apr 14 15:38:19 2014 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLGenericDispatchNode.java Mon Apr 14 18:20:09 2014 +0200 @@ -42,7 +42,7 @@ * SL has a quite simple call lookup: just ask the function for the current call target, and * call it. */ - return DefaultCallNode.callProxy(this, function.getCallTarget(), frame, arguments); + return function.getCallTarget().call(arguments); } public FrameAccess getOutsideFrameAccess() { diff -r f3e74d317e83 -r d3add9b82b71 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Mon Apr 14 15:38:19 2014 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon Apr 14 18:20:09 2014 +0200 @@ -786,12 +786,22 @@ return tty->time_stamp().milliseconds(); C2V_END +bool matches(jlongArray methods, Method* method) { + typeArrayOop methods_oop = (typeArrayOop) JNIHandles::resolve(methods); + + for (int i = 0; i < methods_oop->length(); i++) { + if (methods_oop->long_at(i) == (jlong) method) { + return true; + } + } + return false; +} + // public native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, ResolvedJavaMethod method); -C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv *env, jobject compilerToVM, jobject hs_frame, jobject hs_method)) +C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv *env, jobject compilerToVM, jobject hs_frame, jlongArray methods)) ResourceMark rm; if (!thread->has_last_Java_frame()) return NULL; - methodHandle method = hs_method == NULL ? NULL : asMethod(HotSpotResolvedJavaMethod::metaspaceMethod(hs_method)); Handle result = InstanceKlass::cast(HotSpotStackFrameReference::klass())->allocate_instance(thread); HotSpotStackFrameReference::klass()->initialize(thread); @@ -840,7 +850,7 @@ if (vf->is_compiled_frame()) { // compiled method frame compiledVFrame* cvf = compiledVFrame::cast(vf); - if (method == NULL || cvf->method() == method()) { + if (methods == NULL || matches(methods, cvf->method())) { GrowableArray* objects = cvf->scope()->objects(); bool reallocated = false; if (objects != NULL) { @@ -864,23 +874,15 @@ locals = cvf->locals(); HotSpotStackFrameReference::set_bci(result, cvf->bci()); - if (hs_method == NULL) { - HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) cvf->method()); - } else { - HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) method()); - } + HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) cvf->method()); } } else if (vf->is_interpreted_frame()) { // interpreted method frame interpretedVFrame* ivf = interpretedVFrame::cast(vf); - if (method == NULL || ivf->method() == method()) { + if (methods == NULL || matches(methods, ivf->method())) { locals = ivf->locals(); HotSpotStackFrameReference::set_bci(result, ivf->bci()); - if (hs_method == NULL) { - HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) ivf->method()); - } else { - HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) method()); - } + HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) ivf->method()); HotSpotStackFrameReference::set_localIsVirtual(result, NULL); } } @@ -1031,6 +1033,7 @@ #define CLASS "Ljava/lang/Class;" #define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;" #define HS_RESOLVED_METHOD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;" +#define RESOLVED_METHOD "Lcom/oracle/graal/api/meta/ResolvedJavaMethod;" #define HS_COMPILED_CODE "Lcom/oracle/graal/hotspot/HotSpotCompiledCode;" #define HS_CONFIG "Lcom/oracle/graal/hotspot/HotSpotVMConfig;" #define HS_INSTALLED_CODE "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;" @@ -1093,7 +1096,7 @@ {CC"isMature", CC"("METASPACE_METHOD_DATA")Z", FN_PTR(isMature)}, {CC"hasCompiledCodeForOSR", CC"("METASPACE_METHOD"II)Z", FN_PTR(hasCompiledCodeForOSR)}, {CC"getTimeStamp", CC"()J", FN_PTR(getTimeStamp)}, - {CC"getNextStackFrame", CC"("HS_STACK_FRAME_REF HS_RESOLVED_METHOD")"HS_STACK_FRAME_REF, FN_PTR(getNextStackFrame)}, + {CC"getNextStackFrame", CC"("HS_STACK_FRAME_REF "[J)"HS_STACK_FRAME_REF, FN_PTR(getNextStackFrame)}, {CC"materializeVirtualObjects", CC"("HS_STACK_FRAME_REF"Z)V", FN_PTR(materializeVirtualObjects)}, };