Rémi Forax a écrit : > John Rose a écrit : > >> On May 2, 2009, at 5:55 PM, Rémi Forax wrote: >> >> >> >>> I badly need it. >>> I want a bootstrap method, a factory method of CallSite because >>> depending on invokedynamic name I want to store different kind of >>> profile. >>> I think that one bootstrap method that can return different CallSite >>> implementations >>> allow more freedom. >>> >>> >> D'oh! Thanks. >> >> Indeed, factories are strictly more powerful than classes. >> >> So will this work for you? >> >> bootstrap-method : method handle = lambda(callsite symbolic info) >> => (result : CallSite) >> >> > yes. > >> I think the bootstrap method should not be required to perform any >> side-effects on the call site; that should be a separate step in the >> call-site life cycle, embodied in a method. Did we say the bootstrap >> method might be allowed to run earlier than the first call, for more >> eager creation of call sites? (For code prelinking of some sort, not >> yet invented.) >> >> > > Earlier means between the call to registerBootstrapMethod and the first > call > The problem is that registerBootstrapMethod can be anywhere in the code, > I don't see an analysis that can be used by the VM to find where to > call the BSM earlier. > > Furthermore, the BSM itself can be a static method of the class containing > the invokedynamic, so the BSM will be able to run without static fields > correctly initialized ? > > >> Then the steps are: >> >> 1. prepare bytecodes & (virtually) allocate target variables, >> initialized to null (unlinked state) >> >> 2. (before or upon first invocation) call bootstrap method to >> permanently create CallSite (the JVM may throw an error if BSM hands >> it a CallSite already attached to a call: this implies invisible JVM >> cookies are in there somewhere) >> >> 3. at the "first call" (precisely, to an unlinked call site), do >> CallSite.initialize (which must link the site, else error) >> >> 4. at every call, pick up the non-null target, and just jump through it >> >> 5. once a target is set non-null, it can never go null again, except >> (perhaps?) at a safepoint as a result of bulk unlinking >> >> A call site is unlinked if and only if its target method is null. And >> setTarget(null) is always rejected. >> >> As it is currently coded, steps 2 and 3 might happen several times, >> either by racing threads as with the other invoke bytecodes, or in >> this case via re-entrant execution (probably a user error, but maybe >> not!). >> >> Yes, racing threads can redundantly link, but the process is all one- >> way, monotonic, so it completes. And it doesn't run bytecodes, except >> to load classes, which serializes through a system dictionary lock. >> For the interpreter linkage logic, see the hotspot sources, routine >> InterpreterRuntime::resolve_invoke. >> >> The odd thing with 292 is that, because we are using upcalls that run >> Java code, the application code (the MOP) can witness the races as >> they occur. We could serialize those events, with some care to avoid >> DOS attacks and unintentional interference between unrelated code. >> Sounds like more trouble that it's worth. The JVM can promise to pick >> a winner and commit at most one CallSite object per bytecoded call >> site. I suppose that's an issue for the EG to worry about. >> >> > > I see a way to avoid thread race. > The idea is to mandate that registerBootstrap method is always called > before the initialization > of the static block ends. > In that case, 2 and 3 can be done under the lock used to initialize the > static block. > > In fact, I don't care if 3 is called more than once if it's documented > in the spec. > But I don't like the fact that a call site created by the BSM is garbaged. > Users may want to maintain a list of call sites (for invalidations?) and > I don't see > how to do that if step 2 can produce call sites than will not be used. > Answering to myself: the problem of doing 3) at the end of the static block is that this disallow to use invokedynamic in the static block. It appears to me that this is a too strong restriction.
Perhaps we could rely on an explicit call ? Something like : Linkage.initializeInvokeDynamic(bootstrapClass, bootstrapMethodName); that sould be executed by the static block and only once. > >> -- John >> >> > Rémi > Rémi > _______________________________________________ > mlvm-dev mailing list > [email protected] > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > _______________________________________________ mlvm-dev mailing list [email protected] http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
