Good news, bad news
Rémi Forax
forax at univ-mlv.fr
Mon May 23 16:17:26 PDT 2011
On 05/24/2011 12:44 AM, Tom Rodriguez wrote:
> On May 23, 2011, at 3:27 PM, Charles Oliver Nutter wrote:
>
>> On Mon, May 23, 2011 at 5:20 PM, Tom Rodriguez<tom.rodriguez at oracle.com> wrote:
>>> On May 23, 2011, at 2:50 PM, Charles Oliver Nutter wrote:
>>>> I also do not see any indication *why* nothing inlines past this
>>>> point. Usually it would say "too big" or something.
>>> If there's no message then it wasn't even a candidate for inlining, either because the path was trimmed away by the optimizer or there wasn't enough information to bind the callsite to a particular method. It's probably the latter in this case.
>> Good to know I'm reading this output right :) Is there another logging
>> flag that will log these situations too? I'd like to have that not
>> just for invokedynamic opto.
>>
>>> Actually my guess is that the selectAlternative machinery is what's screwing it up. That code gets emitted as:
>>>
>>> (test ? a : b).invokeExact();
>>>
>>> instead of
>>>
>>> if (test) a.invokeExact(); else b.invokeExact();
>>>
>>> Since the first one only uses a single call site we can't statically inline even if a and b are constants. The optimizer could do that optimization but it currently doesn't. Can you build the guard differently? We'll need to build a new call site optimization to deal with the selectAlternative logic.
>> Is this a question for me? If so...
>>
>> Build the guard differently as in don't use
>> MethodHandles.guardWithTest? I probably could, but it would require
>> inserting "normal" Java code into the call path, which should in
>> theory be megamorphic (since all invokedynamic everywhere will go
>> through that same piece of code). Something like:
>>
>> IRubyObject myGuardWithTest(MethodHandle dmh, args...) {
>> if (test(args) {
>> return dmh.invokeExact(args);
>> } else {
>> inline cache
>> }
>> }
>>
>> I'd *love* for intermediate static Java snippits like this to inline
>> straight through, even if invokeExact would be megamorphic under
>> normal circumstances...but I don't think that's the case right now,
>> right?
> I haven't been following 292 that closely but it used to be a piece of code that did precisely that.
>
> + private Object invoke_L0() throws Throwable {
> + if ((boolean) test.invokeExact())
> + return target.invokeExact();
> + return fallback.invokeExact();
> + }
>
> It looks like it was reworked at some point to use selectAlternative but the optimizer was never updated to deal with it properly. It's not particularly hard, we just need to generate code like we would for a bimorphic call site. The current code expects to either get a constant or something else and doesn't inline if it's something else. In this case we have a Phi of two constants which we just need to split.
>
> I'm still unclear why you couldn't write your own variant of guardWithTest and have it work but my knowledge of what's really allowed is somewhat limited.
The main problem of writing your own variant is that you will have to
write 256 * (number_of_primitive_type + 1) variants.
The main idea of GWT (and all other method handle combiners) is that
they provide a way to get such polymorphic variant
without coding all combinations.
The benefit is also that these combiners are known by the VM that can
provide
dedicated path that are more efficient,
by ex, the arguments of GWT is pushed only once and used by the test
*and* the target (or fallback)
or better guarantee about how trees of combiners are inlined.
> tom
Rémi
More information about the mlvm-dev
mailing list