# HG changeset patch # User Tom Rodriguez # Date 1415039499 28800 # Node ID e04712c8928a8861215249b5c146c98dc6b2876c # Parent ab489bac3bc8e9336c013ee478f67a8725b3720d# Parent 17c98fad698036f4c83d8339151ed3511830a223 Merge diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java Mon Nov 03 10:31:39 2014 -0800 @@ -39,8 +39,8 @@ import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.sparc.*; import com.oracle.graal.lir.sparc.SPARCMove.CompareAndSwapOp; +import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.CallTargetNode.InvokeKind; public class SPARCHotSpotNodeLIRBuilder extends SPARCNodeLIRBuilder implements HotSpotNodeLIRBuilder { diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Mon Nov 03 10:31:39 2014 -0800 @@ -47,11 +47,11 @@ /** * use - * + * *
  * mx unittest AheadOfTimeCompilationTest @-XX:CompileCommand='print,*AheadOfTimeCompilationTest.*'
  * 
- * + * * to print disassembly. */ public class AheadOfTimeCompilationTest extends GraalCompilerTest { diff -r ab489bac3bc8 -r e04712c8928a 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 Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java Mon Nov 03 10:31:39 2014 -0800 @@ -23,7 +23,7 @@ package com.oracle.graal.hotspot.test; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*; +import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectTypeImpl.*; import java.lang.reflect.*; @@ -47,7 +47,7 @@ @Test public void testModifiersForInternal() { for (Class c : classesWithInternalFields) { - HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromObjectClass(c); + HotSpotResolvedObjectType type = HotSpotResolvedObjectTypeImpl.fromObjectClass(c); for (ResolvedJavaField field : type.getInstanceFields(false)) { if (field.isInternal()) { Assert.assertEquals(0, ~getReflectionFieldModifiers() & field.getModifiers()); @@ -57,13 +57,13 @@ } /** - * Tests that {@link HotSpotResolvedObjectType#createField(String, JavaType, long, int)} always - * returns the same object for an internal field. + * Tests that {@link HotSpotResolvedObjectTypeImpl#createField(String, JavaType, long, int)} + * always returns the same object for an internal field. */ @Test public void testCachingForInternalFields() { for (Class c : classesWithInternalFields) { - HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromObjectClass(c); + HotSpotResolvedObjectTypeImpl type = HotSpotResolvedObjectTypeImpl.fromObjectClass(c); for (ResolvedJavaField field : type.getInstanceFields(false)) { if (field.isInternal()) { HotSpotResolvedJavaField expected = (HotSpotResolvedJavaField) field; diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedObjectTypeTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedObjectTypeTest.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedObjectTypeTest.java Mon Nov 03 10:31:39 2014 -0800 @@ -27,13 +27,13 @@ import com.oracle.graal.hotspot.meta.*; /** - * Tests {@link HotSpotResolvedObjectType} functionality. + * Tests {@link HotSpotResolvedJavaMethod} functionality. */ public class HotSpotResolvedObjectTypeTest { @Test public void testGetSourceFileName() throws Throwable { - Assert.assertEquals("Object.java", HotSpotResolvedObjectType.fromObjectClass(Object.class).getSourceFileName()); - Assert.assertEquals("HotSpotResolvedObjectTypeTest.java", HotSpotResolvedObjectType.fromObjectClass(this.getClass()).getSourceFileName()); + Assert.assertEquals("Object.java", HotSpotResolvedObjectTypeImpl.fromObjectClass(Object.class).getSourceFileName()); + Assert.assertEquals("HotSpotResolvedObjectTypeTest.java", HotSpotResolvedObjectTypeImpl.fromObjectClass(this.getClass()).getSourceFileName()); } } diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Mon Nov 03 10:31:39 2014 -0800 @@ -355,7 +355,7 @@ DebugEnvironment.initialize(TTY.cachedOut); } - HotSpotResolvedJavaMethod method = HotSpotResolvedJavaMethod.fromMetaspace(metaspaceMethod); + HotSpotResolvedJavaMethod method = HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod); compileMethod(method, entryBCI, ctask, id); } diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Mon Nov 03 10:31:39 2014 -0800 @@ -25,7 +25,6 @@ import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.debug.internal.MemUseTrackerImpl.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*; import static com.oracle.graal.nodes.StructuredGraph.*; import java.io.*; @@ -277,7 +276,7 @@ // Pre-load all classes in the constant pool. try { - HotSpotResolvedObjectType objectType = fromObjectClass(javaClass); + HotSpotResolvedObjectType objectType = HotSpotResolvedObjectTypeImpl.fromObjectClass(javaClass); ConstantPool constantPool = objectType.constantPool(); for (int cpi = 1; cpi < constantPool.length(); cpi++) { constantPool.loadReferencedType(cpi, Bytecodes.LDC); diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon Nov 03 10:31:39 2014 -0800 @@ -257,7 +257,7 @@ /** * Graal mirrors are stored as a {@link ClassValue} associated with the {@link Class} of the - * type. This data structure stores both {@link HotSpotResolvedObjectType} and + * type. This data structure stores both {@link HotSpotResolvedJavaMethod} and * {@link HotSpotResolvedPrimitiveType} types. */ private final ClassValue graalMirrors = new ClassValue() { @@ -267,7 +267,7 @@ Kind kind = Kind.fromJavaClass(javaClass); return new HotSpotResolvedPrimitiveType(kind); } else { - return new HotSpotResolvedObjectType(javaClass); + return new HotSpotResolvedObjectTypeImpl(javaClass); } } }; @@ -398,13 +398,14 @@ } // Resolve non-primitive types in the VM. - final long metaspaceKlass = compilerToVm.lookupType(name, accessingType.mirror(), resolve); + HotSpotResolvedObjectTypeImpl hsAccessingType = (HotSpotResolvedObjectTypeImpl) accessingType; + final long metaspaceKlass = compilerToVm.lookupType(name, hsAccessingType.mirror(), resolve); if (metaspaceKlass == 0L) { assert resolve == false; return HotSpotUnresolvedJavaType.create(name); } - return HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass); + return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass); } public HotSpotProviders getHostProviders() { @@ -548,7 +549,7 @@ } else { long[] result = new long[methods.length]; for (int i = 0; i < result.length; i++) { - result[i] = ((HotSpotResolvedJavaMethod) methods[i]).getMetaspaceMethod(); + result[i] = ((HotSpotResolvedJavaMethodImpl) methods[i]).getMetaspaceMethod(); } return result; } diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Mon Nov 03 10:31:39 2014 -0800 @@ -90,7 +90,6 @@ * The methods of MethodHandle that need substitution are signature-polymorphic, i.e., * the VM replicates them for every signature that they are actually used for. * Therefore, we cannot use the usual annotation-driven mechanism to define the - * substitution. */ if (MethodHandleNode.lookupMethodHandleIntrinsic(method) != null) { return MethodHandleNode.class; diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotStackFrameReference.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotStackFrameReference.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotStackFrameReference.java Mon Nov 03 10:31:39 2014 -0800 @@ -73,12 +73,12 @@ @Override public ResolvedJavaMethod getMethod() { - return HotSpotResolvedJavaMethod.fromMetaspace(metaspaceMethod); + return HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod); } @Override public boolean isMethod(ResolvedJavaMethod method) { - return metaspaceMethod == ((HotSpotResolvedJavaMethod) method).getMetaspaceMethod(); + return metaspaceMethod == ((HotSpotResolvedJavaMethodImpl) method).getMetaspaceMethod(); } @Override diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon Nov 03 10:31:39 2014 -0800 @@ -1169,7 +1169,7 @@ @HotSpotVMConstant(name = "JVM_ACC_SYNTHETIC") @Stable public int syntheticFlag; /** - * @see HotSpotResolvedObjectType#createField + * @see HotSpotResolvedObjectTypeImpl#createField */ @HotSpotVMConstant(name = "JVM_RECOGNIZED_FIELD_MODIFIERS") @Stable public int recognizedFieldModifiers; diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java Mon Nov 03 10:31:39 2014 -0800 @@ -125,13 +125,13 @@ } /** - * Gets the holder for this constant pool as {@link HotSpotResolvedObjectType}. + * Gets the holder for this constant pool as {@link HotSpotResolvedObjectTypeImpl}. * * @return holder for this constant pool */ private HotSpotResolvedObjectType getHolder() { final long metaspaceKlass = unsafe.getAddress(metaspaceConstantPool + runtime().getConfig().constantPoolHolderOffset); - return HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass); + return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass); } /** @@ -447,7 +447,7 @@ return HotSpotUnresolvedJavaType.create("L" + name + ";"); } else { assert (metaspacePointer & config.compilerToVMKlassTag) == 0; - return HotSpotResolvedObjectType.fromMetaspaceKlass(metaspacePointer); + return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspacePointer); } } @@ -456,13 +456,13 @@ final int index = toConstantPoolIndex(cpi, opcode); final long metaspaceMethod = runtime().getCompilerToVM().lookupMethodInPool(metaspaceConstantPool, index, (byte) opcode); if (metaspaceMethod != 0L) { - return HotSpotResolvedJavaMethod.fromMetaspace(metaspaceMethod); + return HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod); } else { // Get the method's name and signature. String name = getNameRefAt(index); String signature = getSignatureRefAt(index); if (opcode == Bytecodes.INVOKEDYNAMIC) { - HotSpotResolvedObjectType holder = HotSpotResolvedObjectType.fromObjectClass(MethodHandle.class); + HotSpotResolvedObjectTypeImpl holder = HotSpotResolvedObjectTypeImpl.fromObjectClass(MethodHandle.class); return new HotSpotMethodUnresolved(name, signature, holder); } else { final int klassIndex = getKlassRefIndexAt(index); @@ -492,7 +492,7 @@ final int holderIndex = getKlassRefIndexAt(index); JavaType holder = lookupType(holderIndex, opcode); - if (holder instanceof HotSpotResolvedObjectType) { + if (holder instanceof HotSpotResolvedObjectTypeImpl) { long[] info = new long[2]; long metaspaceKlass; try { @@ -504,7 +504,7 @@ */ return new HotSpotUnresolvedField(holder, name, type); } - HotSpotResolvedObjectType resolvedHolder = HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass); + HotSpotResolvedObjectTypeImpl resolvedHolder = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass); final int flags = (int) info[0]; final long offset = info[1]; return resolvedHolder.createField(name, type, offset, flags); @@ -554,7 +554,7 @@ case UnresolvedClass: case UnresolvedClassInError: final long metaspaceKlass = runtime().getCompilerToVM().constantPoolKlassAt(metaspaceConstantPool, index); - HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass); + HotSpotResolvedObjectTypeImpl type = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass); Class klass = type.mirror(); if (!klass.isPrimitive() && !klass.isArray()) { unsafe.ensureClassInitialized(klass); diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Mon Nov 03 10:31:39 2014 -0800 @@ -107,8 +107,8 @@ o = unsafe.getObject(base, displacement); } else if (baseConstant instanceof HotSpotMetaspaceConstant) { Object metaspaceObject = HotSpotMetaspaceConstant.getMetaspaceObject(baseConstant); - if (metaspaceObject instanceof HotSpotResolvedObjectType && initialDisplacement == runtime.getConfig().classMirrorOffset) { - o = ((HotSpotResolvedObjectType) metaspaceObject).mirror(); + if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl && initialDisplacement == runtime.getConfig().classMirrorOffset) { + o = ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror(); } else { throw GraalInternalError.shouldNotReachHere(); } @@ -166,10 +166,10 @@ assert bits == 32 && kind == Kind.Int; long klassPointer = config().getKlassEncoding().uncompress((int) rawValue); assert klassPointer == runtime.getCompilerToVM().readUnsafeKlassPointer(base); - return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(klassPointer), true); + return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(klassPointer), true); } else { assert bits == 64 && kind == Kind.Long; - return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(rawValue), false); + return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(rawValue), false); } } else { switch (kind) { @@ -231,7 +231,7 @@ } if (constant instanceof HotSpotMetaspaceConstant) { Object obj = HotSpotMetaspaceConstant.getMetaspaceObject(constant); - if (obj instanceof HotSpotResolvedObjectType) { + if (obj instanceof HotSpotResolvedObjectTypeImpl) { return (ResolvedJavaType) obj; } } diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Mon Nov 03 10:31:39 2014 -0800 @@ -24,7 +24,7 @@ import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.hotspot.meta.HotSpotResolvedJavaType.*; -import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*; +import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectTypeImpl.*; import java.lang.reflect.*; @@ -52,7 +52,7 @@ return fromClass(clazz); } - public HotSpotResolvedObjectType lookupJavaType(JavaConstant constant) { + public HotSpotResolvedObjectTypeImpl lookupJavaType(JavaConstant constant) { if (constant.isNull() || !(constant instanceof HotSpotObjectConstant)) { return null; } @@ -89,7 +89,7 @@ Class holder = reflectionMethod.getDeclaringClass(); final int slot = reflectionMethodSlot.getInt(reflectionMethod); final long metaspaceMethod = runtime.getCompilerToVM().getMetaspaceMethod(holder, slot); - return HotSpotResolvedJavaMethod.fromMetaspace(metaspaceMethod); + return HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod); } catch (IllegalArgumentException | IllegalAccessException e) { throw new GraalInternalError(e); } @@ -100,7 +100,7 @@ Class holder = reflectionConstructor.getDeclaringClass(); final int slot = reflectionConstructorSlot.getInt(reflectionConstructor); final long metaspaceMethod = runtime.getCompilerToVM().getMetaspaceMethod(holder, slot); - return HotSpotResolvedJavaMethod.fromMetaspace(metaspaceMethod); + return HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod); } catch (IllegalArgumentException | IllegalAccessException e) { throw new GraalInternalError(e); } @@ -115,11 +115,11 @@ final int modifiers = reflectionField.getModifiers(); final long offset = Modifier.isStatic(modifiers) ? unsafe.staticFieldOffset(reflectionField) : unsafe.objectFieldOffset(reflectionField); - HotSpotResolvedObjectType holder = fromObjectClass(fieldHolder); + HotSpotResolvedObjectTypeImpl holder = fromObjectClass(fieldHolder); HotSpotResolvedJavaType type = fromClass(fieldType); if (offset != -1) { - HotSpotResolvedObjectType resolved = holder; + HotSpotResolvedObjectTypeImpl resolved = holder; return resolved.createField(name, type, offset, modifiers); } else { throw GraalInternalError.shouldNotReachHere("unresolved field " + reflectionField); @@ -295,7 +295,7 @@ @Override public long getMemorySize(JavaConstant constant) { if (constant.getKind() == Kind.Object) { - HotSpotResolvedObjectType lookupJavaType = this.lookupJavaType(constant); + HotSpotResolvedObjectTypeImpl lookupJavaType = this.lookupJavaType(constant); if (lookupJavaType == null) { return 0; diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Mon Nov 03 10:31:39 2014 -0800 @@ -71,7 +71,7 @@ */ private final long metaspaceMethodData; - HotSpotMethodData(long metaspaceMethodData) { + public HotSpotMethodData(long metaspaceMethodData) { this.metaspaceMethodData = metaspaceMethodData; } @@ -492,7 +492,7 @@ outer: for (int i = 0; i < typeProfileWidth; i++) { long receiverKlass = data.readWord(position, getTypeOffset(i)); if (receiverKlass != 0) { - HotSpotResolvedObjectType klass = HotSpotResolvedObjectType.fromMetaspaceKlass(receiverKlass); + HotSpotResolvedObjectTypeImpl klass = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(receiverKlass); long count = data.readUnsignedInt(position, getTypeCountOffset(i)); /* * Because of races in the profile collection machinery it's possible for a @@ -630,7 +630,7 @@ for (int i = 0; i < profileWidth; i++) { long method = data.readWord(position, getMethodOffset(i)); if (method != 0) { - methods[entries] = HotSpotResolvedJavaMethod.fromMetaspace(method); + methods[entries] = HotSpotResolvedJavaMethodImpl.fromMetaspace(method); long count = data.readUnsignedInt(position, getMethodCountOffset(i)); totalCount += count; counts[entries] = count; diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodHandleAccessProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodHandleAccessProvider.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodHandleAccessProvider.java Mon Nov 03 10:31:39 2014 -0800 @@ -24,7 +24,7 @@ import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.meta.HotSpotResolvedJavaType.*; -import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*; +import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectTypeImpl.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; @@ -65,7 +65,7 @@ private static ResolvedJavaMethod findMethodInClass(String className, String methodName) throws ClassNotFoundException { Class clazz = Class.forName(className); - HotSpotResolvedObjectType type = fromObjectClass(clazz); + HotSpotResolvedObjectTypeImpl type = fromObjectClass(clazz); ResolvedJavaMethod result = null; for (ResolvedJavaMethod method : type.getDeclaredMethods()) { if (method.getName().equals(methodName)) { @@ -91,7 +91,7 @@ @Override public IntrinsicMethod lookupMethodHandleIntrinsic(ResolvedJavaMethod method) { - int intrinsicId = ((HotSpotResolvedJavaMethod) method).intrinsicId(); + int intrinsicId = ((HotSpotResolvedJavaMethodImpl) method).intrinsicId(); if (intrinsicId != 0) { HotSpotVMConfig config = runtime().getConfig(); if (intrinsicId == config.vmIntrinsicInvokeBasic) { @@ -148,6 +148,6 @@ /* Load injected field: JVM_Method* MemberName.vmtarget */ JavaConstant vmtarget = LazyInitialization.memberNameVmtargetField.readValue(memberName); /* Create a method from the vmtarget method pointer. */ - return HotSpotResolvedJavaMethod.fromMetaspace(vmtarget.asLong()); + return HotSpotResolvedJavaMethodImpl.fromMetaspace(vmtarget.asLong()); } } diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Mon Nov 03 10:31:39 2014 -0800 @@ -24,7 +24,7 @@ import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*; +import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectTypeImpl.*; import java.lang.annotation.*; import java.lang.reflect.*; @@ -45,7 +45,7 @@ public class HotSpotResolvedJavaField extends CompilerObject implements ResolvedJavaField { private static final long serialVersionUID = 7692985878836955683L; - private final HotSpotResolvedObjectType holder; + private final HotSpotResolvedObjectTypeImpl holder; private final String name; private JavaType type; private final int offset; @@ -55,7 +55,7 @@ */ private final int modifiers; - public HotSpotResolvedJavaField(HotSpotResolvedObjectType holder, String name, JavaType type, long offset, int modifiers) { + public HotSpotResolvedJavaField(HotSpotResolvedObjectTypeImpl holder, String name, JavaType type, long offset, int modifiers) { this.holder = holder; this.name = name; this.type = type; @@ -255,7 +255,7 @@ if (isStatic()) { return false; } - return getDeclaringClass().isAssignableFrom(HotSpotResolvedObjectType.fromObjectClass(object.getClass())); + return getDeclaringClass().isAssignableFrom(HotSpotResolvedObjectTypeImpl.fromObjectClass(object.getClass())); } @Override @@ -292,7 +292,7 @@ } @Override - public HotSpotResolvedObjectType getDeclaringClass() { + public HotSpotResolvedObjectTypeImpl getDeclaringClass() { return holder; } diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Nov 03 10:31:39 2014 -0800 @@ -22,267 +22,43 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.compiler.common.GraalInternalError.*; -import static com.oracle.graal.compiler.common.GraalOptions.*; -import static com.oracle.graal.compiler.common.UnsafeAccess.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; - -import java.lang.annotation.*; import java.lang.reflect.*; -import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; -import com.oracle.graal.debug.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.debug.*; -import com.oracle.graal.nodes.*; /** * Implementation of {@link JavaMethod} for resolved HotSpot methods. */ -public final class HotSpotResolvedJavaMethod extends HotSpotMethod implements ResolvedJavaMethod { - - private static final long serialVersionUID = -5486975070147586588L; - - /** - * Reference to metaspace Method object. - */ - private final long metaspaceMethod; - - private final HotSpotResolvedObjectType holder; - private final HotSpotConstantPool constantPool; - private final HotSpotSignature signature; - private HotSpotMethodData methodData; - private byte[] code; - private Member toJavaCache; - - /** - * Gets the holder of a HotSpot metaspace method native object. - * - * @param metaspaceMethod a metaspace Method object - * @return the {@link ResolvedJavaType} corresponding to the holder of the - * {@code metaspaceMethod} - */ - public static HotSpotResolvedObjectType getHolder(long metaspaceMethod) { - HotSpotVMConfig config = runtime().getConfig(); - final long metaspaceConstMethod = unsafe.getAddress(metaspaceMethod + config.methodConstMethodOffset); - final long metaspaceConstantPool = unsafe.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset); - final long metaspaceKlass = unsafe.getAddress(metaspaceConstantPool + config.constantPoolHolderOffset); - return HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass); - } - - /** - * Gets the {@link ResolvedJavaMethod} for a HotSpot metaspace method native object. - * - * @param metaspaceMethod a metaspace Method object - * @return the {@link ResolvedJavaMethod} corresponding to {@code metaspaceMethod} - */ - public static HotSpotResolvedJavaMethod fromMetaspace(long metaspaceMethod) { - HotSpotResolvedObjectType holder = getHolder(metaspaceMethod); - return holder.createMethod(metaspaceMethod); - } - - HotSpotResolvedJavaMethod(HotSpotResolvedObjectType holder, long metaspaceMethod) { - // It would be too much work to get the method name here so we fill it in later. - super(null); - this.metaspaceMethod = metaspaceMethod; - this.holder = holder; - - HotSpotVMConfig config = runtime().getConfig(); - final long constMethod = getConstMethod(); - - /* - * Get the constant pool from the metaspace method. Some methods (e.g. intrinsics for - * signature-polymorphic method handle methods) have their own constant pool instead of the - * one from their holder. - */ - final long metaspaceConstantPool = unsafe.getAddress(constMethod + config.constMethodConstantsOffset); - this.constantPool = new HotSpotConstantPool(metaspaceConstantPool); - - final int nameIndex = unsafe.getChar(constMethod + config.constMethodNameIndexOffset); - this.name = constantPool.lookupUtf8(nameIndex); - - final int signatureIndex = unsafe.getChar(constMethod + config.constMethodSignatureIndexOffset); - this.signature = (HotSpotSignature) constantPool.lookupSignature(signatureIndex); - } - - /** - * Returns a pointer to this method's constant method data structure ( - * {@code Method::_constMethod}). - * - * @return pointer to this method's ConstMethod - */ - private long getConstMethod() { - assert metaspaceMethod != 0; - return unsafe.getAddress(metaspaceMethod + runtime().getConfig().methodConstMethodOffset); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof HotSpotResolvedJavaMethod) { - HotSpotResolvedJavaMethod that = (HotSpotResolvedJavaMethod) obj; - return that.metaspaceMethod == metaspaceMethod; - } - return false; - } - - @Override - public int hashCode() { - return (int) metaspaceMethod; - } - - /** - * Returns this method's flags ({@code Method::_flags}). - * - * @return flags of this method - */ - private int getFlags() { - return unsafe.getByte(metaspaceMethod + runtime().getConfig().methodFlagsOffset); - } - - /** - * Returns this method's constant method flags ({@code ConstMethod::_flags}). - * - * @return flags of this method's ConstMethod - */ - private int getConstMethodFlags() { - return unsafe.getChar(getConstMethod() + runtime().getConfig().constMethodFlagsOffset); - } - - @Override - public HotSpotResolvedObjectType getDeclaringClass() { - return holder; - } - - /** - * Gets the address of the C++ Method object for this method. - */ - public JavaConstant getMetaspaceMethodConstant() { - return HotSpotMetaspaceConstant.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this, false); - } - - public long getMetaspaceMethod() { - return metaspaceMethod; - } - - @Override - public JavaConstant getEncoding() { - return getMetaspaceMethodConstant(); - } - - /** - * Gets the complete set of modifiers for this method which includes the JVM specification - * modifiers as well as the HotSpot internal modifiers. - */ - public int getAllModifiers() { - return unsafe.getInt(metaspaceMethod + runtime().getConfig().methodAccessFlagsOffset); - } - - @Override - public int getModifiers() { - return getAllModifiers() & Modifier.methodModifiers(); - } - - @Override - public boolean canBeStaticallyBound() { - return (isFinal() || isPrivate() || isStatic() || holder.isFinal()) && !isAbstract(); - } - - @Override - public byte[] getCode() { - if (getCodeSize() == 0) { - return null; - } - if (code == null && holder.isLinked()) { - code = runtime().getCompilerToVM().getBytecode(metaspaceMethod); - assert code.length == getCodeSize() : "expected: " + getCodeSize() + ", actual: " + code.length; - } - return code; - } - - @Override - public int getCodeSize() { - return unsafe.getChar(getConstMethod() + runtime().getConfig().constMethodCodeSizeOffset); - } - - @Override - public ExceptionHandler[] getExceptionHandlers() { - final boolean hasExceptionTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasExceptionTable) != 0; - if (!hasExceptionTable) { - return new ExceptionHandler[0]; - } - - HotSpotVMConfig config = runtime().getConfig(); - final int exceptionTableLength = runtime().getCompilerToVM().exceptionTableLength(metaspaceMethod); - ExceptionHandler[] handlers = new ExceptionHandler[exceptionTableLength]; - long exceptionTableElement = runtime().getCompilerToVM().exceptionTableStart(metaspaceMethod); - - for (int i = 0; i < exceptionTableLength; i++) { - final int startPc = unsafe.getChar(exceptionTableElement + config.exceptionTableElementStartPcOffset); - final int endPc = unsafe.getChar(exceptionTableElement + config.exceptionTableElementEndPcOffset); - final int handlerPc = unsafe.getChar(exceptionTableElement + config.exceptionTableElementHandlerPcOffset); - int catchTypeIndex = unsafe.getChar(exceptionTableElement + config.exceptionTableElementCatchTypeIndexOffset); - - JavaType catchType; - if (catchTypeIndex == 0) { - catchType = null; - } else { - final int opcode = -1; // opcode is not used - catchType = constantPool.lookupType(catchTypeIndex, opcode); - - // Check for Throwable which catches everything. - if (catchType instanceof HotSpotResolvedObjectType) { - HotSpotResolvedObjectType resolvedType = (HotSpotResolvedObjectType) catchType; - if (resolvedType.mirror() == Throwable.class) { - catchTypeIndex = 0; - catchType = null; - } - } - } - handlers[i] = new ExceptionHandler(startPc, endPc, handlerPc, catchTypeIndex, catchType); - - // Go to the next ExceptionTableElement - exceptionTableElement += config.exceptionTableElementSize; - } - - return handlers; - } +public interface HotSpotResolvedJavaMethod extends ResolvedJavaMethod { /** * Returns true if this method has a {@code CallerSensitive} annotation. * * @return true if CallerSensitive annotation present, false otherwise */ - public boolean isCallerSensitive() { - return (getFlags() & runtime().getConfig().methodFlagsCallerSensitive) != 0; - } + boolean isCallerSensitive(); + + HotSpotResolvedObjectTypeImpl getDeclaringClass(); /** * Returns true if this method has a {@code ForceInline} annotation. * * @return true if ForceInline annotation present, false otherwise */ - public boolean isForceInline() { - return (getFlags() & runtime().getConfig().methodFlagsForceInline) != 0; - } + boolean isForceInline(); /** * Returns true if this method has a {@code DontInline} annotation. * * @return true if DontInline annotation present, false otherwise */ - public boolean isDontInline() { - return (getFlags() & runtime().getConfig().methodFlagsDontInline) != 0; - } + boolean isDontInline(); /** * Manually adds a DontInline annotation to this method. */ - public void setNotInlineable() { - runtime().getCompilerToVM().doNotInlineOrCompile(metaspaceMethod); - } + void setNotInlineable(); /** * Returns true if this method is one of the special methods that is ignored by security stack @@ -290,203 +66,28 @@ * * @return true if special method ignored by security stack walks, false otherwise */ - public boolean ignoredBySecurityStackWalk() { - return runtime().getCompilerToVM().methodIsIgnoredBySecurityStackWalk(metaspaceMethod); - } - - public boolean hasBalancedMonitors() { - HotSpotVMConfig config = runtime().getConfig(); - final int modifiers = getAllModifiers(); - - // Method has no monitorenter/exit bytecodes. - if ((modifiers & config.jvmAccHasMonitorBytecodes) == 0) { - return false; - } - - // Check to see if a previous compilation computed the monitor-matching analysis. - if ((modifiers & config.jvmAccMonitorMatch) != 0) { - return true; - } - - // This either happens only once if monitors are balanced or very rarely multiple-times. - return runtime().getCompilerToVM().hasBalancedMonitors(metaspaceMethod); - } - - @Override - public boolean isClassInitializer() { - return "".equals(name) && isStatic(); - } - - @Override - public boolean isConstructor() { - return "".equals(name) && !isStatic(); - } - - @Override - public int getMaxLocals() { - if (isAbstract() || isNative()) { - return 0; - } - HotSpotVMConfig config = runtime().getConfig(); - return unsafe.getChar(getConstMethod() + config.methodMaxLocalsOffset); - } + boolean ignoredBySecurityStackWalk(); - @Override - public int getMaxStackSize() { - if (isAbstract() || isNative()) { - return 0; - } - HotSpotVMConfig config = runtime().getConfig(); - return config.extraStackEntries + unsafe.getChar(getConstMethod() + config.constMethodMaxStackOffset); - } - - @Override - public StackTraceElement asStackTraceElement(int bci) { - if (bci < 0 || bci >= getCodeSize()) { - // HotSpot code can only construct stack trace elements for valid bcis - StackTraceElement ste = runtime().getCompilerToVM().getStackTraceElement(metaspaceMethod, 0); - return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1); - } - return runtime().getCompilerToVM().getStackTraceElement(metaspaceMethod, bci); - } + boolean hasBalancedMonitors(); - public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver) { - if (receiver.isInterface()) { - // Cannot trust interfaces. Because of: - // interface I { void foo(); } - // class A { public void foo() {} } - // class B extends A implements I { } - // class C extends B { public void foo() { } } - // class D extends B { } - // Would lead to identify C.foo() as the unique concrete method for I.foo() without - // seeing A.foo(). - return null; - } - final long uniqueConcreteMethod = runtime().getCompilerToVM().findUniqueConcreteMethod(receiver.getMetaspaceKlass(), metaspaceMethod); - if (uniqueConcreteMethod == 0) { - return null; - } - return fromMetaspace(uniqueConcreteMethod); - } - - @Override - public HotSpotSignature getSignature() { - return signature; - } - - /** - * Gets the value of {@code Method::_code}. - * - * @return the value of {@code Method::_code} - */ - private long getCompiledCode() { - HotSpotVMConfig config = runtime().getConfig(); - return unsafe.getAddress(metaspaceMethod + config.methodCodeOffset); - } + ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectTypeImpl receiver); /** * Returns whether this method has compiled code. * * @return true if this method has compiled code, false otherwise */ - public boolean hasCompiledCode() { - return getCompiledCode() != 0L; - } + boolean hasCompiledCode(); /** * @param level * @return true if the currently installed code was generated at {@code level}. */ - public boolean hasCompiledCodeAtLevel(int level) { - long compiledCode = getCompiledCode(); - if (compiledCode != 0) { - return unsafe.getInt(compiledCode + runtime().getConfig().nmethodCompLevelOffset) == level; - } - return false; - } - - private static final String TraceMethodDataFilter = System.getProperty("graal.traceMethodDataFilter"); - - @Override - public ProfilingInfo getProfilingInfo() { - return getProfilingInfo(true, true); - } - - public ProfilingInfo getCompilationProfilingInfo(boolean isOSR) { - return getProfilingInfo(!isOSR, isOSR); - } - - private ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) { - ProfilingInfo info; - - if (UseProfilingInformation.getValue() && methodData == null) { - long metaspaceMethodData = unsafeReadWord(metaspaceMethod + runtime().getConfig().methodDataOffset); - if (metaspaceMethodData != 0) { - methodData = new HotSpotMethodData(metaspaceMethodData); - if (TraceMethodDataFilter != null && this.format("%H.%n").contains(TraceMethodDataFilter)) { - TTY.println("Raw method data for " + this.format("%H.%n(%p)") + ":"); - TTY.println(methodData.toString()); - } - } - } - - if (methodData == null || (!methodData.hasNormalData() && !methodData.hasExtraData())) { - // Be optimistic and return false for exceptionSeen. A methodDataOop is allocated in - // case of a deoptimization. - info = DefaultProfilingInfo.get(TriState.FALSE); - } else { - info = new HotSpotProfilingInfo(methodData, this, includeNormal, includeOSR); - } - return info; - } + boolean hasCompiledCodeAtLevel(int level); - @Override - public void reprofile() { - runtime().getCompilerToVM().reprofile(metaspaceMethod); - } - - @Override - public ConstantPool getConstantPool() { - return constantPool; - } - - @Override - public Annotation[][] getParameterAnnotations() { - if (isConstructor()) { - Constructor javaConstructor = toJavaConstructor(); - return javaConstructor == null ? null : javaConstructor.getParameterAnnotations(); - } - Method javaMethod = toJava(); - return javaMethod == null ? null : javaMethod.getParameterAnnotations(); - } + ProfilingInfo getCompilationProfilingInfo(boolean isOSR); - @Override - public Annotation[] getAnnotations() { - if (isConstructor()) { - Constructor javaConstructor = toJavaConstructor(); - return javaConstructor == null ? new Annotation[0] : javaConstructor.getAnnotations(); - } - Method javaMethod = toJava(); - return javaMethod == null ? new Annotation[0] : javaMethod.getAnnotations(); - } - - @Override - public T getAnnotation(Class annotationClass) { - if (isConstructor()) { - Constructor javaConstructor = toJavaConstructor(); - return javaConstructor == null ? null : javaConstructor.getAnnotation(annotationClass); - } - Method javaMethod = toJava(); - return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass); - } - - @Override - public boolean isSynthetic() { - int modifiers = getAllModifiers(); - return (runtime().getConfig().syntheticFlag & modifiers) != 0; - } - - public boolean isDefault() { + default boolean isDefault() { if (isConstructor()) { return false; } @@ -495,123 +96,6 @@ return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface(); } - @Override - public Type[] getGenericParameterTypes() { - if (isConstructor()) { - Constructor javaConstructor = toJavaConstructor(); - return javaConstructor == null ? null : javaConstructor.getGenericParameterTypes(); - } - Method javaMethod = toJava(); - return javaMethod == null ? null : javaMethod.getGenericParameterTypes(); - } - - public Class[] signatureToTypes() { - Signature sig = getSignature(); - int count = sig.getParameterCount(false); - Class[] result = new Class[count]; - for (int i = 0; i < result.length; ++i) { - result[i] = ((HotSpotResolvedJavaType) sig.getParameterType(i, holder).resolve(holder)).mirror(); - } - return result; - } - - private Method toJava() { - if (toJavaCache != null) { - return (Method) toJavaCache; - } - try { - Method result = holder.mirror().getDeclaredMethod(name, signatureToTypes()); - toJavaCache = result; - return result; - } catch (NoSuchMethodException e) { - return null; - } - } - - private Constructor toJavaConstructor() { - if (toJavaCache != null) { - return (Constructor) toJavaCache; - } - try { - Constructor result = holder.mirror().getDeclaredConstructor(signatureToTypes()); - toJavaCache = result; - return result; - } catch (NoSuchMethodException e) { - return null; - } - } - - @Override - public boolean canBeInlined() { - if (isDontInline()) { - return false; - } - return runtime().getCompilerToVM().canInlineMethod(metaspaceMethod); - } - - @Override - public boolean shouldBeInlined() { - if (isForceInline()) { - return true; - } - return runtime().getCompilerToVM().shouldInlineMethod(metaspaceMethod); - } - - @Override - public LineNumberTable getLineNumberTable() { - final boolean hasLineNumberTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasLineNumberTable) != 0; - if (!hasLineNumberTable) { - return null; - } - - long[] values = runtime().getCompilerToVM().getLineNumberTable(metaspaceMethod); - if (values.length == 0) { - // Empty table so treat is as non-existent - return null; - } - assert values.length % 2 == 0; - int[] bci = new int[values.length / 2]; - int[] line = new int[values.length / 2]; - - for (int i = 0; i < values.length / 2; i++) { - bci[i] = (int) values[i * 2]; - line[i] = (int) values[i * 2 + 1]; - } - - return new LineNumberTableImpl(line, bci); - } - - @Override - public LocalVariableTable getLocalVariableTable() { - final boolean hasLocalVariableTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasLocalVariableTable) != 0; - if (!hasLocalVariableTable) { - return null; - } - - HotSpotVMConfig config = runtime().getConfig(); - long localVariableTableElement = runtime().getCompilerToVM().getLocalVariableTableStart(metaspaceMethod); - final int localVariableTableLength = runtime().getCompilerToVM().getLocalVariableTableLength(metaspaceMethod); - Local[] locals = new Local[localVariableTableLength]; - - for (int i = 0; i < localVariableTableLength; i++) { - final int startBci = unsafe.getChar(localVariableTableElement + config.localVariableTableElementStartBciOffset); - final int endBci = startBci + unsafe.getChar(localVariableTableElement + config.localVariableTableElementLengthOffset); - final int nameCpIndex = unsafe.getChar(localVariableTableElement + config.localVariableTableElementNameCpIndexOffset); - final int typeCpIndex = unsafe.getChar(localVariableTableElement + config.localVariableTableElementDescriptorCpIndexOffset); - final int slot = unsafe.getChar(localVariableTableElement + config.localVariableTableElementSlotOffset); - - String localName = getConstantPool().lookupUtf8(nameCpIndex); - String localType = getConstantPool().lookupUtf8(typeCpIndex); - - locals[i] = new LocalImpl(localName, localType, holder, startBci, endBci, slot); - - // Go to the next LocalVariableTableElement - localVariableTableElement += config.localVariableTableElementSize; - } - - return new LocalVariableTableImpl(locals); - } - /** * Returns the offset of this method into the v-table. The method must have a v-table entry as * indicated by {@link #isInVirtualMethodTable(ResolvedJavaType)}, otherwise an exception is @@ -619,129 +103,9 @@ * * @return the offset of this method into the v-table */ - public int vtableEntryOffset(ResolvedJavaType resolved) { - guarantee(isInVirtualMethodTable(resolved), "%s does not have a vtable entry", this); - HotSpotVMConfig config = runtime().getConfig(); - final int vtableIndex = getVtableIndex((HotSpotResolvedObjectType) resolved); - return config.instanceKlassVtableStartOffset + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset; - } - - @Override - public boolean isInVirtualMethodTable(ResolvedJavaType resolved) { - if (resolved instanceof HotSpotResolvedObjectType) { - HotSpotResolvedObjectType hotspotResolved = (HotSpotResolvedObjectType) resolved; - int vtableIndex = getVtableIndex(hotspotResolved); - return vtableIndex >= 0 && vtableIndex < hotspotResolved.getVtableLength(); - } - return false; - } - - private int getVtableIndex(HotSpotResolvedObjectType resolved) { - if (!holder.isLinked()) { - return runtime().getConfig().invalidVtableIndex; - } - if (holder.isInterface()) { - if (resolved.isInterface()) { - return runtime().getConfig().invalidVtableIndex; - } - return getVtableIndexForInterface(resolved); - } - return getVtableIndex(); - } - - /** - * Returns this method's virtual table index. - * - * @return virtual table index - */ - private int getVtableIndex() { - assert !holder.isInterface(); - HotSpotVMConfig config = runtime().getConfig(); - int result = unsafe.getInt(metaspaceMethod + config.methodVtableIndexOffset); - assert result >= config.nonvirtualVtableIndex : "must be linked"; - return result; - } - - private int getVtableIndexForInterface(ResolvedJavaType resolved) { - HotSpotResolvedObjectType hotspotType = (HotSpotResolvedObjectType) resolved; - return runtime().getCompilerToVM().getVtableIndexForInterface(hotspotType.getMetaspaceKlass(), getMetaspaceMethod()); - } + int vtableEntryOffset(ResolvedJavaType resolved); - /** - * The {@link SpeculationLog} for methods compiled by Graal hang off this per-declaring-type - * {@link ClassValue}. The raw Method* value is safe to use as a key in the map as a) it is - * never moves and b) we never read from it. - *

- * One implication is that we will preserve {@link SpeculationLog}s for methods that have been - * redefined via class redefinition. It's tempting to periodically flush such logs but we cannot - * read the JVM_ACC_IS_OBSOLETE bit (or anything else) via the raw pointer as obsoleted methods - * are subject to clean up and deletion (see InstanceKlass::purge_previous_versions_internal). - */ - private static final ClassValue> SpeculationLogs = new ClassValue>() { - @Override - protected Map computeValue(java.lang.Class type) { - return new HashMap<>(4); - } - }; - - public SpeculationLog getSpeculationLog() { - Map map = SpeculationLogs.get(holder.mirror()); - synchronized (map) { - SpeculationLog log = map.get(this.metaspaceMethod); - if (log == null) { - log = new HotSpotSpeculationLog(); - map.put(metaspaceMethod, log); - } - return log; - } - } - - public int intrinsicId() { - HotSpotVMConfig config = runtime().getConfig(); - return unsafe.getByte(metaspaceMethod + config.methodIntrinsicIdOffset) & 0xff; - } - - @Override - public JavaConstant invoke(JavaConstant receiver, JavaConstant[] arguments) { - assert !isConstructor(); - Method javaMethod = toJava(); - javaMethod.setAccessible(true); - - Object[] objArguments = new Object[arguments.length]; - for (int i = 0; i < arguments.length; i++) { - objArguments[i] = HotSpotObjectConstant.asBoxedValue(arguments[i]); - } - Object objReceiver = receiver != null ? HotSpotObjectConstant.asObject(receiver) : null; - - try { - Object objResult = javaMethod.invoke(objReceiver, objArguments); - return javaMethod.getReturnType() == void.class ? null : HotSpotObjectConstant.forBoxedValue(getSignature().getReturnKind(), objResult); - - } catch (IllegalAccessException | InvocationTargetException ex) { - throw new IllegalArgumentException(ex); - } - } - - @Override - public JavaConstant newInstance(JavaConstant[] arguments) { - assert isConstructor(); - Constructor javaConstructor = toJavaConstructor(); - javaConstructor.setAccessible(true); - - Object[] objArguments = new Object[arguments.length]; - for (int i = 0; i < arguments.length; i++) { - objArguments[i] = HotSpotObjectConstant.asBoxedValue(arguments[i]); - } - - try { - Object objResult = javaConstructor.newInstance(objArguments); - assert objResult != null; - return HotSpotObjectConstant.forObject(objResult); - - } catch (IllegalAccessException | InvocationTargetException | InstantiationException ex) { - throw new IllegalArgumentException(ex); - } - } + int intrinsicId(); /** * Allocates a compile id for this method by asking the VM for one. @@ -749,14 +113,9 @@ * @param entryBCI entry bci * @return compile id */ - public int allocateCompileId(int entryBCI) { - return runtime().getCompilerToVM().allocateCompileId(metaspaceMethod, entryBCI); - } + int allocateCompileId(int entryBCI); - public boolean hasCodeAtLevel(int entryBCI, int level) { - if (entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI) { - return hasCompiledCodeAtLevel(level); - } - return runtime().getCompilerToVM().hasCompiledCodeForOSR(metaspaceMethod, entryBCI, level); - } + boolean hasCodeAtLevel(int entryBCI, int level); + + SpeculationLog getSpeculationLog(); } diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java Mon Nov 03 10:31:39 2014 -0800 @@ -0,0 +1,762 @@ +/* + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.meta; + +import static com.oracle.graal.compiler.common.GraalInternalError.*; +import static com.oracle.graal.compiler.common.GraalOptions.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; + +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.util.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.meta.ProfilingInfo.TriState; +import com.oracle.graal.debug.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.debug.*; +import com.oracle.graal.nodes.*; + +/** + * Implementation of {@link JavaMethod} for resolved HotSpot methods. + */ +public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod { + + private static final long serialVersionUID = -5486975070147586588L; + + /** + * Reference to metaspace Method object. + */ + private final long metaspaceMethod; + + private final HotSpotResolvedObjectTypeImpl holder; + private final HotSpotConstantPool constantPool; + private final HotSpotSignature signature; + private HotSpotMethodData methodData; + private byte[] code; + private Member toJavaCache; + + /** + * Gets the holder of a HotSpot metaspace method native object. + * + * @param metaspaceMethod a metaspace Method object + * @return the {@link ResolvedJavaType} corresponding to the holder of the + * {@code metaspaceMethod} + */ + public static HotSpotResolvedObjectTypeImpl getHolder(long metaspaceMethod) { + HotSpotVMConfig config = runtime().getConfig(); + final long metaspaceConstMethod = unsafe.getAddress(metaspaceMethod + config.methodConstMethodOffset); + final long metaspaceConstantPool = unsafe.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset); + final long metaspaceKlass = unsafe.getAddress(metaspaceConstantPool + config.constantPoolHolderOffset); + return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass); + } + + /** + * Gets the {@link ResolvedJavaMethod} for a HotSpot metaspace method native object. + * + * @param metaspaceMethod a metaspace Method object + * @return the {@link ResolvedJavaMethod} corresponding to {@code metaspaceMethod} + */ + public static HotSpotResolvedJavaMethod fromMetaspace(long metaspaceMethod) { + HotSpotResolvedObjectTypeImpl holder = getHolder(metaspaceMethod); + return holder.createMethod(metaspaceMethod); + } + + public HotSpotResolvedJavaMethodImpl(HotSpotResolvedObjectTypeImpl holder, long metaspaceMethod) { + // It would be too much work to get the method name here so we fill it in later. + super(null); + this.metaspaceMethod = metaspaceMethod; + this.holder = holder; + + HotSpotVMConfig config = runtime().getConfig(); + final long constMethod = getConstMethod(); + + /* + * Get the constant pool from the metaspace method. Some methods (e.g. intrinsics for + * signature-polymorphic method handle methods) have their own constant pool instead of the + * one from their holder. + */ + final long metaspaceConstantPool = unsafe.getAddress(constMethod + config.constMethodConstantsOffset); + this.constantPool = new HotSpotConstantPool(metaspaceConstantPool); + + final int nameIndex = unsafe.getChar(constMethod + config.constMethodNameIndexOffset); + this.name = constantPool.lookupUtf8(nameIndex); + + final int signatureIndex = unsafe.getChar(constMethod + config.constMethodSignatureIndexOffset); + this.signature = (HotSpotSignature) constantPool.lookupSignature(signatureIndex); + } + + /** + * Returns a pointer to this method's constant method data structure ( + * {@code Method::_constMethod}). + * + * @return pointer to this method's ConstMethod + */ + private long getConstMethod() { + assert metaspaceMethod != 0; + return unsafe.getAddress(metaspaceMethod + runtime().getConfig().methodConstMethodOffset); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof HotSpotResolvedJavaMethod) { + HotSpotResolvedJavaMethodImpl that = (HotSpotResolvedJavaMethodImpl) obj; + return that.metaspaceMethod == metaspaceMethod; + } + return false; + } + + @Override + public int hashCode() { + return (int) metaspaceMethod; + } + + /** + * Returns this method's flags ({@code Method::_flags}). + * + * @return flags of this method + */ + private int getFlags() { + return unsafe.getByte(metaspaceMethod + runtime().getConfig().methodFlagsOffset); + } + + /** + * Returns this method's constant method flags ({@code ConstMethod::_flags}). + * + * @return flags of this method's ConstMethod + */ + private int getConstMethodFlags() { + return unsafe.getChar(getConstMethod() + runtime().getConfig().constMethodFlagsOffset); + } + + @Override + public HotSpotResolvedObjectTypeImpl getDeclaringClass() { + return holder; + } + + /** + * Gets the address of the C++ Method object for this method. + */ + public JavaConstant getMetaspaceMethodConstant() { + return HotSpotMetaspaceConstant.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this, false); + } + + public long getMetaspaceMethod() { + return metaspaceMethod; + } + + @Override + public JavaConstant getEncoding() { + return getMetaspaceMethodConstant(); + } + + /** + * Gets the complete set of modifiers for this method which includes the JVM specification + * modifiers as well as the HotSpot internal modifiers. + */ + public int getAllModifiers() { + return unsafe.getInt(metaspaceMethod + runtime().getConfig().methodAccessFlagsOffset); + } + + @Override + public int getModifiers() { + return getAllModifiers() & Modifier.methodModifiers(); + } + + @Override + public boolean canBeStaticallyBound() { + return (isFinal() || isPrivate() || isStatic() || holder.isFinal()) && !isAbstract(); + } + + @Override + public byte[] getCode() { + if (getCodeSize() == 0) { + return null; + } + if (code == null && holder.isLinked()) { + code = runtime().getCompilerToVM().getBytecode(metaspaceMethod); + assert code.length == getCodeSize() : "expected: " + getCodeSize() + ", actual: " + code.length; + } + return code; + } + + @Override + public int getCodeSize() { + return unsafe.getChar(getConstMethod() + runtime().getConfig().constMethodCodeSizeOffset); + } + + @Override + public ExceptionHandler[] getExceptionHandlers() { + final boolean hasExceptionTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasExceptionTable) != 0; + if (!hasExceptionTable) { + return new ExceptionHandler[0]; + } + + HotSpotVMConfig config = runtime().getConfig(); + final int exceptionTableLength = runtime().getCompilerToVM().exceptionTableLength(metaspaceMethod); + ExceptionHandler[] handlers = new ExceptionHandler[exceptionTableLength]; + long exceptionTableElement = runtime().getCompilerToVM().exceptionTableStart(metaspaceMethod); + + for (int i = 0; i < exceptionTableLength; i++) { + final int startPc = unsafe.getChar(exceptionTableElement + config.exceptionTableElementStartPcOffset); + final int endPc = unsafe.getChar(exceptionTableElement + config.exceptionTableElementEndPcOffset); + final int handlerPc = unsafe.getChar(exceptionTableElement + config.exceptionTableElementHandlerPcOffset); + int catchTypeIndex = unsafe.getChar(exceptionTableElement + config.exceptionTableElementCatchTypeIndexOffset); + + JavaType catchType; + if (catchTypeIndex == 0) { + catchType = null; + } else { + final int opcode = -1; // opcode is not used + catchType = constantPool.lookupType(catchTypeIndex, opcode); + + // Check for Throwable which catches everything. + if (catchType instanceof HotSpotResolvedObjectTypeImpl) { + HotSpotResolvedObjectTypeImpl resolvedType = (HotSpotResolvedObjectTypeImpl) catchType; + if (resolvedType.mirror() == Throwable.class) { + catchTypeIndex = 0; + catchType = null; + } + } + } + handlers[i] = new ExceptionHandler(startPc, endPc, handlerPc, catchTypeIndex, catchType); + + // Go to the next ExceptionTableElement + exceptionTableElement += config.exceptionTableElementSize; + } + + return handlers; + } + + /** + * Returns true if this method has a {@code CallerSensitive} annotation. + * + * @return true if CallerSensitive annotation present, false otherwise + */ + public boolean isCallerSensitive() { + return (getFlags() & runtime().getConfig().methodFlagsCallerSensitive) != 0; + } + + /** + * Returns true if this method has a {@code ForceInline} annotation. + * + * @return true if ForceInline annotation present, false otherwise + */ + public boolean isForceInline() { + return (getFlags() & runtime().getConfig().methodFlagsForceInline) != 0; + } + + /** + * Returns true if this method has a {@code DontInline} annotation. + * + * @return true if DontInline annotation present, false otherwise + */ + public boolean isDontInline() { + return (getFlags() & runtime().getConfig().methodFlagsDontInline) != 0; + } + + /** + * Manually adds a DontInline annotation to this method. + */ + public void setNotInlineable() { + runtime().getCompilerToVM().doNotInlineOrCompile(metaspaceMethod); + } + + /** + * Returns true if this method is one of the special methods that is ignored by security stack + * walks. + * + * @return true if special method ignored by security stack walks, false otherwise + */ + public boolean ignoredBySecurityStackWalk() { + return runtime().getCompilerToVM().methodIsIgnoredBySecurityStackWalk(metaspaceMethod); + } + + public boolean hasBalancedMonitors() { + HotSpotVMConfig config = runtime().getConfig(); + final int modifiers = getAllModifiers(); + + // Method has no monitorenter/exit bytecodes. + if ((modifiers & config.jvmAccHasMonitorBytecodes) == 0) { + return false; + } + + // Check to see if a previous compilation computed the monitor-matching analysis. + if ((modifiers & config.jvmAccMonitorMatch) != 0) { + return true; + } + + // This either happens only once if monitors are balanced or very rarely multiple-times. + return runtime().getCompilerToVM().hasBalancedMonitors(metaspaceMethod); + } + + @Override + public boolean isClassInitializer() { + return "".equals(name) && isStatic(); + } + + @Override + public boolean isConstructor() { + return "".equals(name) && !isStatic(); + } + + @Override + public int getMaxLocals() { + if (isAbstract() || isNative()) { + return 0; + } + HotSpotVMConfig config = runtime().getConfig(); + return unsafe.getChar(getConstMethod() + config.methodMaxLocalsOffset); + } + + @Override + public int getMaxStackSize() { + if (isAbstract() || isNative()) { + return 0; + } + HotSpotVMConfig config = runtime().getConfig(); + return config.extraStackEntries + unsafe.getChar(getConstMethod() + config.constMethodMaxStackOffset); + } + + @Override + public StackTraceElement asStackTraceElement(int bci) { + if (bci < 0 || bci >= getCodeSize()) { + // HotSpot code can only construct stack trace elements for valid bcis + StackTraceElement ste = runtime().getCompilerToVM().getStackTraceElement(metaspaceMethod, 0); + return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1); + } + return runtime().getCompilerToVM().getStackTraceElement(metaspaceMethod, bci); + } + + public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectTypeImpl receiver) { + if (receiver.isInterface()) { + // Cannot trust interfaces. Because of: + // interface I { void foo(); } + // class A { public void foo() {} } + // class B extends A implements I { } + // class C extends B { public void foo() { } } + // class D extends B { } + // Would lead to identify C.foo() as the unique concrete method for I.foo() without + // seeing A.foo(). + return null; + } + final long uniqueConcreteMethod = runtime().getCompilerToVM().findUniqueConcreteMethod(receiver.getMetaspaceKlass(), metaspaceMethod); + if (uniqueConcreteMethod == 0) { + return null; + } + return fromMetaspace(uniqueConcreteMethod); + } + + @Override + public HotSpotSignature getSignature() { + return signature; + } + + /** + * Gets the value of {@code Method::_code}. + * + * @return the value of {@code Method::_code} + */ + private long getCompiledCode() { + HotSpotVMConfig config = runtime().getConfig(); + return unsafe.getAddress(metaspaceMethod + config.methodCodeOffset); + } + + /** + * Returns whether this method has compiled code. + * + * @return true if this method has compiled code, false otherwise + */ + public boolean hasCompiledCode() { + return getCompiledCode() != 0L; + } + + /** + * @param level + * @return true if the currently installed code was generated at {@code level}. + */ + public boolean hasCompiledCodeAtLevel(int level) { + long compiledCode = getCompiledCode(); + if (compiledCode != 0) { + return unsafe.getInt(compiledCode + runtime().getConfig().nmethodCompLevelOffset) == level; + } + return false; + } + + private static final String TraceMethodDataFilter = System.getProperty("graal.traceMethodDataFilter"); + + @Override + public ProfilingInfo getProfilingInfo() { + return getProfilingInfo(true, true); + } + + public ProfilingInfo getCompilationProfilingInfo(boolean isOSR) { + return getProfilingInfo(!isOSR, isOSR); + } + + private ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) { + ProfilingInfo info; + + if (UseProfilingInformation.getValue() && methodData == null) { + long metaspaceMethodData = unsafeReadWord(metaspaceMethod + runtime().getConfig().methodDataOffset); + if (metaspaceMethodData != 0) { + methodData = new HotSpotMethodData(metaspaceMethodData); + if (TraceMethodDataFilter != null && this.format("%H.%n").contains(TraceMethodDataFilter)) { + TTY.println("Raw method data for " + this.format("%H.%n(%p)") + ":"); + TTY.println(methodData.toString()); + } + } + } + + if (methodData == null || (!methodData.hasNormalData() && !methodData.hasExtraData())) { + // Be optimistic and return false for exceptionSeen. A methodDataOop is allocated in + // case of a deoptimization. + info = DefaultProfilingInfo.get(TriState.FALSE); + } else { + info = new HotSpotProfilingInfo(methodData, this, includeNormal, includeOSR); + } + return info; + } + + @Override + public void reprofile() { + runtime().getCompilerToVM().reprofile(metaspaceMethod); + } + + @Override + public ConstantPool getConstantPool() { + return constantPool; + } + + @Override + public Annotation[][] getParameterAnnotations() { + if (isConstructor()) { + Constructor javaConstructor = toJavaConstructor(); + return javaConstructor == null ? null : javaConstructor.getParameterAnnotations(); + } + Method javaMethod = toJava(); + return javaMethod == null ? null : javaMethod.getParameterAnnotations(); + } + + @Override + public Annotation[] getAnnotations() { + if (isConstructor()) { + Constructor javaConstructor = toJavaConstructor(); + return javaConstructor == null ? new Annotation[0] : javaConstructor.getAnnotations(); + } + Method javaMethod = toJava(); + return javaMethod == null ? new Annotation[0] : javaMethod.getAnnotations(); + } + + @Override + public T getAnnotation(Class annotationClass) { + if (isConstructor()) { + Constructor javaConstructor = toJavaConstructor(); + return javaConstructor == null ? null : javaConstructor.getAnnotation(annotationClass); + } + Method javaMethod = toJava(); + 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; + } + // Copied from java.lang.Method.isDefault() + int mask = Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC; + return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface(); + } + + @Override + public Type[] getGenericParameterTypes() { + if (isConstructor()) { + Constructor javaConstructor = toJavaConstructor(); + return javaConstructor == null ? null : javaConstructor.getGenericParameterTypes(); + } + Method javaMethod = toJava(); + return javaMethod == null ? null : javaMethod.getGenericParameterTypes(); + } + + public Class[] signatureToTypes() { + Signature sig = getSignature(); + int count = sig.getParameterCount(false); + Class[] result = new Class[count]; + for (int i = 0; i < result.length; ++i) { + result[i] = ((HotSpotResolvedJavaType) sig.getParameterType(i, holder).resolve(holder)).mirror(); + } + return result; + } + + private Method toJava() { + if (toJavaCache != null) { + return (Method) toJavaCache; + } + try { + Method result = holder.mirror().getDeclaredMethod(name, signatureToTypes()); + toJavaCache = result; + return result; + } catch (NoSuchMethodException e) { + return null; + } + } + + private Constructor toJavaConstructor() { + if (toJavaCache != null) { + return (Constructor) toJavaCache; + } + try { + Constructor result = holder.mirror().getDeclaredConstructor(signatureToTypes()); + toJavaCache = result; + return result; + } catch (NoSuchMethodException e) { + return null; + } + } + + @Override + public boolean canBeInlined() { + if (isDontInline()) { + return false; + } + return runtime().getCompilerToVM().canInlineMethod(metaspaceMethod); + } + + @Override + public boolean shouldBeInlined() { + if (isForceInline()) { + return true; + } + return runtime().getCompilerToVM().shouldInlineMethod(metaspaceMethod); + } + + @Override + public LineNumberTable getLineNumberTable() { + final boolean hasLineNumberTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasLineNumberTable) != 0; + if (!hasLineNumberTable) { + return null; + } + + long[] values = runtime().getCompilerToVM().getLineNumberTable(metaspaceMethod); + if (values.length == 0) { + // Empty table so treat is as non-existent + return null; + } + assert values.length % 2 == 0; + int[] bci = new int[values.length / 2]; + int[] line = new int[values.length / 2]; + + for (int i = 0; i < values.length / 2; i++) { + bci[i] = (int) values[i * 2]; + line[i] = (int) values[i * 2 + 1]; + } + + return new LineNumberTableImpl(line, bci); + } + + @Override + public LocalVariableTable getLocalVariableTable() { + final boolean hasLocalVariableTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasLocalVariableTable) != 0; + if (!hasLocalVariableTable) { + return null; + } + + HotSpotVMConfig config = runtime().getConfig(); + long localVariableTableElement = runtime().getCompilerToVM().getLocalVariableTableStart(metaspaceMethod); + final int localVariableTableLength = runtime().getCompilerToVM().getLocalVariableTableLength(metaspaceMethod); + Local[] locals = new Local[localVariableTableLength]; + + for (int i = 0; i < localVariableTableLength; i++) { + final int startBci = unsafe.getChar(localVariableTableElement + config.localVariableTableElementStartBciOffset); + final int endBci = startBci + unsafe.getChar(localVariableTableElement + config.localVariableTableElementLengthOffset); + final int nameCpIndex = unsafe.getChar(localVariableTableElement + config.localVariableTableElementNameCpIndexOffset); + final int typeCpIndex = unsafe.getChar(localVariableTableElement + config.localVariableTableElementDescriptorCpIndexOffset); + final int slot = unsafe.getChar(localVariableTableElement + config.localVariableTableElementSlotOffset); + + String localName = getConstantPool().lookupUtf8(nameCpIndex); + String localType = getConstantPool().lookupUtf8(typeCpIndex); + + locals[i] = new LocalImpl(localName, localType, holder, startBci, endBci, slot); + + // Go to the next LocalVariableTableElement + localVariableTableElement += config.localVariableTableElementSize; + } + + return new LocalVariableTableImpl(locals); + } + + /** + * Returns the offset of this method into the v-table. The method must have a v-table entry as + * indicated by {@link #isInVirtualMethodTable(ResolvedJavaType)}, otherwise an exception is + * thrown. + * + * @return the offset of this method into the v-table + */ + public int vtableEntryOffset(ResolvedJavaType resolved) { + guarantee(isInVirtualMethodTable(resolved), "%s does not have a vtable entry", this); + HotSpotVMConfig config = runtime().getConfig(); + final int vtableIndex = getVtableIndex((HotSpotResolvedObjectTypeImpl) resolved); + return config.instanceKlassVtableStartOffset + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset; + } + + @Override + public boolean isInVirtualMethodTable(ResolvedJavaType resolved) { + if (resolved instanceof HotSpotResolvedObjectTypeImpl) { + HotSpotResolvedObjectTypeImpl hotspotResolved = (HotSpotResolvedObjectTypeImpl) resolved; + int vtableIndex = getVtableIndex(hotspotResolved); + return vtableIndex >= 0 && vtableIndex < hotspotResolved.getVtableLength(); + } + return false; + } + + private int getVtableIndex(HotSpotResolvedObjectTypeImpl resolved) { + if (!holder.isLinked()) { + return runtime().getConfig().invalidVtableIndex; + } + if (holder.isInterface()) { + if (resolved.isInterface()) { + return runtime().getConfig().invalidVtableIndex; + } + return getVtableIndexForInterface(resolved); + } + return getVtableIndex(); + } + + /** + * Returns this method's virtual table index. + * + * @return virtual table index + */ + private int getVtableIndex() { + assert !holder.isInterface(); + HotSpotVMConfig config = runtime().getConfig(); + int result = unsafe.getInt(metaspaceMethod + config.methodVtableIndexOffset); + assert result >= config.nonvirtualVtableIndex : "must be linked"; + return result; + } + + private int getVtableIndexForInterface(ResolvedJavaType resolved) { + HotSpotResolvedObjectTypeImpl hotspotType = (HotSpotResolvedObjectTypeImpl) resolved; + return runtime().getCompilerToVM().getVtableIndexForInterface(hotspotType.getMetaspaceKlass(), getMetaspaceMethod()); + } + + /** + * The {@link SpeculationLog} for methods compiled by Graal hang off this per-declaring-type + * {@link ClassValue}. The raw Method* value is safe to use as a key in the map as a) it is + * never moves and b) we never read from it. + *

+ * One implication is that we will preserve {@link SpeculationLog}s for methods that have been + * redefined via class redefinition. It's tempting to periodically flush such logs but we cannot + * read the JVM_ACC_IS_OBSOLETE bit (or anything else) via the raw pointer as obsoleted methods + * are subject to clean up and deletion (see InstanceKlass::purge_previous_versions_internal). + */ + private static final ClassValue> SpeculationLogs = new ClassValue>() { + @Override + protected Map computeValue(java.lang.Class type) { + return new HashMap<>(4); + } + }; + + public SpeculationLog getSpeculationLog() { + Map map = SpeculationLogs.get(holder.mirror()); + synchronized (map) { + SpeculationLog log = map.get(this.metaspaceMethod); + if (log == null) { + log = new HotSpotSpeculationLog(); + map.put(metaspaceMethod, log); + } + return log; + } + } + + public int intrinsicId() { + HotSpotVMConfig config = runtime().getConfig(); + return unsafe.getByte(metaspaceMethod + config.methodIntrinsicIdOffset) & 0xff; + } + + @Override + public JavaConstant invoke(JavaConstant receiver, JavaConstant[] arguments) { + assert !isConstructor(); + Method javaMethod = toJava(); + javaMethod.setAccessible(true); + + Object[] objArguments = new Object[arguments.length]; + for (int i = 0; i < arguments.length; i++) { + objArguments[i] = HotSpotObjectConstant.asBoxedValue(arguments[i]); + } + Object objReceiver = receiver != null ? HotSpotObjectConstant.asObject(receiver) : null; + + try { + Object objResult = javaMethod.invoke(objReceiver, objArguments); + return javaMethod.getReturnType() == void.class ? null : HotSpotObjectConstant.forBoxedValue(getSignature().getReturnKind(), objResult); + + } catch (IllegalAccessException | InvocationTargetException ex) { + throw new IllegalArgumentException(ex); + } + } + + @Override + public JavaConstant newInstance(JavaConstant[] arguments) { + assert isConstructor(); + Constructor javaConstructor = toJavaConstructor(); + javaConstructor.setAccessible(true); + + Object[] objArguments = new Object[arguments.length]; + for (int i = 0; i < arguments.length; i++) { + objArguments[i] = HotSpotObjectConstant.asBoxedValue(arguments[i]); + } + + try { + Object objResult = javaConstructor.newInstance(objArguments); + assert objResult != null; + return HotSpotObjectConstant.forObject(objResult); + + } catch (IllegalAccessException | InvocationTargetException | InstantiationException ex) { + throw new IllegalArgumentException(ex); + } + } + + /** + * Allocates a compile id for this method by asking the VM for one. + * + * @param entryBCI entry bci + * @return compile id + */ + public int allocateCompileId(int entryBCI) { + return runtime().getCompilerToVM().allocateCompileId(metaspaceMethod, entryBCI); + } + + public boolean hasCodeAtLevel(int entryBCI, int level) { + if (entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI) { + return hasCompiledCodeAtLevel(level); + } + return runtime().getCompilerToVM().hasCompiledCodeForOSR(metaspaceMethod, entryBCI, level); + } +} diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Mon Nov 03 10:31:39 2014 -0800 @@ -22,721 +22,51 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.compiler.common.UnsafeAccess.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static java.util.Objects.*; - -import java.lang.annotation.*; -import java.lang.reflect.*; -import java.net.*; -import java.util.*; - import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; /** * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes. */ -public final class HotSpotResolvedObjectType extends HotSpotResolvedJavaType { - - private static final long serialVersionUID = 3481514353553840471L; - - /** - * The Java class this type represents. - */ - private final Class javaClass; - - private HashMap fieldCache; - private HashMap methodCache; - private HotSpotResolvedJavaField[] instanceFields; - private HotSpotResolvedObjectType[] interfaces; - private ConstantPool constantPool; - private HotSpotResolvedObjectType arrayOfType; +public interface HotSpotResolvedObjectType extends ResolvedJavaType { - /** - * Gets the Graal mirror for a {@link Class} object. - * - * @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass} - */ - public static HotSpotResolvedObjectType fromObjectClass(Class javaClass) { - return (HotSpotResolvedObjectType) runtime().fromClass(javaClass); - } - - /** - * Gets the Graal mirror from a HotSpot metaspace Klass native object. - * - * @param metaspaceKlass a metaspace Klass object boxed in a {@link JavaConstant} - * @return the {@link HotSpotResolvedObjectType} corresponding to {@code klassConstant} - */ - public static HotSpotResolvedObjectType fromMetaspaceKlass(JavaConstant metaspaceKlass) { - assert metaspaceKlass.getKind() == Kind.Long; - return fromMetaspaceKlass(metaspaceKlass.asLong()); - } - - /** - * Gets the Graal mirror from a HotSpot metaspace Klass native object. - * - * @param metaspaceKlass a metaspace Klass object - * @return the {@link ResolvedJavaType} corresponding to {@code metaspaceKlass} - */ - public static HotSpotResolvedObjectType fromMetaspaceKlass(long metaspaceKlass) { - assert metaspaceKlass != 0; - Class javaClass = runtime().getCompilerToVM().getJavaMirror(metaspaceKlass); - assert javaClass != null; - return fromObjectClass(javaClass); - } + HotSpotResolvedObjectType getArrayClass(); - /** - * Creates the Graal mirror for a {@link Class} object. - * - *

- * NOTE: Creating an instance of this class does not install the mirror for the - * {@link Class} type. Use {@link #fromObjectClass(Class)}, - * {@link #fromMetaspaceKlass(JavaConstant)} or {@link #fromMetaspaceKlass(long)} instead. - *

- * - * @param javaClass the Class to create the mirror for - */ - public HotSpotResolvedObjectType(Class javaClass) { - super(getSignatureName(javaClass)); - this.javaClass = javaClass; - assert getName().charAt(0) != '[' || isArray() : getName(); - } - - /** - * Returns the name of this type as it would appear in a signature. - */ - private static String getSignatureName(Class javaClass) { - if (javaClass.isArray()) { - return javaClass.getName().replace('.', '/'); - } - return "L" + javaClass.getName().replace('.', '/') + ";"; - } - - /** - * Gets the metaspace Klass for this type. - */ - public long getMetaspaceKlass() { - return HotSpotGraalRuntime.unsafeReadWord(javaClass, runtime().getConfig().klassOffset); - } + ResolvedJavaType getComponentType(); - @Override - public int getModifiers() { - return mirror().getModifiers(); - } - - public int getAccessFlags() { - HotSpotVMConfig config = runtime().getConfig(); - return unsafe.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset); - } + HotSpotResolvedObjectType findUniqueConcreteSubtype(); - @Override - public ResolvedJavaType getArrayClass() { - if (arrayOfType == null) { - arrayOfType = fromObjectClass(Array.newInstance(mirror(), 0).getClass()); - } - return arrayOfType; - } - - @Override - public ResolvedJavaType getComponentType() { - Class javaComponentType = mirror().getComponentType(); - return javaComponentType == null ? null : fromClass(javaComponentType); - } - - @Override - public ResolvedJavaType findUniqueConcreteSubtype() { - HotSpotVMConfig config = runtime().getConfig(); - if (isArray()) { - return getElementalType().isFinal() ? this : null; - } else if (isInterface()) { - HotSpotResolvedObjectType type = getSingleImplementor(); - if (type == null) { - return null; - } + HotSpotResolvedObjectType getSuperclass(); - /* - * If the implementor field contains itself that indicates that the interface has more - * than one implementors (see: InstanceKlass::add_implementor). The isInterface check - * takes care of this fact since this class is an interface. - */ - if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) { - return null; - } - return type; - } else { - HotSpotResolvedObjectType type = this; - while (type.isAbstract()) { - long subklass = type.getSubklass(); - if (subklass == 0 || unsafeReadWord(subklass + config.nextSiblingOffset) != 0) { - return null; - } - type = fromMetaspaceKlass(subklass); - } - if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) { - return null; - } - return type; - } - } - - /** - * Returns if type {@code type} is a leaf class. This is the case if the - * {@code Klass::_subklass} field of the underlying class is zero. - * - * @return true if the type is a leaf class - */ - private boolean isLeafClass() { - return getSubklass() == 0; - } + HotSpotResolvedObjectType[] getInterfaces(); - /** - * Returns the {@code Klass::_subklass} field of the underlying metaspace klass for the given - * type {@code type}. - * - * @return value of the subklass field as metaspace klass pointer - */ - private long getSubklass() { - return unsafeReadWord(getMetaspaceKlass() + runtime().getConfig().subklassOffset); - } - - @Override - public HotSpotResolvedObjectType getSuperclass() { - Class javaSuperclass = mirror().getSuperclass(); - return javaSuperclass == null ? null : (HotSpotResolvedObjectType) fromObjectClass(javaSuperclass); - } - - @Override - public HotSpotResolvedObjectType[] getInterfaces() { - if (interfaces == null) { - Class[] javaInterfaces = mirror().getInterfaces(); - HotSpotResolvedObjectType[] result = new HotSpotResolvedObjectType[javaInterfaces.length]; - for (int i = 0; i < javaInterfaces.length; i++) { - result[i] = fromObjectClass(javaInterfaces[i]); - } - interfaces = result; - } - return interfaces; - } - - @Override - public HotSpotResolvedObjectType getSingleImplementor() { - if (!isInterface()) { - throw new GraalInternalError("Cannot call getImplementor() on a non-interface type: " + this); - } - final long implementorMetaspaceKlass = runtime().getCompilerToVM().getKlassImplementor(getMetaspaceKlass()); + HotSpotResolvedObjectType getSupertype(); - // No implementor. - if (implementorMetaspaceKlass == 0) { - return null; - } - - return fromMetaspaceKlass(implementorMetaspaceKlass); - } - - public HotSpotResolvedObjectType getSupertype() { - if (isArray()) { - ResolvedJavaType componentType = getComponentType(); - if (mirror() == Object[].class || componentType.isPrimitive()) { - return fromObjectClass(Object.class); - } - return (HotSpotResolvedObjectType) ((HotSpotResolvedObjectType) componentType).getSupertype().getArrayClass(); - } - if (isInterface()) { - return fromObjectClass(Object.class); - } - return getSuperclass(); - } + HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType); - @Override - public ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType) { - if (otherType.isPrimitive()) { - return null; - } else { - HotSpotResolvedObjectType t1 = this; - HotSpotResolvedObjectType t2 = (HotSpotResolvedObjectType) otherType; - while (true) { - if (t1.isAssignableFrom(t2)) { - return t1; - } - if (t2.isAssignableFrom(t1)) { - return t2; - } - t1 = t1.getSupertype(); - t2 = t2.getSupertype(); - } - } - } + HotSpotResolvedObjectType asExactType(); - @Override - public ResolvedJavaType asExactType() { - if (isArray()) { - return getComponentType().asExactType() != null ? this : null; - } - return isFinal() ? this : null; - } - - @Override - public JavaConstant getEncoding(Representation r) { - switch (r) { - case JavaClass: - return HotSpotObjectConstant.forObject(mirror()); - case ObjectHub: - return klass(); - default: - throw GraalInternalError.shouldNotReachHere("unexpected representation " + r); - } - } - - @Override - public boolean hasFinalizableSubclass() { - assert !isArray(); - return runtime().getCompilerToVM().hasFinalizableSubclass(getMetaspaceKlass()); - } - - @Override - public boolean hasFinalizer() { - HotSpotVMConfig config = runtime().getConfig(); - return (getAccessFlags() & config.klassHasFinalizerFlag) != 0; - } - - @Override - public boolean isPrimitive() { + default boolean isPrimitive() { return false; } - @Override - public boolean isArray() { - return mirror().isArray(); - } - - @Override - public boolean isInitialized() { - return isArray() ? true : getInitState() == runtime().getConfig().instanceKlassStateFullyInitialized; - } - - @Override - public boolean isLinked() { - return isArray() ? true : getInitState() >= runtime().getConfig().instanceKlassStateLinked; - } - - /** - * Returns the value of the state field {@code InstanceKlass::_init_state} of the metaspace - * klass. - * - * @return state field value of this type - */ - private int getInitState() { - assert !isArray() : "_init_state only exists in InstanceKlass"; - return unsafe.getByte(getMetaspaceKlass() + runtime().getConfig().instanceKlassInitStateOffset) & 0xFF; - } - - @Override - public void initialize() { - if (!isInitialized()) { - unsafe.ensureClassInitialized(mirror()); - assert isInitialized(); - } - } - - @Override - public boolean isInstance(JavaConstant obj) { - if (obj.getKind() == Kind.Object && !obj.isNull()) { - return mirror().isInstance(HotSpotObjectConstant.asObject(obj)); - } - return false; - } - - @Override - public boolean isInstanceClass() { - return !isArray() && !isInterface(); - } - - @Override - public boolean isInterface() { - return mirror().isInterface(); - } - - @Override - public boolean isAssignableFrom(ResolvedJavaType other) { - assert other != null; - if (other instanceof HotSpotResolvedObjectType) { - HotSpotResolvedObjectType otherType = (HotSpotResolvedObjectType) other; - return mirror().isAssignableFrom(otherType.mirror()); - } - return false; - } - - @Override - public boolean isJavaLangObject() { - return javaClass.equals(Object.class); - } - - @Override - public Kind getKind() { + default Kind getKind() { return Kind.Object; } - @Override - public ResolvedJavaMethod resolveConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) { - ResolvedJavaMethod resolvedMethod = resolveMethod(method, callerType, true); - if (resolvedMethod == null || resolvedMethod.isAbstract()) { - return null; - } - return resolvedMethod; - } - - @Override - public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType, boolean includeAbstract) { - if (!includeAbstract) { - return resolveConcreteMethod(method, callerType); - } - assert !callerType.isArray(); - if (!method.isAbstract() && method.getDeclaringClass().equals(this) && method.isPublic()) { - return method; - } - if (!method.getDeclaringClass().isAssignableFrom(this)) { - return null; - } - HotSpotResolvedJavaMethod hotSpotMethod = (HotSpotResolvedJavaMethod) method; - HotSpotResolvedObjectType hotSpotCallerType = (HotSpotResolvedObjectType) callerType; - final long resolvedMetaspaceMethod = runtime().getCompilerToVM().resolveMethod(getMetaspaceKlass(), hotSpotMethod.getMetaspaceMethod(), hotSpotCallerType.getMetaspaceKlass()); - if (resolvedMetaspaceMethod == 0) { - return null; - } - return HotSpotResolvedJavaMethod.fromMetaspace(resolvedMetaspaceMethod); - } - - public ConstantPool constantPool() { - if (constantPool == null) { - final long metaspaceConstantPool = unsafe.getAddress(getMetaspaceKlass() + runtime().getConfig().instanceKlassConstantsOffset); - constantPool = new HotSpotConstantPool(metaspaceConstantPool); - } - return constantPool; - } + ConstantPool constantPool(); /** * Gets the instance size of this type. If an instance of this type cannot be fast path * allocated, then the returned value is negative (its absolute value gives the size). Must not * be called if this is an array or interface type. */ - public int instanceSize() { - assert !isArray(); - assert !isInterface(); - - HotSpotVMConfig config = runtime().getConfig(); - final int layoutHelper = unsafe.getInt(getMetaspaceKlass() + config.klassLayoutHelperOffset); - assert layoutHelper > config.klassLayoutHelperNeutralValue : "must be instance"; - - // See: Klass::layout_helper_size_in_bytes - int size = layoutHelper & ~config.klassLayoutHelperInstanceSlowPathBit; - - // See: Klass::layout_helper_needs_slow_path - boolean needsSlowPath = (layoutHelper & config.klassLayoutHelperInstanceSlowPathBit) != 0; - - return needsSlowPath ? -size : size; - } - - public synchronized HotSpotResolvedJavaMethod createMethod(long metaspaceMethod) { - HotSpotResolvedJavaMethod method = null; - if (methodCache == null) { - methodCache = new HashMap<>(8); - } else { - method = methodCache.get(metaspaceMethod); - } - if (method == null) { - method = new HotSpotResolvedJavaMethod(this, metaspaceMethod); - methodCache.put(metaspaceMethod, method); - } - return method; - } + int instanceSize(); - public int getVtableLength() { - HotSpotVMConfig config = runtime().getConfig(); - if (isInterface() || isArray()) { - /* Everything has the core vtable of java.lang.Object */ - return config.baseVtableLength; - } - int result = unsafe.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize); - assert result >= config.baseVtableLength : unsafe.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) + " " + config.vtableEntrySize; - 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 long id = offset + ((long) flags << 32); - - // (thomaswue) Must cache the fields, because the local load elimination only works if the - // objects from two field lookups are identical. - if (fieldCache == null) { - fieldCache = new HashMap<>(8); - } else { - result = fieldCache.get(id); - } - - if (result == null) { - result = new HotSpotResolvedJavaField(this, fieldName, type, offset, rawFlags); - fieldCache.put(id, result); - } else { - assert result.getName().equals(fieldName); - // assert result.getType().equals(type); - assert result.offset() == offset; - assert result.getModifiers() == flags; - } - - return result; - } + int getVtableLength(); @Override - public ResolvedJavaMethod findUniqueConcreteMethod(ResolvedJavaMethod method) { - HotSpotResolvedJavaMethod hmethod = (HotSpotResolvedJavaMethod) method; - HotSpotResolvedObjectType declaredHolder = hmethod.getDeclaringClass(); - /* - * Sometimes the receiver type in the graph hasn't stabilized to a subtype of declared - * holder, usually because of phis, so make sure that the type is related to the declared - * type before using it for lookup. Unlinked types should also be ignored because we can't - * resolve the proper method to invoke. Generally unlinked types in invokes should result in - * a deopt instead since they can't really be used if they aren't linked yet. - */ - if (!declaredHolder.isAssignableFrom(this) || this.isArray() || this.equals(declaredHolder) || !isLinked() || isInterface()) { - return hmethod.uniqueConcreteMethod(declaredHolder); - } - /* - * The holder may be a subtype of the decaredHolder so make sure to resolve the method to - * the correct method for the subtype. - */ - HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) resolveMethod(hmethod, this, true); - if (resolvedMethod == null) { - // The type isn't known to implement the method. - return null; - } - - return resolvedMethod.uniqueConcreteMethod(this); - } - - /** - * This class represents the field information for one field contained in the fields array of an - * {@code InstanceKlass}. The implementation is similar to the native {@code FieldInfo} class. - */ - private class FieldInfo { - /** - * Native pointer into the array of Java shorts. - */ - private final long metaspaceData; - - /** - * Creates a field info for the field in the fields array at index {@code index}. - * - * @param index index to the fields array - */ - public FieldInfo(int index) { - HotSpotVMConfig config = runtime().getConfig(); - // Get Klass::_fields - final long metaspaceFields = unsafe.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset); - assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code"; - metaspaceData = metaspaceFields + config.arrayU2DataOffset + config.fieldInfoFieldSlots * Short.BYTES * index; - } - - private int getAccessFlags() { - return readFieldSlot(runtime().getConfig().fieldInfoAccessFlagsOffset); - } - - private int getNameIndex() { - return readFieldSlot(runtime().getConfig().fieldInfoNameIndexOffset); - } - - private int getSignatureIndex() { - return readFieldSlot(runtime().getConfig().fieldInfoSignatureIndexOffset); - } - - public int getOffset() { - HotSpotVMConfig config = runtime().getConfig(); - final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset); - final int highPacked = readFieldSlot(config.fieldInfoHighPackedOffset); - final int offset = ((highPacked << Short.SIZE) | lowPacked) >> config.fieldInfoTagSize; - return offset; - } - - /** - * Helper method to read an entry (slot) from the field array. Currently field info is laid - * on top an array of Java shorts. - */ - private int readFieldSlot(int index) { - return unsafe.getChar(metaspaceData + Short.BYTES * index); - } - - /** - * Returns the name of this field as a {@link String}. If the field is an internal field the - * name index is pointing into the vmSymbols table. - */ - public String getName() { - final int nameIndex = getNameIndex(); - return isInternal() ? HotSpotVmSymbols.symbolAt(nameIndex) : constantPool().lookupUtf8(nameIndex); - } - - /** - * Returns the signature of this field as {@link String}. If the field is an internal field - * the signature index is pointing into the vmSymbols table. - */ - public String getSignature() { - final int signatureIndex = getSignatureIndex(); - return isInternal() ? HotSpotVmSymbols.symbolAt(signatureIndex) : constantPool().lookupUtf8(signatureIndex); - } - - public JavaType getType() { - String signature = getSignature(); - return runtime().lookupType(signature, HotSpotResolvedObjectType.this, false); - } - - private boolean isInternal() { - return (getAccessFlags() & runtime().getConfig().jvmAccFieldInternal) != 0; - } - - public boolean isStatic() { - return Modifier.isStatic(getAccessFlags()); - } - - public boolean hasGenericSignature() { - return (getAccessFlags() & runtime().getConfig().jvmAccFieldHasGenericSignature) != 0; - } - } - - private static class OffsetComparator implements Comparator { - @Override - public int compare(HotSpotResolvedJavaField o1, HotSpotResolvedJavaField o2) { - return o1.offset() - o2.offset(); - } - } - - @Override - public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) { - if (instanceFields == null) { - if (isArray() || isInterface()) { - instanceFields = new HotSpotResolvedJavaField[0]; - } else { - final int fieldCount = getFieldCount(); - ArrayList fieldsArray = new ArrayList<>(fieldCount); - - for (int i = 0; i < fieldCount; i++) { - FieldInfo field = new FieldInfo(i); - - // We are only interested in instance fields. - if (!field.isStatic()) { - HotSpotResolvedJavaField resolvedJavaField = createField(field.getName(), field.getType(), field.getOffset(), field.getAccessFlags()); - fieldsArray.add(resolvedJavaField); - } - } - - fieldsArray.sort(new OffsetComparator()); - - HotSpotResolvedJavaField[] myFields = fieldsArray.toArray(new HotSpotResolvedJavaField[0]); - - if (mirror() != Object.class) { - HotSpotResolvedJavaField[] superFields = (HotSpotResolvedJavaField[]) getSuperclass().getInstanceFields(true); - HotSpotResolvedJavaField[] fields = Arrays.copyOf(superFields, superFields.length + myFields.length); - System.arraycopy(myFields, 0, fields, superFields.length, myFields.length); - instanceFields = fields; - } else { - assert myFields.length == 0 : "java.lang.Object has fields!"; - instanceFields = myFields; - } - - } - } - if (!includeSuperclasses) { - int myFieldsStart = 0; - while (myFieldsStart < instanceFields.length && !instanceFields[myFieldsStart].getDeclaringClass().equals(this)) { - myFieldsStart++; - } - if (myFieldsStart == 0) { - return instanceFields; - } - if (myFieldsStart == instanceFields.length) { - return new HotSpotResolvedJavaField[0]; - } - return Arrays.copyOfRange(instanceFields, myFieldsStart, instanceFields.length); - } - return instanceFields; - } - - @Override - public ResolvedJavaField[] getStaticFields() { - if (isArray()) { - return new HotSpotResolvedJavaField[0]; - } else { - final int fieldCount = getFieldCount(); - ArrayList fieldsArray = new ArrayList<>(fieldCount); - - for (int i = 0; i < fieldCount; i++) { - FieldInfo field = new FieldInfo(i); - - // We are only interested in static fields. - if (field.isStatic()) { - HotSpotResolvedJavaField resolvedJavaField = createField(field.getName(), field.getType(), field.getOffset(), field.getAccessFlags()); - fieldsArray.add(resolvedJavaField); - } - } - - fieldsArray.sort(new OffsetComparator()); - return fieldsArray.toArray(new HotSpotResolvedJavaField[fieldsArray.size()]); - } - } - - /** - * Returns the actual field count of this class's internal {@code InstanceKlass::_fields} array - * by walking the array and discounting the generic signature slots at the end of the array. - * - *

- * See {@code FieldStreamBase::init_generic_signature_start_slot} - */ - private int getFieldCount() { - HotSpotVMConfig config = runtime().getConfig(); - final long metaspaceFields = unsafe.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset); - int metaspaceFieldsLength = unsafe.getInt(metaspaceFields + config.arrayU1LengthOffset); - int fieldCount = 0; - - for (int i = 0, index = 0; i < metaspaceFieldsLength; i += config.fieldInfoFieldSlots, index++) { - FieldInfo field = new FieldInfo(index); - if (field.hasGenericSignature()) { - metaspaceFieldsLength--; - } - fieldCount++; - } - return fieldCount; - } - - @Override - public Class mirror() { - return javaClass; - } - - @Override - public String getSourceFileName() { - HotSpotVMConfig config = runtime().getConfig(); - final int sourceFileNameIndex = unsafe.getChar(getMetaspaceKlass() + config.instanceKlassSourceFileNameIndexOffset); - if (sourceFileNameIndex == 0) { - return null; - } - return constantPool().lookupUtf8(sourceFileNameIndex); - } - - @Override - public T getAnnotation(Class annotationClass) { - return mirror().getAnnotation(annotationClass); - } + ResolvedJavaMethod findUniqueConcreteMethod(ResolvedJavaMethod method); /** * Performs a fast-path check that this type is resolved in the context of a given accessing @@ -745,135 +75,20 @@ * {@linkplain HotSpotGraalRuntime#lookupType(String, HotSpotResolvedObjectType, boolean) * re-resolving} the type. */ - public boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass) { - assert accessingClass != null; - ResolvedJavaType elementType = getElementalType(); - if (elementType.isPrimitive()) { - // Primitive type resolution is context free. - return true; - } - if (elementType.getName().startsWith("Ljava/")) { - // Classes in a java.* package can only be defined by the - // boot class loader. This is enforced by ClassLoader.preDefineClass() - assert mirror().getClassLoader() == null; - return true; - } - ClassLoader thisCl = mirror().getClassLoader(); - ClassLoader accessingClassCl = ((HotSpotResolvedObjectType) accessingClass).mirror().getClassLoader(); - return thisCl == accessingClassCl; - } - - @Override - public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { - if (isDefinitelyResolvedWithRespectTo(requireNonNull(accessingClass))) { - return this; - } - HotSpotResolvedObjectType accessingType = (HotSpotResolvedObjectType) accessingClass; - return (ResolvedJavaType) runtime().lookupType(getName(), accessingType, true); - } + boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass); /** * Gets the metaspace Klass boxed in a {@link JavaConstant}. */ - public JavaConstant klass() { - return HotSpotMetaspaceConstant.forMetaspaceObject(runtime().getTarget().wordKind, getMetaspaceKlass(), this, false); - } - - public boolean isPrimaryType() { - return runtime().getConfig().secondarySuperCacheOffset != superCheckOffset(); - } - - public int superCheckOffset() { - HotSpotVMConfig config = runtime().getConfig(); - return unsafe.getInt(getMetaspaceKlass() + config.superCheckOffsetOffset); - } - - public long prototypeMarkWord() { - HotSpotVMConfig config = runtime().getConfig(); - if (isArray()) { - return config.arrayPrototypeMarkWord(); - } else { - return unsafeReadWord(getMetaspaceKlass() + config.prototypeMarkWordOffset); - } - } + JavaConstant klass(); - @Override - public ResolvedJavaField findInstanceFieldWithOffset(long offset) { - ResolvedJavaField[] declaredFields = getInstanceFields(true); - for (ResolvedJavaField field : declaredFields) { - if (((HotSpotResolvedJavaField) field).offset() == offset) { - return field; - } - } - return null; - } + boolean isPrimaryType(); - @Override - public URL getClassFilePath() { - Class cls = mirror(); - return cls.getResource(MetaUtil.getSimpleName(cls, true).replace('.', '$') + ".class"); - } - - @Override - public boolean isLocal() { - return mirror().isLocalClass(); - } - - @Override - public boolean isMember() { - return mirror().isMemberClass(); - } + int superCheckOffset(); - @Override - public HotSpotResolvedObjectType getEnclosingType() { - final Class encl = mirror().getEnclosingClass(); - return encl == null ? null : fromObjectClass(encl); - } - - @Override - public ResolvedJavaMethod[] getDeclaredConstructors() { - Constructor[] constructors = mirror().getDeclaredConstructors(); - ResolvedJavaMethod[] result = new ResolvedJavaMethod[constructors.length]; - for (int i = 0; i < constructors.length; i++) { - result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaConstructor(constructors[i]); - assert result[i].isConstructor(); - } - return result; - } + long prototypeMarkWord(); - @Override - public ResolvedJavaMethod[] getDeclaredMethods() { - Method[] methods = mirror().getDeclaredMethods(); - ResolvedJavaMethod[] result = new ResolvedJavaMethod[methods.length]; - for (int i = 0; i < methods.length; i++) { - result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaMethod(methods[i]); - assert !result[i].isConstructor(); - } - return result; - } + HotSpotResolvedObjectType getEnclosingType(); - public ResolvedJavaMethod getClassInitializer() { - final long metaspaceMethod = runtime().getCompilerToVM().getClassInitializer(getMetaspaceKlass()); - if (metaspaceMethod != 0L) { - return createMethod(metaspaceMethod); - } - return null; - } - - @Override - public JavaConstant newArray(int length) { - return HotSpotObjectConstant.forObject(Array.newInstance(mirror(), length)); - } - - @Override - public String toString() { - return "HotSpotType<" + getName() + ", resolved>"; - } - - private static final HotSpotResolvedObjectType trustedInterfaceType = fromObjectClass(TrustedInterface.class); - - @Override - public boolean isTrustedInterfaceType() { - return trustedInterfaceType.isAssignableFrom(this); - } + ResolvedJavaMethod getClassInitializer(); } diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java Mon Nov 03 10:31:39 2014 -0800 @@ -0,0 +1,879 @@ +/* + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.meta; + +import static com.oracle.graal.compiler.common.UnsafeAccess.*; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static java.util.Objects.*; + +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.net.*; +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.hotspot.*; + +/** + * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes. + */ +public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType { + + private static final long serialVersionUID = 3481514353553840471L; + + /** + * The Java class this type represents. + */ + private final Class javaClass; + + private HashMap fieldCache; + private HashMap methodCache; + private HotSpotResolvedJavaField[] instanceFields; + private HotSpotResolvedObjectTypeImpl[] interfaces; + private ConstantPool constantPool; + private HotSpotResolvedObjectTypeImpl arrayOfType; + + /** + * Gets the Graal mirror for a {@link Class} object. + * + * @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass} + */ + public static HotSpotResolvedObjectTypeImpl fromObjectClass(Class javaClass) { + return (HotSpotResolvedObjectTypeImpl) runtime().fromClass(javaClass); + } + + /** + * Gets the Graal mirror from a HotSpot metaspace Klass native object. + * + * @param metaspaceKlass a metaspace Klass object boxed in a {@link JavaConstant} + * @return the {@link HotSpotResolvedObjectTypeImpl} corresponding to {@code klassConstant} + */ + public static HotSpotResolvedObjectTypeImpl fromMetaspaceKlass(JavaConstant metaspaceKlass) { + assert metaspaceKlass.getKind() == Kind.Long; + return fromMetaspaceKlass(metaspaceKlass.asLong()); + } + + /** + * Gets the Graal mirror from a HotSpot metaspace Klass native object. + * + * @param metaspaceKlass a metaspace Klass object + * @return the {@link ResolvedJavaType} corresponding to {@code metaspaceKlass} + */ + public static HotSpotResolvedObjectTypeImpl fromMetaspaceKlass(long metaspaceKlass) { + assert metaspaceKlass != 0; + Class javaClass = runtime().getCompilerToVM().getJavaMirror(metaspaceKlass); + assert javaClass != null; + return fromObjectClass(javaClass); + } + + /** + * Creates the Graal mirror for a {@link Class} object. + * + *

+ * NOTE: Creating an instance of this class does not install the mirror for the + * {@link Class} type. Use {@link #fromObjectClass(Class)}, + * {@link #fromMetaspaceKlass(JavaConstant)} or {@link #fromMetaspaceKlass(long)} instead. + *

+ * + * @param javaClass the Class to create the mirror for + */ + public HotSpotResolvedObjectTypeImpl(Class javaClass) { + super(getSignatureName(javaClass)); + this.javaClass = javaClass; + assert getName().charAt(0) != '[' || isArray() : getName(); + } + + /** + * Returns the name of this type as it would appear in a signature. + */ + private static String getSignatureName(Class javaClass) { + if (javaClass.isArray()) { + return javaClass.getName().replace('.', '/'); + } + return "L" + javaClass.getName().replace('.', '/') + ";"; + } + + /** + * Gets the metaspace Klass for this type. + */ + public long getMetaspaceKlass() { + return HotSpotGraalRuntime.unsafeReadWord(javaClass, runtime().getConfig().klassOffset); + } + + @Override + public int getModifiers() { + return mirror().getModifiers(); + } + + public int getAccessFlags() { + HotSpotVMConfig config = runtime().getConfig(); + return unsafe.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset); + } + + @Override + public HotSpotResolvedObjectType getArrayClass() { + if (arrayOfType == null) { + arrayOfType = fromObjectClass(Array.newInstance(mirror(), 0).getClass()); + } + return arrayOfType; + } + + @Override + public ResolvedJavaType getComponentType() { + Class javaComponentType = mirror().getComponentType(); + return javaComponentType == null ? null : fromClass(javaComponentType); + } + + @Override + public HotSpotResolvedObjectType findUniqueConcreteSubtype() { + HotSpotVMConfig config = runtime().getConfig(); + if (isArray()) { + return getElementalType().isFinal() ? this : null; + } else if (isInterface()) { + HotSpotResolvedObjectTypeImpl type = getSingleImplementor(); + if (type == null) { + return null; + } + + /* + * If the implementor field contains itself that indicates that the interface has more + * than one implementors (see: InstanceKlass::add_implementor). The isInterface check + * takes care of this fact since this class is an interface. + */ + if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) { + return null; + } + return type; + } else { + HotSpotResolvedObjectTypeImpl type = this; + while (type.isAbstract()) { + long subklass = type.getSubklass(); + if (subklass == 0 || unsafeReadWord(subklass + config.nextSiblingOffset) != 0) { + return null; + } + type = fromMetaspaceKlass(subklass); + } + if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) { + return null; + } + return type; + } + } + + /** + * Returns if type {@code type} is a leaf class. This is the case if the + * {@code Klass::_subklass} field of the underlying class is zero. + * + * @return true if the type is a leaf class + */ + private boolean isLeafClass() { + return getSubklass() == 0; + } + + /** + * Returns the {@code Klass::_subklass} field of the underlying metaspace klass for the given + * type {@code type}. + * + * @return value of the subklass field as metaspace klass pointer + */ + private long getSubklass() { + return unsafeReadWord(getMetaspaceKlass() + runtime().getConfig().subklassOffset); + } + + @Override + public HotSpotResolvedObjectTypeImpl getSuperclass() { + Class javaSuperclass = mirror().getSuperclass(); + return javaSuperclass == null ? null : (HotSpotResolvedObjectTypeImpl) fromObjectClass(javaSuperclass); + } + + @Override + public HotSpotResolvedObjectTypeImpl[] getInterfaces() { + if (interfaces == null) { + Class[] javaInterfaces = mirror().getInterfaces(); + HotSpotResolvedObjectTypeImpl[] result = new HotSpotResolvedObjectTypeImpl[javaInterfaces.length]; + for (int i = 0; i < javaInterfaces.length; i++) { + result[i] = fromObjectClass(javaInterfaces[i]); + } + interfaces = result; + } + return interfaces; + } + + @Override + public HotSpotResolvedObjectTypeImpl getSingleImplementor() { + if (!isInterface()) { + throw new GraalInternalError("Cannot call getImplementor() on a non-interface type: " + this); + } + final long implementorMetaspaceKlass = runtime().getCompilerToVM().getKlassImplementor(getMetaspaceKlass()); + + // No implementor. + if (implementorMetaspaceKlass == 0) { + return null; + } + + return fromMetaspaceKlass(implementorMetaspaceKlass); + } + + public HotSpotResolvedObjectTypeImpl getSupertype() { + if (isArray()) { + ResolvedJavaType componentType = getComponentType(); + if (mirror() == Object[].class || componentType.isPrimitive()) { + return fromObjectClass(Object.class); + } + return (HotSpotResolvedObjectTypeImpl) ((HotSpotResolvedObjectTypeImpl) componentType).getSupertype().getArrayClass(); + } + if (isInterface()) { + return fromObjectClass(Object.class); + } + return getSuperclass(); + } + + @Override + public HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType) { + if (otherType.isPrimitive()) { + return null; + } else { + HotSpotResolvedObjectTypeImpl t1 = this; + HotSpotResolvedObjectTypeImpl t2 = (HotSpotResolvedObjectTypeImpl) otherType; + while (true) { + if (t1.isAssignableFrom(t2)) { + return t1; + } + if (t2.isAssignableFrom(t1)) { + return t2; + } + t1 = t1.getSupertype(); + t2 = t2.getSupertype(); + } + } + } + + @Override + public HotSpotResolvedObjectType asExactType() { + if (isArray()) { + return getComponentType().asExactType() != null ? this : null; + } + return isFinal() ? this : null; + } + + @Override + public JavaConstant getEncoding(Representation r) { + switch (r) { + case JavaClass: + return HotSpotObjectConstant.forObject(mirror()); + case ObjectHub: + return klass(); + default: + throw GraalInternalError.shouldNotReachHere("unexpected representation " + r); + } + } + + @Override + public boolean hasFinalizableSubclass() { + assert !isArray(); + return runtime().getCompilerToVM().hasFinalizableSubclass(getMetaspaceKlass()); + } + + @Override + public boolean hasFinalizer() { + HotSpotVMConfig config = runtime().getConfig(); + return (getAccessFlags() & config.klassHasFinalizerFlag) != 0; + } + + @Override + public boolean isPrimitive() { + return false; + } + + @Override + public boolean isArray() { + return mirror().isArray(); + } + + @Override + public boolean isInitialized() { + return isArray() ? true : getInitState() == runtime().getConfig().instanceKlassStateFullyInitialized; + } + + @Override + public boolean isLinked() { + return isArray() ? true : getInitState() >= runtime().getConfig().instanceKlassStateLinked; + } + + /** + * Returns the value of the state field {@code InstanceKlass::_init_state} of the metaspace + * klass. + * + * @return state field value of this type + */ + private int getInitState() { + assert !isArray() : "_init_state only exists in InstanceKlass"; + return unsafe.getByte(getMetaspaceKlass() + runtime().getConfig().instanceKlassInitStateOffset) & 0xFF; + } + + @Override + public void initialize() { + if (!isInitialized()) { + unsafe.ensureClassInitialized(mirror()); + assert isInitialized(); + } + } + + @Override + public boolean isInstance(JavaConstant obj) { + if (obj.getKind() == Kind.Object && !obj.isNull()) { + return mirror().isInstance(HotSpotObjectConstant.asObject(obj)); + } + return false; + } + + @Override + public boolean isInstanceClass() { + return !isArray() && !isInterface(); + } + + @Override + public boolean isInterface() { + return mirror().isInterface(); + } + + @Override + public boolean isAssignableFrom(ResolvedJavaType other) { + assert other != null; + if (other instanceof HotSpotResolvedObjectTypeImpl) { + HotSpotResolvedObjectTypeImpl otherType = (HotSpotResolvedObjectTypeImpl) other; + return mirror().isAssignableFrom(otherType.mirror()); + } + return false; + } + + @Override + public boolean isJavaLangObject() { + return javaClass.equals(Object.class); + } + + @Override + public Kind getKind() { + return Kind.Object; + } + + @Override + public ResolvedJavaMethod resolveConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) { + ResolvedJavaMethod resolvedMethod = resolveMethod(method, callerType, true); + if (resolvedMethod == null || resolvedMethod.isAbstract()) { + return null; + } + return resolvedMethod; + } + + @Override + public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType, boolean includeAbstract) { + if (!includeAbstract) { + return resolveConcreteMethod(method, callerType); + } + assert !callerType.isArray(); + if (!method.isAbstract() && method.getDeclaringClass().equals(this) && method.isPublic()) { + return method; + } + if (!method.getDeclaringClass().isAssignableFrom(this)) { + return null; + } + HotSpotResolvedJavaMethodImpl hotSpotMethod = (HotSpotResolvedJavaMethodImpl) method; + HotSpotResolvedObjectTypeImpl hotSpotCallerType = (HotSpotResolvedObjectTypeImpl) callerType; + final long resolvedMetaspaceMethod = runtime().getCompilerToVM().resolveMethod(getMetaspaceKlass(), hotSpotMethod.getMetaspaceMethod(), hotSpotCallerType.getMetaspaceKlass()); + if (resolvedMetaspaceMethod == 0) { + return null; + } + return HotSpotResolvedJavaMethodImpl.fromMetaspace(resolvedMetaspaceMethod); + } + + public ConstantPool constantPool() { + if (constantPool == null) { + final long metaspaceConstantPool = unsafe.getAddress(getMetaspaceKlass() + runtime().getConfig().instanceKlassConstantsOffset); + constantPool = new HotSpotConstantPool(metaspaceConstantPool); + } + return constantPool; + } + + /** + * Gets the instance size of this type. If an instance of this type cannot be fast path + * allocated, then the returned value is negative (its absolute value gives the size). Must not + * be called if this is an array or interface type. + */ + public int instanceSize() { + assert !isArray(); + assert !isInterface(); + + HotSpotVMConfig config = runtime().getConfig(); + final int layoutHelper = unsafe.getInt(getMetaspaceKlass() + config.klassLayoutHelperOffset); + assert layoutHelper > config.klassLayoutHelperNeutralValue : "must be instance"; + + // See: Klass::layout_helper_size_in_bytes + int size = layoutHelper & ~config.klassLayoutHelperInstanceSlowPathBit; + + // See: Klass::layout_helper_needs_slow_path + boolean needsSlowPath = (layoutHelper & config.klassLayoutHelperInstanceSlowPathBit) != 0; + + return needsSlowPath ? -size : size; + } + + public synchronized HotSpotResolvedJavaMethod createMethod(long metaspaceMethod) { + HotSpotResolvedJavaMethod method = null; + if (methodCache == null) { + methodCache = new HashMap<>(8); + } else { + method = methodCache.get(metaspaceMethod); + } + if (method == null) { + method = new HotSpotResolvedJavaMethodImpl(this, metaspaceMethod); + methodCache.put(metaspaceMethod, method); + } + return method; + } + + public int getVtableLength() { + HotSpotVMConfig config = runtime().getConfig(); + if (isInterface() || isArray()) { + /* Everything has the core vtable of java.lang.Object */ + return config.baseVtableLength; + } + int result = unsafe.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize); + assert result >= config.baseVtableLength : unsafe.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) + " " + config.vtableEntrySize; + 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 long id = offset + ((long) flags << 32); + + // (thomaswue) Must cache the fields, because the local load elimination only works if the + // objects from two field lookups are identical. + if (fieldCache == null) { + fieldCache = new HashMap<>(8); + } else { + result = fieldCache.get(id); + } + + if (result == null) { + result = new HotSpotResolvedJavaField(this, fieldName, type, offset, rawFlags); + fieldCache.put(id, result); + } else { + assert result.getName().equals(fieldName); + // assert result.getType().equals(type); + assert result.offset() == offset; + assert result.getModifiers() == flags; + } + + return result; + } + + @Override + public ResolvedJavaMethod findUniqueConcreteMethod(ResolvedJavaMethod method) { + HotSpotResolvedJavaMethod hmethod = (HotSpotResolvedJavaMethod) method; + HotSpotResolvedObjectTypeImpl declaredHolder = hmethod.getDeclaringClass(); + /* + * Sometimes the receiver type in the graph hasn't stabilized to a subtype of declared + * holder, usually because of phis, so make sure that the type is related to the declared + * type before using it for lookup. Unlinked types should also be ignored because we can't + * resolve the proper method to invoke. Generally unlinked types in invokes should result in + * a deopt instead since they can't really be used if they aren't linked yet. + */ + if (!declaredHolder.isAssignableFrom(this) || this.isArray() || this.equals(declaredHolder) || !isLinked() || isInterface()) { + return hmethod.uniqueConcreteMethod(declaredHolder); + } + /* + * The holder may be a subtype of the decaredHolder so make sure to resolve the method to + * the correct method for the subtype. + */ + HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) resolveMethod(hmethod, this, true); + if (resolvedMethod == null) { + // The type isn't known to implement the method. + return null; + } + + return resolvedMethod.uniqueConcreteMethod(this); + } + + /** + * This class represents the field information for one field contained in the fields array of an + * {@code InstanceKlass}. The implementation is similar to the native {@code FieldInfo} class. + */ + private class FieldInfo { + /** + * Native pointer into the array of Java shorts. + */ + private final long metaspaceData; + + /** + * Creates a field info for the field in the fields array at index {@code index}. + * + * @param index index to the fields array + */ + public FieldInfo(int index) { + HotSpotVMConfig config = runtime().getConfig(); + // Get Klass::_fields + final long metaspaceFields = unsafe.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset); + assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code"; + metaspaceData = metaspaceFields + config.arrayU2DataOffset + config.fieldInfoFieldSlots * Short.BYTES * index; + } + + private int getAccessFlags() { + return readFieldSlot(runtime().getConfig().fieldInfoAccessFlagsOffset); + } + + private int getNameIndex() { + return readFieldSlot(runtime().getConfig().fieldInfoNameIndexOffset); + } + + private int getSignatureIndex() { + return readFieldSlot(runtime().getConfig().fieldInfoSignatureIndexOffset); + } + + public int getOffset() { + HotSpotVMConfig config = runtime().getConfig(); + final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset); + final int highPacked = readFieldSlot(config.fieldInfoHighPackedOffset); + final int offset = ((highPacked << Short.SIZE) | lowPacked) >> config.fieldInfoTagSize; + return offset; + } + + /** + * Helper method to read an entry (slot) from the field array. Currently field info is laid + * on top an array of Java shorts. + */ + private int readFieldSlot(int index) { + return unsafe.getChar(metaspaceData + Short.BYTES * index); + } + + /** + * Returns the name of this field as a {@link String}. If the field is an internal field the + * name index is pointing into the vmSymbols table. + */ + public String getName() { + final int nameIndex = getNameIndex(); + return isInternal() ? HotSpotVmSymbols.symbolAt(nameIndex) : constantPool().lookupUtf8(nameIndex); + } + + /** + * Returns the signature of this field as {@link String}. If the field is an internal field + * the signature index is pointing into the vmSymbols table. + */ + public String getSignature() { + final int signatureIndex = getSignatureIndex(); + return isInternal() ? HotSpotVmSymbols.symbolAt(signatureIndex) : constantPool().lookupUtf8(signatureIndex); + } + + public JavaType getType() { + String signature = getSignature(); + return runtime().lookupType(signature, HotSpotResolvedObjectTypeImpl.this, false); + } + + private boolean isInternal() { + return (getAccessFlags() & runtime().getConfig().jvmAccFieldInternal) != 0; + } + + public boolean isStatic() { + return Modifier.isStatic(getAccessFlags()); + } + + public boolean hasGenericSignature() { + return (getAccessFlags() & runtime().getConfig().jvmAccFieldHasGenericSignature) != 0; + } + } + + private static class OffsetComparator implements java.util.Comparator { + @Override + public int compare(HotSpotResolvedJavaField o1, HotSpotResolvedJavaField o2) { + return o1.offset() - o2.offset(); + } + } + + @Override + public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) { + if (instanceFields == null) { + if (isArray() || isInterface()) { + instanceFields = new HotSpotResolvedJavaField[0]; + } else { + final int fieldCount = getFieldCount(); + ArrayList fieldsArray = new ArrayList<>(fieldCount); + + for (int i = 0; i < fieldCount; i++) { + FieldInfo field = new FieldInfo(i); + + // We are only interested in instance fields. + if (!field.isStatic()) { + HotSpotResolvedJavaField resolvedJavaField = createField(field.getName(), field.getType(), field.getOffset(), field.getAccessFlags()); + fieldsArray.add(resolvedJavaField); + } + } + + fieldsArray.sort(new OffsetComparator()); + + HotSpotResolvedJavaField[] myFields = fieldsArray.toArray(new HotSpotResolvedJavaField[0]); + + if (mirror() != Object.class) { + HotSpotResolvedJavaField[] superFields = (HotSpotResolvedJavaField[]) getSuperclass().getInstanceFields(true); + HotSpotResolvedJavaField[] fields = Arrays.copyOf(superFields, superFields.length + myFields.length); + System.arraycopy(myFields, 0, fields, superFields.length, myFields.length); + instanceFields = fields; + } else { + assert myFields.length == 0 : "java.lang.Object has fields!"; + instanceFields = myFields; + } + + } + } + if (!includeSuperclasses) { + int myFieldsStart = 0; + while (myFieldsStart < instanceFields.length && !instanceFields[myFieldsStart].getDeclaringClass().equals(this)) { + myFieldsStart++; + } + if (myFieldsStart == 0) { + return instanceFields; + } + if (myFieldsStart == instanceFields.length) { + return new HotSpotResolvedJavaField[0]; + } + return Arrays.copyOfRange(instanceFields, myFieldsStart, instanceFields.length); + } + return instanceFields; + } + + @Override + public ResolvedJavaField[] getStaticFields() { + if (isArray()) { + return new HotSpotResolvedJavaField[0]; + } else { + final int fieldCount = getFieldCount(); + ArrayList fieldsArray = new ArrayList<>(fieldCount); + + for (int i = 0; i < fieldCount; i++) { + FieldInfo field = new FieldInfo(i); + + // We are only interested in static fields. + if (field.isStatic()) { + HotSpotResolvedJavaField resolvedJavaField = createField(field.getName(), field.getType(), field.getOffset(), field.getAccessFlags()); + fieldsArray.add(resolvedJavaField); + } + } + + fieldsArray.sort(new OffsetComparator()); + return fieldsArray.toArray(new HotSpotResolvedJavaField[fieldsArray.size()]); + } + } + + /** + * Returns the actual field count of this class's internal {@code InstanceKlass::_fields} array + * by walking the array and discounting the generic signature slots at the end of the array. + * + *

+ * See {@code FieldStreamBase::init_generic_signature_start_slot} + */ + private int getFieldCount() { + HotSpotVMConfig config = runtime().getConfig(); + final long metaspaceFields = unsafe.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset); + int metaspaceFieldsLength = unsafe.getInt(metaspaceFields + config.arrayU1LengthOffset); + int fieldCount = 0; + + for (int i = 0, index = 0; i < metaspaceFieldsLength; i += config.fieldInfoFieldSlots, index++) { + FieldInfo field = new FieldInfo(index); + if (field.hasGenericSignature()) { + metaspaceFieldsLength--; + } + fieldCount++; + } + return fieldCount; + } + + @Override + public Class mirror() { + return javaClass; + } + + @Override + public String getSourceFileName() { + HotSpotVMConfig config = runtime().getConfig(); + final int sourceFileNameIndex = unsafe.getChar(getMetaspaceKlass() + config.instanceKlassSourceFileNameIndexOffset); + if (sourceFileNameIndex == 0) { + return null; + } + return constantPool().lookupUtf8(sourceFileNameIndex); + } + + @Override + public T getAnnotation(Class annotationClass) { + return mirror().getAnnotation(annotationClass); + } + + /** + * Performs a fast-path check that this type is resolved in the context of a given accessing + * class. A negative result does not mean this type is not resolved with respect to + * {@code accessingClass}. That can only be determined by + * {@linkplain HotSpotGraalRuntime#lookupType(String, HotSpotResolvedObjectType, boolean) + * re-resolving} the type. + */ + public boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass) { + assert accessingClass != null; + ResolvedJavaType elementType = getElementalType(); + if (elementType.isPrimitive()) { + // Primitive type resolution is context free. + return true; + } + if (elementType.getName().startsWith("Ljava/")) { + // Classes in a java.* package can only be defined by the + // boot class loader. This is enforced by ClassLoader.preDefineClass() + assert mirror().getClassLoader() == null; + return true; + } + ClassLoader thisCl = mirror().getClassLoader(); + ClassLoader accessingClassCl = ((HotSpotResolvedObjectTypeImpl) accessingClass).mirror().getClassLoader(); + return thisCl == accessingClassCl; + } + + @Override + public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { + if (isDefinitelyResolvedWithRespectTo(requireNonNull(accessingClass))) { + return this; + } + HotSpotResolvedObjectTypeImpl accessingType = (HotSpotResolvedObjectTypeImpl) accessingClass; + return (ResolvedJavaType) runtime().lookupType(getName(), accessingType, true); + } + + /** + * Gets the metaspace Klass boxed in a {@link JavaConstant}. + */ + public JavaConstant klass() { + return HotSpotMetaspaceConstant.forMetaspaceObject(runtime().getTarget().wordKind, getMetaspaceKlass(), this, false); + } + + public boolean isPrimaryType() { + return runtime().getConfig().secondarySuperCacheOffset != superCheckOffset(); + } + + public int superCheckOffset() { + HotSpotVMConfig config = runtime().getConfig(); + return unsafe.getInt(getMetaspaceKlass() + config.superCheckOffsetOffset); + } + + public long prototypeMarkWord() { + HotSpotVMConfig config = runtime().getConfig(); + if (isArray()) { + return config.arrayPrototypeMarkWord(); + } else { + return unsafeReadWord(getMetaspaceKlass() + config.prototypeMarkWordOffset); + } + } + + @Override + public ResolvedJavaField findInstanceFieldWithOffset(long offset) { + ResolvedJavaField[] declaredFields = getInstanceFields(true); + for (ResolvedJavaField field : declaredFields) { + if (((HotSpotResolvedJavaField) field).offset() == offset) { + return field; + } + } + return null; + } + + @Override + public URL getClassFilePath() { + Class cls = mirror(); + return cls.getResource(MetaUtil.getSimpleName(cls, true).replace('.', '$') + ".class"); + } + + @Override + public boolean isLocal() { + return mirror().isLocalClass(); + } + + @Override + public boolean isMember() { + return mirror().isMemberClass(); + } + + @Override + public HotSpotResolvedObjectTypeImpl getEnclosingType() { + final Class encl = mirror().getEnclosingClass(); + return encl == null ? null : fromObjectClass(encl); + } + + @Override + public ResolvedJavaMethod[] getDeclaredConstructors() { + Constructor[] constructors = mirror().getDeclaredConstructors(); + ResolvedJavaMethod[] result = new ResolvedJavaMethod[constructors.length]; + for (int i = 0; i < constructors.length; i++) { + result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaConstructor(constructors[i]); + assert result[i].isConstructor(); + } + return result; + } + + @Override + public ResolvedJavaMethod[] getDeclaredMethods() { + Method[] methods = mirror().getDeclaredMethods(); + ResolvedJavaMethod[] result = new ResolvedJavaMethod[methods.length]; + for (int i = 0; i < methods.length; i++) { + result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaMethod(methods[i]); + assert !result[i].isConstructor(); + } + return result; + } + + public ResolvedJavaMethod getClassInitializer() { + final long metaspaceMethod = runtime().getCompilerToVM().getClassInitializer(getMetaspaceKlass()); + if (metaspaceMethod != 0L) { + return createMethod(metaspaceMethod); + } + return null; + } + + @Override + public JavaConstant newArray(int length) { + return HotSpotObjectConstant.forObject(Array.newInstance(mirror(), length)); + } + + @Override + public String toString() { + return "HotSpotType<" + getName() + ", resolved>"; + } + + private static final HotSpotResolvedObjectTypeImpl trustedInterfaceType = fromObjectClass(TrustedInterface.class); + + @Override + public boolean isTrustedInterfaceType() { + return trustedInterfaceType.isAssignableFrom(this); + } +} diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Mon Nov 03 10:31:39 2014 -0800 @@ -42,7 +42,7 @@ /** * Gets the Graal mirror for a {@link Kind}. * - * @return the {@link HotSpotResolvedObjectType} corresponding to {@code kind} + * @return the {@link HotSpotResolvedObjectTypeImpl} corresponding to {@code kind} */ public static ResolvedJavaType fromKind(Kind kind) { Class javaClass = kind.toJavaClass(); @@ -71,12 +71,12 @@ } @Override - public HotSpotResolvedObjectType getArrayClass() { + public HotSpotResolvedObjectTypeImpl getArrayClass() { if (kind == Kind.Void) { return null; } Class javaArrayMirror = Array.newInstance(mirror(), 0).getClass(); - return HotSpotResolvedObjectType.fromObjectClass(javaArrayMirror); + return HotSpotResolvedObjectTypeImpl.fromObjectClass(javaArrayMirror); } public ResolvedJavaType getElementalType() { diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java Mon Nov 03 10:31:39 2014 -0800 @@ -133,8 +133,8 @@ return false; } - if (type instanceof HotSpotResolvedObjectType) { - return ((HotSpotResolvedObjectType) type).isDefinitelyResolvedWithRespectTo(accessingClass); + if (type instanceof HotSpotResolvedObjectTypeImpl) { + return ((HotSpotResolvedObjectTypeImpl) type).isDefinitelyResolvedWithRespectTo(accessingClass); } return true; } @@ -160,7 +160,7 @@ ResolvedJavaType type = parameterTypes[index]; if (!checkValidCache(type, accessingClass)) { - type = (ResolvedJavaType) runtime().lookupType(parameters.get(index), (HotSpotResolvedObjectType) accessingClass, true); + type = (ResolvedJavaType) runtime().lookupType(parameters.get(index), (HotSpotResolvedObjectTypeImpl) accessingClass, true); parameterTypes[index] = type; } return type; @@ -185,7 +185,7 @@ return getUnresolvedOrPrimitiveType(returnType); } if (!checkValidCache(returnTypeCache, accessingClass)) { - returnTypeCache = (ResolvedJavaType) runtime().lookupType(returnType, (HotSpotResolvedObjectType) accessingClass, true); + returnTypeCache = (ResolvedJavaType) runtime().lookupType(returnType, (HotSpotResolvedObjectTypeImpl) accessingClass, true); } return returnTypeCache; } diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java Mon Nov 03 10:31:39 2014 -0800 @@ -85,6 +85,6 @@ @Override public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { - return (ResolvedJavaType) runtime().lookupType(getName(), (HotSpotResolvedObjectType) accessingClass, true); + return (ResolvedJavaType) runtime().lookupType(getName(), (HotSpotResolvedObjectTypeImpl) accessingClass, true); } } diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Mon Nov 03 10:31:39 2014 -0800 @@ -22,8 +22,8 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.spi.*; -import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; @@ -65,9 +65,8 @@ @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forJavaClass, ValueNode forObject) { if (forJavaClass.isConstant()) { - Class c = (Class) HotSpotObjectConstant.asObject(forJavaClass.asJavaConstant()); - if (c != null && !c.isPrimitive()) { - HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromObjectClass(c); + ResolvedJavaType type = tool.getConstantReflection().asJavaType(forJavaClass.asJavaConstant()); + if (type != null && !type.isPrimitive()) { return CheckCastNode.create(type, forObject, null, false); } } diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java Mon Nov 03 10:31:39 2014 -0800 @@ -22,9 +22,9 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; -import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; @@ -61,16 +61,16 @@ ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { ValueNode object = getObject(); - Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asJavaConstant()); - if (c != null) { - if (c.isPrimitive()) { + ConstantReflectionProvider constantReflection = tool.getConstantReflection(); + ResolvedJavaType type = constantReflection.asJavaType(javaClass.asJavaConstant()); + if (type != null) { + if (type.isPrimitive()) { return ConstantNode.forBoolean(false); } if (object.isConstant()) { - Object o = HotSpotObjectConstant.asObject(object.asJavaConstant()); - return ConstantNode.forBoolean(o != null && c.isInstance(o)); + JavaConstant c = object.asJavaConstant(); + return ConstantNode.forBoolean(c.isNonNull() && type.isInstance(c)); } - HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromObjectClass(c); InstanceOfNode instanceOf = InstanceOfNode.create(type, object, null); return ConditionalNode.create(instanceOf, ConstantNode.forBoolean(true), ConstantNode.forBoolean(false)); } diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java Mon Nov 03 10:31:39 2014 -0800 @@ -58,7 +58,7 @@ @Override public boolean inferStamp() { if (stamp() == defaultStamp && hub.isConstant()) { - updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectType.fromMetaspaceKlass(hub.asJavaConstant()))); + updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(hub.asJavaConstant()))); return true; } return false; diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Mon Nov 03 10:31:39 2014 -0800 @@ -56,7 +56,7 @@ @Override public boolean inferStamp() { if (stamp() == defaultStamp && hub.isConstant()) { - updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectType.fromMetaspaceKlass(hub.asJavaConstant()))); + updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(hub.asJavaConstant()))); return true; } return false; diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Mon Nov 03 10:31:39 2014 -0800 @@ -60,7 +60,7 @@ @Override public boolean inferStamp() { if (stamp() == defaultStamp && hub.isConstant()) { - updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectType.fromMetaspaceKlass(hub.asJavaConstant()))); + updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(hub.asJavaConstant()))); return true; } return false; diff -r ab489bac3bc8 -r e04712c8928a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Mon Nov 03 10:17:24 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Mon Nov 03 10:31:39 2014 -0800 @@ -25,6 +25,7 @@ import static com.oracle.graal.compiler.GraalCompiler.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.meta.ResolvedJavaType.Representation; import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -100,7 +101,7 @@ if (!method.ignoredBySecurityStackWalk()) { // We have reached the desired frame; return the holder class. HotSpotResolvedObjectType callerClass = method.getDeclaringClass(); - return ConstantNode.forConstant(HotSpotObjectConstant.forObject(callerClass.mirror()), metaAccess); + return ConstantNode.forConstant(callerClass.getEncoding(Representation.JavaClass), metaAccess); } break; } diff -r ab489bac3bc8 -r e04712c8928a src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp --- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp Mon Nov 03 10:17:24 2014 -0800 +++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp Mon Nov 03 10:31:39 2014 -0800 @@ -92,7 +92,7 @@ #ifdef ASSERT Method* method = NULL; // we need to check, this might also be an unresolved method - if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) { + if (hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass())) { method = getMethodFromHotSpotMethod(hotspot_method); } #endif diff -r ab489bac3bc8 -r e04712c8928a src/cpu/x86/vm/graalCodeInstaller_x86.cpp --- a/src/cpu/x86/vm/graalCodeInstaller_x86.cpp Mon Nov 03 10:17:24 2014 -0800 +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.cpp Mon Nov 03 10:31:39 2014 -0800 @@ -132,7 +132,7 @@ #ifdef ASSERT Method* method = NULL; // we need to check, this might also be an unresolved method - if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) { + if (hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass())) { method = getMethodFromHotSpotMethod(hotspot_method); } #endif diff -r ab489bac3bc8 -r e04712c8928a src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Mon Nov 03 10:17:24 2014 -0800 +++ b/src/share/vm/classfile/systemDictionary.hpp Mon Nov 03 10:31:39 2014 -0800 @@ -197,8 +197,8 @@ GRAAL_ONLY(do_klass(HotSpotReferenceMap_klass, com_oracle_graal_hotspot_HotSpotReferenceMap, Graal)) \ GRAAL_ONLY(do_klass(HotSpotInstalledCode_klass, com_oracle_graal_hotspot_meta_HotSpotInstalledCode, Graal)) \ GRAAL_ONLY(do_klass(HotSpotNmethod_klass, com_oracle_graal_hotspot_meta_HotSpotNmethod, Graal)) \ - GRAAL_ONLY(do_klass(HotSpotResolvedJavaMethod_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, Graal)) \ - GRAAL_ONLY(do_klass(HotSpotResolvedObjectType_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, Graal)) \ + GRAAL_ONLY(do_klass(HotSpotResolvedJavaMethodImpl_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethodImpl, Graal)) \ + GRAAL_ONLY(do_klass(HotSpotResolvedObjectTypeImpl_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedObjectTypeImpl, Graal)) \ GRAAL_ONLY(do_klass(HotSpotMonitorValue_klass, com_oracle_graal_hotspot_meta_HotSpotMonitorValue, Graal)) \ GRAAL_ONLY(do_klass(HotSpotCompressedNullConstant_klass, com_oracle_graal_hotspot_meta_HotSpotCompressedNullConstant, Graal)) \ GRAAL_ONLY(do_klass(HotSpotObjectConstant_klass, com_oracle_graal_hotspot_meta_HotSpotObjectConstant, Graal)) \ diff -r ab489bac3bc8 -r e04712c8928a src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Mon Nov 03 10:17:24 2014 -0800 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Nov 03 10:31:39 2014 -0800 @@ -304,8 +304,8 @@ GRAAL_ONLY(template(com_oracle_graal_hotspot_bridge_CompilerToVMImpl, "com/oracle/graal/hotspot/bridge/CompilerToVMImpl")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotInstalledCode, "com/oracle/graal/hotspot/meta/HotSpotInstalledCode")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotNmethod, "com/oracle/graal/hotspot/meta/HotSpotNmethod")) \ - GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod")) \ - GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType")) \ + GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethodImpl, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl")) \ + GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectTypeImpl, "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue, "com/oracle/graal/hotspot/meta/HotSpotMonitorValue")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotCompressedNullConstant, "com/oracle/graal/hotspot/meta/HotSpotCompressedNullConstant")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotObjectConstant, "com/oracle/graal/hotspot/meta/HotSpotObjectConstant")) \ diff -r ab489bac3bc8 -r e04712c8928a src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Mon Nov 03 10:17:24 2014 -0800 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Mon Nov 03 10:31:39 2014 -0800 @@ -65,8 +65,8 @@ LocationValue* CodeInstaller::_illegal_value = new (ResourceObj::C_HEAP, mtCompiler) LocationValue(Location()); Method* getMethodFromHotSpotMethod(oop hotspot_method) { - assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotResolvedJavaMethod::klass()), "sanity"); - return asMethod(HotSpotResolvedJavaMethod::metaspaceMethod(hotspot_method)); + assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass()), "sanity"); + return asMethod(HotSpotResolvedJavaMethodImpl::metaspaceMethod(hotspot_method)); } const int MapWordBits = 64; @@ -166,8 +166,8 @@ } static void record_metadata_reference(oop obj, jlong prim, jboolean compressed, OopRecorder* oop_recorder) { - if (obj->is_a(HotSpotResolvedObjectType::klass())) { - Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(obj)); + if (obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) { + Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj)); if (compressed) { assert(Klass::decode_klass((narrowKlass) prim) == klass, err_msg("%s @ " INTPTR_FORMAT " != " INTPTR_FORMAT, klass->name()->as_C_string(), p2i(klass), prim)); } else { @@ -175,8 +175,8 @@ } int index = oop_recorder->find_index(klass); TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string()); - } else if (obj->is_a(HotSpotResolvedJavaMethod::klass())) { - Method* method = (Method*) (address) HotSpotResolvedJavaMethod::metaspaceMethod(obj); + } else if (obj->is_a(HotSpotResolvedJavaMethodImpl::klass())) { + Method* method = (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(obj); assert(!compressed, err_msg("unexpected compressed method pointer %s @ " INTPTR_FORMAT " = " INTPTR_FORMAT, method->name()->as_C_string(), p2i(method), prim)); int index = oop_recorder->find_index(method); TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), method->name()->as_C_string()); @@ -186,7 +186,7 @@ } } -// Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectType.klass()). +// Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectTypeImpl.klass()). static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) { if (constant->is_a(HotSpotMetaspaceConstant::klass())) { oop obj = HotSpotMetaspaceConstant::metaspaceObject(constant); @@ -324,7 +324,7 @@ } else if (value->is_a(VirtualObject::klass())) { oop type = VirtualObject::type(value); int id = VirtualObject::id(value); - oop javaMirror = HotSpotResolvedObjectType::javaClass(type); + oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type); Klass* klass = java_lang_Class::as_Klass(javaMirror); bool isLongArray = klass == Universe::longArrayKlassObj(); @@ -655,15 +655,15 @@ void CodeInstaller::assumption_NoFinalizableSubclass(Handle assumption) { Handle receiverType_handle = Assumptions_NoFinalizableSubclass::receiverType(assumption()); - Klass* receiverType = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(receiverType_handle)); + Klass* receiverType = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(receiverType_handle)); _dependencies->assert_has_no_finalizable_subclasses(receiverType); } void CodeInstaller::assumption_ConcreteSubtype(Handle assumption) { Handle context_handle = Assumptions_ConcreteSubtype::context(assumption()); Handle subtype_handle = Assumptions_ConcreteSubtype::subtype(assumption()); - Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(context_handle)); - Klass* subtype = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(subtype_handle)); + Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(context_handle)); + Klass* subtype = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(subtype_handle)); if (context != subtype) { assert(context->is_abstract(), ""); @@ -678,7 +678,7 @@ Handle context_handle = Assumptions_ConcreteMethod::context(assumption()); methodHandle impl = getMethodFromHotSpotMethod(impl_handle()); - Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(context_handle)); + Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(context_handle)); _dependencies->assert_unique_concrete_method(context, impl()); } diff -r ab489bac3bc8 -r e04712c8928a src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Mon Nov 03 10:17:24 2014 -0800 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Mon Nov 03 10:31:39 2014 -0800 @@ -146,7 +146,7 @@ }; /** - * Gets the Method metaspace object from a HotSpotResolvedJavaMethod Java object. + * Gets the Method metaspace object from a HotSpotResolvedJavaMethodImpl Java object. */ Method* getMethodFromHotSpotMethod(oop hotspot_method); diff -r ab489bac3bc8 -r e04712c8928a src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Mon Nov 03 10:17:24 2014 -0800 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon Nov 03 10:31:39 2014 -0800 @@ -510,7 +510,7 @@ } if (CITimeEach) { - methodHandle method = asMethod(HotSpotResolvedJavaMethod::metaspaceMethod(hotspot_method)); + methodHandle method = asMethod(HotSpotResolvedJavaMethodImpl::metaspaceMethod(hotspot_method)); float bytes_per_sec = 1.0 * processedBytecodes / timer.seconds(); tty->print_cr("%3d seconds: %f bytes/sec: %f (bytes %d)", id, timer.seconds(), bytes_per_sec, processedBytecodes); diff -r ab489bac3bc8 -r e04712c8928a src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Mon Nov 03 10:17:24 2014 -0800 +++ b/src/share/vm/graal/graalJavaAccess.hpp Mon Nov 03 10:31:39 2014 -0800 @@ -48,11 +48,11 @@ */ #define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, typeArrayOop_field, objArrayOop_field, static_oop_field, static_int_field) \ - start_class(HotSpotResolvedObjectType) \ - oop_field(HotSpotResolvedObjectType, javaClass, "Ljava/lang/Class;") \ + start_class(HotSpotResolvedObjectTypeImpl) \ + oop_field(HotSpotResolvedObjectTypeImpl, javaClass, "Ljava/lang/Class;") \ end_class \ - start_class(HotSpotResolvedJavaMethod) \ - long_field(HotSpotResolvedJavaMethod, metaspaceMethod) \ + start_class(HotSpotResolvedJavaMethodImpl) \ + long_field(HotSpotResolvedJavaMethodImpl, metaspaceMethod) \ end_class \ start_class(InstalledCode) \ long_field(InstalledCode, address) \ diff -r ab489bac3bc8 -r e04712c8928a src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Mon Nov 03 10:17:24 2014 -0800 +++ b/src/share/vm/runtime/deoptimization.cpp Mon Nov 03 10:31:39 2014 -0800 @@ -915,7 +915,7 @@ } // Restore fields of an eliminated instance object using the same field order -// returned by HotSpotResolvedObjectType.getInstanceFields(true) +// returned by HotSpotResolvedObjectTypeImpl.getInstanceFields(true) static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap* reg_map, ObjectValue* sv, int svIndex, oop obj) { if (klass->superklass() != NULL) { svIndex = reassign_fields_by_klass(klass->superklass(), fr, reg_map, sv, svIndex, obj);