Spread problem with > 10 arguments

Rémi Forax forax at univ-mlv.fr
Fri Jul 10 06:13:39 PDT 2009


Fredrik Öhrström a écrit :
> John Rose skrev:
>
>   
>> Implementation code, you'll see places where bytecode generation is  
>> stubbed out, and that is some cause for concern.
>>     
> Yes, this is an important discussion point since bytecode generation
> was what we are trying to avoid by creating invokedyn et al.
>
>   
>> you can implement the varargs mechanisms on top of it, but  
>> the code complexity is lower (I think) than putting varargs processing  
>> directly into the runtime.
>>     

Hi Fredrik,
(comments inlined)

> Ah, but generic invocation does not create Object 
> arrays! I could have proposed this, since obviously 
> JRockit can optimize these away. But I didn't. The 
> reason is that varargs enforce a permanently added 
> cost, but generic invocation does not. 
>
> Generic invocation requires the  number of 
> arguments to be the same because it will
> reuse the storage locations for the arguments!
>
> If the JVM has detected that an exact invocation call 
> is not possible using the single compare that you 
> have already in place. 
>
> Then for an interpreter, the extra cost of a generic 
> invocation call:
>
> 1)  where all args are references and the destination 
> method takes all object references, is almost zero! 
> No boxing, no casting.
>   


It's surely a stupid question but I don't understand
how the VM knows that such generic method exists.

Moreover, because generic invocation doesn't create a varargs array,
Do all adapters need to have 256 methods, because you can have
potentially a call with 255 arguments ?


> 2)  where all args are references and the destination method takes
> non-object references, is a cast per non-object reference. This cast
> can be fast-pathed into a single compare per object reference.
> If a destination requires a primitive, the unboxing is simply a
> mov instruction. 
>
> 3) where some args are primitive. Then you have to box the primitive
> before the call. Yes, this requires an alloc of an object. 
> However, if the destination method actually does something more 
> complex than working with primitives (most likely), then you 
> will have object allocations here as well. Therefore the 
> box alloc will only be a percentage of the total 
> number of allocations needed to execute the call.
>   

I don't agree.
If you take a look to adapters in MethodHandles, the code is really simple
and apart convert/spread/collect, you don't need this allocation.

Furthermore, I can see another problem,
because adapters will internaly calls another method handle using 
MethodHandle.invoke,
there is a real risk of a cascade of boxing/unboxing if by example one 
method handle out of two
is a convertArgument.


[...]

> But as I am trying to say, the cost for generic invocation in an 
> interpreter is not that high. For a chain of transforms the cost 
> will only be incurred at entry into the chain and at exit. 
> If the dynamic language uses object for its primitive values 
> (like RubyFixnum for example) there will be no boxing at 
> entry at all! If we add real fixnums to java, there will
> be no boxing at all either!
>   

The backport works like that, and its seems to work pretty well.

> I would like to throw out an open question:
>
> For dynamic languages like Ruby, that do not have 
> typed primitives and can work with arbitrarily large
> numbers, when will the transform happen where these numbers
> are translated from number-objects into ints when used
> as method arguments?
>
> If this can happen at static compile time of the Ruby
> program into bytecodes. Then you have a weird situation
> where you are able to deduce that both the caller
> and the destination will never exceed the int-capacity,
> but you will not know the actual destination! Since 
> if you did, at static compile time, you would be
> able to use a normal call instead. 
>
> On the other hand, if this can only happen during 
> runtime, then for a small interpreting-only JVM,
> you will have to take into account that the Ruby 
> optimizer will be interpreted! What will the
> cost/benefit analysis be for this? It seems
> unlikely to me that it would make sense to 
> over-optimize in such an environment. Better
> to work with number-objects and get almost
> zero cost at the transforms using generic 
> invocation.
>  
> What do you think?
>   

The generic invocation seems to me more a way to implements JSR292 on a VM
than a spec that all VMs should implement.

> //Fredrik
>   

Rémi



More information about the mlvm-dev mailing list