Mercurial > hg > truffle
changeset 18563:e43065342bab
Merge.
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 26 Nov 2014 23:25:56 +0100 |
parents | 4f27e4a4b4c5 (diff) 3fb1231699de (current diff) |
children | 22217b2353b1 966081b8e830 |
files | |
diffstat | 14 files changed, 176 insertions(+), 86 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/Context.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/Context.java Wed Nov 26 23:25:56 2014 +0100 @@ -41,6 +41,7 @@ public class Context implements AutoCloseable { private static final ThreadLocal<Context> currentContext = new ThreadLocal<>(); + private static final ThreadLocal<Context> previousContext = new ThreadLocal<>(); private final Map<Class<?>, Fields> fieldsMap = new HashMap<>(); @@ -328,13 +329,15 @@ return srcValue; } dstValue = pool.get(srcValue); + if (dstValue == null && previousPool != null) { + dstValue = previousPool.get(srcValue); + } if (dstValue == null) { if (srcValue instanceof Remote) { dstValue = get(srcValue); } else { dstValue = copies.get(srcValue); if (dstValue == null) { - assert !worklist.contains(srcValue) : id(srcValue); // System.out.printf("worklist+: %s%n", s(srcValue)); worklist.add(srcValue); copies.put(srcValue, copies); @@ -356,6 +359,7 @@ * In addition, copies in {@link #pool} are re-used. */ private Object copy(Object root) { + long start = System.currentTimeMillis(); assert !(isAssignableTo(root.getClass(), DontCopyClasses) || SharedGlobals.containsKey(root)); // System.out.printf("----- %s ------%n", s(obj)); assert pool.get(root) == null; @@ -364,6 +368,12 @@ IdentityHashMap<Object, Object> copies = new IdentityHashMap<>(); copies.put(root, copies); copy0(worklist, copies); + if (DEBUG) { + long duration = System.currentTimeMillis() - start; + if (duration > 10) { + System.out.printf("After copying %s (proxies: %d, pool: %d) %d ms%n", root.getClass().getSimpleName(), proxies.size(), pool.size(), duration); + } + } return pool.get(root); } @@ -382,10 +392,22 @@ public Context() { assert currentContext.get() == null : currentContext.get(); currentContext.set(this); + Context previous = previousContext.get(); + if (previous != null) { + previousPool = previous.pool; + pool = new IdentityHashMap<>(previousPool.size()); + } else { + pool = new IdentityHashMap<>(); + previousPool = null; + } } private final Map<Object, Object> proxies = new IdentityHashMap<>(); - private final Map<Object, Object> pool = new IdentityHashMap<>(); + private final Map<Object, Object> pool; + private final Map<Object, Object> previousPool; + + int invocationCacheHits; + int invocationCacheMisses; /** * Gets the value of a given object within this context. @@ -399,7 +421,7 @@ Object proxy = proxies.get(obj); if (proxy == null) { Class<?>[] interfaces = ProxyUtil.getAllInterfaces(obj.getClass()); - proxy = Proxy.newProxyInstance(obj.getClass().getClassLoader(), interfaces, new Handler<>(obj, this)); + proxy = Proxy.newProxyInstance(obj.getClass().getClassLoader(), interfaces, new Handler<>(obj)); proxies.put(obj, proxy); } return (T) proxy; @@ -421,9 +443,27 @@ } } + private static final boolean DEBUG = Boolean.getBoolean("graal.replayContext.debug"); + public void close() { assert currentContext.get() == this : currentContext.get(); + if (DEBUG) { + int overlap = 0; + if (previousPool != null) { + for (Object key : previousPool.keySet()) { + if (pool.containsKey(key)) { + overlap++; + } + } + } + if (DEBUG) { + System.out.printf("proxies: %d, pool: %d, overlap: %d, invocation cache hits: %d, invocation cache misses: %d%n", proxies.size(), pool.size(), overlap, invocationCacheHits, + invocationCacheMisses); + } + } currentContext.set(null); + previousContext.set(this); + } /** @@ -439,7 +479,7 @@ throw new GraalInternalError("Expecting proxy, found instance of %s", o.getClass()); } } else { - if (!Proxy.isProxyClass(o.getClass())) { + if (Proxy.isProxyClass(o.getClass())) { throw new GraalInternalError("Expecting instance of %s, found proxy", o.getClass()); } } @@ -448,6 +488,33 @@ return true; } + private NoContext leave; + int activeInvocations; + + /** + * Enters a scope that disables the {@linkplain Context#getCurrent() current} context. The + * disabled scope is exited when {@link NoContext#close()} is called on the returned object. + */ + public NoContext leave() { + return new NoContext(); + } + + public class NoContext implements AutoCloseable { + NoContext() { + assert currentContext.get() == Context.this; + assert Context.this.leave == null; + Context.this.leave = this; + currentContext.set(null); + } + + public void close() { + assert leave == this; + assert currentContext.get() == null; + currentContext.set(Context.this); + leave = null; + } + } + /** * Gets the currently active context for the calling thread. * @@ -456,4 +523,14 @@ public static Context getCurrent() { return currentContext.get(); } + + public boolean inProxyInvocation() { + return activeInvocations != 0; + } + + public static void breakpoint() { + if (getCurrent() != null) { + System.console(); + } + } }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/Handler.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/Handler.java Wed Nov 26 23:25:56 2014 +0100 @@ -24,29 +24,19 @@ import java.lang.reflect.*; import java.util.*; +import java.util.concurrent.*; public class Handler<T> implements InvocationHandler { private final T delegate; - private final Context context; - - Map<Invocation, Object> cachedInvocations = new HashMap<>(); - - public Handler(T delegate, Context context) { - this.delegate = delegate; - this.context = context; - } - public T getDelegate() { - return delegate; - } + /** + * Proxies objects may be visible to multiple threads. + */ + Map<Invocation, Object> cachedInvocations = new ConcurrentHashMap<>(); - static Object unproxifyObject(Object obj) { - if (obj != null && Proxy.isProxyClass(obj.getClass())) { - Handler<?> h = (Handler<?>) Proxy.getInvocationHandler(obj); - return h.delegate; - } - return obj; + public Handler(T delegate) { + this.delegate = delegate; } static Object[] unproxify(Object[] args) { @@ -56,12 +46,23 @@ Object[] res = args; for (int i = 0; i < args.length; i++) { Object arg = args[i]; - if (arg != null && Proxy.isProxyClass(arg.getClass())) { - Handler<?> h = (Handler<?>) Proxy.getInvocationHandler(arg); - if (res == args) { - res = args.clone(); + if (arg != null) { + if (Proxy.isProxyClass(arg.getClass())) { + Handler<?> h = (Handler<?>) Proxy.getInvocationHandler(arg); + if (res == args) { + res = args.clone(); + } + res[i] = h.delegate; + } else if (arg instanceof Object[]) { + Object[] arrayArg = (Object[]) arg; + arrayArg = unproxify(arrayArg); + if (arrayArg != arg) { + if (res == args) { + res = args.clone(); + } + res[i] = arrayArg; + } } - res[i] = h.delegate; } } return res; @@ -72,14 +73,19 @@ return method.getReturnType() != Void.TYPE; } + private static final Object NULL_RESULT = new Object(); + @Override public Object invoke(Object proxy, Method method, Object[] a) throws Throwable { Object[] args = unproxify(a); boolean isCacheable = isCacheable(method); Invocation invocation = new Invocation(method, delegate, args); if (isCacheable) { - if (cachedInvocations.containsKey(invocation)) { - Object result = cachedInvocations.get(invocation); + Object result = cachedInvocations.get(invocation); + if (result != null) { + if (result == NULL_RESULT) { + result = null; + } // System.out.println(invocation + ": " + result); return result; } @@ -87,11 +93,21 @@ // System.out.println("not cacheable: " + method); } - Object result = invocation.invoke(); - result = context.get(result); - if (isCacheable) { - cachedInvocations.put(invocation, result); + Context context = Context.getCurrent(); + assert context != null; + try { + assert context.activeInvocations >= 0; + context.activeInvocations++; + Object result = invocation.invoke(); + result = context.get(result); + if (isCacheable) { + context.invocationCacheHits--; + cachedInvocations.put(invocation, result == null ? NULL_RESULT : result); + } + return result; + } finally { + assert context.activeInvocations > 0; + context.activeInvocations--; } - return result; } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Wed Nov 26 23:25:56 2014 +0100 @@ -734,11 +734,15 @@ protected CompilationResult recompile(Context c, Mode mode, ResolvedJavaMethod installedCodeOwner) { try (Debug.Scope s = Debug.scope(mode.name(), new DebugDumpScope(mode.name(), true))) { - StructuredGraph graphToCompile = parseForCompile(installedCodeOwner); + StructuredGraph graphToCompile; + CallingConvention cc; - lastCompiledGraph = graphToCompile; - - CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graphToCompile.method(), false); + try (Context.NoContext l = c.leave()) { + graphToCompile = parseForCompile(installedCodeOwner); + lastCompiledGraph = graphToCompile; + cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graphToCompile.method(), false); + } + graphToCompile = c.get(graphToCompile); Request<CompilationResult> request = c.get(new GraalCompiler.Request<>(graphToCompile, null, cc, installedCodeOwner, getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graphToCompile), getSpeculationLog(), getSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default));
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Nov 26 23:25:56 2014 +0100 @@ -25,7 +25,6 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; -//import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import java.util.*;
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Wed Nov 26 23:25:56 2014 +0100 @@ -190,7 +190,7 @@ } } - InvokeNode kernelStart = createInvoke(getClass(), "getKernelStart", ConstantNode.forConstant(HotSpotObjectConstantImpl.forObject(kernel), providers.getMetaAccess(), getGraph())); + InvokeNode kernelStart = createInvoke(getClass(), "getKernelStart", ConstantNode.forConstant(kernel.asConstant(), providers.getMetaAccess(), getGraph())); AllocaNode buf = append(AllocaNode.create(bufSize / wordSize, new BitSet())); ValueNode objectParametersOffsets;
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java Wed Nov 26 23:25:56 2014 +0100 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.test; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectTypeImpl.*; import java.lang.reflect.*; @@ -35,7 +34,7 @@ /** * Tests {@link HotSpotResolvedJavaField} functionality. */ -public class HotSpotResolvedJavaFieldTest { +public class HotSpotResolvedJavaFieldTest extends HotSpotGraalCompilerTest { private static final Class<?>[] classesWithInternalFields = {Class.class, ClassLoader.class}; @@ -63,7 +62,7 @@ @Test public void testCachingForInternalFields() { for (Class<?> c : classesWithInternalFields) { - HotSpotResolvedObjectTypeImpl type = HotSpotResolvedObjectTypeImpl.fromObjectClass(c); + HotSpotResolvedObjectType type = HotSpotResolvedObjectTypeImpl.fromObjectClass(c); for (ResolvedJavaField field : type.getInstanceFields(false)) { if (field.isInternal()) { HotSpotResolvedJavaField expected = (HotSpotResolvedJavaField) field; @@ -77,7 +76,7 @@ @Test public void testIsInObject() { for (Field f : String.class.getDeclaredFields()) { - HotSpotResolvedJavaField rf = (HotSpotResolvedJavaField) runtime().getHostProviders().getMetaAccess().lookupJavaField(f); + HotSpotResolvedJavaField rf = (HotSpotResolvedJavaField) getMetaAccess().lookupJavaField(f); Assert.assertEquals(rf.toString(), rf.isInObject("a string"), !rf.isStatic()); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Wed Nov 26 23:25:56 2014 +0100 @@ -41,6 +41,7 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.remote.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; @@ -80,10 +81,26 @@ } /** + * Checks that all accesses to a {@link HotSpotGraalRuntimeProvider} within a replay context are + * through references to a captured {@link HotSpotGraalRuntimeProvider}, not through the static + * {@link HotSpotGraalRuntimeProvider} instance of the runtime hosting the replay. + */ + private static boolean checkRuntimeAccess() { + Context c = Context.getCurrent(); + if (c != null) { + if (!c.inProxyInvocation()) { + throw new GraalInternalError("Cannot access HotSpotGraalRuntime statically in replay/remote context"); + } + } + return true; + } + + /** * Gets the singleton {@link HotSpotGraalRuntime} object. */ public static HotSpotGraalRuntime runtime() { assert instance != null; + assert checkRuntimeAccess(); return instance; } @@ -240,13 +257,6 @@ } /** - * Reads a word value from a given address. - */ - public static long unsafeReadWord(long address) { - return unsafe.getAddress(address); - } - - /** * Reads a klass pointer from a constant object. */ public static long unsafeReadKlassPointer(Object object) { @@ -390,7 +400,7 @@ // If the name represents a primitive type we can short-circuit the lookup. if (name.length() == 1) { Kind kind = Kind.fromPrimitiveOrVoidTypeChar(name.charAt(0)); - return HotSpotResolvedPrimitiveType.fromKind(kind); + return fromClass(kind.toJavaClass()); } // Resolve non-primitive types in the VM.
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Wed Nov 26 23:25:56 2014 +0100 @@ -113,4 +113,9 @@ public long getStart() { return isValid() ? super.getStart() : 0; } + + public JavaConstant asConstant() { + return HotSpotObjectConstantImpl.forObject(this); + } + }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java Wed Nov 26 23:25:56 2014 +0100 @@ -41,7 +41,7 @@ private static final long serialVersionUID = 3592151693708093496L; - public static JavaConstant forObject(Object object) { + static JavaConstant forObject(Object object) { return forObject(object, false); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java Wed Nov 26 23:25:56 2014 +0100 @@ -421,7 +421,7 @@ ProfilingInfo info; if (UseProfilingInformation.getValue() && methodData == null) { - long metaspaceMethodData = unsafeReadWord(metaspaceMethod + runtime().getConfig().methodDataOffset); + long metaspaceMethodData = unsafe.getAddress(metaspaceMethod + runtime().getConfig().methodDataOffset); if (metaspaceMethodData != 0) { methodData = new HotSpotMethodData(metaspaceMethodData); if (TraceMethodDataFilter != null && this.format("%H.%n").contains(TraceMethodDataFilter)) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java Wed Nov 26 23:25:56 2014 +0100 @@ -35,8 +35,8 @@ * * @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass} */ - public static HotSpotResolvedJavaType fromClass(Class<?> javaClass) { - return (HotSpotResolvedJavaType) runtime().fromClass(javaClass); + public static ResolvedJavaType fromClass(Class<?> javaClass) { + return runtime().fromClass(javaClass); } public HotSpotResolvedJavaType(String name) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java Wed Nov 26 23:25:56 2014 +0100 @@ -52,7 +52,7 @@ private HotSpotResolvedJavaField[] instanceFields; private HotSpotResolvedObjectTypeImpl[] interfaces; private ConstantPool constantPool; - private HotSpotResolvedObjectTypeImpl arrayOfType; + private HotSpotResolvedObjectType arrayOfType; /** * Gets the Graal mirror for a {@link Class} object. @@ -66,17 +66,6 @@ /** * 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 ResolvedJavaType fromMetaspaceKlass(Constant metaspaceKlass) { - HotSpotMetaspaceConstant klass = (HotSpotMetaspaceConstant) metaspaceKlass; - return klass.asResolvedJavaType(); - } - - /** - * 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} */ @@ -92,8 +81,8 @@ * * <p> * <b>NOTE</b>: Creating an instance of this class does not install the mirror for the - * {@link Class} type. Use {@link #fromObjectClass(Class)}, - * {@link #fromMetaspaceKlass(Constant)} or {@link #fromMetaspaceKlass(long)} instead. + * {@link Class} type. Use {@link #fromObjectClass(Class)} or {@link #fromMetaspaceKlass(long)} + * instead. * </p> * * @param javaClass the Class to create the mirror for @@ -118,7 +107,10 @@ * Gets the metaspace Klass for this type. */ public long getMetaspaceKlass() { - return HotSpotGraalRuntime.unsafeReadWord(javaClass, runtime().getConfig().klassOffset); + if (HotSpotGraalRuntime.getHostWordKind() == Kind.Long) { + return unsafe.getLong(javaClass, (long) runtime().getConfig().klassOffset); + } + return unsafe.getInt(javaClass, (long) runtime().getConfig().klassOffset) & 0xFFFFFFFFL; } @Override @@ -169,7 +161,7 @@ HotSpotResolvedObjectTypeImpl type = this; while (type.isAbstract()) { long subklass = type.getSubklass(); - if (subklass == 0 || unsafeReadWord(subklass + config.nextSiblingOffset) != 0) { + if (subklass == 0 || unsafe.getAddress(subklass + config.nextSiblingOffset) != 0) { return null; } type = fromMetaspaceKlass(subklass); @@ -198,7 +190,7 @@ * @return value of the subklass field as metaspace klass pointer */ private long getSubklass() { - return unsafeReadWord(getMetaspaceKlass() + runtime().getConfig().subklassOffset); + return unsafe.getAddress(getMetaspaceKlass() + runtime().getConfig().subklassOffset); } @Override @@ -791,7 +783,7 @@ if (isArray()) { return config.arrayPrototypeMarkWord(); } else { - return unsafeReadWord(getMetaspaceKlass() + config.prototypeMarkWordOffset); + return unsafe.getAddress(getMetaspaceKlass() + config.prototypeMarkWordOffset); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Wed Nov 26 23:25:56 2014 +0100 @@ -40,21 +40,11 @@ private final Kind kind; /** - * Gets the Graal mirror for a {@link Kind}. - * - * @return the {@link HotSpotResolvedObjectTypeImpl} corresponding to {@code kind} - */ - public static ResolvedJavaType fromKind(Kind kind) { - Class<?> javaClass = kind.toJavaClass(); - return fromClass(javaClass); - } - - /** * Creates the Graal mirror for a primitive {@link Kind}. * * <p> * <b>NOTE</b>: Creating an instance of this class does not install the mirror for the - * {@link Class} type. Use {@link #fromKind(Kind)} or {@link #fromClass(Class)} instead. + * {@link Class} type. Use {@link #fromClass(Class)} instead. * </p> * * @param kind the Kind to create the mirror for
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Wed Nov 26 12:36:48 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Wed Nov 26 23:25:56 2014 +0100 @@ -48,8 +48,6 @@ */ public class HotSpotReplacementsUtil { - // Must be @Fold as the security checks in HotSpotGraalRuntime.runtime() - // don't work well inside snippets @Fold public static HotSpotVMConfig config() { return runtime().getConfig();