8295537: Enhance TRACE_METHOD_LINKAGE to show the target MethodHandle
Reviewed-by: jvernee, redestad, mchung
This commit is contained in:
parent
182c215888
commit
fd668dc44f
@ -158,21 +158,29 @@ abstract non-sealed class BoundMethodHandle extends MethodHandle {
|
|||||||
final int fieldCount() { return speciesData().fieldCount(); }
|
final int fieldCount() { return speciesData().fieldCount(); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Object internalProperties() {
|
Object internalProperties(int indentLevel) {
|
||||||
return "\n& BMH="+internalValues();
|
return "\n" + debugPrefix(indentLevel) + "& BMH=" + internalValues(indentLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
final String internalValues() {
|
final String internalValues(int indentLevel) {
|
||||||
|
String prefix = debugPrefix(indentLevel);
|
||||||
int count = fieldCount();
|
int count = fieldCount();
|
||||||
if (count == 1) {
|
if (count == 1 && indentLevel < 0) {
|
||||||
return "[" + arg(0) + "]";
|
return "[" + arg(0) + "]";
|
||||||
}
|
}
|
||||||
StringBuilder sb = new StringBuilder("[");
|
StringBuilder sb = new StringBuilder("[");
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
sb.append("\n ").append(i).append(": ( ").append(arg(i)).append(" )");
|
Object theArg = arg(i);
|
||||||
|
sb.append("\n ").append(prefix).append(i);
|
||||||
|
if (indentLevel >= 0 && theArg instanceof MethodHandle) {
|
||||||
|
sb.append(": MethodHandle = {").append(((MethodHandle)theArg).debugString(indentLevel+1));
|
||||||
|
sb.append("\n ").append(prefix).append("}");
|
||||||
|
} else {
|
||||||
|
sb.append(": ( ").append(theArg).append(" )");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return sb.append("\n]").toString();
|
return sb.append("\n").append(prefix).append("]").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*non-public*/
|
/*non-public*/
|
||||||
|
@ -170,8 +170,8 @@ sealed class DirectMethodHandle extends MethodHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String internalProperties() {
|
String internalProperties(int indentLevel) {
|
||||||
return "\n& DMH.MN="+internalMemberName();
|
return "\n" + debugPrefix(indentLevel) + "& DMH.MN=" + internalMemberName();
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Implementation methods.
|
//// Implementation methods.
|
||||||
|
@ -1029,12 +1029,18 @@ class LambdaForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
return debugString(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
String debugString(int indentLevel) {
|
||||||
|
String prefix = MethodHandle.debugPrefix(indentLevel);
|
||||||
String lambdaName = lambdaName();
|
String lambdaName = lambdaName();
|
||||||
StringBuilder buf = new StringBuilder(lambdaName + "=Lambda(");
|
StringBuilder buf = new StringBuilder(lambdaName);
|
||||||
|
buf.append("=Lambda(");
|
||||||
for (int i = 0; i < names.length; i++) {
|
for (int i = 0; i < names.length; i++) {
|
||||||
if (i == arity) buf.append(")=>{");
|
if (i == arity) buf.append(")=>{");
|
||||||
Name n = names[i];
|
Name n = names[i];
|
||||||
if (i >= arity) buf.append("\n ");
|
if (i >= arity) buf.append("\n ").append(prefix);
|
||||||
buf.append(n.paramString());
|
buf.append(n.paramString());
|
||||||
if (i < arity) {
|
if (i < arity) {
|
||||||
if (i+1 < arity) buf.append(",");
|
if (i+1 < arity) buf.append(",");
|
||||||
|
@ -1688,9 +1688,19 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
|
|||||||
}
|
}
|
||||||
/** Return a string with a several lines describing the method handle structure.
|
/** Return a string with a several lines describing the method handle structure.
|
||||||
* This string would be suitable for display in an IDE debugger.
|
* This string would be suitable for display in an IDE debugger.
|
||||||
|
* @param indentLevel If negative, return only information about this MethodHandle.
|
||||||
|
* Otherwise, return information about this MethodHandle and (recursively) all other
|
||||||
|
* MethodHandles, if any, that are invoked directly or indirectly by this MethodHandle.
|
||||||
|
* During the recursion, `indentLevel` is incremented (see
|
||||||
|
* BoundMethodHandle.internalValues()) to improve readability of
|
||||||
|
* the nested structure.
|
||||||
*/
|
*/
|
||||||
|
String debugString(int indentLevel) {
|
||||||
|
return type + " : " + internalForm().debugString(indentLevel) +
|
||||||
|
internalProperties(indentLevel);
|
||||||
|
}
|
||||||
String debugString() {
|
String debugString() {
|
||||||
return type+" : "+internalForm()+internalProperties();
|
return debugString(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Implementation methods.
|
//// Implementation methods.
|
||||||
@ -1787,12 +1797,29 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*non-public*/
|
/*non-public*/
|
||||||
Object internalValues() {
|
Object internalValues(int indentLevel) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Various debugging methods in MethodHandle (and subclasses thereof) and LambdaForm
|
||||||
|
* take an `indentLevel` argument, so that {@link java.lang.invoke.MethodHandle.debugString(int)}
|
||||||
|
* can return nested structures in a readable fashion. This method returns a string to be
|
||||||
|
* prepended to each line at the specified level.
|
||||||
|
*/
|
||||||
|
static String debugPrefix(int indentLevel) {
|
||||||
|
if (indentLevel <= 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return " ".repeat(indentLevel);
|
||||||
|
}
|
||||||
|
|
||||||
/*non-public*/
|
/*non-public*/
|
||||||
Object internalProperties() {
|
Object internalProperties() {
|
||||||
|
return internalProperties(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object internalProperties(int indentLevel) {
|
||||||
// Override to something to follow this.form, like "\n& FOO=bar"
|
// Override to something to follow this.form, like "\n& FOO=bar"
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -281,6 +281,12 @@ class MethodHandleNatives {
|
|||||||
type,
|
type,
|
||||||
staticArguments,
|
staticArguments,
|
||||||
caller);
|
caller);
|
||||||
|
if (TRACE_METHOD_LINKAGE) {
|
||||||
|
MethodHandle target = callSite.getTarget();
|
||||||
|
System.out.println("linkCallSite target class => " + target.getClass().getName());
|
||||||
|
System.out.println("linkCallSite target => " + target.debugString(0));
|
||||||
|
}
|
||||||
|
|
||||||
if (callSite instanceof ConstantCallSite) {
|
if (callSite instanceof ConstantCallSite) {
|
||||||
appendixResult[0] = callSite.dynamicInvoker();
|
appendixResult[0] = callSite.dynamicInvoker();
|
||||||
return Invokers.linkToTargetMethod(type);
|
return Invokers.linkToTargetMethod(type);
|
||||||
@ -298,13 +304,13 @@ class MethodHandleNatives {
|
|||||||
Object bsmReference = bootstrapMethod.internalMemberName();
|
Object bsmReference = bootstrapMethod.internalMemberName();
|
||||||
if (bsmReference == null) bsmReference = bootstrapMethod;
|
if (bsmReference == null) bsmReference = bootstrapMethod;
|
||||||
String staticArglist = staticArglistForTrace(staticArguments);
|
String staticArglist = staticArglistForTrace(staticArguments);
|
||||||
System.out.println("linkCallSite "+caller.getName()+" "+
|
System.out.println("linkCallSite "+getCallerInfo(caller)+" "+
|
||||||
bsmReference+" "+
|
bsmReference+" "+
|
||||||
name+type+"/"+staticArglist);
|
name+type+"/"+staticArglist);
|
||||||
try {
|
try {
|
||||||
MemberName res = linkCallSiteImpl(caller, bootstrapMethod, name, type,
|
MemberName res = linkCallSiteImpl(caller, bootstrapMethod, name, type,
|
||||||
staticArguments, appendixResult);
|
staticArguments, appendixResult);
|
||||||
System.out.println("linkCallSite => "+res+" + "+appendixResult[0]);
|
System.out.println("linkCallSite linkage => "+res+" + "+appendixResult[0]);
|
||||||
return res;
|
return res;
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
ex.printStackTrace(); // print now in case exception is swallowed
|
ex.printStackTrace(); // print now in case exception is swallowed
|
||||||
@ -313,6 +319,20 @@ class MethodHandleNatives {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a human-readable description of the caller. Something like
|
||||||
|
* "java.base/java.security.Security.<clinit>(Security.java:82)"
|
||||||
|
*/
|
||||||
|
private static String getCallerInfo(Class<?> caller) {
|
||||||
|
for (StackTraceElement e : Thread.currentThread().getStackTrace()) {
|
||||||
|
if (e.getClassName().equals(caller.getName())) {
|
||||||
|
return e.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// fallback if the caller is somehow missing from the stack.
|
||||||
|
return caller.getName();
|
||||||
|
}
|
||||||
|
|
||||||
// this implements the upcall from the JVM, MethodHandleNatives.linkDynamicConstant:
|
// this implements the upcall from the JVM, MethodHandleNatives.linkDynamicConstant:
|
||||||
static Object linkDynamicConstant(Object callerObj,
|
static Object linkDynamicConstant(Object callerObj,
|
||||||
Object bootstrapMethodObj,
|
Object bootstrapMethodObj,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user