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 package jdk.vm.ci.hotspot;
24
25 import static java.util.Objects.requireNonNull;
26 import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
27 import static jdk.vm.ci.hotspot.HotSpotConstantPool.isSignaturePolymorphicHolder;
28 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
29 import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
30 import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
31
32 import java.lang.annotation.Annotation;
33 import java.lang.reflect.Array;
34 import java.lang.reflect.Constructor;
35 import java.lang.reflect.Method;
36 import java.lang.reflect.Modifier;
37 import java.nio.ByteOrder;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.HashMap;
41
42 import jdk.vm.ci.common.JVMCIError;
43 import jdk.vm.ci.meta.Assumptions.AssumptionResult;
44 import jdk.vm.ci.meta.Assumptions.ConcreteMethod;
45 import jdk.vm.ci.meta.Assumptions.ConcreteSubtype;
46 import jdk.vm.ci.meta.Assumptions.LeafType;
47 import jdk.vm.ci.meta.Assumptions.NoFinalizableSubclass;
48 import jdk.vm.ci.meta.Constant;
49 import jdk.vm.ci.meta.JavaConstant;
50 import jdk.vm.ci.meta.JavaKind;
51 import jdk.vm.ci.meta.JavaType;
52 import jdk.vm.ci.meta.ModifiersProvider;
53 import jdk.vm.ci.meta.ResolvedJavaField;
54 import jdk.vm.ci.meta.ResolvedJavaMethod;
55 import jdk.vm.ci.meta.ResolvedJavaType;
56
57 /**
58 * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
59 */
60 final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, MetaspaceWrapperObject {
61
62 /**
63 * The Java class this type represents.
64 */
65 private final Class<?> javaClass;
66 private HashMap<Long, HotSpotResolvedJavaField> fieldCache;
67 private HashMap<Long, HotSpotResolvedJavaMethodImpl> methodCache;
68 private HotSpotResolvedJavaField[] instanceFields;
69 private HotSpotResolvedObjectTypeImpl[] interfaces;
70 private HotSpotConstantPool constantPool;
71 final HotSpotJVMCIMetaAccessContext context;
72 private HotSpotResolvedObjectType arrayOfType;
135
136 @Override
137 public long getMetaspacePointer() {
138 return getMetaspaceKlass();
139 }
140
141 /**
142 * The Klass* for this object is kept alive by the direct reference to {@link #javaClass} so no
143 * extra work is required.
144 */
145 @Override
146 public boolean isRegistered() {
147 return true;
148 }
149
150 @Override
151 public int getModifiers() {
152 if (isArray()) {
153 return (getElementalType().getModifiers() & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)) | Modifier.FINAL | Modifier.ABSTRACT;
154 } else {
155 return getAccessFlags() & ModifiersProvider.jvmClassModifiers();
156 }
157 }
158
159 public int getAccessFlags() {
160 HotSpotVMConfig config = config();
161 return UNSAFE.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset);
162 }
163
164 @Override
165 public HotSpotResolvedObjectType getArrayClass() {
166 if (arrayOfType == null) {
167 arrayOfType = fromObjectClass(Array.newInstance(mirror(), 0).getClass());
168 }
169 return arrayOfType;
170 }
171
172 @Override
173 public ResolvedJavaType getComponentType() {
174 Class<?> javaComponentType = mirror().getComponentType();
175 return javaComponentType == null ? null : runtime().fromClass(javaComponentType);
490 methodCache.put(metaspaceMethod, method);
491 context.add(method);
492 }
493 return method;
494 }
495
496 public int getVtableLength() {
497 HotSpotVMConfig config = config();
498 if (isInterface() || isArray()) {
499 /* Everything has the core vtable of java.lang.Object */
500 return config.baseVtableLength();
501 }
502 int result = UNSAFE.getInt(getMetaspaceKlass() + config.klassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize);
503 assert result >= config.baseVtableLength() : UNSAFE.getInt(getMetaspaceKlass() + config.klassVtableLengthOffset) + " " + config.vtableEntrySize;
504 return result;
505 }
506
507 synchronized HotSpotResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags) {
508 HotSpotResolvedJavaField result = null;
509
510 final int flags = rawFlags & ModifiersProvider.jvmFieldModifiers();
511
512 final long id = offset + ((long) flags << 32);
513
514 // Must cache the fields, because the local load elimination only works if the
515 // objects from two field lookups are identical.
516 if (fieldCache == null) {
517 fieldCache = new HashMap<>(8);
518 } else {
519 result = fieldCache.get(id);
520 }
521
522 if (result == null) {
523 result = new HotSpotResolvedJavaFieldImpl(this, fieldName, type, offset, rawFlags);
524 fieldCache.put(id, result);
525 } else {
526 assert result.getName().equals(fieldName);
527 /*
528 * Comparing the types directly is too strict, because the type in the cache could be
529 * resolved while the incoming type is unresolved. The name comparison is sufficient
530 * because the type will always be resolved in the context of the holder.
|
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 package jdk.vm.ci.hotspot;
24
25 import static java.util.Objects.requireNonNull;
26 import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
27 import static jdk.vm.ci.hotspot.HotSpotConstantPool.isSignaturePolymorphicHolder;
28 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
29 import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmClassModifiers;
30 import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
31 import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
32
33 import java.lang.annotation.Annotation;
34 import java.lang.reflect.Array;
35 import java.lang.reflect.Constructor;
36 import java.lang.reflect.Method;
37 import java.lang.reflect.Modifier;
38 import java.nio.ByteOrder;
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.HashMap;
42
43 import jdk.vm.ci.common.JVMCIError;
44 import jdk.vm.ci.meta.Assumptions.AssumptionResult;
45 import jdk.vm.ci.meta.Assumptions.ConcreteMethod;
46 import jdk.vm.ci.meta.Assumptions.ConcreteSubtype;
47 import jdk.vm.ci.meta.Assumptions.LeafType;
48 import jdk.vm.ci.meta.Assumptions.NoFinalizableSubclass;
49 import jdk.vm.ci.meta.Constant;
50 import jdk.vm.ci.meta.JavaConstant;
51 import jdk.vm.ci.meta.JavaKind;
52 import jdk.vm.ci.meta.JavaType;
53 import jdk.vm.ci.meta.ResolvedJavaField;
54 import jdk.vm.ci.meta.ResolvedJavaMethod;
55 import jdk.vm.ci.meta.ResolvedJavaType;
56
57 /**
58 * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
59 */
60 final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, MetaspaceWrapperObject {
61
62 /**
63 * The Java class this type represents.
64 */
65 private final Class<?> javaClass;
66 private HashMap<Long, HotSpotResolvedJavaField> fieldCache;
67 private HashMap<Long, HotSpotResolvedJavaMethodImpl> methodCache;
68 private HotSpotResolvedJavaField[] instanceFields;
69 private HotSpotResolvedObjectTypeImpl[] interfaces;
70 private HotSpotConstantPool constantPool;
71 final HotSpotJVMCIMetaAccessContext context;
72 private HotSpotResolvedObjectType arrayOfType;
135
136 @Override
137 public long getMetaspacePointer() {
138 return getMetaspaceKlass();
139 }
140
141 /**
142 * The Klass* for this object is kept alive by the direct reference to {@link #javaClass} so no
143 * extra work is required.
144 */
145 @Override
146 public boolean isRegistered() {
147 return true;
148 }
149
150 @Override
151 public int getModifiers() {
152 if (isArray()) {
153 return (getElementalType().getModifiers() & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)) | Modifier.FINAL | Modifier.ABSTRACT;
154 } else {
155 return getAccessFlags() & jvmClassModifiers();
156 }
157 }
158
159 public int getAccessFlags() {
160 HotSpotVMConfig config = config();
161 return UNSAFE.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset);
162 }
163
164 @Override
165 public HotSpotResolvedObjectType getArrayClass() {
166 if (arrayOfType == null) {
167 arrayOfType = fromObjectClass(Array.newInstance(mirror(), 0).getClass());
168 }
169 return arrayOfType;
170 }
171
172 @Override
173 public ResolvedJavaType getComponentType() {
174 Class<?> javaComponentType = mirror().getComponentType();
175 return javaComponentType == null ? null : runtime().fromClass(javaComponentType);
490 methodCache.put(metaspaceMethod, method);
491 context.add(method);
492 }
493 return method;
494 }
495
496 public int getVtableLength() {
497 HotSpotVMConfig config = config();
498 if (isInterface() || isArray()) {
499 /* Everything has the core vtable of java.lang.Object */
500 return config.baseVtableLength();
501 }
502 int result = UNSAFE.getInt(getMetaspaceKlass() + config.klassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize);
503 assert result >= config.baseVtableLength() : UNSAFE.getInt(getMetaspaceKlass() + config.klassVtableLengthOffset) + " " + config.vtableEntrySize;
504 return result;
505 }
506
507 synchronized HotSpotResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags) {
508 HotSpotResolvedJavaField result = null;
509
510 final int flags = rawFlags & HotSpotModifiers.jvmFieldModifiers();
511
512 final long id = offset + ((long) flags << 32);
513
514 // Must cache the fields, because the local load elimination only works if the
515 // objects from two field lookups are identical.
516 if (fieldCache == null) {
517 fieldCache = new HashMap<>(8);
518 } else {
519 result = fieldCache.get(id);
520 }
521
522 if (result == null) {
523 result = new HotSpotResolvedJavaFieldImpl(this, fieldName, type, offset, rawFlags);
524 fieldCache.put(id, result);
525 } else {
526 assert result.getName().equals(fieldName);
527 /*
528 * Comparing the types directly is too strict, because the type in the cache could be
529 * resolved while the incoming type is unresolved. The name comparison is sufficient
530 * because the type will always be resolved in the context of the holder.
|