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