jdk7 b58, VM doesn't smell good

Chanwit Kaewkasi chanwit at gmail.com
Sun May 10 08:37:32 PDT 2009


Hi Remi,

I am running John's FidgetDemo with b58 and everything is fine.

I am using -XX:+EnableInvokeDynamic.
I compile the program with -target 7.

Perhaps,  I'll try your program posted here and see if I get the same error.

Cheers,

Chanwit

On Sun, May 10, 2009 at 4:02 PM, Rémi Forax <forax at univ-mlv.fr> wrote:
> The runtime of jdk7 b58 doesn't work too.
>
> java -cp test-classes/ fr.umlv.indy.visitor.test.Main0
> Java HotSpot(TM) Server VM warning: JSR 292 method handles are disabled
> in this JVM.  Use -XX:+EnableMethodHandles to enable.
> Exception in thread "main" java.lang.UnsatisfiedLinkError:
> sun.dyn.MethodHandleNatives.getConstant(I)I
>    at sun.dyn.MethodHandleNatives.getConstant(Native Method)
>    at sun.dyn.MethodHandleNatives.<clinit>(MethodHandleNatives.java:133)
>    at sun.dyn.MemberName.<init>(MemberName.java:291)
>    at java.dyn.MethodHandles$Lookup.unreflect(MethodHandles.java:307)
>    at fr.umlv.indy.visitor.AbstractVisitor.<init>(AbstractVisitor.java:41)
>    at fr.umlv.indy.visitor.test.Main0$1.<init>(Main0.java:7)
>    at fr.umlv.indy.visitor.test.Main0.main(Main0.java:7)
>
> Here, the behavior is Ok, I need to enable method handles.
>
>  java -cp test-classes/ -XX:+EnableMethodHandles
> fr.umlv.indy.visitor.test.Main0
> Java HotSpot(TM) Server VM warning: JSR 292 invokedynamic is disabled in
> this JVM.  Use -XX:+EnableInvokeDynamic to enable.
> Exception in thread "main" java.lang.NoClassDefFoundError:
> fr/umlv/indy/visitor/AbstractVisitor
>    at
> fr.umlv.indy.visitor.AbstractVisitor.genericVisit(AbstractVisitor.java:73)
>    at fr.umlv.indy.visitor.test.Main0.main(Main0.java:19)
>
> I love this error message, NoClassDefFound AbstractVisitor in
> genericVisit of AbstractVisitor ??
> Ok, perhaps the message is just not the good one.
>
> Moreover, the VM asks for enabling invoke dynamic but the code (below)
> doesn't use it ?
> The line 73 of AbstractVisitor.genericVisit is an invokevistual on a
> MethodHandle.
>    handle(target.getClass()).<void>invoke(this, target);
>
> It's a regression, this code was working with tl/hotspot (changeset
> 738:53d9bf689e80).
>
> I have checked if it is not because the compiler use invokedynamic
> instead of invokevirtual
> but this is not the case :
> public void genericVisit(java.lang.Object);
>  Code:
>   0:    aload_0
>   1:    aload_1
>   2:    invokevirtual    #5; //Method
> java/lang/Object.getClass:()Ljava/lang/Class;
>   5:    invokevirtual    #40; //Method
> handle:(Ljava/lang/Class;)Ljava/dyn/MethodHandle;
>   8:    aload_0
>   9:    aload_1
>   10:    invokevirtual    #41; //Method
> java/dyn/MethodHandle.invoke:(Lfr/umlv/indy/visitor/AbstractVisitor;Ljava/lang/Object;)V
>   13:    return
>
> Trying to enable invoke dynamic :
> java -cp test-classes/ -XX:+EnableInvokeDynamic
> fr.umlv.indy.visitor.test.Main0
> Exception in thread "main" java.lang.NoClassDefFoundError:
> fr/umlv/indy/visitor/AbstractVisitor
>    at
> fr.umlv.indy.visitor.AbstractVisitor.genericVisit(AbstractVisitor.java:73)
>    at fr.umlv.indy.visitor.test.Main0.main(Main0.java:19)
>
> It doesn't work, same stupid error.
>
> It seems that something goes wrong between hotspot code in tl and its
> integration
> in jdk7 workspace.
>
> I hope this mail will help !
>
> Rémi
> PS: here are the two classes I have used, if you want to reproduce the bug.
>
> -----------------------------------------------------------------------------------------------------------------
> package fr.umlv.indy.visitor;
>
> import java.dyn.MethodHandle;
> import java.dyn.MethodHandles;
> import java.dyn.MethodType;
> import java.dyn.MethodHandles.Lookup;
> import java.lang.reflect.Method;
> import java.util.ArrayList;
> import java.util.List;
> import java.util.Map;
> import java.util.Map.Entry;
> import java.util.concurrent.ConcurrentHashMap;
>
> public abstract class AbstractVisitor {
>  private final ConcurrentHashMap<Class<?>, MethodHandle> map;
>
>  protected AbstractVisitor() {
>    ConcurrentHashMap<Class<?>, MethodHandle> map=
>      new ConcurrentHashMap<Class<?>, MethodHandle>();
>
>    // should use public lookup but NPE (bug, fixed in mlvm repository)
>    // Lookup lookup = MethodHandles.Lookup.PUBLIC_LOOKUP;
>    Lookup lookup = MethodHandles.lookup();
>
>    for(Method method : getClass().getMethods()) {
>      if ("visit".equals(method.getName())) {
>
>        Class<?>[] types = method.getParameterTypes();
>        if (types.length!=1)
>          throw new IllegalStateException("wrong number of parameter
> "+method);
>        Class<?> type=types[0];
>        if (type.isInterface() || type.isPrimitive() ||
> method.getReturnType()!=void.class)
>          throw new IllegalStateException("invalid method signature
> "+method);
>
>        //System.out.println("register "+method);
>
>        // should be not needed but generate currently a NPE
>        method.setAccessible(true);
>
>        //MethodHandle methodHandle =
> MethodHandles.Lookup.PUBLIC_LOOKUP.unreflect(method);
>        MethodHandle methodHandle = lookup.unreflect(method);
>
>        //System.out.println("methodHandle type "+methodHandle.type());
>        methodHandle = MethodHandles.convertArguments(methodHandle,
> MethodType.make(void.class, AbstractVisitor.class, Object.class));
>
>        //System.out.println("mh type "+methodHandle.type());
>
>        map.put(type, methodHandle);
>      }
>    }
>
>    this.map=map;
>  }
>
>  private MethodHandle findNewMethodHandle(Class<?> type) {
>    MethodHandle methodHandle=superHandle(type);
>    map.put(type, methodHandle);
>    return methodHandle;
>  }
>
>  private MethodHandle superHandle(Class<?> type) {
>    ConcurrentHashMap<Class<?>, MethodHandle> map = this.map;
>    for(Class<?>
> clazz=type.getSuperclass();clazz!=null;clazz=clazz.getSuperclass()) {
>      MethodHandle methodHandle = map.get(clazz);
>      if (methodHandle != null) {
>        return methodHandle;
>      }
>    }
>    throw new RuntimeException("no visit method applicable for "+type);
>  }
>
>  public void genericVisit(Object target) {
>    handle(target.getClass()).<void>invoke(this, target);
>  }
>
>  public MethodHandle handle(Class<?> type) {
>    MethodHandle methodHandle=map.get(type);
>    if (methodHandle!=null) {
>      return methodHandle;
>    }
>    return findNewMethodHandle(type);
>  }
>
>  public MethodHandle oneApplicable(Class<?> type) {
>    MethodHandle oneApplicable=null;
>    for(Entry<Class<?>, MethodHandle> entry:map.entrySet()) {
>      if (type.isAssignableFrom(entry.getKey())) {
>        if (oneApplicable==null)
>          oneApplicable=entry.getValue();
>        else
>          return null;
>      }
>    }
>    return oneApplicable;
>  }
> }
>
> -------------------------------------------------------------------------------------------------------------------
> package fr.umlv.indy.visitor.test;
>
> import fr.umlv.indy.visitor.AbstractVisitor;
>
> public class Main0 {
>  public static void main(String[] args) {
>    AbstractVisitor visitor=new AbstractVisitor() {
>      public void visit(String text) {
>        System.out.println("text "+text);
>      }
>      public void visit(Integer integer) {
>        System.out.println("integer "+integer);
>      }
>      public void visit(Object o) {
>        System.out.println("object "+o);
>      }
>    };
>
>    visitor.genericVisit("toto");
>    visitor.genericVisit(3);
>    visitor.genericVisit(4.0);
>  }
> }
>
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>



-- 
Chanwit Kaewkasi
PhD Candidate,
Centre for Novel Computing
School of Computer Science
The University of Manchester
Oxford Road
Manchester
M13 9PL, UK



More information about the mlvm-dev mailing list