0

I am trying to use ASM for my project and hit a performance issue where I am trying to get required object using a static method and its called like 1000 times

visitor.visitMethodInsn(Opcodes.INVOKESTATIC, TrackingConstants.TO_HELPER_CLASS, "getRTTDObject",TrackingConstants.TO_HELPER_GET_CLIENT_METHOD_DESC);

visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, TrackingConstants.CLIENT_INTERFACE_CLASS, "getPattern",TrackingConstants.CLIENT_INTERFACE_CLASS_GETPATTERN_METHOD_DESC);     

This first call is causing me overhead(where I get required object and pass to next line for performing "getPattern" on the object.During investigation I realized that the object which I am trying to retrieve via the static method is available with me from the starting itself so if I was able to push that Java object onto stack and avoid the static calls I wouldn't not face any performance issues.

I tried couple of ways with no luck and finally tried to create new Field of the object but get an IllegalArgumentException similar to this post Creating a new field with asm 4 after going through the link I realized that we need write code to create the object and can't directly use existing object.

So is there no way I can load my existing Java object onto stack (I guess it will already be on stack, is there a way I can use it) and perform required operations instead of using Static call to get it? Is there a way I can achieve it?

Community
  • 1
  • 1
VishwanathB
  • 139
  • 2
  • 10
  • Have you determined that this is actually a performance bottleneck? Have you determined that the JVM isn't caching/inlining this already? – Antimony Oct 07 '13 at 13:14
  • Hi Antimony,No i use profiler to identify where bottle neck is and found that the static calls being made are consuming around 1.8%.How can i know if caching/inlining is done?You meant these repeated static calls needs to be cached and that is supposed to be taken care by JVM?? – VishwanathB Oct 07 '13 at 13:22
  • Well the JVM is supposed to do stuff like that automatically. Not sure why it isn't in this case. – Antimony Oct 07 '13 at 17:32
  • I will check with some of the JVM folks i know.Coming back to my question so there is no way i can load existing java object to avoid static calls??i have a getter method in my methodadapter which gives me the java object is.. there a way i can load this to my current stack which i am trying to populate using ASM?i came to know from your earlier reply that visitLdcInsn wont work here... – VishwanathB Oct 08 '13 at 15:33
  • The only ways to get an existing nonconstant object are from a method call or field access. But if the method or field is simple enough, it should be inlined anyway. – Antimony Oct 08 '13 at 19:46
  • 1.8% is not a real bottleneck. And it’s not the call overhead (such information is not available to a profiler), it’s the method itself. So if your static method consumes too much cpu time you should look at what your static method does. Or maybe you just didn’t profile long enough. The first invocation is always slower than subsequent ones. – Holger Oct 09 '13 at 07:36

1 Answers1

1

Once the object is on the stack (presumably after you call your static method the first time), you can:

  1. Emit a DUP instruction to duplicate the value already on the stack each time it is needed. This is probably the most performant option, but it requires you to craft your bytecode in such a way that the value will always be at/near the top of the stack when you need it. There are a few variants of the DUP instruction to choose from, each with different behavior; see the JVM Specification §6.5 for details.

  2. Call the static method once, then store the result in a temporary variable (use one of the ASTORE instruction variants). Push it onto the stack when it's needed by using the corresponding ALOAD variant.

Depending on the structure of your method, you may also combine these techniques (load from a temporary local, DUP as necessary, do something unrelated, repeat, etc.).

Mike Strobel
  • 25,075
  • 57
  • 69