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