Closed liach closed 4 months ago
I have already confirmed that in hot code the JIT can see through many layers of wrappers and remove the boxing, arrays and lambdas entirely. As such, handles would offer no performance benefit and would be much less ergonomic to use.
Well, if you write if (1 == 2)
or an empty loop, JIT profiling can see through it too as long as the bytecode paths aren't shared and your methods are below FreqInlineSize. (The operation object is constant from a callsite, which plays a role too) The actual benefits here is the simpler generation.
invoke
/invokeExact
calls in injectors are much easier to transform to actual method calls: the type is pretty close, everything on the stack can be passed to the call as-is; you just need to pop the handle from the stack after returning.Of course, since you still have to support the existing Operation interface, I would totally understand if you think the maintenance cost of the new feature outweighs the benefit.
All in all, I don't really see any benefits whatsoever, along with many drawbacks.
An advantage of
MethodHandle
is that java compiler can generate any invocation method descriptor forinvokeExact
andinvoke
when they are surrounded by casts. This allows the call type (as from the NameAndType CP entry) to be preserved in the bytecode so it's easier for bytecode transfromation to substitute a call toMethodHandle
(just call and then drop MH on stack), or the bytecode generator can pass actualMethodHandle
s loaded from constant pool, which is still more friendly to JIT compilation thanOperation
objects.In contrast, the existing
Operation
takes a varargs array; though this looks simple in usage, it actually incurs extra costs in actual calls with varargs array allocations and type conversions, which is also complex and error-prone on the implementation side. https://github.com/LlamaLad7/MixinExtras/blob/b186f229cf76b69148d4e27902f9c4472cedb9af/src/main/java/com/llamalad7/mixinextras/utils/OperationUtils.java#L56