Yet Another bug
Rémi Forax
forax at univ-mlv.fr
Tue May 12 16:25:30 PDT 2009
Rémi Forax a écrit :
> John Rose a écrit :
>
>> I hope b59 smells better. I just pushed the changes I've chosen for
>> b59 to the patch repo.
>>
>> I am working on other changes too, but I am in point-fix mode, as JDK7
>> M3 settles down for JavaOne.
>>
>> My goal at the moment is to find workarounds for broken stuff, so as
>> not to be making widespread changes.
>>
>> Here are some workarounds that will help:
>>
>> --- Use MethodHandles.lookup().findFoo(...) if you run into trouble
>> with cached or public lookup-factories.
>>
>> Try to access only methods on the current class (the one calling
>> lookup()), or else public methods in public classes.
>>
>> This avoids bugs with the access checking logic, by exercising the
>> simplest forms of access checking.
>>
>>
> Or use reflection (getMethods()), set accessibility
> (setAccessible(true)) and
> use MethodHandle.unreflect(java.lang.reflect.Method).
>
>
>> --- In your method handle invocation sites and in invokedynamic sites,
>> prefer method handles of built-in types.
>>
>> A symptom of when you might want to do this is "NoClassDefFound" at an
>> invoke site, for an application class that obviously exists.
>>
>> Generally speaking, the inserted leading argument type to
>> Lookup.findVirtual only gets in the way. Use convertArguments to
>> change the leading argument to Object, or bind it to an instance
>> immediately.
>>
>>
> I've found that if you convert the leading argument of the method handler,
> you have to cast the leading argument of MethodHandle.invoke() too.
>
> // in my example
> methodHandle = MethodHandles.convertArguments(methodHandle,
> MethodType.make(void.class,
> /*AbstractVisitor.class*/ Object.class, // workaround
> to NoClassDefFound bug
> Object.class));
>
> // and then
> methodHandle.<void>invoke((Object)this, target);
> cast is needed here ------^
>
>
>> --- When currying method handles with insertArgument, insert only a
>> leading argument (#0) to a direct method handle.
>>
>> If you have something more complicated you want to do with currying,
>> consider using a JavaMethodHandle instead.
>>
>> (Yes, all this should be taken care of for you, and it will be!)
>>
>> -- John
>>
>>
>
> And it works like a charm :)
>
untile the next bug ...
The following code crash.
It doesn't crash if there is only one invokedynamic.
public class YACrash {
public void m(Object o) {
System.out.println("m "+o);
}
public static void main(String[] args) {
YACrash crash = new YACrash();
InvokeDynamic.<void>call((Object)crash, 3);
InvokeDynamic.<void>call((Object)crash, 4.0); // crash occurs here
}
static final MethodHandle stub;
static {
Linkage.registerBootstrapMethod("linker");
MethodHandle mh=MethodHandles.lookup().findVirtual(YACrash.class,
"m", MethodType.make(void.class, Object.class));
mh=MethodHandles.convertArguments(
mh,
MethodType.make(void.class, Object.class, Object.class));
stub=mh;
}
public static CallSite linker(Class<?> declaringClass, String name,
MethodType type) {
return new CallSite(declaringClass, name, type) {
@Override
protected MethodHandle initialTarget() {
return MethodHandles.convertArguments(
stub,
type());
}
};
}
}
Rémi
More information about the mlvm-dev
mailing list