8011210: fix reporting of call site locations; print them on -tcs=miss
Reviewed-by: jlaskey, hannesw
This commit is contained in:
parent
9d4ac8b057
commit
a4b42a9a25
@ -144,6 +144,9 @@ public class DynamicLinker {
|
|||||||
private static final String CLASS_NAME = DynamicLinker.class.getName();
|
private static final String CLASS_NAME = DynamicLinker.class.getName();
|
||||||
private static final String RELINK_METHOD_NAME = "relink";
|
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 LinkerServices linkerServices;
|
||||||
private final int runtimeContextArgCount;
|
private final int runtimeContextArgCount;
|
||||||
private final boolean syncOnRelink;
|
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
|
* 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.
|
* 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
|
* @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 relinked.
|
* not invoked while a call site is being linked.
|
||||||
*/
|
*/
|
||||||
public static StackTraceElement getRelinkedCallSiteLocation() {
|
public static StackTraceElement getLinkedCallSiteLocation() {
|
||||||
final StackTraceElement[] trace = new Throwable().getStackTrace();
|
final StackTraceElement[] trace = new Throwable().getStackTrace();
|
||||||
for(int i = 0; i < trace.length - 1; ++i) {
|
for(int i = 0; i < trace.length - 1; ++i) {
|
||||||
final StackTraceElement frame = trace[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 trace[i + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ public class LinkerCallSite extends ChainedCallSite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String getScriptLocation() {
|
private static String getScriptLocation() {
|
||||||
final StackTraceElement caller = DynamicLinker.getRelinkedCallSiteLocation();
|
final StackTraceElement caller = DynamicLinker.getLinkedCallSiteLocation();
|
||||||
return caller == null ? "unknown location" : (caller.getFileName() + ":" + caller.getLineNumber());
|
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 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 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) {
|
TracingLinkerCallSite(final NashornCallSiteDescriptor desc) {
|
||||||
super(desc);
|
super(desc);
|
||||||
@ -363,7 +363,7 @@ public class LinkerCallSite extends ChainedCallSite {
|
|||||||
return relink;
|
return relink;
|
||||||
}
|
}
|
||||||
final MethodType type = relink.type();
|
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) {
|
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
|
* @throws Throwable if invocation failes or throws exception/error
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public void traceMiss(final Object... args) throws Throwable {
|
public void traceMiss(final String desc, final Object... args) throws Throwable {
|
||||||
tracePrint(Context.getCurrentErr(), "MISS ", args, null);
|
tracePrint(Context.getCurrentErr(), desc, args, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
|
private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user