简体   繁体   English

使用ASM将现有的Java对象加载到堆栈上

[英]Loading an existing java object onto stack using ASM

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 我正在尝试将ASM用于我的项目,并遇到一个性能问题,在该问题中,我尝试使用静态方法来获取所需的对象,其调用时间约为1000次

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. 第一次调用使我产生开销(在这里我得到了所需的对象,并传递到下一行以对该对象执行“ getPattern”。在调查过程中,我意识到我尝试通过静态方法检索的对象对我来说是可用的)。自启动,因此,如果我能够将该Java对象推入堆栈并避免进行静态调用,那么我就不会遇到任何性能问题。

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. 我尝试了几种运气不佳的方法,最后尝试创建对象的新字段,但得到了一个类似于本文的IllegalArgumentException。通过链接后,我用汇编语言4创建了一个新字段,我意识到我们需要编写代码来创建对象并不能直接使用现有对象。

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? 所以没有办法将现有的Java对象加载到堆栈上(我想它已经在堆栈上了,有没有办法可以使用它)并执行所需的操作,而不是使用静态调用来获取它? Is there a way I can achieve it? 有办法可以实现吗?

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. 每次发出一条DUP指令以复制堆栈中已经存在的值。 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; DUP指令有几种变体可供选择,每种变体具有不同的行为。 see the JVM Specification §6.5 for details. 有关详细信息,请参见JVM规范§6.5

  2. Call the static method once, then store the result in a temporary variable (use one of the ASTORE instruction variants). 调用一次静态方法,然后将结果存储在一个临时变量中(使用ASTORE指令变体之一)。 Push it onto the stack when it's needed by using the corresponding ALOAD variant. 需要时,使用相应的ALOAD变体将其压入堆栈。

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.). 根据您的方法的结构,您还可以结合使用这些技术(从临时本地加载,根据需要DUP ,执行无关的操作,重复操作等)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM