Maksim Melnik
Maksim Melnik

Reputation: 555

OpenJDK 8 Lambdas processing

In my current project I want to be able to "reinstantiate" a lambda method (don't know if "reinstantiate" is the right word though)

Consider a following example

public static void main(String[] args) throws Throwable {
    TestUser tu = new TestUser();

    ITest1 lam = t->{
        System.out.println("whoops" + tu.toString());
        return 1;
    };

    tu.doExec(lam);

    calls++;
    if( calls == 1) main(args);
}

Here I ve tried to debug through the JVM calls and I noticed that JVM creates and MethodType and MethodHandle objects for the metafactory method (which creates builds CallSite) and for my lambda method. Now once this is done linkCallSite is invoked. This method builds the CallSite and links the lambda method to it just once. At this point, my question is, can I somehow delete the lambda CallSite and LambdaForm from the jvm and somehow trigger the whole process again?

And another question, when debugging through the JVM calls i noticed that every time when JVM executes the lambda method, a method Ljava/lang/invoke/LambdaForm$MH/818403870;.linkToTargetMethod(Object) gets invoked, which i cannot find sourcecode of, neither in JVM cpp sources, nor in java. How exactly is this method called, or where does it get invoked?

I know the question is kind of complicated, so I am open to your questions. Thank you in advance.

Upvotes: 3

Views: 944

Answers (1)

apangin
apangin

Reputation: 98284

can I somehow delete the lambda CallSite and LambdaForm from the jvm and somehow trigger the whole process again?

invokedynamic is linked to a CallSite (or sometimes directly to the target method) just once at the bytecode resolution time. The resolution result is saved in the constant pool cache and is not modified afterwards.

One possible way to reset the constant pool cache is to redefine the class. I don't count reloading the class in a different ClassLoader, since this is technically the same as loading a new class not related to an old one.

So, in order to trigger linkCallSite stuff once again, you may call Instrumentation.redefineClasses or the equivalent JVM TI RedefineClasses function.

How exactly is this method called, or where does it get invoked?

linkToTargetMethod is an adapter created dynamically in runtime to invoke a MethodHandle linked to the specific invokedynamic bytecode. It is basically the implementation of invokedynamic that calls this adapter.

Here is the source where this adapter is generated.

Upvotes: 1

Related Questions