On Mon, Aug 25, 2014 at 4:32 AM, Marcus Lagergren <marcus.lagerg...@oracle.com> wrote: > LambdaForms were most likely introduced as a platform independent way of > implementing methodhandle combinators in 8, because the 7 native > implementation was not very stable, but it was probably a mistake to add them > as “real” classes instead of code snippets that can just be spliced in around > the callsite. (I completely lack history here, so flame me if I am wrong)
That's how I remember it, yes. The native impl was not only a bit unstable...it was a security black hole because of all the special-casing for method handles in the JIT, and it had serious issues tracking type information correctly (infamous NCDFE problem). LFs aren't perfect, but we are way better off now than we were with that implementation. I do remember a conversation I had with Chris Thalinger about how it seemed wrong that method handles were treated as a middle grey area between call site and target, potentially not inlining in either direction. My suggestion was to treat all handles bound into a call site as though they were simply added bytecode in the surrounding method...essentially, force inline non-direct handles into the caller immediately (for some definition of "immediately") and let the only remaining decision be which DMHs to inline as well. It worked ok for simple cases we tried, but there were some places it didn't work well. I don't remember the details. We also did a rough equivalent to indy for JRuby's dispatch, but supported on any JVM: * All Ruby-callable methods have unique generated invoker class for arities 0-3,N. These invokers contained all argument adaptation, heap frame management, etc...just like a force-compiled MH chain. * Each call site gets a synthetic method body that does lookup, caching, and dispatch. Dispatch passes directly into those 0-3,N call paths, and for matching arities it should inline straight through (the invokers implement all direct-path arities as direct calls to the appropriate code). These generated call site methods were only monomorphic, but this setup gave us fully inlinable dynamic dispatches without indy. It worked well if we bumped up inlining thresholds (this was pre-incremental JIT) but we shelved it at the time. However, I'm probably going to explore this path again to get near-indy speeds on non-indy JVMs for the new IR-based JIT. Put a bit more directly: I can generate a load of bytecode to get indy-like behavior with or without indy too. The gulf between the current indy implementation and my way – explicitly generating code where and when I need it – is LambdaForm interpretation and translation. > For 9, it seems that we need a way to implement an indy that doesn’t result > in class generation and installation of anonymous runtime classes. Note that > _class installation_ as such is also a large overhead in the JVM - even more > so when we regenerate more code to get more optimal types. I think we need to > move from separate classes to inlined code, or something that requires > minimium bookkeeping. I think this may be subject to profile pollution as > well, but I haven’t been able to get my head around the ramifications yet. I am going to play with the property Jochen mentioned, which forces LFs to JIT much sooner. I feel like we're almost where we need to be, but it feels like LFs need to be more directly represented as IR in C2 rather than going through this foggy middle ground of JVM bytecode. *I* can do foggy JVM bytecode...indy should be doing a lot better than that. Hell, should MethodHandle be backed by Graal IR instead of LFs? It would still be interpretable, but when we go to JIT the chain we're losing a lot less in translation, and we can do site or target-specific specialization at that point. I always saw MHs as a general-purpose call site IR. Maybe we should make good on that. - Charlie _______________________________________________ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev