From 2aa9e219e7f42edc6c9f6b0c080db4026dbf6039 Mon Sep 17 00:00:00 2001 From: Robert Scott Date: Sun, 26 Jan 2020 19:22:44 +0000 Subject: [PATCH] Instrumentor: also skip classes with methods now too large for JVM's 64k limit --- .../sv/kelinci/instrumentor/Instrumentor.java | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/instrumentor/src/main/java/edu/cmu/sv/kelinci/instrumentor/Instrumentor.java b/instrumentor/src/main/java/edu/cmu/sv/kelinci/instrumentor/Instrumentor.java index 855e2ec..8f5a070 100644 --- a/instrumentor/src/main/java/edu/cmu/sv/kelinci/instrumentor/Instrumentor.java +++ b/instrumentor/src/main/java/edu/cmu/sv/kelinci/instrumentor/Instrumentor.java @@ -42,7 +42,8 @@ public static void main(String[] args) { // load all classes to instrument (instrument library classes?) Set inputClasses = Options.v().getInput(); - Set skipped = new HashSet<>(); + Set skipped_jsr_ret = new HashSet<>(); + Set skipped_largemethod = new HashSet<>(); for (String cls : inputClasses) { System.out.println("Instrumenting class: " + cls); @@ -64,21 +65,32 @@ public static void main(String[] args) { byte[] bytes = cw.toByteArray(); writeClass(cls, bytes); } catch (RuntimeException rte) { - if (rte.getMessage().contains("JSR/RET")) { + final String msg = rte.getMessage(); + if (msg.contains("JSR/RET")) { /** * This is an exception related to a particular construct in the bytecode that * is not supported by ASM. It is deprecated and should not be present in bytecode * generated by a recent compiler. However, the JDK contains it and it may occur elsewhere. + * * This catch simply skips the class and warns the user. */ - System.out.println("\n[WARNING] RuntimeException thrown during instrumentation: " + rte.getMessage()); - System.out.println("Skipping instrumentation of class " + cls + "\n"); - // include original, uninstrumented class in output - loadAndWriteResource(cls); - skipped.add(cls); + skipped_jsr_ret.add(cls); + } else if (msg.contains("Method code too large")) { + /** + * Adding instrumentation to classes might push some large + * methods' size over the JVM's 64k method limit. + * + * This catch simply skips the class and warns the user. + */ + skipped_largemethod.add(cls); } else { throw rte; } + + System.out.println("\n[WARNING] RuntimeException thrown during instrumentation: " + rte.getMessage()); + System.out.println("Skipping instrumentation of class " + cls + "\n"); + // include original, uninstrumented class in output + loadAndWriteResource(cls); } } @@ -97,14 +109,24 @@ public static void main(String[] args) { loadAndWriteResource(resource); } - if (skipped.size() > 0) { + if (skipped_jsr_ret.size() > 0) { System.out.println("\nWARNING!!! Instrumentation of some classes has been skipped."); System.out.println("This is due to the JSR/RET bytecode construct that is not supported by ASM."); System.out.println("It is deprecated and should not be present in bytecode generated by a recent compiler."); System.out.println("If this is your code, try using a different compiler."); System.out.println("If this is a library, there might be not too much harm in skipping instrumentation of these classes."); System.out.println("Classes that were skipped:"); - for (String cls : skipped) + for (String cls : skipped_jsr_ret) + System.out.println(cls); + } + + if (skipped_largemethod.size() > 0) { + System.out.println("\nWARNING!!! Instrumentation of some classes has been skipped."); + System.out.println("This is due to the instrumentation pushing the size of a."); + System.out.println("method over the JVM's 64k method limit"); + System.out.println("If this is your code, try splitting it into smaller methods."); + System.out.println("Classes that were skipped:"); + for (String cls : skipped_largemethod) System.out.println(cls); } }