raphw / byte-buddy

Runtime code generation for the Java virtual machine.
https://bytebuddy.net
Apache License 2.0
6.28k stars 806 forks source link

Sharing Advice.Locals across multiple Advices #611

Open JonasKunz opened 5 years ago

JonasKunz commented 5 years ago

In our project we are currently writing a Java agent and use ByteBuddy to perform some configurable instrumentation. Based on the configuration we apply one or multiple Advices to methods. The problem is now that these Advices would like to share some method local data. Whenever we decide to instrument a method, we first apply an Advice which looks like this:

public class MyContextAdvice {

    @Advice.OnMethodEnter
    public static void onEnter(@Advice.Local("context") bootstrap.MyContext context) {
        context = bootstrap.MyContext.enterNewContext();
    }

    @Advice.OnMethodExit
    public static void onExit(@Advice.Local("context") bootstrap.MyContex context) {
        context.close();
    }
}

The other Advices which are then applied to the same method would like to access the "context" generated by MyContextAdvice. As I see it this is currently not possible using Advice.Local as all Advices are translated to individual ASMVisitorWrappers which have no knowledge of each other. Is there any other way of realizing this behaviour or do we have to fallback to using ASM? As the code is performance critical I would like to avoid "hacks" such as maintaining a custom stack using ThreadLocals.

raphw commented 5 years ago

This is not currently possible but might be a valuable extension. I think I could include an API that allows to chain Advice using something like Advice.to(...).andThen(Advice.to(...)).on(...) where the @Local values from the first advice were accessible to the second one.

I need to rework some of the Local handling at some point anyways and I will try to include this as a feature.

In the mean-time, you can implement a custom binding where you use ASM to read from a given offset where the local variables are stored if you know that some advice is applied before a second one. It should not be too hard to implement but obviously, Byte Buddy will not warn you from generating illegal byte code.

JonasKunz commented 5 years ago

Perfect! Thanks for the fast response.