# HG changeset patch # User Gilles Duboscq # Date 1434642665 -7200 # Node ID 4c9d4fe1cbd8d369dc9b89c523552d2979bcfa83 # Parent 78f2cb84bb41e70d9afab080d2890ee991539d3a Add ModifiersProvider.isSynthetic, isVarArgs and isBridge. getModifiers now returns the JVM modifiers (not masked by Modifier.methodModifiers() for example) diff -r 78f2cb84bb41 -r 4c9d4fe1cbd8 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java Wed Jun 17 15:34:39 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java Thu Jun 18 17:51:05 2015 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.hotspot.test; -import static com.oracle.jvmci.hotspot.HotSpotResolvedObjectTypeImpl.*; - import java.lang.reflect.*; import org.junit.*; @@ -49,7 +47,7 @@ HotSpotResolvedObjectType type = HotSpotResolvedObjectTypeImpl.fromObjectClass(c); for (ResolvedJavaField field : type.getInstanceFields(false)) { if (field.isInternal()) { - Assert.assertEquals(0, ~getReflectionFieldModifiers() & field.getModifiers()); + Assert.assertEquals(0, ~ModifiersProvider.jvmFieldModifiers() & field.getModifiers()); } } } diff -r 78f2cb84bb41 -r 4c9d4fe1cbd8 jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotResolvedJavaFieldImpl.java --- a/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotResolvedJavaFieldImpl.java Wed Jun 17 15:34:39 2015 +0200 +++ b/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotResolvedJavaFieldImpl.java Thu Jun 18 17:51:05 2015 +0200 @@ -24,7 +24,6 @@ import static com.oracle.jvmci.hotspot.HotSpotJVMCIRuntime.*; import static com.oracle.jvmci.hotspot.HotSpotResolvedJavaFieldImpl.Options.*; -import static com.oracle.jvmci.hotspot.HotSpotResolvedObjectTypeImpl.*; import java.lang.annotation.*; import java.lang.reflect.*; @@ -126,7 +125,7 @@ @Override public int getModifiers() { - return modifiers & getReflectionFieldModifiers(); + return modifiers & ModifiersProvider.jvmFieldModifiers(); } @Override diff -r 78f2cb84bb41 -r 4c9d4fe1cbd8 jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java --- a/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java Wed Jun 17 15:34:39 2015 +0200 +++ b/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java Thu Jun 18 17:51:05 2015 +0200 @@ -183,7 +183,7 @@ @Override public int getModifiers() { - return getAllModifiers() & Modifier.methodModifiers(); + return getAllModifiers() & ModifiersProvider.jvmMethodModifiers(); } @Override @@ -474,12 +474,6 @@ return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass); } - @Override - public boolean isSynthetic() { - int modifiers = getAllModifiers(); - return (runtime().getConfig().syntheticFlag & modifiers) != 0; - } - public boolean isDefault() { if (isConstructor()) { return false; diff -r 78f2cb84bb41 -r 4c9d4fe1cbd8 jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotResolvedObjectTypeImpl.java --- a/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotResolvedObjectTypeImpl.java Wed Jun 17 15:34:39 2015 +0200 +++ b/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotResolvedObjectTypeImpl.java Thu Jun 18 17:51:05 2015 +0200 @@ -118,7 +118,11 @@ @Override public int getModifiers() { - return mirror().getModifiers(); + if (isArray()) { + return (getElementalType().getModifiers() & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)) | Modifier.FINAL | Modifier.ABSTRACT; + } else { + return getAccessFlags() & ModifiersProvider.jvmClassModifiers(); + } } public int getAccessFlags() { @@ -473,19 +477,10 @@ return result; } - /** - * Gets the mask used to filter out HotSpot internal flags for fields when a {@link Field} - * object is created. This is the value of {@code JVM_RECOGNIZED_FIELD_MODIFIERS} in - * {@code jvm.h}, not {@link Modifier#fieldModifiers()}. - */ - public static int getReflectionFieldModifiers() { - return runtime().getConfig().recognizedFieldModifiers; - } - public synchronized HotSpotResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags) { HotSpotResolvedJavaField result = null; - final int flags = rawFlags & getReflectionFieldModifiers(); + final int flags = rawFlags & ModifiersProvider.jvmFieldModifiers(); final long id = offset + ((long) flags << 32); diff -r 78f2cb84bb41 -r 4c9d4fe1cbd8 jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/MetaUtil.java --- a/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/MetaUtil.java Wed Jun 17 15:34:39 2015 +0200 +++ b/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/MetaUtil.java Thu Jun 18 17:51:05 2015 +0200 @@ -23,6 +23,7 @@ package com.oracle.jvmci.meta; import java.io.*; +import java.lang.reflect.*; import java.util.*; /** @@ -354,4 +355,17 @@ } return obj.getClass().getName() + "@" + System.identityHashCode(obj); } + + /** + * Used to lookup constants from {@link Modifier} that are not public (VARARGS, SYNTHETIC etc.). + */ + static int getNonPublicModifierStaticField(String name) { + try { + Field field = Modifier.class.getDeclaredField(name); + field.setAccessible(true); + return field.getInt(null); + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { + throw new InternalError(e); + } + } } diff -r 78f2cb84bb41 -r 4c9d4fe1cbd8 jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ModifiersProvider.java --- a/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ModifiersProvider.java Wed Jun 17 15:34:39 2015 +0200 +++ b/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ModifiersProvider.java Thu Jun 18 17:51:05 2015 +0200 @@ -31,9 +31,17 @@ * language {@linkplain #getModifiers() modifiers}. */ public interface ModifiersProvider { + int BRIDGE = MetaUtil.getNonPublicModifierStaticField("BRIDGE"); + int VARARGS = MetaUtil.getNonPublicModifierStaticField("VARARGS"); + int SYNTHETIC = MetaUtil.getNonPublicModifierStaticField("SYNTHETIC"); + int ANNOTATION = MetaUtil.getNonPublicModifierStaticField("ANNOTATION"); + int ENUM = MetaUtil.getNonPublicModifierStaticField("ENUM"); + int MANDATED = MetaUtil.getNonPublicModifierStaticField("MANDATED"); /** - * Returns the Java language modifiers for this element. + * Returns the Java Virtual Machine modifiers for this element. Note that this can differ from + * standard Java Reflection modifiers. For example at the JVM level, classes ( + * {@link ResolvedJavaType}) can not be private or protected. */ int getModifiers(); @@ -137,4 +145,17 @@ default boolean isConcrete() { return !isAbstract(); } + + static int jvmClassModifiers() { + // no SUPER + return PUBLIC | FINAL | INTERFACE | ABSTRACT | ANNOTATION | ENUM | SYNTHETIC; + } + + static int jvmMethodModifiers() { + return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | SYNCHRONIZED | BRIDGE | VARARGS | NATIVE | ABSTRACT | STRICT | SYNTHETIC; + } + + static int jvmFieldModifiers() { + return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | VOLATILE | TRANSIENT | ENUM | SYNTHETIC; + } } diff -r 78f2cb84bb41 -r 4c9d4fe1cbd8 jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaMethod.java --- a/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaMethod.java Wed Jun 17 15:34:39 2015 +0200 +++ b/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaMethod.java Thu Jun 18 17:51:05 2015 +0200 @@ -23,6 +23,7 @@ package com.oracle.jvmci.meta; import java.lang.annotation.*; +import java.lang.invoke.*; import java.lang.reflect.*; /** @@ -80,7 +81,31 @@ * Determines if this method is a synthetic method as defined by the Java Language * Specification. */ - boolean isSynthetic(); + default boolean isSynthetic() { + return (SYNTHETIC & getModifiers()) == SYNTHETIC; + } + + /** + * Checks that the method is a varargs + * method. + * + * @return whether the method is a varargs method + */ + default boolean isVarArgs() { + return (VARARGS & getModifiers()) == VARARGS; + } + + /** + * Checks that the method is a bridge + * method. + * + * @return whether the method is a bridge method + */ + default boolean isBridge() { + return (BRIDGE & getModifiers()) == BRIDGE; + } /** * Returns {@code true} if this method is a default method; returns {@code false} otherwise. diff -r 78f2cb84bb41 -r 4c9d4fe1cbd8 jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestMetaAccessProvider.java --- a/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestMetaAccessProvider.java Wed Jun 17 15:34:39 2015 +0200 +++ b/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestMetaAccessProvider.java Thu Jun 18 17:51:05 2015 +0200 @@ -40,13 +40,12 @@ public void lookupJavaTypeTest() { for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); - assertNotNull(type); - assertEquals(c.getModifiers(), type.getModifiers()); - assertEquals(type.getName(), toInternalName(c.getName())); - assertEquals(type.getName(), toInternalName(type.toJavaName())); - assertEquals(c.getName(), type.toClassName()); + assertNotNull(c.toString(), type); + assertEquals(c.toString(), type.getName(), toInternalName(c.getName())); + assertEquals(c.toString(), type.getName(), toInternalName(type.toJavaName())); + assertEquals(c.toString(), c.getName(), type.toClassName()); if (!type.isArray()) { - assertEquals(c.getName(), type.toJavaName()); + assertEquals(c.toString(), c.getName(), type.toJavaName()); } } } @@ -57,9 +56,6 @@ for (Method reflect : c.getDeclaredMethods()) { ResolvedJavaMethod method = metaAccess.lookupJavaMethod(reflect); assertNotNull(method); - int expected = reflect.getModifiers() & Modifier.methodModifiers(); - int actual = method.getModifiers(); - assertEquals(String.format("%s: 0x%x != 0x%x", reflect, expected, actual), expected, actual); assertTrue(method.getDeclaringClass().equals(metaAccess.lookupJavaType(reflect.getDeclaringClass()))); } } @@ -71,9 +67,6 @@ for (Field reflect : c.getDeclaredFields()) { ResolvedJavaField field = metaAccess.lookupJavaField(reflect); assertNotNull(field); - int expected = reflect.getModifiers(); - int actual = field.getModifiers(); - assertEquals(String.format("%s: 0x%x != 0x%x", reflect, expected, actual), expected, actual); assertTrue(field.getDeclaringClass().equals(metaAccess.lookupJavaType(reflect.getDeclaringClass()))); } } diff -r 78f2cb84bb41 -r 4c9d4fe1cbd8 jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaMethod.java --- a/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaMethod.java Wed Jun 17 15:34:39 2015 +0200 +++ b/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaMethod.java Thu Jun 18 17:51:05 2015 +0200 @@ -22,9 +22,6 @@ */ package com.oracle.jvmci.runtime.test; -import com.oracle.jvmci.meta.ExceptionHandler; -import com.oracle.jvmci.meta.ResolvedJavaMethod; -import com.oracle.jvmci.meta.ConstantPool; import static org.junit.Assert.*; import java.lang.annotation.*; @@ -33,6 +30,8 @@ import org.junit.*; +import com.oracle.jvmci.meta.*; + /** * Tests for {@link ResolvedJavaMethod}. */ @@ -81,9 +80,15 @@ public void getModifiersTest() { for (Map.Entry e : methods.entrySet()) { ResolvedJavaMethod m = e.getValue(); - int expected = e.getKey().getModifiers() & Modifier.methodModifiers(); + int expected = e.getKey().getModifiers(); int actual = m.getModifiers(); - assertEquals(expected, actual); + assertEquals(String.format("%s: 0x%x != 0x%x", m, expected, actual), expected, actual); + } + for (Map.Entry, ResolvedJavaMethod> e : constructors.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + int expected = e.getKey().getModifiers(); + int actual = m.getModifiers(); + assertEquals(String.format("%s: 0x%x != 0x%x", m, expected, actual), expected, actual); } } @@ -128,6 +133,30 @@ } @Test + public void isBridgeTest() { + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertEquals(e.getKey().isBridge(), m.isBridge()); + } + for (Map.Entry, ResolvedJavaMethod> e : constructors.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertEquals(false, m.isBridge()); + } + } + + @Test + public void isVarArgsTest() { + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertEquals(e.getKey().isVarArgs(), m.isVarArgs()); + } + for (Map.Entry, ResolvedJavaMethod> e : constructors.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertEquals(e.getKey().isVarArgs(), m.isVarArgs()); + } + } + + @Test public void isSynchronizedTest() { for (Map.Entry e : methods.entrySet()) { ResolvedJavaMethod m = e.getValue(); diff -r 78f2cb84bb41 -r 4c9d4fe1cbd8 jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaType.java --- a/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaType.java Wed Jun 17 15:34:39 2015 +0200 +++ b/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaType.java Thu Jun 18 17:51:05 2015 +0200 @@ -96,9 +96,19 @@ public void getModifiersTest() { for (Class c : classes) { ResolvedJavaType type = metaAccess.lookupJavaType(c); - int expected = c.getModifiers(); - int actual = type.getModifiers(); - assertEquals(expected, actual); + int expected = c.getModifiers() & ModifiersProvider.jvmClassModifiers(); + int actual = type.getModifiers() & ModifiersProvider.jvmClassModifiers(); + Class elementalType = c; + while (elementalType.isArray()) { + elementalType = elementalType.getComponentType(); + } + if (elementalType.isMemberClass()) { + // member class get their modifiers from the inner-class attribute in the JVM and + // from the classfile header in jvmci + expected &= ~(Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED); + actual &= ~(Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED); + } + assertEquals(String.format("%s: 0x%x != 0x%x", type, expected, actual), expected, actual); } } diff -r 78f2cb84bb41 -r 4c9d4fe1cbd8 jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TypeUniverse.java --- a/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TypeUniverse.java Wed Jun 17 15:34:39 2015 +0200 +++ b/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TypeUniverse.java Thu Jun 18 17:51:05 2015 +0200 @@ -55,6 +55,26 @@ private static List constants; + public class InnerClass { + + } + + public static class InnerStaticClass { + + } + + public static final class InnerStaticFinalClass { + + } + + private class PrivateInnerClass { + + } + + protected class ProtectedInnerClass { + + } + static { Unsafe theUnsafe = null; try { @@ -71,10 +91,11 @@ unsafe = theUnsafe; Class[] initialClasses = {void.class, boolean.class, byte.class, short.class, char.class, int.class, float.class, long.class, double.class, Object.class, Class.class, boolean[].class, - byte[].class, short[].class, char[].class, int[].class, float[].class, long[].class, double[].class, Object[].class, Class[].class, boolean[][].class, byte[][].class, - short[][].class, char[][].class, int[][].class, float[][].class, long[][].class, double[][].class, Object[][].class, Class[][].class, ClassLoader.class, String.class, - Serializable.class, Cloneable.class, Test.class, TestMetaAccessProvider.class, List.class, Collection.class, Map.class, Queue.class, HashMap.class, LinkedHashMap.class, - IdentityHashMap.class, AbstractCollection.class, AbstractList.class, ArrayList.class, TrustedInterface.class}; + byte[].class, short[].class, char[].class, int[].class, float[].class, long[].class, double[].class, Object[].class, Class[].class, List[].class, boolean[][].class, + byte[][].class, short[][].class, char[][].class, int[][].class, float[][].class, long[][].class, double[][].class, Object[][].class, Class[][].class, List[][].class, + ClassLoader.class, String.class, Serializable.class, Cloneable.class, Test.class, TestMetaAccessProvider.class, List.class, Collection.class, Map.class, Queue.class, + HashMap.class, LinkedHashMap.class, IdentityHashMap.class, AbstractCollection.class, AbstractList.class, ArrayList.class, TrustedInterface.class, InnerClass.class, + InnerStaticClass.class, InnerStaticFinalClass.class, PrivateInnerClass.class, ProtectedInnerClass.class}; for (Class c : initialClasses) { addClass(c); }