Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlexRogalskiy/3c3f76e3a7ea56e7a595d8b82db1b66b to your computer and use it in GitHub Desktop.
Save AlexRogalskiy/3c3f76e3a7ea56e7a595d8b82db1b66b to your computer and use it in GitHub Desktop.
Patch for InnerClassLambdaMetafactory to generate line number debug info
diff --git a/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java b/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
--- a/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java (revision 57611b30219191160f7faccb811b41a31c25c0b8)
+++ b/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java (date 1626887157914)
@@ -315,6 +315,18 @@
return generateInnerClass();
}
+ private static StackTraceElement getCallerFrame() {
+ StackTraceElement[] trace = new Exception().getStackTrace();
+ for (int i = 0; i < trace.length - 1; i++) {
+ StackTraceElement ste = trace[i];
+ if (ste.getClassName().equals("java.lang.invoke.MethodHandleNatives") &&
+ ste.getMethodName().equals("linkCallSite")) {
+ return trace[i + 1];
+ }
+ }
+ return null;
+ }
+
/**
* Generate a class file which implements the functional
* interface, define and return the class.
@@ -344,6 +356,14 @@
cw.visit(CLASSFILE_VERSION, ACC_SUPER + ACC_FINAL + ACC_SYNTHETIC,
lambdaClassName, null,
JAVA_LANG_OBJECT, interfaceNames);
+ int lineNumber;
+ StackTraceElement ste = getCallerFrame();
+ if (ste != null) {
+ cw.visitSource(ste.getFileName(), null);
+ lineNumber = ste.getLineNumber();
+ } else {
+ lineNumber = -1;
+ }
// Generate final fields to be filled in by constructor
for (int i = 0; i < argDescs.length; i++) {
@@ -363,14 +383,14 @@
// Forward the SAM method
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, interfaceMethodName,
interfaceMethodType.toMethodDescriptorString(), null, null);
- new ForwardingMethodGenerator(mv).generate(interfaceMethodType);
+ new ForwardingMethodGenerator(mv, lineNumber).generate(interfaceMethodType);
// Forward the altMethods
if (altMethods != null) {
for (MethodType mt : altMethods) {
mv = cw.visitMethod(ACC_PUBLIC, interfaceMethodName,
mt.toMethodDescriptorString(), null, null);
- new ForwardingMethodGenerator(mv).generate(mt);
+ new ForwardingMethodGenerator(mv, lineNumber).generate(mt);
}
}
@@ -541,14 +561,19 @@
* method, converting arguments, as needed.
*/
private class ForwardingMethodGenerator extends TypeConvertingMethodAdapter {
+ private final int lineNumber;
- ForwardingMethodGenerator(MethodVisitor mv) {
+ ForwardingMethodGenerator(MethodVisitor mv, int lineNumber) {
super(mv);
+ this.lineNumber = lineNumber;
}
void generate(MethodType methodType) {
visitCode();
+ Label start = new Label();
+ visitLabel(start);
+
if (implKind == MethodHandleInfo.REF_newInvokeSpecial) {
visitTypeInsn(NEW, implMethodClassName);
visitInsn(DUP);
@@ -585,6 +610,9 @@
visitInsn(getReturnOpcode(samReturnClass));
// Maxs computed by ClassWriter.COMPUTE_MAXS,these arguments ignored
visitMaxs(-1, -1);
+ if (lineNumber >= 0) {
+ visitLineNumber(lineNumber, start);
+ }
visitEnd();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment