1 /*
2 * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /**
25 * @test
26 * @requires vm.jvmci
27 * @library ../../../../../
28 * @modules java.base/jdk.internal.reflect
29 * jdk.internal.vm.ci/jdk.vm.ci.meta
30 * jdk.internal.vm.ci/jdk.vm.ci.runtime
31 * jdk.internal.vm.ci/jdk.vm.ci.common
32 * java.base/jdk.internal.misc
33 * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.runtime.test.TestResolvedJavaType
34 */
35
36 package jdk.vm.ci.runtime.test;
37
38 import static java.lang.reflect.Modifier.isAbstract;
39 import static java.lang.reflect.Modifier.isFinal;
40 import static java.lang.reflect.Modifier.isPrivate;
41 import static java.lang.reflect.Modifier.isProtected;
42 import static java.lang.reflect.Modifier.isPublic;
43 import static java.lang.reflect.Modifier.isStatic;
44 import static org.junit.Assert.assertArrayEquals;
45 import static org.junit.Assert.assertEquals;
46 import static org.junit.Assert.assertFalse;
47 import static org.junit.Assert.assertNotNull;
48 import static org.junit.Assert.assertNull;
49 import static org.junit.Assert.assertTrue;
50
51 import java.lang.annotation.Annotation;
52 import java.lang.invoke.MethodHandles.Lookup;
53 import java.lang.reflect.AccessibleObject;
54 import java.lang.reflect.Constructor;
55 import java.lang.reflect.Field;
56 import java.lang.reflect.Method;
57 import java.lang.reflect.Modifier;
58 import java.util.Arrays;
59 import java.util.Collections;
60 import java.util.function.Supplier;
61 import java.util.HashMap;
62 import java.util.HashSet;
63 import java.util.Map;
64 import java.util.Set;
65
66 import org.junit.Test;
67
68 import jdk.internal.reflect.ConstantPool;
69 import jdk.vm.ci.common.JVMCIError;
70 import jdk.vm.ci.meta.Assumptions.AssumptionResult;
71 import jdk.vm.ci.meta.JavaConstant;
72 import jdk.vm.ci.meta.JavaKind;
73 import jdk.vm.ci.meta.ResolvedJavaField;
74 import jdk.vm.ci.meta.ResolvedJavaMethod;
75 import jdk.vm.ci.meta.ResolvedJavaType;
76
77 /**
78 * Tests for {@link ResolvedJavaType}.
79 */
80 @SuppressWarnings("unchecked")
81 public class TestResolvedJavaType extends TypeUniverse {
82 private static final Class<? extends Annotation> SIGNATURE_POLYMORPHIC_CLASS = findPolymorphicSignatureClass();
83
84 public TestResolvedJavaType() {
85 }
86
87 private static Class<? extends Annotation> findPolymorphicSignatureClass() {
139 @Test
140 public void isInstanceClassTest() {
141 for (Class<?> c : classes) {
142 ResolvedJavaType type = metaAccess.lookupJavaType(c);
143 boolean expected = !c.isArray() && !c.isPrimitive() && !c.isInterface();
144 boolean actual = type.isInstanceClass();
145 assertEquals(expected, actual);
146 }
147 }
148
149 @Test
150 public void isArrayTest() {
151 for (Class<?> c : classes) {
152 ResolvedJavaType type = metaAccess.lookupJavaType(c);
153 boolean expected = c.isArray();
154 boolean actual = type.isArray();
155 assertEquals(expected, actual);
156 }
157 }
158
159 @Test
160 public void getHostClassTest() {
161 for (Class<?> c : classes) {
162 ResolvedJavaType type = metaAccess.lookupJavaType(c);
163 ResolvedJavaType host = type.getHostClass();
164 if (!type.equals(predicateType)) {
165 assertNull(host);
166 } else {
167 assertNotNull(host);
168 }
169 }
170
171 class LocalClass {}
172 Cloneable clone = new Cloneable() {};
173 assertNull(metaAccess.lookupJavaType(LocalClass.class).getHostClass());
174 assertNull(metaAccess.lookupJavaType(clone.getClass()).getHostClass());
175
176 Supplier<Runnable> lambda = () -> () -> System.out.println("run");
177 ResolvedJavaType lambdaType = metaAccess.lookupJavaType(lambda.getClass());
178 ResolvedJavaType nestedLambdaType = metaAccess.lookupJavaType(lambda.get().getClass());
179 assertNotNull(lambdaType.getHostClass());
180 assertNotNull(nestedLambdaType.getHostClass());
181 assertEquals(lambdaType.getHostClass(), nestedLambdaType.getHostClass());
182 }
183
184 @Test
185 public void getModifiersTest() {
186 for (Class<?> c : classes) {
187 ResolvedJavaType type = metaAccess.lookupJavaType(c);
188 int mask = Modifier.classModifiers() & ~Modifier.STATIC;
189 int expected = c.getModifiers() & mask;
190 int actual = type.getModifiers() & mask;
191 Class<?> elementalType = c;
192 while (elementalType.isArray()) {
193 elementalType = elementalType.getComponentType();
194 }
195 if (elementalType.isMemberClass()) {
196 // member class get their modifiers from the inner-class attribute in the JVM and
197 // from the classfile header in jvmci
198 expected &= ~(Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED);
199 actual &= ~(Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED);
200 }
201 assertEquals(String.format("%s: 0x%x != 0x%x", type, expected, actual), expected, actual);
749 }
750 return null;
751 }
752
753 public Field lookupField(Set<Field> fields, ResolvedJavaField key) {
754 for (Field f : fields) {
755 if (fieldsEqual(f, key)) {
756 return f;
757 }
758 }
759 return null;
760 }
761
762 private static boolean isHiddenFromReflection(ResolvedJavaField f) {
763 if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Throwable.class)) && f.getName().equals("backtrace")) {
764 return true;
765 }
766 if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(ConstantPool.class)) && f.getName().equals("constantPoolOop")) {
767 return true;
768 }
769 if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Class.class)) && f.getName().equals("classLoader")) {
770 return true;
771 }
772 if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Lookup.class))) {
773 return f.getName().equals("allowedModes") || f.getName().equals("lookupClass");
774 }
775 if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(ClassLoader.class)) ||
776 f.getDeclaringClass().equals(metaAccess.lookupJavaType(AccessibleObject.class)) ||
777 f.getDeclaringClass().equals(metaAccess.lookupJavaType(Constructor.class)) ||
778 f.getDeclaringClass().equals(metaAccess.lookupJavaType(Field.class)) ||
779 f.getDeclaringClass().equals(metaAccess.lookupJavaType(Method.class)) ||
780 f.getDeclaringClass().equals(metaAccess.lookupJavaType(Module.class))) {
781 return true;
782 }
783 return false;
784 }
785
786 @Test
787 public void getInstanceFieldsTest() {
788 for (Class<?> c : classes) {
789 ResolvedJavaType type = metaAccess.lookupJavaType(c);
790 for (boolean includeSuperclasses : new boolean[]{true, false}) {
|
1 /*
2 * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /**
25 * @test
26 * @requires vm.jvmci
27 * @library ../../../../../
28 * @modules java.base/jdk.internal.org.objectweb.asm
29 * java.base/jdk.internal.reflect
30 * jdk.internal.vm.ci/jdk.vm.ci.meta
31 * jdk.internal.vm.ci/jdk.vm.ci.runtime
32 * jdk.internal.vm.ci/jdk.vm.ci.common
33 * java.base/jdk.internal.misc
34 * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.runtime.test.TestResolvedJavaType
35 */
36
37 package jdk.vm.ci.runtime.test;
38
39 import static java.lang.reflect.Modifier.isAbstract;
40 import static java.lang.reflect.Modifier.isFinal;
41 import static java.lang.reflect.Modifier.isPrivate;
42 import static java.lang.reflect.Modifier.isProtected;
43 import static java.lang.reflect.Modifier.isPublic;
44 import static java.lang.reflect.Modifier.isStatic;
45 import static org.junit.Assert.assertArrayEquals;
46 import static org.junit.Assert.assertEquals;
47 import static org.junit.Assert.assertFalse;
48 import static org.junit.Assert.assertNotNull;
49 import static org.junit.Assert.assertNull;
50 import static org.junit.Assert.assertTrue;
51
52 import java.lang.annotation.Annotation;
53 import java.lang.invoke.MethodHandles.Lookup;
54 import java.lang.reflect.AccessibleObject;
55 import java.lang.reflect.Constructor;
56 import java.lang.reflect.Field;
57 import java.lang.reflect.Method;
58 import java.lang.reflect.Modifier;
59 import java.util.Arrays;
60 import java.util.Collections;
61 import java.util.function.Supplier;
62 import java.util.HashMap;
63 import java.util.HashSet;
64 import java.util.Map;
65 import java.util.Set;
66
67 import org.junit.Test;
68
69 import jdk.internal.org.objectweb.asm.*;
70 import jdk.internal.reflect.ConstantPool;
71 import jdk.vm.ci.common.JVMCIError;
72 import jdk.vm.ci.meta.Assumptions.AssumptionResult;
73 import jdk.vm.ci.meta.JavaConstant;
74 import jdk.vm.ci.meta.JavaKind;
75 import jdk.vm.ci.meta.ResolvedJavaField;
76 import jdk.vm.ci.meta.ResolvedJavaMethod;
77 import jdk.vm.ci.meta.ResolvedJavaType;
78
79 /**
80 * Tests for {@link ResolvedJavaType}.
81 */
82 @SuppressWarnings("unchecked")
83 public class TestResolvedJavaType extends TypeUniverse {
84 private static final Class<? extends Annotation> SIGNATURE_POLYMORPHIC_CLASS = findPolymorphicSignatureClass();
85
86 public TestResolvedJavaType() {
87 }
88
89 private static Class<? extends Annotation> findPolymorphicSignatureClass() {
141 @Test
142 public void isInstanceClassTest() {
143 for (Class<?> c : classes) {
144 ResolvedJavaType type = metaAccess.lookupJavaType(c);
145 boolean expected = !c.isArray() && !c.isPrimitive() && !c.isInterface();
146 boolean actual = type.isInstanceClass();
147 assertEquals(expected, actual);
148 }
149 }
150
151 @Test
152 public void isArrayTest() {
153 for (Class<?> c : classes) {
154 ResolvedJavaType type = metaAccess.lookupJavaType(c);
155 boolean expected = c.isArray();
156 boolean actual = type.isArray();
157 assertEquals(expected, actual);
158 }
159 }
160
161 private static Class<?> anonClass() throws Exception {
162 ClassWriter cw = new ClassWriter(0);
163 cw.visit(Opcodes.V1_8, Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, "Anon", null, "java/lang/Object", null);
164 FieldVisitor intField = cw.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "intField", "I", null, 0);
165 intField.visitEnd();
166 cw.visitEnd();
167 return unsafe.defineAnonymousClass(TypeUniverse.class, cw.toByteArray(), null);
168 }
169
170 @Test
171 public void getHostClassTest() throws Exception {
172 ResolvedJavaType type = metaAccess.lookupJavaType(anonClass());
173 ResolvedJavaType host = type.getHostClass();
174 assertNotNull(host);
175 for (Class<?> c : classes) {
176 type = metaAccess.lookupJavaType(c);
177 host = type.getHostClass();
178 assertNull(host);
179 if (type.equals(predicateType)) {
180 assertTrue(c.isHiddenClass());
181 }
182 }
183
184 class LocalClass {}
185 Cloneable clone = new Cloneable() {};
186 assertNull(metaAccess.lookupJavaType(LocalClass.class).getHostClass());
187 assertNull(metaAccess.lookupJavaType(clone.getClass()).getHostClass());
188
189 Supplier<Runnable> lambda = () -> () -> System.out.println("run");
190 ResolvedJavaType lambdaType = metaAccess.lookupJavaType(lambda.getClass());
191 ResolvedJavaType nestedLambdaType = metaAccess.lookupJavaType(lambda.get().getClass());
192 assertNull(lambdaType.getHostClass());
193 assertTrue(lambda.getClass().isHiddenClass());
194 assertNull(nestedLambdaType.getHostClass());
195 assertTrue(lambda.get().getClass().isHiddenClass());
196 }
197
198 @Test
199 public void getModifiersTest() {
200 for (Class<?> c : classes) {
201 ResolvedJavaType type = metaAccess.lookupJavaType(c);
202 int mask = Modifier.classModifiers() & ~Modifier.STATIC;
203 int expected = c.getModifiers() & mask;
204 int actual = type.getModifiers() & mask;
205 Class<?> elementalType = c;
206 while (elementalType.isArray()) {
207 elementalType = elementalType.getComponentType();
208 }
209 if (elementalType.isMemberClass()) {
210 // member class get their modifiers from the inner-class attribute in the JVM and
211 // from the classfile header in jvmci
212 expected &= ~(Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED);
213 actual &= ~(Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED);
214 }
215 assertEquals(String.format("%s: 0x%x != 0x%x", type, expected, actual), expected, actual);
763 }
764 return null;
765 }
766
767 public Field lookupField(Set<Field> fields, ResolvedJavaField key) {
768 for (Field f : fields) {
769 if (fieldsEqual(f, key)) {
770 return f;
771 }
772 }
773 return null;
774 }
775
776 private static boolean isHiddenFromReflection(ResolvedJavaField f) {
777 if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Throwable.class)) && f.getName().equals("backtrace")) {
778 return true;
779 }
780 if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(ConstantPool.class)) && f.getName().equals("constantPoolOop")) {
781 return true;
782 }
783 if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Class.class))) {
784 return f.getName().equals("classLoader") || f.getName().equals("classData");
785 }
786 if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Lookup.class))) {
787 return f.getName().equals("allowedModes") || f.getName().equals("lookupClass");
788 }
789 if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(ClassLoader.class)) ||
790 f.getDeclaringClass().equals(metaAccess.lookupJavaType(AccessibleObject.class)) ||
791 f.getDeclaringClass().equals(metaAccess.lookupJavaType(Constructor.class)) ||
792 f.getDeclaringClass().equals(metaAccess.lookupJavaType(Field.class)) ||
793 f.getDeclaringClass().equals(metaAccess.lookupJavaType(Method.class)) ||
794 f.getDeclaringClass().equals(metaAccess.lookupJavaType(Module.class))) {
795 return true;
796 }
797 return false;
798 }
799
800 @Test
801 public void getInstanceFieldsTest() {
802 for (Class<?> c : classes) {
803 ResolvedJavaType type = metaAccess.lookupJavaType(c);
804 for (boolean includeSuperclasses : new boolean[]{true, false}) {
|