aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorattila <none@none>2013-07-15 16:58:23 +0200
committerattila <none@none>2013-07-15 16:58:23 +0200
commit5bc5ea6a3016b6dee8a660b88adda3c008e6c490 (patch)
treef7a6da90a5048c3da267bebdc5bd8f638b7aae7f
parentd83551540bbea3857bf2125db88b226f3b60424e (diff)
downloadnashorn-5bc5ea6a3016b6dee8a660b88adda3c008e6c490.tar.gz
8011210: fix reporting of call site locations; print them on -tcs=miss
Reviewed-by: jlaskey, hannesw
-rw-r--r--src/jdk/internal/dynalink/DynamicLinker.java47
-rw-r--r--src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java10
2 files changed, 47 insertions, 10 deletions
diff --git a/src/jdk/internal/dynalink/DynamicLinker.java b/src/jdk/internal/dynalink/DynamicLinker.java
index c0930dae..155ff309 100644
--- a/src/jdk/internal/dynalink/DynamicLinker.java
+++ b/src/jdk/internal/dynalink/DynamicLinker.java
@@ -144,6 +144,9 @@ public class DynamicLinker {
private static final String CLASS_NAME = DynamicLinker.class.getName();
private static final String RELINK_METHOD_NAME = "relink";
+ private static final String INITIAL_LINK_CLASS_NAME = "java.lang.invoke.MethodHandleNatives";
+ private static final String INITIAL_LINK_METHOD_NAME = "linkCallSite";
+
private final LinkerServices linkerServices;
private final int runtimeContextArgCount;
private final boolean syncOnRelink;
@@ -262,20 +265,54 @@ public class DynamicLinker {
}
/**
- * Returns a stack trace element describing the location of the call site currently being relinked on the current
+ * Returns a stack trace element describing the location of the call site currently being linked on the current
* thread. The operation internally creates a Throwable object and inspects its stack trace, so it's potentially
* expensive. The recommended usage for it is in writing diagnostics code.
- * @return a stack trace element describing the location of the call site currently being relinked, or null if it is
- * not invoked while a call site is being relinked.
+ * @return a stack trace element describing the location of the call site currently being linked, or null if it is
+ * not invoked while a call site is being linked.
*/
- public static StackTraceElement getRelinkedCallSiteLocation() {
+ public static StackTraceElement getLinkedCallSiteLocation() {
final StackTraceElement[] trace = new Throwable().getStackTrace();
for(int i = 0; i < trace.length - 1; ++i) {
final StackTraceElement frame = trace[i];
- if(RELINK_METHOD_NAME.equals(frame.getMethodName()) && CLASS_NAME.equals(frame.getClassName())) {
+ if(isRelinkFrame(frame) || isInitialLinkFrame(frame)) {
return trace[i + 1];
}
}
return null;
}
+
+ /**
+ * Deprecated because of not precise name.
+ * @deprecated Use {@link #getLinkedCallSiteLocation()} instead.
+ * @return see non-deprecated method
+ */
+ @Deprecated
+ public static StackTraceElement getRelinkedCallSiteLocation() {
+ return getLinkedCallSiteLocation();
+ }
+
+ /**
+ * Returns true if the frame represents {@code MethodHandleNatives.linkCallSite()}, the frame immediately on top of
+ * the call site frame when the call site is being linked for the first time.
+ * @param frame the frame
+ * @return true if this frame represents {@code MethodHandleNatives.linkCallSite()}
+ */
+ private static boolean isInitialLinkFrame(final StackTraceElement frame) {
+ return testFrame(frame, INITIAL_LINK_METHOD_NAME, INITIAL_LINK_CLASS_NAME);
+ }
+
+ /**
+ * Returns true if the frame represents {@code DynamicLinker.relink()}, the frame immediately on top of the call
+ * site frame when the call site is being relinked (linked for second and subsequent times).
+ * @param frame the frame
+ * @return true if this frame represents {@code DynamicLinker.relink()}
+ */
+ private static boolean isRelinkFrame(final StackTraceElement frame) {
+ return testFrame(frame, RELINK_METHOD_NAME, CLASS_NAME);
+ }
+
+ private static boolean testFrame(final StackTraceElement frame, final String methodName, final String className) {
+ return methodName.equals(frame.getMethodName()) && className.equals(frame.getClassName());
+ }
}
diff --git a/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java b/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java
index 5665f02f..271bee5f 100644
--- a/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java
+++ b/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java
@@ -133,7 +133,7 @@ public class LinkerCallSite extends ChainedCallSite {
}
private static String getScriptLocation() {
- final StackTraceElement caller = DynamicLinker.getRelinkedCallSiteLocation();
+ final StackTraceElement caller = DynamicLinker.getLinkedCallSiteLocation();
return caller == null ? "unknown location" : (caller.getFileName() + ":" + caller.getLineNumber());
}
@@ -317,7 +317,7 @@ public class LinkerCallSite extends ChainedCallSite {
private static final MethodHandle TRACEOBJECT = findOwnMH("traceObject", Object.class, MethodHandle.class, Object[].class);
private static final MethodHandle TRACEVOID = findOwnMH("traceVoid", void.class, MethodHandle.class, Object[].class);
- private static final MethodHandle TRACEMISS = findOwnMH("traceMiss", void.class, Object[].class);
+ private static final MethodHandle TRACEMISS = findOwnMH("traceMiss", void.class, String.class, Object[].class);
TracingLinkerCallSite(final NashornCallSiteDescriptor desc) {
super(desc);
@@ -363,7 +363,7 @@ public class LinkerCallSite extends ChainedCallSite {
return relink;
}
final MethodType type = relink.type();
- return MH.foldArguments(relink, MH.asType(MH.asCollector(MH.bindTo(TRACEMISS, this), Object[].class, type.parameterCount()), type.changeReturnType(void.class)));
+ return MH.foldArguments(relink, MH.asType(MH.asCollector(MH.insertArguments(TRACEMISS, 0, this, "MISS " + getScriptLocation() + " "), Object[].class, type.parameterCount()), type.changeReturnType(void.class)));
}
private void printObject(final PrintWriter out, final Object arg) {
@@ -482,8 +482,8 @@ public class LinkerCallSite extends ChainedCallSite {
* @throws Throwable if invocation failes or throws exception/error
*/
@SuppressWarnings("unused")
- public void traceMiss(final Object... args) throws Throwable {
- tracePrint(Context.getCurrentErr(), "MISS ", args, null);
+ public void traceMiss(final String desc, final Object... args) throws Throwable {
+ tracePrint(Context.getCurrentErr(), desc, args, null);
}
private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {