Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instrumentor: also skip classes with methods now too large for JVM's 64k limit #18

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public static void main(String[] args) {
// load all classes to instrument (instrument library classes?)
Set<String> inputClasses = Options.v().getInput();

Set<String> skipped = new HashSet<>();
Set<String> skipped_jsr_ret = new HashSet<>();
Set<String> skipped_largemethod = new HashSet<>();

for (String cls : inputClasses) {
System.out.println("Instrumenting class: " + cls);
Expand All @@ -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);
}

}
Expand All @@ -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);
}
}
Expand Down