Am 22.08.23 um 22:38 schrieb Charles Oliver Nutter:
On Tue, Aug 22, 2023 at 3:07 PM Jochen Theodorou <[email protected]> wrote:
Is there any possible circumstance in which the class Foo can now be
garbage collected? My assumption is no.

I can't speak to varhandles but this is very much like how JRuby
handles all of our jitted Ruby methods and indy binding. Under normal
circumstances, most Ruby methods get jit-compiled to bytecode lazily
and loaded into a unique classloader each; that classloader is not
rooted anywhere, so that if the Ruby method goes away, the jitted
class can also go away.

But don't you get problems with the method going away and then being
required again?

If the method was transient in the Ruby world (e.g. created on a
"singleton" object that goes out of scope) but is still bound at a
call site, it will not get garbage collected. We've actually had some
"won't fix" bug reports about indy call sites rooting methods or
classes that were called once (as is our expectation, not a bug).

I can maybe actually make my description more clear with an example in
pseudo Java:

'''
class ScriptRunner {
  public runScript10times(String script) {
    Object instance = compileJava(script)
    for (int i=0; i<10; i++) {
      instance.getClass().getMethod("run").invoke(instance)
    }
  }
}
'''

where compileJava will compile the script into bytecode and load it
under the assumption that it is a run() method. The script could be
normal Java. Then compileJava would maybe leverage javac for this and a
bit of reflection and a classloader that is only for that class to be
defined in. Let us assume ScriptRunner will stay around for a long time
and the classloader used is not referenced anywhere.

Anyway... my assumption for Java would be now, that after the method
call is done:
* instance can be collected and is in fact pretty fast.
* since instance and classloader are not referenced, the script class is
becoming collectable
* the script class can be collected once GC gets to it.

Now let us assume ScriptRunner is almost Java, everything is the same,
but the call to run()
"instance.getClass().getMethod("run").invoke(instance)" is now done
using invokedynamic "instance.run()". Let us assume there will be a
runtime selection of the run method, that does something like the
pseudo-Java version, unreflects the method and invokes the handle as
well as installs it in the mutable callsite as target (with guards to
detect a new script class).

Then it seems to me like:
* instance can be collected like above
* the class will be hard/strong referenced by the MethodHandle instance
type information in the callsite
* the script class can be collected only once the callsite target is
rewritten or the class ScriptRunner goes away.

Am I wrong?


bye Jochen
_______________________________________________
mlvm-dev mailing list
[email protected]
https://mail.openjdk.org/mailman/listinfo/mlvm-dev

Reply via email to