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

Failing to split use case #1

Open
Shadowrs opened this issue Sep 10, 2018 · 4 comments
Open

Failing to split use case #1

Shadowrs opened this issue Sep 10, 2018 · 4 comments

Comments

@Shadowrs
Copy link

Shadowrs commented Sep 10, 2018

Firstly, this is some awesome work so thank you for your time.

JD-GUI can display the class. Jar is here https://www.dropbox.com/s/u36hzev27hcgq8h/large%20method.jar?dl=1

The offending method in question has a huge switch statement. 31152 Instructions.

alt

Code I'm using


MethodNode       big     = myClassNode.methods.get(0);
System.out.println("identified big method: "+big+" ... attempting to split");
SplitMethod.Result result = new SplitMethod(Opcodes.ASM5).split(node.name, big, 2000, 15000, 15000);
if (result == null)
	throw new NullPointerException("splitmethod failed :(");
node.methods.remove(big);
node.methods.add(result.trimmedMethod);
node.methods.add(result.splitOffMethod);

System.out.println("attempting new nodeToClass of customized node!");
Class<?> c = nodeToClass(node, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); // splitting removes both, so needed here

Output
Exception in thread "Thread-7" java.lang.NullPointerException: splitmethod failed :(

Disclosure, Im new to ASM. I tried ASM 4&5 in constructor params and min/max ranges of 2k - 15k, 20k 25k

@cretz
Copy link
Owner

cretz commented Sep 10, 2018

Yeah, this is a limitation of the algorithm I chose. I specifically chose to split off a large set of instructions without jumps. If there are no large sets of instructions, but instead a bunch of small sets inside a switch, it will take a different algorithm.

I'm afraid it doesn't fit my use case to split large switches, but this shouldn't hard to dev. Just take LookupSwitchInsnNode and take out half (or however many) the pairs, make a new method, have the default case of the now=halved lookup call the other with the same index var, and build the switch there.

@vinok88
Copy link

vinok88 commented Jun 25, 2019

I also got a null pointer thrown from this line, https://github.com/cretz/msplit/blob/master/src/main/java/msplit/Splitter.java#L352. This caused because there is a throw instruction before this store instruction. After throws and returns, the adapter you use clears the stack. Hence it is very frequent to hit this NPE. A fix from you would be nice.

@mikevoronov
Copy link

@vinok88 got the same NPE with GOTO instruction on cretz/asmble#30. I am trying to investigate it now, could you please provide your test case?

@mikevoronov
Copy link

mikevoronov commented Aug 29, 2019

The problem here is in absence of StackMapTable generation. Docs for AnalyzerAdapter says that

If this adapter is used with a class that does not contain stack map table attributes 
(i.e., pre Java 6 classes) then this adapter may not be able to compute the stack map frame for each instruction.

And here stack and locals set to null.

More docs could be found in the visitFrame docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants