Bootstrap method question

Rémi Forax forax at univ-mlv.fr
Sat Jun 12 05:09:48 PDT 2010


Le 12/06/2010 10:03, Howard Lovatt a écrit :
> This is probably my mistake, but I thought it worth checking anyway!
>
> I am playing around with multiple dispatch in the MLVM, in particular.
>
> public class Cost {
>   /* Written by PEC! */ static {
>     final MethodHandle bootstrap = MethodHandles.lookup().findStatic( 
> CostCalculatorDispatcher.class,
>                                                                      
>  "cost",
>                                                                      
>  Dispatchers.bootstrapType );
>     Linkage.registerBootstrapMethod( Cost.class, bootstrap );
>   }
>
>   public static void main( final String[] notUsed ) {
>     final List<Item> shoppingCart = new ArrayList<Item>();
>     shoppingCart.add( new Book( 20, 0.5 ) );
>     shoppingCart.add( new CD( 25 ) );
>     System.out.println( "cost = " + cost( shoppingCart ) );
>   }
>
>   public static double cost( final List<Item> shoppingCart ) {
>     final CostCalculator price = new Price();
>     final CostCalculator postage = new Postage();
>     double cost = 0;
>     for ( final Item item : shoppingCart ) {
>       try { /* Written by PEC! */
>         cost += InvokeDynamic.<double>cost( price, item );
>       } catch ( Throwable e ) {
>         throw new MultipleDispatchException( e );
>       }
>       try { /* Written by PEC! */
>         cost += InvokeDynamic.<double>cost( postage, item );
>       } catch ( Throwable e ) {
>         throw new MultipleDispatchException( e );
>       }
>     }
>     return cost;
>   }
> }
>
> The bootstrap method gets called, but its type argument is:
>
> (invokedynamicmultipledispatch.CostCalculator,invokedynamicmultipledispatch.Item)double
>
> IE the static types, I was expecting the dynamic types:
>
> (invokedynamicmultipledispatch.Price,invokedynamicmultipledispatch.Book)double
> etc.
>
> What am I doing wrong?

Hi Howard,
the bootstrap method is called when the VM need an implementation.
Because some VMs has no interpreter, JikesRVM or JRockit by example,
this linking can be done before the evaluation of the calling arguments.

So if you want to have access to the actual classes of the calling 
arguments,
the bootstrap method must register a method handle to collect them.

Here is a skeleton of how it should work :

public class RT {
   public static CallSite bootstrap(Class<?> declaringClass, String 
name, MethodType methodType) {
     CallSite callSite = new CallSite();
     MethodHandle target = MethodHandles.insertArguments(slowPath, 0, 
callSite);
     target = MethodHandles.collectArguments(target, methodType);
     callSite.setTarget(target);
     return callSite;
   }

   private static final MethodHandle slowPath =  
RT#slowPath(ClassSite,Object[]);

   public Object slowPath(CallSite callsite, Object[] args) {
     // find the target method handle depending of the classes of arguments
     MethodHandle specific = ...
     // create a test for those classes
     MethodHandle test = ...

     MethodHandle guard = MethodHandles.guardWithTest(test, specific, 
callSite.getTarget());
     callSite.setTarget(guard);

     return specific.invokeVarargs(args);
   }
}

The idea is to first register a generic method that will be called with 
an array of all arguments,
I've named it slowPath. slowPath is also the name of the corresponding 
method handle
(created with using a ldc, the syntax with a sharp in the middle).
In the bootstrap method, I use adapters to adapt the generic method to 
the signature of
the callsite, with collectArguments. I also 'specialize' the slowpath 
with the callsite to be able to
change the callsite target later.

So slowpath will be called with an array of arguments, here you have to 
find the most specific
method depending on the argument classes. You have also to create a test 
method that
will returns true if the arguments classes doesn't change. This part is 
not mandatory but
allow to avoid to do the lookup each time.
After I create a guard that says, if the test is true called the 
specific method otherwise,
called the last target (which can be the slowpath or a guard with a test 
and an older target).
So I create a tree of guard that ends with an adapter to the slowpath.

At the end, I need to find the result of the call and use invokeVarargs 
which will
call the method handle using the array values as calling arguments.

>
>
>  -- Howard.

Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20100612/34673e1b/attachment.html 


More information about the mlvm-dev mailing list