--- old/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompiledClass.java 2018-12-11 11:12:37.000000000 -0800 +++ new/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompiledClass.java 2018-12-11 11:12:37.000000000 -0800 @@ -333,8 +333,7 @@ AOTKlassData data = klassData.get(name); if (data != null) { HotSpotResolvedObjectType oldType = data.getType(); - assert oldType == type : "duplicate classes for name " + type.getName() + ", fingerprints old: " + oldType.getFingerprint() + ", new: " + type.getFingerprint() + - ", klass pointers old: " + oldType.klass() + ", new: " + type.klass(); + assert oldType.equals(type) : "duplicate classes for name " + type.getName(); } return data; } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/SnippetReflectionProvider.java 2018-12-11 11:12:38.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/SnippetReflectionProvider.java 2018-12-11 11:12:38.000000000 -0800 @@ -61,20 +61,6 @@ T asObject(Class type, JavaConstant constant); /** - * Gets the object reference a given constant represents if it is of a given type. The constant - * must have kind {@link JavaKind#Object}. - * - * @param type the expected type of the object represented by {@code constant}. If the object is - * required to be of this type, then wrap the call to this method in - * {@link Objects#requireNonNull(Object)}. - * @param constant an object constant - * @return the object value represented by {@code constant} if it is an - * {@link ResolvedJavaType#isInstance(JavaConstant) instance of} {@code type} otherwise - * {@code null} - */ - Object asObject(ResolvedJavaType type, JavaConstant constant); - - /** * Creates a boxed constant for the given kind from an Object. The object needs to be of the * Java boxed type corresponding to the kind. * @@ -82,7 +68,13 @@ * @param value the Java boxed value: a {@link Byte} instance for {@link JavaKind#Byte}, etc. * @return the boxed copy of {@code value} */ - JavaConstant forBoxed(JavaKind kind, Object value); + default JavaConstant forBoxed(JavaKind kind, Object value) { + if (kind == JavaKind.Object) { + return forObject(value); + } else { + return JavaConstant.forBoxedPrimitive(value); + } + } /** * Gets the value to bind to an injected parameter in a node intrinsic. @@ -97,7 +89,8 @@ * Get the original Java class corresponding to a {@link ResolvedJavaType}. * * @param type the type for which the original Java class is requested - * @return the original Java class corresponding to the {@code type} parameter + * @return the original Java class corresponding to {@code type} or {@code null} if this object + * cannot map {@link ResolvedJavaType} instances to {@link Class} instances */ Class originalClass(ResolvedJavaType type); } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/Fields.java 2018-12-11 11:12:39.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/Fields.java 2018-12-11 11:12:39.000000000 -0800 @@ -326,7 +326,7 @@ public void appendFields(StringBuilder sb) { for (int i = 0; i < offsets.length; i++) { - sb.append(i == 0 ? "" : ", ").append(getName(i)).append('@').append(offsets[i]); + sb.append(i == 0 ? "" : ", ").append(getDeclaringClass(i).getSimpleName()).append('.').append(getName(i)).append('@').append(offsets[i]); } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/JavaConstantFieldProvider.java 2018-12-11 11:12:41.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/JavaConstantFieldProvider.java 2018-12-11 11:12:40.000000000 -0800 @@ -24,6 +24,8 @@ package org.graalvm.compiler.core.common.spi; +import java.util.Arrays; + import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.OptionKey; @@ -46,9 +48,26 @@ protected JavaConstantFieldProvider(MetaAccessProvider metaAccess) { try { - this.stringValueField = metaAccess.lookupJavaField(String.class.getDeclaredField("value")); - this.stringHashField = metaAccess.lookupJavaField(String.class.getDeclaredField("hash")); - } catch (NoSuchFieldException | SecurityException e) { + ResolvedJavaType stringType = metaAccess.lookupJavaType(String.class); + ResolvedJavaField[] stringFields = stringType.getInstanceFields(false); + ResolvedJavaField valueField = null; + ResolvedJavaField hashField = null; + for (ResolvedJavaField field : stringFields) { + if (field.getName().equals("value")) { + valueField = field; + } else if (field.getName().equals("hash")) { + hashField = field; + } + } + if (valueField == null) { + throw new GraalError("missing field value " + Arrays.toString(stringFields)); + } + if (hashField == null) { + throw new GraalError("missing field hash " + Arrays.toString(stringFields)); + } + stringValueField = valueField; + stringHashField = hashField; + } catch (SecurityException e) { throw new GraalError(e); } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/StubAVXTest.java 2018-12-11 11:12:42.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/StubAVXTest.java 2018-12-11 11:12:41.000000000 -0800 @@ -31,9 +31,12 @@ import org.graalvm.compiler.asm.amd64.AMD64Address; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.bytecode.BytecodeProvider; +import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; import org.graalvm.compiler.core.common.type.DataPointerConstant; +import org.graalvm.compiler.debug.DebugContext; +import org.graalvm.compiler.hotspot.HotSpotBackend; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; @@ -46,6 +49,7 @@ import org.graalvm.compiler.lir.gen.LIRGeneratorTool; import org.graalvm.compiler.lir.jtt.LIRTest; import org.graalvm.compiler.lir.jtt.LIRTestSpecification; +import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.extended.ForeignCallNode; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; @@ -67,7 +71,6 @@ import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.Value; -import org.graalvm.compiler.hotspot.HotSpotBackend; public class StubAVXTest extends LIRTest { @@ -183,10 +186,16 @@ } @Override - protected BytecodeProvider getReplacementsBytecodeProvider() { + protected void registerSnippet() { + } + + @Override + protected StructuredGraph buildInitialGraph(DebugContext debug, CompilationIdentifier compilationId, Object[] args) { + // Build the snippet graph directly since snippet registration is closed at this point. ReplacementsImpl d = (ReplacementsImpl) providers.getReplacements(); - MetaAccessProvider metaAccess = d.providers.getMetaAccess(); - return new ClassfileBytecodeProvider(metaAccess, d.snippetReflection, ClassLoader.getSystemClassLoader()); + MetaAccessProvider metaAccess = d.getProviders().getMetaAccess(); + BytecodeProvider bytecodes = new ClassfileBytecodeProvider(metaAccess, d.snippetReflection, ClassLoader.getSystemClassLoader()); + return d.makeGraph(debug, bytecodes, method, args, null, false, null); } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java 2018-12-11 11:12:43.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java 2018-12-11 11:12:42.000000000 -0800 @@ -150,6 +150,7 @@ providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers, snippetReflection, wordTypes, plugins); + replacements.setProviders(providers); } try (InitTimer rt = timer("instantiate backend")) { return createBackend(config, graalRuntime, providers); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java 2018-12-11 11:12:44.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java 2018-12-11 11:12:44.000000000 -0800 @@ -410,7 +410,6 @@ "java/lang/StringLatin1.compareToUTF16([B[B)I", "java/lang/StringUTF16.compareTo([B[B)I", "java/lang/StringUTF16.compareToLatin1([B[B)I", - "java/lang/Thread.onSpinWait()V", "jdk/internal/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I", "jdk/internal/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J", "jdk/internal/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I", @@ -418,6 +417,7 @@ "jdk/internal/misc/Unsafe.getAndSet" + oopName + "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;"); } add(toBeInvestigated, + "java/lang/Thread.onSpinWait()V", "jdk/internal/misc/Unsafe.getCharUnaligned(Ljava/lang/Object;J)C", "jdk/internal/misc/Unsafe.getIntUnaligned(Ljava/lang/Object;J)I", "jdk/internal/misc/Unsafe.getLongUnaligned(Ljava/lang/Object;J)J", --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/LoadJavaMirrorWithKlassTest.java 2018-12-11 11:12:45.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/LoadJavaMirrorWithKlassTest.java 2018-12-11 11:12:45.000000000 -0800 @@ -55,6 +55,11 @@ public int hashCode() { return clazz.hashCode(); } + + @Override + public String toString() { + return "Wrapper-" + clazz; + } } @Override --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierAdditionTest.java 2018-12-11 11:12:46.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierAdditionTest.java 2018-12-11 11:12:46.000000000 -0800 @@ -24,13 +24,14 @@ package org.graalvm.compiler.hotspot.test; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.config; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.referentOffset; import java.lang.ref.WeakReference; +import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; +import org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase; import org.graalvm.compiler.hotspot.nodes.G1PostWriteBarrier; import org.graalvm.compiler.hotspot.nodes.G1PreWriteBarrier; import org.graalvm.compiler.hotspot.nodes.G1ReferentFieldReadBarrier; @@ -38,6 +39,8 @@ import org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; +import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; +import org.graalvm.compiler.nodes.graphbuilderconf.NodeIntrinsicPluginFactory; import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType; import org.graalvm.compiler.nodes.memory.ReadNode; import org.graalvm.compiler.nodes.memory.WriteNode; @@ -51,6 +54,7 @@ import org.graalvm.compiler.phases.common.inlining.policy.InlineEverythingPolicy; import org.graalvm.compiler.phases.tiers.HighTierContext; import org.graalvm.compiler.phases.tiers.MidTierContext; +import org.graalvm.compiler.replacements.NodeIntrinsificationProvider; import org.junit.Assert; import org.junit.Test; @@ -71,7 +75,6 @@ public class WriteBarrierAdditionTest extends HotSpotGraalCompilerTest { private final GraalHotSpotVMConfig config = runtime().getVMConfig(); - private static final long referentOffset = referentOffset(); public static class Container { @@ -167,8 +170,20 @@ testHelper("test5Snippet", config.useG1GC ? 1 : 0); } + @Override + protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) { + NodeIntrinsicPluginFactory.InjectionProvider injection = new NodeIntrinsificationProvider(getMetaAccess(), getSnippetReflection(), getProviders().getForeignCalls(), null); + new PluginFactory_WriteBarrierAdditionTest().registerPlugins(invocationPlugins, injection); + super.registerInvocationPlugins(invocationPlugins); + } + + @Fold + public static boolean useCompressedOops(@Fold.InjectedParameter GraalHotSpotVMConfig config) { + return config.useCompressedOops; + } + public static Object test5Snippet() throws Exception { - return UNSAFE.getObject(wr, config(null).useCompressedOops ? 12L : 16L); + return UNSAFE.getObject(wr, useCompressedOops(GraalHotSpotVMConfigBase.INJECTED_VMCONFIG) ? 12L : 16L); } /** @@ -177,7 +192,7 @@ */ @Test public void test6() throws Exception { - test2("testUnsafeLoad", UNSAFE, wr, Long.valueOf(referentOffset), null); + test2("testUnsafeLoad", UNSAFE, wr, Long.valueOf(referentOffset(getMetaAccess())), null); } /** @@ -186,7 +201,7 @@ */ @Test public void test7() throws Exception { - test2("testUnsafeLoad", UNSAFE, con, Long.valueOf(referentOffset), null); + test2("testUnsafeLoad", UNSAFE, con, Long.valueOf(referentOffset(getMetaAccess())), null); } /** @@ -299,7 +314,7 @@ Assert.assertTrue(read.getAddress() instanceof OffsetAddressNode); JavaConstant constDisp = ((OffsetAddressNode) read.getAddress()).getOffset().asJavaConstant(); Assert.assertNotNull(constDisp); - Assert.assertEquals(referentOffset, constDisp.asLong()); + Assert.assertEquals(referentOffset(getMetaAccess()), constDisp.asLong()); Assert.assertTrue(config.useG1GC); Assert.assertEquals(BarrierType.PRECISE, read.getBarrierType()); Assert.assertTrue(read.next() instanceof G1ReferentFieldReadBarrier); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigBase.java 2018-12-11 11:12:47.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigBase.java 2018-12-11 11:12:47.000000000 -0800 @@ -29,6 +29,8 @@ import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.compiler.api.replacements.Fold.InjectedParameter; +import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext; +import org.graalvm.compiler.options.OptionValues; import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.hotspot.HotSpotVMConfigAccess; @@ -71,6 +73,8 @@ */ public static final GraalHotSpotVMConfig INJECTED_VMCONFIG = null; public static final MetaAccessProvider INJECTED_METAACCESS = null; + public static final OptionValues INJECTED_OPTIONVALUES = null; + public static final IntrinsicContext INJECTED_INTRINSIC_CONTEXT = null; public final String osName = getHostOSName(); public final String osArch = getHostArchitectureName(); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java 2018-12-11 11:12:48.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java 2018-12-11 11:12:48.000000000 -0800 @@ -36,8 +36,6 @@ import java.util.List; import java.util.ListIterator; import java.util.Map; -import java.util.stream.Stream; -import java.util.stream.Stream.Builder; import org.graalvm.compiler.api.replacements.MethodSubstitution; import org.graalvm.compiler.api.replacements.Snippet; @@ -113,13 +111,13 @@ byte[] dataSection = new byte[data.getSectionSize()]; ByteBuffer buffer = ByteBuffer.wrap(dataSection).order(ByteOrder.nativeOrder()); - Builder patchBuilder = Stream.builder(); + List patches = new ArrayList<>(); data.buildDataSection(buffer, (position, vmConstant) -> { - patchBuilder.accept(new DataPatch(position, new ConstantReference(vmConstant))); + patches.add(new DataPatch(position, new ConstantReference(vmConstant))); }); int dataSectionAlignment = data.getSectionAlignment(); - DataPatch[] dataSectionPatches = patchBuilder.build().toArray(len -> new DataPatch[len]); + DataPatch[] dataSectionPatches = patches.toArray(new DataPatch[patches.size()]); int totalFrameSize = compResult.getTotalFrameSize(); StackSlot customStackArea = compResult.getCustomStackArea(); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java 2018-12-11 11:12:50.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java 2018-12-11 11:12:49.000000000 -0800 @@ -45,6 +45,7 @@ import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction; import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.core.common.GraalOptions; +import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; import org.graalvm.compiler.core.target.Backend; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugContext.Description; @@ -328,8 +329,12 @@ return (T) this; } else if (clazz == SnippetReflectionProvider.class) { return (T) getHostProviders().getSnippetReflection(); + } else if (clazz == GraalHotSpotVMConfig.class) { + return (T) getVMConfig(); } else if (clazz == StampProvider.class) { return (T) getHostProviders().getStampProvider(); + } else if (ForeignCallsProvider.class.isAssignableFrom(clazz)) { + return (T) getHostProviders().getForeignCalls(); } return null; } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java 2018-12-11 11:12:51.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java 2018-12-11 11:12:50.000000000 -0800 @@ -92,6 +92,7 @@ Iterable factories = Collections.singletonList(new GraalDebugHandlersFactory(providers.getSnippetReflection())); lowerer.initialize(options, factories, providers, config); } + providers.getReplacements().closeSnippetRegistration(); } protected CallingConvention makeCallingConvention(StructuredGraph graph, Stub stub) { --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java 2018-12-11 11:12:52.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java 2018-12-11 11:12:51.000000000 -0800 @@ -26,7 +26,9 @@ import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; import org.graalvm.compiler.bytecode.BytecodeProvider; +import org.graalvm.compiler.hotspot.meta.HotSpotWordOperationPlugin; import org.graalvm.compiler.hotspot.word.HotSpotOperation; +import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderPlugin; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.util.Providers; import org.graalvm.compiler.printer.GraalDebugHandlersFactory; @@ -40,13 +42,25 @@ * them. */ public class HotSpotReplacementsImpl extends ReplacementsImpl { - public HotSpotReplacementsImpl(OptionValues options, Providers providers, SnippetReflectionProvider snippetReflection, BytecodeProvider bytecodeProvider, TargetDescription target) { super(options, new GraalDebugHandlersFactory(snippetReflection), providers, snippetReflection, bytecodeProvider, target); } @Override - protected boolean hasGenericInvocationPluginAnnotation(ResolvedJavaMethod method) { - return method.getAnnotation(HotSpotOperation.class) != null || super.hasGenericInvocationPluginAnnotation(method); + public Class getIntrinsifyingPlugin(ResolvedJavaMethod method) { + return method.getAnnotation(HotSpotOperation.class) != null ? HotSpotWordOperationPlugin.class : super.getIntrinsifyingPlugin(method); + } + + private boolean snippetRegistrationClosed; + + @Override + public void registerSnippet(ResolvedJavaMethod method, ResolvedJavaMethod original, Object receiver, boolean trackNodeSourcePosition) { + assert !snippetRegistrationClosed; + super.registerSnippet(method, original, receiver, trackNodeSourcePosition); + } + + @Override + public void closeSnippetRegistration() { + snippetRegistrationClosed = true; } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java 2018-12-11 11:12:53.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java 2018-12-11 11:12:53.000000000 -0800 @@ -59,14 +59,11 @@ import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; import org.graalvm.compiler.hotspot.nodes.BeginLockScopeNode; -import org.graalvm.compiler.hotspot.replacements.arraycopy.HotSpotArraycopySnippets; -import org.graalvm.compiler.nodes.ComputeObjectAddressNode; import org.graalvm.compiler.hotspot.nodes.G1ArrayRangePostWriteBarrier; import org.graalvm.compiler.hotspot.nodes.G1ArrayRangePreWriteBarrier; import org.graalvm.compiler.hotspot.nodes.G1PostWriteBarrier; import org.graalvm.compiler.hotspot.nodes.G1PreWriteBarrier; import org.graalvm.compiler.hotspot.nodes.G1ReferentFieldReadBarrier; -import org.graalvm.compiler.nodes.GetObjectAddressNode; import org.graalvm.compiler.hotspot.nodes.HotSpotCompressionNode; import org.graalvm.compiler.hotspot.nodes.HotSpotDirectCallTargetNode; import org.graalvm.compiler.hotspot.nodes.HotSpotIndirectCallTargetNode; @@ -90,20 +87,22 @@ import org.graalvm.compiler.hotspot.replacements.LoadExceptionObjectSnippets; import org.graalvm.compiler.hotspot.replacements.MonitorSnippets; import org.graalvm.compiler.hotspot.replacements.NewObjectSnippets; +import org.graalvm.compiler.hotspot.replacements.ObjectCloneSnippets; import org.graalvm.compiler.hotspot.replacements.StringToBytesSnippets; import org.graalvm.compiler.hotspot.replacements.UnsafeLoadSnippets; import org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets; import org.graalvm.compiler.hotspot.replacements.aot.ResolveConstantSnippets; -import org.graalvm.compiler.replacements.arraycopy.ArrayCopyNode; -import org.graalvm.compiler.replacements.arraycopy.ArrayCopySnippets; -import org.graalvm.compiler.replacements.arraycopy.ArrayCopyWithSlowPathNode; +import org.graalvm.compiler.hotspot.replacements.arraycopy.HotSpotArraycopySnippets; import org.graalvm.compiler.hotspot.replacements.profiling.ProfileSnippets; +import org.graalvm.compiler.hotspot.stubs.ForeignCallSnippets; import org.graalvm.compiler.hotspot.word.KlassPointer; import org.graalvm.compiler.nodes.AbstractBeginNode; import org.graalvm.compiler.nodes.AbstractDeoptimizeNode; import org.graalvm.compiler.nodes.CompressionNode.CompressionOp; +import org.graalvm.compiler.nodes.ComputeObjectAddressNode; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.FixedNode; +import org.graalvm.compiler.nodes.GetObjectAddressNode; import org.graalvm.compiler.nodes.Invoke; import org.graalvm.compiler.nodes.LogicNode; import org.graalvm.compiler.nodes.LoweredCallTargetNode; @@ -159,6 +158,9 @@ import org.graalvm.compiler.nodes.util.GraphUtil; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.replacements.DefaultJavaLoweringProvider; +import org.graalvm.compiler.replacements.arraycopy.ArrayCopyNode; +import org.graalvm.compiler.replacements.arraycopy.ArrayCopySnippets; +import org.graalvm.compiler.replacements.arraycopy.ArrayCopyWithSlowPathNode; import org.graalvm.compiler.replacements.nodes.AssertionNode; import jdk.internal.vm.compiler.word.LocationIdentity; @@ -196,6 +198,9 @@ protected ResolveConstantSnippets.Templates resolveConstantSnippets; protected ProfileSnippets.Templates profileSnippets; + protected ObjectCloneSnippets.Templates objectCloneSnippets; + protected ForeignCallSnippets.Templates foreignCallSnippets; + public DefaultHotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, TargetDescription target) { super(metaAccess, foreignCalls, target, runtime.getVMConfig().useCompressedOops); @@ -221,6 +226,8 @@ hashCodeSnippets = new HashCodeSnippets.Templates(options, factories, providers, target); resolveConstantSnippets = new ResolveConstantSnippets.Templates(options, factories, providers, target); profileSnippets = new ProfileSnippets.Templates(options, factories, providers, target); + objectCloneSnippets = new ObjectCloneSnippets.Templates(options, factories, providers, target); + foreignCallSnippets = new ForeignCallSnippets.Templates(options, factories, providers, target); } public MonitorSnippets.Templates getMonitorSnippets() { @@ -286,7 +293,7 @@ } else if (n instanceof DynamicNewInstanceNode) { DynamicNewInstanceNode newInstanceNode = (DynamicNewInstanceNode) n; if (newInstanceNode.getClassClass() == null) { - JavaConstant classClassMirror = constantReflection.forObject(Class.class); + JavaConstant classClassMirror = constantReflection.asJavaClass(metaAccess.lookupJavaType(Class.class)); ConstantNode classClass = ConstantNode.forConstant(classClassMirror, tool.getMetaAccess(), graph); newInstanceNode.setClassClass(classClass); } @@ -300,7 +307,7 @@ } else if (n instanceof DynamicNewArrayNode) { DynamicNewArrayNode dynamicNewArrayNode = (DynamicNewArrayNode) n; if (dynamicNewArrayNode.getVoidClass() == null) { - JavaConstant voidClassMirror = constantReflection.forObject(void.class); + JavaConstant voidClassMirror = constantReflection.asJavaClass(metaAccess.lookupJavaType(void.class)); ConstantNode voidClass = ConstantNode.forConstant(voidClassMirror, tool.getMetaAccess(), graph); dynamicNewArrayNode.setVoidClass(voidClass); } @@ -770,8 +777,7 @@ @Override public int fieldOffset(ResolvedJavaField f) { - HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) f; - return field.getOffset(); + return f.getOffset(); } @Override @@ -783,4 +789,14 @@ protected final JavaKind getStorageKind(ResolvedJavaField field) { return field.getJavaKind(); } + + @Override + public ObjectCloneSnippets.Templates getObjectCloneSnippets() { + return objectCloneSnippets; + } + + @Override + public ForeignCallSnippets.Templates getForeignCallSnippets() { + return foreignCallSnippets; + } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java 2018-12-11 11:12:54.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java 2018-12-11 11:12:54.000000000 -0800 @@ -34,8 +34,6 @@ import java.lang.invoke.MutableCallSite; import java.lang.invoke.VolatileCallSite; import java.lang.reflect.Array; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.math.BigInteger; import java.util.zip.CRC32; @@ -45,7 +43,6 @@ import org.graalvm.compiler.core.common.type.ObjectStamp; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.core.common.type.TypeReference; -import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode; import org.graalvm.compiler.hotspot.replacements.AESCryptSubstitutions; @@ -66,7 +63,6 @@ import org.graalvm.compiler.hotspot.replacements.SHA5Substitutions; import org.graalvm.compiler.hotspot.replacements.SHASubstitutions; import org.graalvm.compiler.hotspot.replacements.ThreadSubstitutions; -import org.graalvm.compiler.replacements.arraycopy.ArrayCopyNode; import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.NamedLocationIdentity; @@ -95,6 +91,7 @@ import org.graalvm.compiler.replacements.NodeIntrinsificationProvider; import org.graalvm.compiler.replacements.ReplacementsImpl; import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins; +import org.graalvm.compiler.replacements.arraycopy.ArrayCopyNode; import org.graalvm.compiler.serviceprovider.GraalServices; import org.graalvm.compiler.word.WordOperationPlugin; import org.graalvm.compiler.word.WordTypes; @@ -458,18 +455,8 @@ if (config.useMultiplyToLenIntrinsic()) { assert config.multiplyToLen != 0L; if (Java8OrEarlier) { - try { - Method m = BigInteger.class.getDeclaredMethod("multiplyToLen", int[].class, int.class, int[].class, int.class, int[].class); - if (Modifier.isStatic(m.getModifiers())) { - r.registerMethodSubstitution(BigIntegerSubstitutions.class, "multiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class, int.class, - int[].class); - } else { - r.registerMethodSubstitution(BigIntegerSubstitutions.class, "multiplyToLen", Receiver.class, int[].class, int.class, int[].class, int.class, - int[].class); - } - } catch (NoSuchMethodException | SecurityException e) { - throw new GraalError(e); - } + r.registerMethodSubstitution(BigIntegerSubstitutions.class, "multiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class, int.class, + int[].class); } else { r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMultiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class, int.class, int[].class); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotLoweringProvider.java 2018-12-11 11:12:55.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotLoweringProvider.java 2018-12-11 11:12:55.000000000 -0800 @@ -26,6 +26,8 @@ import org.graalvm.compiler.debug.DebugHandlersFactory; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; +import org.graalvm.compiler.hotspot.replacements.ObjectCloneSnippets; +import org.graalvm.compiler.hotspot.stubs.ForeignCallSnippets; import org.graalvm.compiler.nodes.spi.LoweringProvider; import org.graalvm.compiler.options.OptionValues; @@ -35,4 +37,8 @@ public interface HotSpotLoweringProvider extends LoweringProvider { void initialize(OptionValues options, Iterable factories, HotSpotProviders providers, GraalHotSpotVMConfig config); + + ObjectCloneSnippets.Templates getObjectCloneSnippets(); + + ForeignCallSnippets.Templates getForeignCallSnippets(); } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotProviders.java 2018-12-11 11:12:56.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotProviders.java 2018-12-11 11:12:56.000000000 -0800 @@ -26,6 +26,7 @@ import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; import org.graalvm.compiler.core.common.spi.ConstantFieldProvider; +import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; import org.graalvm.compiler.nodes.spi.LoweringProvider; @@ -33,6 +34,7 @@ import org.graalvm.compiler.phases.tiers.SuitesProvider; import org.graalvm.compiler.phases.util.Providers; +import jdk.vm.ci.code.CodeCacheProvider; import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.vm.ci.meta.MetaAccessProvider; @@ -90,4 +92,53 @@ public HotSpotWordTypes getWordTypes() { return wordTypes; } + + @Override + public Providers copyWith(MetaAccessProvider substitution) { + return new HotSpotProviders(substitution, getCodeCache(), getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), getLowerer(), getReplacements(), getSuites(), + getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + } + + @Override + public Providers copyWith(CodeCacheProvider substitution) { + return new HotSpotProviders(getMetaAccess(), (HotSpotCodeCacheProvider) substitution, getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), getLowerer(), getReplacements(), + getSuites(), + getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + } + + @Override + public Providers copyWith(ConstantReflectionProvider substitution) { + return new HotSpotProviders(getMetaAccess(), getCodeCache(), substitution, getConstantFieldProvider(), getForeignCalls(), getLowerer(), getReplacements(), getSuites(), + getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + } + + @Override + public Providers copyWith(ConstantFieldProvider substitution) { + return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), substitution, getForeignCalls(), getLowerer(), getReplacements(), getSuites(), + getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + } + + @Override + public Providers copyWith(ForeignCallsProvider substitution) { + return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), getConstantFieldProvider(), (HotSpotForeignCallsProvider) substitution, getLowerer(), getReplacements(), + getSuites(), + getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + } + + @Override + public Providers copyWith(LoweringProvider substitution) { + return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), substitution, getReplacements(), getSuites(), + getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + } + + @Override + public Providers copyWith(Replacements substitution) { + return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), getLowerer(), substitution, getSuites(), + getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + } + + public Providers copyWith(Plugins substitution) { + return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), getLowerer(), getReplacements(), getSuites(), + getRegisters(), getSnippetReflection(), getWordTypes(), substitution); + } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSnippetReflectionProvider.java 2018-12-11 11:12:57.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSnippetReflectionProvider.java 2018-12-11 11:12:57.000000000 -0800 @@ -55,21 +55,15 @@ } @Override - public Object asObject(ResolvedJavaType type, JavaConstant constant) { - if (constant.isNull()) { - return null; - } - HotSpotObjectConstant hsConstant = (HotSpotObjectConstant) constant; - return hsConstant.asObject(type); - } - - @Override public T asObject(Class type, JavaConstant constant) { if (constant.isNull()) { return null; } - HotSpotObjectConstant hsConstant = (HotSpotObjectConstant) constant; - return hsConstant.asObject(type); + if (constant instanceof HotSpotObjectConstant) { + HotSpotObjectConstant hsConstant = (HotSpotObjectConstant) constant; + return hsConstant.asObject(type); + } + return null; } @Override --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotWordOperationPlugin.java 2018-12-11 11:12:58.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotWordOperationPlugin.java 2018-12-11 11:12:58.000000000 -0800 @@ -66,7 +66,7 @@ * Extends {@link WordOperationPlugin} to handle {@linkplain HotSpotOperation HotSpot word * operations}. */ -class HotSpotWordOperationPlugin extends WordOperationPlugin { +public class HotSpotWordOperationPlugin extends WordOperationPlugin { HotSpotWordOperationPlugin(SnippetReflectionProvider snippetReflection, WordTypes wordTypes) { super(snippetReflection, wordTypes); } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java 2018-12-11 11:12:59.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java 2018-12-11 11:12:59.000000000 -0800 @@ -45,6 +45,7 @@ import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; import org.graalvm.compiler.nodes.util.GraphUtil; +import org.graalvm.compiler.word.Word; import jdk.internal.vm.compiler.word.LocationIdentity; import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant; @@ -70,7 +71,7 @@ } @NodeIntrinsic - public static native KlassPointer initializeKlass(KlassPointer value, Object string); + public static native KlassPointer initializeKlass(KlassPointer value, Word string); @Override public Node canonical(CanonicalizerTool tool) { --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java 2018-12-11 11:13:00.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java 2018-12-11 11:13:00.000000000 -0800 @@ -43,6 +43,7 @@ import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; import org.graalvm.compiler.nodes.util.GraphUtil; +import org.graalvm.compiler.word.Word; import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant; import jdk.vm.ci.hotspot.HotSpotObjectConstant; @@ -79,10 +80,10 @@ public static native Object resolveObject(Object value, Object symbol); @NodeIntrinsic - public static native KlassPointer resolveKlass(KlassPointer value, Object symbol); + public static native KlassPointer resolveKlass(KlassPointer value, Word symbol); @NodeIntrinsic - public static native KlassPointer resolveKlass(KlassPointer value, Object symbol, @ConstantNodeParameter HotSpotConstantLoadAction action); + public static native KlassPointer resolveKlass(KlassPointer value, Word symbol, @ConstantNodeParameter HotSpotConstantLoadAction action); @Override public Node canonical(CanonicalizerTool tool) { --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveMethodAndLoadCountersStubCall.java 2018-12-11 11:13:01.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveMethodAndLoadCountersStubCall.java 2018-12-11 11:13:01.000000000 -0800 @@ -43,6 +43,7 @@ import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; import org.graalvm.compiler.nodes.util.GraphUtil; +import org.graalvm.compiler.word.Word; import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.Value; @@ -67,7 +68,7 @@ } @NodeIntrinsic - public static native MethodCountersPointer resolveMethodAndLoadCounters(MethodPointer method, KlassPointer klassHint, Object methodDescription); + public static native MethodCountersPointer resolveMethodAndLoadCounters(MethodPointer method, KlassPointer klassHint, Word methodDescription); @Override public Node canonical(CanonicalizerTool tool) { --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java 2018-12-11 11:13:02.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java 2018-12-11 11:13:02.000000000 -0800 @@ -24,7 +24,6 @@ package org.graalvm.compiler.hotspot.phases; -import static jdk.vm.ci.meta.SpeculationLog.SpeculationReason; import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Required; import org.graalvm.compiler.core.common.PermanentBailoutException; @@ -77,6 +76,7 @@ import jdk.vm.ci.meta.DeoptimizationReason; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.SpeculationLog; +import jdk.vm.ci.meta.SpeculationLog.SpeculationReason; import jdk.vm.ci.runtime.JVMCICompiler; public class OnStackReplacementPhase extends Phase { --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/AESCryptSubstitutions.java 2018-12-11 11:13:03.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/AESCryptSubstitutions.java 2018-12-11 11:13:03.000000000 -0800 @@ -24,18 +24,20 @@ package org.graalvm.compiler.hotspot.replacements; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_INTRINSIC_CONTEXT; import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS; import static org.graalvm.compiler.hotspot.HotSpotBackend.DECRYPT_BLOCK; import static org.graalvm.compiler.hotspot.HotSpotBackend.DECRYPT_BLOCK_WITH_ORIGINAL_KEY; import static org.graalvm.compiler.hotspot.HotSpotBackend.ENCRYPT_BLOCK; +import static org.graalvm.compiler.hotspot.replacements.CipherBlockChainingSubstitutions.aesCryptType; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.VERY_SLOW_PATH_PROBABILITY; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability; import static org.graalvm.compiler.replacements.ReplacementsUtil.getArrayBaseOffset; import org.graalvm.compiler.api.replacements.ClassSubstitution; +import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.compiler.api.replacements.MethodSubstitution; import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; -import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.graph.Node.ConstantNodeParameter; import org.graalvm.compiler.graph.Node.NodeIntrinsic; import org.graalvm.compiler.nodes.ComputeObjectAddressNode; @@ -43,6 +45,7 @@ import org.graalvm.compiler.nodes.PiNode; import org.graalvm.compiler.nodes.extended.ForeignCallNode; import org.graalvm.compiler.nodes.extended.RawLoadNode; +import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext; import org.graalvm.compiler.word.Word; import jdk.internal.vm.compiler.word.LocationIdentity; import jdk.internal.vm.compiler.word.Pointer; @@ -60,28 +63,20 @@ @ClassSubstitution(className = "com.sun.crypto.provider.AESCrypt", optional = true) public class AESCryptSubstitutions { - static final long kOffset; - static final long lastKeyOffset; - static final Class AESCryptClass; - /** * The AES block size is a constant 128 bits as defined by the * standard. */ static final int AES_BLOCK_SIZE_IN_BYTES = 16; - static { - try { - // Need to use the system class loader as com.sun.crypto.provider.AESCrypt - // is normally loaded by the extension class loader which is not delegated - // to by the JVMCI class loader. - ClassLoader cl = ClassLoader.getSystemClassLoader(); - AESCryptClass = Class.forName("com.sun.crypto.provider.AESCrypt", true, cl); - kOffset = UnsafeAccess.UNSAFE.objectFieldOffset(AESCryptClass.getDeclaredField("K")); - lastKeyOffset = UnsafeAccess.UNSAFE.objectFieldOffset(AESCryptClass.getDeclaredField("lastKey")); - } catch (Exception ex) { - throw new GraalError(ex); - } + @Fold + static long kOffset(@Fold.InjectedParameter IntrinsicContext context) { + return HotSpotReplacementsUtil.getFieldOffset(aesCryptType(context), "K"); + } + + @Fold + static long lastKeyOffset(@Fold.InjectedParameter IntrinsicContext context) { + return HotSpotReplacementsUtil.getFieldOffset(aesCryptType(context), "lastKey"); } @MethodSubstitution(isStatic = false) @@ -123,8 +118,8 @@ private static void crypt(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt, boolean withOriginalKey) { checkArgs(in, inOffset, out, outOffset); - Object realReceiver = PiNode.piCastNonNull(rcvr, AESCryptClass); - Object kObject = RawLoadNode.load(realReceiver, kOffset, JavaKind.Object, LocationIdentity.any()); + Object realReceiver = PiNode.piCastNonNull(rcvr, aesCryptType(INJECTED_INTRINSIC_CONTEXT)); + Object kObject = RawLoadNode.load(realReceiver, kOffset(INJECTED_INTRINSIC_CONTEXT), JavaKind.Object, LocationIdentity.any()); Pointer kAddr = Word.objectToTrackedPointer(kObject).add(getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Int)); Word inAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(in, getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Byte) + inOffset)); Word outAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(out, getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Byte) + outOffset)); @@ -132,7 +127,7 @@ encryptBlockStub(ENCRYPT_BLOCK, inAddr, outAddr, kAddr); } else { if (withOriginalKey) { - Object lastKeyObject = RawLoadNode.load(realReceiver, lastKeyOffset, JavaKind.Object, LocationIdentity.any()); + Object lastKeyObject = RawLoadNode.load(realReceiver, lastKeyOffset(INJECTED_INTRINSIC_CONTEXT), JavaKind.Object, LocationIdentity.any()); Pointer lastKeyAddr = Word.objectToTrackedPointer(lastKeyObject).add(getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Byte)); decryptBlockWithOriginalKeyStub(DECRYPT_BLOCK_WITH_ORIGINAL_KEY, inAddr, outAddr, kAddr, lastKeyAddr); } else { --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CipherBlockChainingSubstitutions.java 2018-12-11 11:13:04.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CipherBlockChainingSubstitutions.java 2018-12-11 11:13:04.000000000 -0800 @@ -24,23 +24,24 @@ package org.graalvm.compiler.hotspot.replacements; -import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_METAACCESS; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_INTRINSIC_CONTEXT; import static org.graalvm.compiler.hotspot.HotSpotBackend.DECRYPT; import static org.graalvm.compiler.hotspot.HotSpotBackend.DECRYPT_WITH_ORIGINAL_KEY; import static org.graalvm.compiler.hotspot.HotSpotBackend.ENCRYPT; -import static org.graalvm.compiler.hotspot.replacements.UnsafeAccess.UNSAFE; +import static org.graalvm.compiler.nodes.PiNode.piCastNonNull; +import static org.graalvm.compiler.nodes.java.InstanceOfNode.doInstanceof; import org.graalvm.compiler.api.replacements.ClassSubstitution; import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.compiler.api.replacements.MethodSubstitution; import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; -import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.graph.Node.ConstantNodeParameter; import org.graalvm.compiler.graph.Node.NodeIntrinsic; import org.graalvm.compiler.nodes.ComputeObjectAddressNode; -import org.graalvm.compiler.nodes.PiNode; import org.graalvm.compiler.nodes.extended.ForeignCallNode; import org.graalvm.compiler.nodes.extended.RawLoadNode; +import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext; import org.graalvm.compiler.replacements.ReplacementsUtil; import org.graalvm.compiler.word.Word; import jdk.internal.vm.compiler.word.LocationIdentity; @@ -48,6 +49,7 @@ import jdk.internal.vm.compiler.word.WordFactory; import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.ResolvedJavaType; // JaCoCo Exclude @@ -57,38 +59,17 @@ @ClassSubstitution(className = "com.sun.crypto.provider.CipherBlockChaining", optional = true) public class CipherBlockChainingSubstitutions { - private static final long embeddedCipherOffset; - private static final long rOffset; - private static final Class cipherBlockChainingClass; - private static final Class feedbackCipherClass; - static { - try { - // Need to use the system class loader as com.sun.crypto.provider.FeedbackCipher - // is normally loaded by the extension class loader which is not delegated - // to by the JVMCI class loader. - ClassLoader cl = ClassLoader.getSystemClassLoader(); - - feedbackCipherClass = Class.forName("com.sun.crypto.provider.FeedbackCipher", true, cl); - embeddedCipherOffset = UNSAFE.objectFieldOffset(feedbackCipherClass.getDeclaredField("embeddedCipher")); - - cipherBlockChainingClass = Class.forName("com.sun.crypto.provider.CipherBlockChaining", true, cl); - rOffset = UNSAFE.objectFieldOffset(cipherBlockChainingClass.getDeclaredField("r")); - } catch (Exception ex) { - throw new GraalError(ex); - } - } - @Fold - static Class getAESCryptClass() { - return AESCryptSubstitutions.AESCryptClass; + static ResolvedJavaType aesCryptType(@Fold.InjectedParameter IntrinsicContext context) { + return HotSpotReplacementsUtil.getType(context, "Lcom/sun/crypto/provider/AESCrypt;"); } @MethodSubstitution(isStatic = false) static int encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass); - Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any()); - if (getAESCryptClass().isInstance(embeddedCipher)) { - Object aesCipher = getAESCryptClass().cast(embeddedCipher); + Object realReceiver = piCastNonNull(rcvr, HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT)); + Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset(INJECTED_INTRINSIC_CONTEXT), JavaKind.Object, LocationIdentity.any()); + if (doInstanceof(aesCryptType(INJECTED_INTRINSIC_CONTEXT), embeddedCipher)) { + Object aesCipher = piCastNonNull(embeddedCipher, aesCryptType(INJECTED_INTRINSIC_CONTEXT)); crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, true, false); return inLength; } else { @@ -96,12 +77,22 @@ } } + @Fold + static long embeddedCipherOffset(@Fold.InjectedParameter IntrinsicContext context) { + return HotSpotReplacementsUtil.getFieldOffset(HotSpotReplacementsUtil.getType(context, "Lcom/sun/crypto/provider/FeedbackCipher;"), "embeddedCipher"); + } + + @Fold + static long rOffset(@Fold.InjectedParameter IntrinsicContext intrinsicContext) { + return HotSpotReplacementsUtil.getFieldOffset(HotSpotReplacementsUtil.methodHolderClass(intrinsicContext), "r"); + } + @MethodSubstitution(isStatic = false, value = "implEncrypt") static int implEncrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass); - Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any()); - if (getAESCryptClass().isInstance(embeddedCipher)) { - Object aesCipher = getAESCryptClass().cast(embeddedCipher); + Object realReceiver = piCastNonNull(rcvr, HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT)); + Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset(INJECTED_INTRINSIC_CONTEXT), JavaKind.Object, LocationIdentity.any()); + if (doInstanceof(aesCryptType(INJECTED_INTRINSIC_CONTEXT), embeddedCipher)) { + Object aesCipher = piCastNonNull(embeddedCipher, aesCryptType(INJECTED_INTRINSIC_CONTEXT)); crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, true, false); return inLength; } else { @@ -111,10 +102,10 @@ @MethodSubstitution(isStatic = false) static int decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass); - Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any()); - if (in != out && getAESCryptClass().isInstance(embeddedCipher)) { - Object aesCipher = getAESCryptClass().cast(embeddedCipher); + Object realReceiver = piCastNonNull(rcvr, HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT)); + Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset(INJECTED_INTRINSIC_CONTEXT), JavaKind.Object, LocationIdentity.any()); + if (in != out && doInstanceof(aesCryptType(INJECTED_INTRINSIC_CONTEXT), embeddedCipher)) { + Object aesCipher = piCastNonNull(embeddedCipher, aesCryptType(INJECTED_INTRINSIC_CONTEXT)); crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false, false); return inLength; } else { @@ -124,10 +115,10 @@ @MethodSubstitution(isStatic = false) static int implDecrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass); - Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any()); - if (in != out && getAESCryptClass().isInstance(embeddedCipher)) { - Object aesCipher = getAESCryptClass().cast(embeddedCipher); + Object realReceiver = piCastNonNull(rcvr, HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT)); + Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset(INJECTED_INTRINSIC_CONTEXT), JavaKind.Object, LocationIdentity.any()); + if (in != out && doInstanceof(aesCryptType(INJECTED_INTRINSIC_CONTEXT), embeddedCipher)) { + Object aesCipher = piCastNonNull(embeddedCipher, aesCryptType(INJECTED_INTRINSIC_CONTEXT)); crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false, false); return inLength; } else { @@ -141,10 +132,10 @@ */ @MethodSubstitution(isStatic = false, value = "decrypt") static int decryptWithOriginalKey(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass); - Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any()); - if (in != out && getAESCryptClass().isInstance(embeddedCipher)) { - Object aesCipher = getAESCryptClass().cast(embeddedCipher); + Object realReceiver = piCastNonNull(rcvr, HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT)); + Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset(INJECTED_INTRINSIC_CONTEXT), JavaKind.Object, LocationIdentity.any()); + if (in != out && doInstanceof(aesCryptType(INJECTED_INTRINSIC_CONTEXT), embeddedCipher)) { + Object aesCipher = piCastNonNull(embeddedCipher, aesCryptType(INJECTED_INTRINSIC_CONTEXT)); crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false, true); return inLength; } else { @@ -157,10 +148,10 @@ */ @MethodSubstitution(isStatic = false, value = "implDecrypt") static int implDecryptWithOriginalKey(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass); - Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any()); - if (in != out && getAESCryptClass().isInstance(embeddedCipher)) { - Object aesCipher = getAESCryptClass().cast(embeddedCipher); + Object realReceiver = piCastNonNull(rcvr, HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT)); + Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset(INJECTED_INTRINSIC_CONTEXT), JavaKind.Object, LocationIdentity.any()); + if (in != out && doInstanceof(aesCryptType(INJECTED_INTRINSIC_CONTEXT), embeddedCipher)) { + Object aesCipher = piCastNonNull(embeddedCipher, aesCryptType(INJECTED_INTRINSIC_CONTEXT)); crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false, true); return inLength; } else { @@ -170,10 +161,10 @@ private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt, boolean withOriginalKey) { AESCryptSubstitutions.checkArgs(in, inOffset, out, outOffset); - Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass); - Object aesCipher = getAESCryptClass().cast(embeddedCipher); - Object kObject = RawLoadNode.load(aesCipher, AESCryptSubstitutions.kOffset, JavaKind.Object, LocationIdentity.any()); - Object rObject = RawLoadNode.load(realReceiver, rOffset, JavaKind.Object, LocationIdentity.any()); + Object realReceiver = piCastNonNull(rcvr, HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT)); + Object aesCipher = piCastNonNull(embeddedCipher, aesCryptType(INJECTED_INTRINSIC_CONTEXT)); + Object kObject = RawLoadNode.load(aesCipher, AESCryptSubstitutions.kOffset(INJECTED_INTRINSIC_CONTEXT), JavaKind.Object, LocationIdentity.any()); + Object rObject = RawLoadNode.load(realReceiver, rOffset(INJECTED_INTRINSIC_CONTEXT), JavaKind.Object, LocationIdentity.any()); Pointer kAddr = Word.objectToTrackedPointer(kObject).add(ReplacementsUtil.getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Int)); Pointer rAddr = Word.objectToTrackedPointer(rObject).add(ReplacementsUtil.getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Byte)); Word inAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(in, ReplacementsUtil.getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Byte) + inOffset)); @@ -182,7 +173,7 @@ encryptAESCryptStub(ENCRYPT, inAddr, outAddr, kAddr, rAddr, inLength); } else { if (withOriginalKey) { - Object lastKeyObject = RawLoadNode.load(aesCipher, AESCryptSubstitutions.lastKeyOffset, JavaKind.Object, LocationIdentity.any()); + Object lastKeyObject = RawLoadNode.load(aesCipher, AESCryptSubstitutions.lastKeyOffset(INJECTED_INTRINSIC_CONTEXT), JavaKind.Object, LocationIdentity.any()); Pointer lastKeyAddr = Word.objectToTrackedPointer(lastKeyObject).add(ReplacementsUtil.getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Byte)); decryptAESCryptWithOriginalKeyStub(DECRYPT_WITH_ORIGINAL_KEY, inAddr, outAddr, kAddr, rAddr, inLength, lastKeyAddr); } else { --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java 2018-12-11 11:13:05.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java 2018-12-11 11:13:05.000000000 -0800 @@ -27,7 +27,8 @@ import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS; import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_VMCONFIG; import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.VERIFY_OOP; -import static org.graalvm.compiler.hotspot.replacements.UnsafeAccess.UNSAFE; + +import java.lang.ref.Reference; import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.compiler.api.replacements.Fold.InjectedParameter; @@ -40,10 +41,10 @@ import org.graalvm.compiler.graph.Node.NodeIntrinsic; import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; -import org.graalvm.compiler.nodes.ComputeObjectAddressNode; import org.graalvm.compiler.hotspot.word.KlassPointer; import org.graalvm.compiler.nodes.CanonicalizableLocation; import org.graalvm.compiler.nodes.CompressionNode; +import org.graalvm.compiler.nodes.ComputeObjectAddressNode; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.NamedLocationIdentity; import org.graalvm.compiler.nodes.NodeView; @@ -52,6 +53,7 @@ import org.graalvm.compiler.nodes.extended.LoadHubNode; import org.graalvm.compiler.nodes.extended.RawLoadNode; import org.graalvm.compiler.nodes.extended.StoreHubNode; +import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext; import org.graalvm.compiler.nodes.memory.Access; import org.graalvm.compiler.nodes.memory.address.AddressNode; import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; @@ -70,7 +72,10 @@ import jdk.vm.ci.meta.Assumptions; import jdk.vm.ci.meta.Assumptions.AssumptionResult; import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.UnresolvedJavaType; //JaCoCo Exclude @@ -133,6 +138,28 @@ } } + public static ResolvedJavaType methodHolderClass(@Fold.InjectedParameter IntrinsicContext context) { + return context.getOriginalMethod().getDeclaringClass(); + } + + static ResolvedJavaType getType(@Fold.InjectedParameter IntrinsicContext context, String typeName) { + try { + UnresolvedJavaType unresolved = UnresolvedJavaType.create(typeName); + return unresolved.resolve(methodHolderClass(context)); + } catch (LinkageError e) { + throw new GraalError(e); + } + } + + static int getFieldOffset(ResolvedJavaType type, String fieldName) { + for (ResolvedJavaField field : type.getInstanceFields(true)) { + if (field.getName().equals(fieldName)) { + return field.getOffset(); + } + } + throw new GraalError("missing field " + fieldName); + } + public static HotSpotJVMCIRuntime runtime() { return HotSpotJVMCIRuntime.runtime(); } @@ -143,9 +170,8 @@ } @Fold - public static GraalHotSpotVMConfig config(@InjectedParameter GraalHotSpotVMConfig config) { - assert config != null; - return config; + public static int klassLayoutHelperNeutralValue(@InjectedParameter GraalHotSpotVMConfig config) { + return config.klassLayoutHelperNeutralValue; } @Fold @@ -199,13 +225,6 @@ return config.pendingExceptionOffset; } - public static final LocationIdentity OBJECT_RESULT_LOCATION = NamedLocationIdentity.mutable("ObjectResult"); - - @Fold - static int objectResultOffset(@InjectedParameter GraalHotSpotVMConfig config) { - return config.threadObjectResultOffset; - } - /** * @see GraalHotSpotVMConfig#threadExceptionOopOffset */ @@ -262,17 +281,6 @@ return thread.readObject(threadPendingExceptionOffset(INJECTED_VMCONFIG), PENDING_EXCEPTION_LOCATION); } - /** - * Gets and clears the object result from a runtime call stored in a thread local. - * - * @return the object that was in the thread local - */ - public static Object getAndClearObjectResult(Word thread) { - Object result = thread.readObject(objectResultOffset(INJECTED_VMCONFIG), OBJECT_RESULT_LOCATION); - thread.writeObject(objectResultOffset(INJECTED_VMCONFIG), null, OBJECT_RESULT_LOCATION); - return result; - } - /* * As far as Java code is concerned this can be considered immutable: it is set just after the * JavaThread is created, before it is published. After that, it is never changed. @@ -307,8 +315,8 @@ } @Fold - public static int pageSize() { - return UNSAFE.pageSize(); + public static int pageSize(@InjectedParameter GraalHotSpotVMConfig config) { + return config.vmPageSize; } public static final LocationIdentity PROTOTYPE_MARK_WORD_LOCATION = NamedLocationIdentity.mutable("PrototypeMarkWord"); @@ -348,6 +356,56 @@ } }; + @Fold + public static int allocatePrefetchStyle(@InjectedParameter GraalHotSpotVMConfig config) { + return config.allocatePrefetchStyle; + } + + @Fold + public static int allocatePrefetchLines(@InjectedParameter GraalHotSpotVMConfig config) { + return config.allocatePrefetchLines; + } + + @Fold + public static int allocatePrefetchDistance(@InjectedParameter GraalHotSpotVMConfig config) { + return config.allocatePrefetchDistance; + } + + @Fold + public static int allocateInstancePrefetchLines(@InjectedParameter GraalHotSpotVMConfig config) { + return config.allocateInstancePrefetchLines; + } + + @Fold + public static int allocatePrefetchStepSize(@InjectedParameter GraalHotSpotVMConfig config) { + return config.allocatePrefetchStepSize; + } + + @Fold + public static int invocationCounterIncrement(@InjectedParameter GraalHotSpotVMConfig config) { + return config.invocationCounterIncrement; + } + + @Fold + public static int invocationCounterOffset(@InjectedParameter GraalHotSpotVMConfig config) { + return config.invocationCounterOffset; + } + + @Fold + public static int backedgeCounterOffset(@InjectedParameter GraalHotSpotVMConfig config) { + return config.backedgeCounterOffset; + } + + @Fold + public static int invocationCounterShift(@InjectedParameter GraalHotSpotVMConfig config) { + return config.invocationCounterShift; + } + + @Fold + public static int stackBias(@InjectedParameter GraalHotSpotVMConfig config) { + return config.stackBias; + } + @NodeIntrinsic(value = KlassLayoutHelperNode.class) public static native int readLayoutHelper(KlassPointer object); @@ -365,7 +423,7 @@ * sure these are still ints and haven't changed. */ final int layoutHelper = readLayoutHelper(klassNonNull); - final int layoutHelperNeutralValue = config(INJECTED_VMCONFIG).klassLayoutHelperNeutralValue; + final int layoutHelperNeutralValue = klassLayoutHelperNeutralValue(INJECTED_VMCONFIG); return (layoutHelper < layoutHelperNeutralValue); } @@ -518,16 +576,16 @@ * Idiom for making {@link GraalHotSpotVMConfig} a constant. */ @Fold - public static GraalHotSpotVMConfig getConfig(@InjectedParameter GraalHotSpotVMConfig config) { - return config; + public static int objectAlignment(@InjectedParameter GraalHotSpotVMConfig config) { + return config.objectAlignment; } /** - * Calls {@link #arrayAllocationSize(int, int, int, GraalHotSpotVMConfig)} using an injected VM - * configuration object. + * Calls {@link #arrayAllocationSize(int, int, int, int)} using an injected VM configuration + * object. */ public static int arrayAllocationSize(int length, int headerSize, int log2ElementSize) { - return arrayAllocationSize(length, headerSize, log2ElementSize, getConfig(INJECTED_VMCONFIG)); + return arrayAllocationSize(length, headerSize, log2ElementSize, objectAlignment(INJECTED_VMCONFIG)); } /** @@ -538,12 +596,11 @@ * @param length the number of elements in the array * @param headerSize the size of the array header * @param log2ElementSize log2 of the size of an element in the array - * @param config the VM configuration providing the - * {@linkplain GraalHotSpotVMConfig#objectAlignment object alignment requirement} + * @param alignment the {@linkplain GraalHotSpotVMConfig#objectAlignment object alignment + * requirement} * @return the size of the memory chunk */ - public static int arrayAllocationSize(int length, int headerSize, int log2ElementSize, GraalHotSpotVMConfig config) { - int alignment = config.objectAlignment; + public static int arrayAllocationSize(int length, int headerSize, int log2ElementSize, int alignment) { int size = (length << log2ElementSize) + headerSize + (alignment - 1); int mask = ~(alignment - 1); return size & mask; @@ -786,12 +843,8 @@ } @Fold - public static long referentOffset() { - try { - return UNSAFE.objectFieldOffset(java.lang.ref.Reference.class.getDeclaredField("referent")); - } catch (Exception e) { - throw new GraalError(e); - } + public static long referentOffset(@InjectedParameter MetaAccessProvider metaAccessProvider) { + return getFieldOffset(metaAccessProvider.lookupJavaType(Reference.class), "referent"); } public static final LocationIdentity OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION = new HotSpotOptimizingLocationIdentity("ObjArrayKlass::_element_klass") { --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java 2018-12-11 11:13:06.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java 2018-12-11 11:13:06.000000000 -0800 @@ -26,7 +26,9 @@ import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE; import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_OPTIONVALUES; import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG; +import static org.graalvm.compiler.hotspot.nodes.AcquiredCASLockNode.mark; import static org.graalvm.compiler.hotspot.nodes.BeginLockScopeNode.beginLockScope; import static org.graalvm.compiler.hotspot.nodes.EndLockScopeNode.endLockScope; import static org.graalvm.compiler.hotspot.nodes.VMErrorNode.vmError; @@ -40,7 +42,6 @@ import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.ageMaskInPlace; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.biasedLockMaskInPlace; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.biasedLockPattern; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.config; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.epochMaskInPlace; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadWordFromObject; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.lockDisplacedMarkOffset; @@ -53,6 +54,7 @@ import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.pageSize; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.prototypeMarkWordOffset; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.stackBias; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.unlockedMask; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useBiasedLocking; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.verifyOop; @@ -69,7 +71,10 @@ import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.VERY_FAST_PATH_PROBABILITY; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability; +import static org.graalvm.compiler.nodes.extended.MembarNode.memoryBarrier; import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER; +import static jdk.internal.vm.compiler.word.WordFactory.unsigned; +import static jdk.internal.vm.compiler.word.WordFactory.zero; import java.util.List; @@ -89,7 +94,6 @@ import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider; -import org.graalvm.compiler.hotspot.nodes.AcquiredCASLockNode; import org.graalvm.compiler.hotspot.nodes.CurrentLockNode; import org.graalvm.compiler.hotspot.nodes.FastAcquireBiasedLockNode; import org.graalvm.compiler.hotspot.nodes.MonitorCounterNode; @@ -219,13 +223,13 @@ private static final boolean PROFILE_CONTEXT = false; @Fold - static boolean doProfile(OptionValues options) { + static boolean doProfile(@Fold.InjectedParameter OptionValues options) { return ProfileMonitors.getValue(options); } @Snippet public static void monitorenter(Object object, KlassPointer hub, @ConstantParameter int lockDepth, @ConstantParameter Register threadRegister, @ConstantParameter Register stackPointerRegister, - @ConstantParameter boolean trace, @ConstantParameter OptionValues options, @ConstantParameter Counters counters) { + @ConstantParameter boolean trace, @ConstantParameter Counters counters) { verifyOop(object); // Load the mark word - this includes a null-check on object @@ -238,17 +242,17 @@ trace(trace, " lock: 0x%016lx\n", lock); trace(trace, " mark: 0x%016lx\n", mark); - incCounter(options); + incCounter(); if (useBiasedLocking(INJECTED_VMCONFIG)) { - if (tryEnterBiased(object, hub, lock, mark, threadRegister, trace, options, counters)) { + if (tryEnterBiased(object, hub, lock, mark, threadRegister, trace, counters)) { return; } // not biased, fall-through } - if (inlineFastLockSupported(options) && probability(SLOW_PATH_PROBABILITY, mark.and(monitorMask(INJECTED_VMCONFIG)).notEqual(0))) { + if (inlineFastLockSupported() && probability(SLOW_PATH_PROBABILITY, mark.and(monitorMask(INJECTED_VMCONFIG)).notEqual(0))) { // Inflated case - if (tryEnterInflated(object, lock, mark, threadRegister, trace, options, counters)) { + if (tryEnterInflated(object, lock, mark, threadRegister, trace, counters)) { return; } } else { @@ -266,9 +270,9 @@ // (address of) the lock slot into the object's mark word. Word currentMark = objectPointer.compareAndSwapWord(markOffset(INJECTED_VMCONFIG), unlockedMark, lock, MARK_WORD_LOCATION); if (probability(FAST_PATH_PROBABILITY, currentMark.equal(unlockedMark))) { - traceObject(trace, "+lock{cas}", object, true, options); + traceObject(trace, "+lock{cas}", object, true); counters.lockCas.inc(); - AcquiredCASLockNode.mark(object); + mark(object); return; } else { trace(trace, " currentMark: 0x%016lx\n", currentMark); @@ -287,16 +291,16 @@ // // assuming both the stack pointer and page_size have their least // significant 2 bits cleared and page_size is a power of 2 - final Word alignedMask = WordFactory.unsigned(wordSize() - 1); - final Word stackPointer = registerAsWord(stackPointerRegister).add(config(INJECTED_VMCONFIG).stackBias); - if (probability(FAST_PATH_PROBABILITY, currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize())).equal(0))) { + final Word alignedMask = unsigned(wordSize() - 1); + final Word stackPointer = registerAsWord(stackPointerRegister).add(stackBias(INJECTED_VMCONFIG)); + if (probability(FAST_PATH_PROBABILITY, currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize(INJECTED_VMCONFIG))).equal(0))) { // Recursively locked => write 0 to the lock slot - lock.writeWord(lockDisplacedMarkOffset(INJECTED_VMCONFIG), WordFactory.zero(), DISPLACED_MARK_WORD_LOCATION); - traceObject(trace, "+lock{cas:recursive}", object, true, options); + lock.writeWord(lockDisplacedMarkOffset(INJECTED_VMCONFIG), zero(), DISPLACED_MARK_WORD_LOCATION); + traceObject(trace, "+lock{cas:recursive}", object, true); counters.lockCasRecursive.inc(); return; } - traceObject(trace, "+lock{stub:failed-cas/stack}", object, true, options); + traceObject(trace, "+lock{stub:failed-cas/stack}", object, true); counters.lockStubFailedCas.inc(); } } @@ -304,7 +308,7 @@ monitorenterStubC(MONITORENTER, object, lock); } - private static boolean tryEnterBiased(Object object, KlassPointer hub, Word lock, Word mark, Register threadRegister, boolean trace, OptionValues options, Counters counters) { + private static boolean tryEnterBiased(Object object, KlassPointer hub, Word lock, Word mark, Register threadRegister, boolean trace, Counters counters) { // See whether the lock is currently biased toward our thread and // whether the epoch is still valid. // Note that the runtime guarantees sufficient alignment of JavaThread @@ -321,7 +325,7 @@ trace(trace, " tmp: 0x%016lx\n", tmp); if (probability(FAST_PATH_PROBABILITY, tmp.equal(0))) { // Object is already biased to current thread -> done - traceObject(trace, "+lock{bias:existing}", object, true, options); + traceObject(trace, "+lock{bias:existing}", object, true); counters.lockBiasExisting.inc(); FastAcquireBiasedLockNode.mark(object); return true; @@ -362,14 +366,14 @@ trace(trace, " biasedMark: 0x%016lx\n", biasedMark); if (probability(VERY_FAST_PATH_PROBABILITY, objectPointer.logicCompareAndSwapWord(markOffset(INJECTED_VMCONFIG), unbiasedMark, biasedMark, MARK_WORD_LOCATION))) { // Object is now biased to current thread -> done - traceObject(trace, "+lock{bias:acquired}", object, true, options); + traceObject(trace, "+lock{bias:acquired}", object, true); counters.lockBiasAcquired.inc(); return true; } // If the biasing toward our thread failed, this means that another thread // owns the bias and we need to revoke that bias. The revocation will occur // in the interpreter runtime. - traceObject(trace, "+lock{stub:revoke}", object, true, options); + traceObject(trace, "+lock{stub:revoke}", object, true); counters.lockStubRevoke.inc(); } else { // At this point we know the epoch has expired, meaning that the @@ -382,14 +386,14 @@ trace(trace, " biasedMark: 0x%016lx\n", biasedMark); if (probability(VERY_FAST_PATH_PROBABILITY, objectPointer.logicCompareAndSwapWord(markOffset(INJECTED_VMCONFIG), mark, biasedMark, MARK_WORD_LOCATION))) { // Object is now biased to current thread -> done - traceObject(trace, "+lock{bias:transfer}", object, true, options); + traceObject(trace, "+lock{bias:transfer}", object, true); counters.lockBiasTransfer.inc(); return true; } // If the biasing toward our thread failed, then another thread // succeeded in biasing it toward itself and we need to revoke that // bias. The revocation will occur in the runtime in the slow case. - traceObject(trace, "+lock{stub:epoch-expired}", object, true, options); + traceObject(trace, "+lock{stub:epoch-expired}", object, true); counters.lockStubEpochExpired.inc(); } // slow-path runtime-call @@ -424,19 +428,19 @@ } @Fold - public static boolean useFastInflatedLocking(OptionValues options) { + public static boolean useFastInflatedLocking(@Fold.InjectedParameter OptionValues options) { return SimpleFastInflatedLocking.getValue(options); } - private static boolean inlineFastLockSupported(OptionValues options) { - return inlineFastLockSupported(INJECTED_VMCONFIG, options); + private static boolean inlineFastLockSupported() { + return inlineFastLockSupported(INJECTED_VMCONFIG, INJECTED_OPTIONVALUES); } private static boolean inlineFastLockSupported(GraalHotSpotVMConfig config, OptionValues options) { return useFastInflatedLocking(options) && monitorMask(config) >= 0 && objectMonitorOwnerOffset(config) >= 0; } - private static boolean tryEnterInflated(Object object, Word lock, Word mark, Register threadRegister, boolean trace, OptionValues options, Counters counters) { + private static boolean tryEnterInflated(Object object, Word lock, Word mark, Register threadRegister, boolean trace, Counters counters) { // write non-zero value to lock slot lock.writeWord(lockDisplacedMarkOffset(INJECTED_VMCONFIG), lock, DISPLACED_MARK_WORD_LOCATION); // mark is a pointer to the ObjectMonitor + monitorMask @@ -447,15 +451,15 @@ // it appears unlocked (owner == 0) if (probability(FREQUENT_PROBABILITY, monitor.logicCompareAndSwapWord(ownerOffset, owner, registerAsWord(threadRegister), OBJECT_MONITOR_OWNER_LOCATION))) { // success - traceObject(trace, "+lock{inflated:cas}", object, true, options); + traceObject(trace, "+lock{inflated:cas}", object, true); counters.inflatedCas.inc(); return true; } else { - traceObject(trace, "+lock{stub:inflated:failed-cas}", object, true, options); + traceObject(trace, "+lock{stub:inflated:failed-cas}", object, true); counters.inflatedFailedCas.inc(); } } else { - traceObject(trace, "+lock{stub:inflated:owned}", object, true, options); + traceObject(trace, "+lock{stub:inflated:owned}", object, true); counters.inflatedOwned.inc(); } return false; @@ -465,22 +469,22 @@ * Calls straight out to the monitorenter stub. */ @Snippet - public static void monitorenterStub(Object object, @ConstantParameter int lockDepth, @ConstantParameter boolean trace, @ConstantParameter OptionValues options) { + public static void monitorenterStub(Object object, @ConstantParameter int lockDepth, @ConstantParameter boolean trace) { verifyOop(object); - incCounter(options); + incCounter(); if (object == null) { DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException); } // BeginLockScope nodes do not read from object so a use of object // cannot float about the null check above final Word lock = beginLockScope(lockDepth); - traceObject(trace, "+lock{stub}", object, true, options); + traceObject(trace, "+lock{stub}", object, true); monitorenterStubC(MONITORENTER, object, lock); } @Snippet public static void monitorexit(Object object, @ConstantParameter int lockDepth, @ConstantParameter Register threadRegister, @ConstantParameter boolean trace, - @ConstantParameter OptionValues options, @ConstantParameter Counters counters) { + @ConstantParameter Counters counters) { trace(trace, " object: 0x%016lx\n", Word.objectToTrackedPointer(object)); final Word mark = loadWordFromObject(object, markOffset(INJECTED_VMCONFIG)); if (useBiasedLocking(INJECTED_VMCONFIG)) { @@ -493,8 +497,8 @@ trace(trace, " mark: 0x%016lx\n", mark); if (probability(FREQUENT_PROBABILITY, mark.and(biasedLockMaskInPlace(INJECTED_VMCONFIG)).equal(WordFactory.unsigned(biasedLockPattern(INJECTED_VMCONFIG))))) { endLockScope(); - decCounter(options); - traceObject(trace, "-lock{bias}", object, false, options); + decCounter(); + traceObject(trace, "-lock{bias}", object, false); counters.unlockBias.inc(); return; } @@ -508,10 +512,10 @@ if (probability(NOT_LIKELY_PROBABILITY, displacedMark.equal(0))) { // Recursive locking => done - traceObject(trace, "-lock{recursive}", object, false, options); + traceObject(trace, "-lock{recursive}", object, false); counters.unlockCasRecursive.inc(); } else { - if (!tryExitInflated(object, mark, lock, threadRegister, trace, options, counters)) { + if (!tryExitInflated(object, mark, lock, threadRegister, trace, counters)) { verifyOop(object); // Test if object's mark word is pointing to the displaced mark word, and if so, // restore @@ -519,18 +523,18 @@ // the displaced mark word, do unlocking via runtime call. Pointer objectPointer = Word.objectToTrackedPointer(object); if (probability(VERY_FAST_PATH_PROBABILITY, objectPointer.logicCompareAndSwapWord(markOffset(INJECTED_VMCONFIG), lock, displacedMark, MARK_WORD_LOCATION))) { - traceObject(trace, "-lock{cas}", object, false, options); + traceObject(trace, "-lock{cas}", object, false); counters.unlockCas.inc(); } else { // The object's mark word was not pointing to the displaced header - traceObject(trace, "-lock{stub}", object, false, options); + traceObject(trace, "-lock{stub}", object, false); counters.unlockStub.inc(); monitorexitStubC(MONITOREXIT, object, lock); } } } endLockScope(); - decCounter(options); + decCounter(); } private static boolean inlineFastUnlockSupported(OptionValues options) { @@ -542,8 +546,8 @@ objectMonitorOwnerOffset(config) >= 0 && objectMonitorRecursionsOffset(config) >= 0; } - private static boolean tryExitInflated(Object object, Word mark, Word lock, Register threadRegister, boolean trace, OptionValues options, Counters counters) { - if (!inlineFastUnlockSupported(options)) { + private static boolean tryExitInflated(Object object, Word mark, Word lock, Register threadRegister, boolean trace, Counters counters) { + if (!inlineFastUnlockSupported(INJECTED_OPTIONVALUES)) { return false; } if (probability(SLOW_PATH_PROBABILITY, mark.and(monitorMask(INJECTED_VMCONFIG)).notEqual(0))) { @@ -565,15 +569,15 @@ // cxq == 0 && entryList == 0 // Nobody is waiting, success // release_store - MembarNode.memoryBarrier(LOAD_STORE | STORE_STORE); - monitor.writeWord(ownerOffset, WordFactory.zero()); - traceObject(trace, "-lock{inflated:simple}", object, false, options); + memoryBarrier(LOAD_STORE | STORE_STORE); + monitor.writeWord(ownerOffset, zero()); + traceObject(trace, "-lock{inflated:simple}", object, false); counters.unlockInflatedSimple.inc(); return true; } } counters.unlockStubInflated.inc(); - traceObject(trace, "-lock{stub:inflated}", object, false, options); + traceObject(trace, "-lock{stub:inflated}", object, false); monitorexitStubC(MONITOREXIT, object, lock); return true; } @@ -584,17 +588,17 @@ * Calls straight out to the monitorexit stub. */ @Snippet - public static void monitorexitStub(Object object, @ConstantParameter int lockDepth, @ConstantParameter boolean trace, @ConstantParameter OptionValues options) { + public static void monitorexitStub(Object object, @ConstantParameter int lockDepth, @ConstantParameter boolean trace) { verifyOop(object); - traceObject(trace, "-lock{stub}", object, false, options); + traceObject(trace, "-lock{stub}", object, false); final Word lock = CurrentLockNode.currentLock(lockDepth); monitorexitStubC(MONITOREXIT, object, lock); endLockScope(); - decCounter(options); + decCounter(); } - public static void traceObject(boolean enabled, String action, Object object, boolean enter, OptionValues options) { - if (doProfile(options)) { + public static void traceObject(boolean enabled, String action, Object object, boolean enter) { + if (doProfile(INJECTED_OPTIONVALUES)) { DynamicCounterNode.counter(enter ? "number of monitor enters" : "number of monitor exits", action, 1, PROFILE_CONTEXT); } if (enabled) { @@ -622,20 +626,20 @@ static native void bkpt(Object object, Word mark, Word tmp, Word value); @Fold - static boolean verifyBalancedMonitors(OptionValues options) { + static boolean verifyBalancedMonitors(@Fold.InjectedParameter OptionValues options) { return VerifyBalancedMonitors.getValue(options); } - public static void incCounter(OptionValues options) { - if (verifyBalancedMonitors(options)) { + static void incCounter() { + if (verifyBalancedMonitors(INJECTED_OPTIONVALUES)) { final Word counter = MonitorCounterNode.counter(); final int count = counter.readInt(0, MONITOR_COUNTER_LOCATION); counter.writeInt(0, count + 1, MONITOR_COUNTER_LOCATION); } } - public static void decCounter(OptionValues options) { - if (verifyBalancedMonitors(options)) { + public static void decCounter() { + if (verifyBalancedMonitors(INJECTED_OPTIONVALUES)) { final Word counter = MonitorCounterNode.counter(); final int count = counter.readInt(0, MONITOR_COUNTER_LOCATION); counter.writeInt(0, count - 1, MONITOR_COUNTER_LOCATION); @@ -750,14 +754,12 @@ args.addConst("threadRegister", registers.getThreadRegister()); args.addConst("stackPointerRegister", registers.getStackPointerRegister()); args.addConst("trace", isTracingEnabledForType(monitorenterNode.object()) || isTracingEnabledForMethod(graph)); - args.addConst("options", graph.getOptions()); args.addConst("counters", counters); } else { args = new Arguments(monitorenterStub, graph.getGuardsStage(), tool.getLoweringStage()); args.add("object", monitorenterNode.object()); args.addConst("lockDepth", monitorenterNode.getMonitorId().getLockDepth()); args.addConst("trace", isTracingEnabledForType(monitorenterNode.object()) || isTracingEnabledForMethod(graph)); - args.addConst("options", graph.getOptions()); args.addConst("counters", counters); } @@ -777,7 +779,6 @@ args.addConst("lockDepth", monitorexitNode.getMonitorId().getLockDepth()); args.addConst("threadRegister", registers.getThreadRegister()); args.addConst("trace", isTracingEnabledForType(monitorexitNode.object()) || isTracingEnabledForMethod(graph)); - args.addConst("options", graph.getOptions()); args.addConst("counters", counters); template(monitorexitNode, args).instantiate(providers.getMetaAccess(), monitorexitNode, DEFAULT_REPLACER, args); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java 2018-12-11 11:13:08.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java 2018-12-11 11:13:07.000000000 -0800 @@ -28,6 +28,7 @@ import static jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint; import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; import static org.graalvm.compiler.core.common.calc.UnsignedMath.belowThan; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_OPTIONVALUES; import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_VMCONFIG; import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_ARRAY; import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_ARRAY_OR_NULL; @@ -41,10 +42,14 @@ import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.PROTOTYPE_MARK_WORD_LOCATION; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_END_LOCATION; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_TOP_LOCATION; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.allocateInstancePrefetchLines; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.allocatePrefetchDistance; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.allocatePrefetchLines; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.allocatePrefetchStepSize; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.allocatePrefetchStyle; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayAllocationSize; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayKlassOffset; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayLengthOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.config; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.initializeObjectHeader; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.instanceHeaderSize; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.isInstanceKlassFullyInitialized; @@ -151,7 +156,7 @@ } @Fold - static String createName(String path, String typeContext, OptionValues options) { + static String createName(@Fold.InjectedParameter OptionValues options, String path, String typeContext) { switch (ProfileAllocationsContext.getValue(options)) { case AllocatingMethod: return ""; @@ -168,34 +173,33 @@ } @Fold - static boolean doProfile(OptionValues options) { + static boolean doProfile(@Fold.InjectedParameter OptionValues options) { return ProfileAllocations.getValue(options); } @Fold - static boolean withContext(OptionValues options) { + static boolean withContext(@Fold.InjectedParameter OptionValues options) { ProfileContext context = ProfileAllocationsContext.getValue(options); return context == ProfileContext.AllocatingMethod || context == ProfileContext.AllocatedTypesInMethod; } - protected static void profileAllocation(String path, long size, String typeContext, OptionValues options) { - if (doProfile(options)) { - String name = createName(path, typeContext, options); + protected static void profileAllocation(String path, long size, String typeContext) { + if (doProfile(INJECTED_OPTIONVALUES)) { + String name = createName(INJECTED_OPTIONVALUES, path, typeContext); - boolean context = withContext(options); + boolean context = withContext(INJECTED_OPTIONVALUES); DynamicCounterNode.counter("number of bytes allocated", name, size, context); DynamicCounterNode.counter("number of allocations", name, 1, context); } } public static void emitPrefetchAllocate(Word address, boolean isArray) { - GraalHotSpotVMConfig config = config(INJECTED_VMCONFIG); - if (config.allocatePrefetchStyle > 0) { + if (allocatePrefetchStyle(INJECTED_VMCONFIG) > 0) { // Insert a prefetch for each allocation only on the fast-path // Generate several prefetch instructions. - int lines = isArray ? config.allocatePrefetchLines : config.allocateInstancePrefetchLines; - int stepSize = config.allocatePrefetchStepSize; - int distance = config.allocatePrefetchDistance; + int lines = isArray ? allocatePrefetchLines(INJECTED_VMCONFIG) : allocateInstancePrefetchLines(INJECTED_VMCONFIG); + int stepSize = allocatePrefetchStepSize(INJECTED_VMCONFIG); + int distance = allocatePrefetchDistance(INJECTED_VMCONFIG); ExplodeLoopNode.explodeLoop(); for (int i = 0; i < lines; i++) { PrefetchAllocateNode.prefetch(OffsetAddressNode.address(address, distance)); @@ -206,13 +210,13 @@ @Snippet public static Object allocateInstance(@ConstantParameter int size, KlassPointer hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, - @ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext, @ConstantParameter OptionValues options, + @ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext, @ConstantParameter Counters counters) { - return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, hub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, options, counters)); + return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, hub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, counters)); } public static Object allocateInstanceHelper(int size, KlassPointer hub, Word prototypeMarkWord, boolean fillContents, - Register threadRegister, boolean constantSize, String typeContext, OptionValues options, Counters counters) { + Register threadRegister, boolean constantSize, String typeContext, Counters counters) { Object result; Word thread = registerAsWord(threadRegister); Word top = readTlabTop(thread); @@ -223,12 +227,13 @@ emitPrefetchAllocate(newTop, false); result = formatObject(hub, size, top, prototypeMarkWord, fillContents, constantSize, counters); } else { - if (counters != null && counters.stub != null) { - counters.stub.inc(); + Counters theCounters = counters; + if (theCounters != null && theCounters.stub != null) { + theCounters.stub.inc(); } result = newInstanceStub(hub); } - profileAllocation("instance", size, typeContext, options); + profileAllocation("instance", size, typeContext); return verifyOop(result); } @@ -248,18 +253,18 @@ @Snippet public static Object allocateInstancePIC(@ConstantParameter int size, KlassPointer hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, - @ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext, @ConstantParameter OptionValues options, + @ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext, @ConstantParameter Counters counters) { // Klass must be initialized by the time the first instance is allocated, therefore we can // just load it from the corresponding cell and avoid the resolution check. We have to use a // fixed load though, to prevent it from floating above the initialization. KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub); - return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, picHub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, options, counters)); + return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, picHub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, counters)); } @Snippet public static Object allocateInstanceDynamic(Class type, Class classClass, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, - @ConstantParameter OptionValues options, @ConstantParameter Counters counters) { + @ConstantParameter Counters counters) { if (probability(SLOW_PATH_PROBABILITY, type == null)) { DeoptimizeNode.deopt(None, RuntimeConstraint); } @@ -269,10 +274,10 @@ DeoptimizeNode.deopt(None, RuntimeConstraint); } - return PiNode.piCastToSnippetReplaceeStamp(allocateInstanceDynamicHelper(type, fillContents, threadRegister, options, counters, nonNullType)); + return PiNode.piCastToSnippetReplaceeStamp(allocateInstanceDynamicHelper(type, fillContents, threadRegister, counters, nonNullType)); } - private static Object allocateInstanceDynamicHelper(Class type, boolean fillContents, Register threadRegister, OptionValues options, Counters counters, Class nonNullType) { + private static Object allocateInstanceDynamicHelper(Class type, boolean fillContents, Register threadRegister, Counters counters, Class nonNullType) { KlassPointer hub = ClassGetHubNode.readClass(nonNullType); if (probability(FAST_PATH_PROBABILITY, !hub.isNull())) { KlassPointer nonNullHub = ClassGetHubNode.piCastNonNull(hub, SnippetAnchorNode.anchor()); @@ -291,7 +296,7 @@ * FIXME(je,ds): we should actually pass typeContext instead of "" but late * binding of parameters is not yet supported by the GraphBuilderPlugin system. */ - return allocateInstanceHelper(layoutHelper, nonNullHub, prototypeMarkWord, fillContents, threadRegister, false, "", options, counters); + return allocateInstanceHelper(layoutHelper, nonNullHub, prototypeMarkWord, fillContents, threadRegister, false, "", counters); } } else { DeoptimizeNode.deopt(None, RuntimeConstraint); @@ -308,19 +313,19 @@ @Snippet public static Object allocatePrimitiveArrayPIC(KlassPointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext, - @ConstantParameter OptionValues options, @ConstantParameter Counters counters) { + @ConstantParameter Counters counters) { // Primitive array types are eagerly pre-resolved. We can use a floating load. KlassPointer picHub = LoadConstantIndirectlyNode.loadKlass(hub); - return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false, options, counters); + return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false, counters); } @Snippet public static Object allocateArrayPIC(KlassPointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext, - @ConstantParameter OptionValues options, @ConstantParameter Counters counters) { + @ConstantParameter Counters counters) { // Array type would be resolved by dominating resolution. KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub); - return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false, options, counters); + return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false, counters); } @Snippet @@ -333,9 +338,19 @@ @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext, - @ConstantParameter OptionValues options, @ConstantParameter Counters counters) { - Object result = allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false, options, counters); + Object result = allocateArrayImpl(hub, + length, + prototypeMarkWord, + headerSize, + log2ElementSize, + fillContents, + threadRegister, + maybeUnroll, + typeContext, + false, + + counters); return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length); } @@ -349,7 +364,7 @@ } private static Object allocateArrayImpl(KlassPointer hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, Register threadRegister, - boolean maybeUnroll, String typeContext, boolean skipNegativeCheck, OptionValues options, Counters counters) { + boolean maybeUnroll, String typeContext, boolean skipNegativeCheck, Counters counters) { Object result; int allocationSize = arrayAllocationSize(length, headerSize, log2ElementSize); Word thread = registerAsWord(threadRegister); @@ -360,14 +375,15 @@ probability(FAST_PATH_PROBABILITY, newTop.belowOrEqual(end))) { writeTlabTop(thread, newTop); emitPrefetchAllocate(newTop, true); - if (counters != null && counters.arrayLoopInit != null) { - counters.arrayLoopInit.inc(); + Counters theCounters = counters; + if (theCounters != null && theCounters.arrayLoopInit != null) { + theCounters.arrayLoopInit.inc(); } result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, maybeUnroll, counters); } else { result = newArrayStub(hub, length); } - profileAllocation("array", allocationSize, typeContext, options); + profileAllocation("array", allocationSize, typeContext); return result; } @@ -421,14 +437,14 @@ @Snippet public static Object allocateArrayDynamic(Class elementType, Class voidClass, int length, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, - @ConstantParameter JavaKind knownElementKind, @ConstantParameter int knownLayoutHelper, Word prototypeMarkWord, @ConstantParameter OptionValues options, + @ConstantParameter JavaKind knownElementKind, @ConstantParameter int knownLayoutHelper, Word prototypeMarkWord, @ConstantParameter Counters counters) { - Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, threadRegister, knownElementKind, knownLayoutHelper, prototypeMarkWord, options, counters); + Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, threadRegister, knownElementKind, knownLayoutHelper, prototypeMarkWord, counters); return result; } private static Object allocateArrayDynamicImpl(Class elementType, Class voidClass, int length, boolean fillContents, Register threadRegister, JavaKind knownElementKind, - int knownLayoutHelper, Word prototypeMarkWord, OptionValues options, Counters counters) { + int knownLayoutHelper, Word prototypeMarkWord, Counters counters) { /* * We only need the dynamic check for void when we have no static information from * knownElementKind. @@ -470,7 +486,7 @@ int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift(INJECTED_VMCONFIG)) & layoutHelperHeaderSizeMask(INJECTED_VMCONFIG); int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift(INJECTED_VMCONFIG)) & layoutHelperLog2ElementSizeMask(INJECTED_VMCONFIG); - Object result = allocateArrayImpl(nonNullKlass, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, false, "dynamic type", true, options, counters); + Object result = allocateArrayImpl(nonNullKlass, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, false, "dynamic type", true, counters); return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length); } @@ -536,13 +552,14 @@ offset += 4; } ReplacementsUtil.runtimeAssert((offset & 0x7) == 0, "unaligned offset"); + Counters theCounters = counters; if (manualUnroll && ((size - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) { ReplacementsUtil.staticAssert(!constantSize, "size shouldn't be constant at instantiation time"); // This case handles arrays of constant length. Instead of having a snippet variant for // each length, generate a chain of stores of maximum length. Once it's inlined the // break statement will trim excess stores. - if (counters != null && counters.instanceSeqInit != null) { - counters.instanceSeqInit.inc(); + if (theCounters != null && theCounters.instanceSeqInit != null) { + theCounters.instanceSeqInit.inc(); } explodeLoop(); @@ -556,13 +573,13 @@ // Use Word instead of int to avoid extension to long in generated code Word off = WordFactory.signed(offset); if (constantSize && ((size - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) { - if (counters != null && counters.instanceSeqInit != null) { - counters.instanceSeqInit.inc(); + if (theCounters != null && theCounters.instanceSeqInit != null) { + theCounters.instanceSeqInit.inc(); } explodeLoop(); } else { - if (counters != null && counters.instanceLoopInit != null) { - counters.instanceLoopInit.inc(); + if (theCounters != null && theCounters.instanceLoopInit != null) { + theCounters.instanceLoopInit.inc(); } } for (; off.rawValue() < size; off = off.add(8)) { @@ -694,7 +711,6 @@ args.addConst("threadRegister", registers.getThreadRegister()); args.addConst("constantSize", true); args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? type.toJavaName(false) : ""); - args.addConst("options", localOptions); args.addConst("counters", counters); SnippetTemplate template = template(newInstanceNode, args); @@ -738,7 +754,6 @@ args.addConst("threadRegister", registers.getThreadRegister()); args.addConst("maybeUnroll", length.isConstant()); args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? arrayType.toJavaName(false) : ""); - args.addConst("options", localOptions); args.addConst("counters", counters); SnippetTemplate template = template(newArrayNode, args); graph.getDebug().log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args); @@ -747,14 +762,12 @@ public void lower(DynamicNewInstanceNode newInstanceNode, HotSpotRegistersProvider registers, LoweringTool tool) { Arguments args = new Arguments(allocateInstanceDynamic, newInstanceNode.graph().getGuardsStage(), tool.getLoweringStage()); - OptionValues localOptions = newInstanceNode.getOptions(); args.add("type", newInstanceNode.getInstanceType()); ValueNode classClass = newInstanceNode.getClassClass(); assert classClass != null; args.add("classClass", classClass); args.addConst("fillContents", newInstanceNode.fillContents()); args.addConst("threadRegister", registers.getThreadRegister()); - args.addConst("options", localOptions); args.addConst("counters", counters); SnippetTemplate template = template(newInstanceNode, args); @@ -763,7 +776,6 @@ public void lower(DynamicNewArrayNode newArrayNode, HotSpotRegistersProvider registers, LoweringTool tool) { StructuredGraph graph = newArrayNode.graph(); - OptionValues localOptions = graph.getOptions(); Arguments args = new Arguments(allocateArrayDynamic, newArrayNode.graph().getGuardsStage(), tool.getLoweringStage()); args.add("elementType", newArrayNode.getElementType()); ValueNode voidClass = newArrayNode.getVoidClass(); @@ -784,7 +796,6 @@ args.addConst("knownLayoutHelper", 0); } args.add("prototypeMarkWord", lookupArrayClass(tool, JavaKind.Object).prototypeMarkWord()); - args.addConst("options", localOptions); args.addConst("counters", counters); SnippetTemplate template = template(newArrayNode, args); template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ObjectCloneNode.java 2018-12-11 11:13:09.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ObjectCloneNode.java 2018-12-11 11:13:08.000000000 -0800 @@ -24,13 +24,12 @@ package org.graalvm.compiler.hotspot.replacements; -import java.lang.reflect.Method; - import org.graalvm.compiler.core.common.type.AbstractPointerStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.StampPair; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.hotspot.meta.HotSpotLoweringProvider; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind; import org.graalvm.compiler.nodes.NodeView; @@ -45,6 +44,7 @@ import org.graalvm.compiler.nodes.spi.LoweringTool; import org.graalvm.compiler.nodes.spi.Replacements; import org.graalvm.compiler.nodes.type.StampTool; +import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo; import org.graalvm.compiler.replacements.nodes.BasicObjectCloneNode; import jdk.vm.ci.meta.Assumptions; @@ -77,11 +77,14 @@ @SuppressWarnings("try") protected StructuredGraph getLoweredSnippetGraph(LoweringTool tool) { ResolvedJavaType type = StampTool.typeOrNull(getObject()); + if (type != null) { if (type.isArray()) { - Method method = ObjectCloneSnippets.arrayCloneMethods.get(type.getComponentType().getJavaKind()); - if (method != null) { - final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(method); + HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) tool.getLowerer(); + ObjectCloneSnippets.Templates objectCloneSnippets = lowerer.getObjectCloneSnippets(); + SnippetInfo info = objectCloneSnippets.arrayCloneMethods.get(type.getComponentType().getJavaKind()); + if (info != null) { + final ResolvedJavaMethod snippetMethod = info.getMethod(); final Replacements replacements = tool.getReplacements(); StructuredGraph snippetGraph = null; DebugContext debug = getDebug(); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ObjectCloneSnippets.java 2018-12-11 11:13:10.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ObjectCloneSnippets.java 2018-12-11 11:13:09.000000000 -0800 @@ -26,40 +26,40 @@ import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_VMCONFIG; -import java.lang.reflect.Method; import java.util.EnumMap; import org.graalvm.compiler.api.directives.GraalDirectives; import org.graalvm.compiler.api.replacements.Snippet; -import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.debug.DebugHandlersFactory; +import org.graalvm.compiler.hotspot.meta.HotSpotProviders; import org.graalvm.compiler.replacements.arraycopy.ArrayCopyCallNode; import org.graalvm.compiler.nodes.java.DynamicNewArrayNode; import org.graalvm.compiler.nodes.java.NewArrayNode; +import org.graalvm.compiler.options.OptionValues; +import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates; +import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo; import org.graalvm.compiler.replacements.Snippets; +import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.JavaKind; public class ObjectCloneSnippets implements Snippets { - public static final EnumMap arrayCloneMethods = new EnumMap<>(JavaKind.class); + public static class Templates extends AbstractTemplates { - static { - arrayCloneMethods.put(JavaKind.Boolean, getCloneMethod("booleanArrayClone", boolean[].class)); - arrayCloneMethods.put(JavaKind.Byte, getCloneMethod("byteArrayClone", byte[].class)); - arrayCloneMethods.put(JavaKind.Char, getCloneMethod("charArrayClone", char[].class)); - arrayCloneMethods.put(JavaKind.Short, getCloneMethod("shortArrayClone", short[].class)); - arrayCloneMethods.put(JavaKind.Int, getCloneMethod("intArrayClone", int[].class)); - arrayCloneMethods.put(JavaKind.Float, getCloneMethod("floatArrayClone", float[].class)); - arrayCloneMethods.put(JavaKind.Long, getCloneMethod("longArrayClone", long[].class)); - arrayCloneMethods.put(JavaKind.Double, getCloneMethod("doubleArrayClone", double[].class)); - arrayCloneMethods.put(JavaKind.Object, getCloneMethod("objectArrayClone", Object[].class)); - } - - private static Method getCloneMethod(String name, Class param) { - try { - return ObjectCloneSnippets.class.getDeclaredMethod(name, param); - } catch (SecurityException | NoSuchMethodException e) { - throw new GraalError(e); + final EnumMap arrayCloneMethods = new EnumMap<>(JavaKind.class); + + public Templates(OptionValues options, Iterable factories, HotSpotProviders providers, TargetDescription target) { + super(options, factories, providers, providers.getSnippetReflection(), target); + arrayCloneMethods.put(JavaKind.Boolean, snippet(ObjectCloneSnippets.class, "booleanArrayClone")); + arrayCloneMethods.put(JavaKind.Byte, snippet(ObjectCloneSnippets.class, "byteArrayClone")); + arrayCloneMethods.put(JavaKind.Char, snippet(ObjectCloneSnippets.class, "charArrayClone")); + arrayCloneMethods.put(JavaKind.Short, snippet(ObjectCloneSnippets.class, "shortArrayClone")); + arrayCloneMethods.put(JavaKind.Int, snippet(ObjectCloneSnippets.class, "intArrayClone")); + arrayCloneMethods.put(JavaKind.Float, snippet(ObjectCloneSnippets.class, "floatArrayClone")); + arrayCloneMethods.put(JavaKind.Long, snippet(ObjectCloneSnippets.class, "longArrayClone")); + arrayCloneMethods.put(JavaKind.Double, snippet(ObjectCloneSnippets.class, "doubleArrayClone")); + arrayCloneMethods.put(JavaKind.Object, snippet(ObjectCloneSnippets.class, "objectArrayClone")); } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA2Substitutions.java 2018-12-11 11:13:11.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA2Substitutions.java 2018-12-11 11:13:10.000000000 -0800 @@ -24,16 +24,18 @@ package org.graalvm.compiler.hotspot.replacements; -import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_METAACCESS; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_INTRINSIC_CONTEXT; import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; import org.graalvm.compiler.api.replacements.ClassSubstitution; +import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.compiler.api.replacements.MethodSubstitution; -import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.hotspot.HotSpotBackend; import org.graalvm.compiler.nodes.ComputeObjectAddressNode; import org.graalvm.compiler.nodes.PiNode; import org.graalvm.compiler.nodes.extended.RawLoadNode; +import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext; import org.graalvm.compiler.replacements.ReplacementsUtil; import org.graalvm.compiler.word.Word; import jdk.internal.vm.compiler.word.LocationIdentity; @@ -44,31 +46,19 @@ @ClassSubstitution(className = "sun.security.provider.SHA2", optional = true) public class SHA2Substitutions { - static final long stateOffset; - - static final Class shaClass; - public static final String implCompressName = Java8OrEarlier ? "implCompress" : "implCompress0"; - static { - try { - // Need to use the system class loader as com.sun.crypto.provider.AESCrypt - // is normally loaded by the extension class loader which is not delegated - // to by the JVMCI class loader. - ClassLoader cl = ClassLoader.getSystemClassLoader(); - shaClass = Class.forName("sun.security.provider.SHA2", true, cl); - stateOffset = UnsafeAccess.UNSAFE.objectFieldOffset(shaClass.getDeclaredField("state")); - } catch (Exception ex) { - throw new GraalError(ex); - } - } - @MethodSubstitution(isStatic = false) static void implCompress0(Object receiver, byte[] buf, int ofs) { - Object realReceiver = PiNode.piCastNonNull(receiver, shaClass); - Object state = RawLoadNode.load(realReceiver, stateOffset, JavaKind.Object, LocationIdentity.any()); + Object realReceiver = PiNode.piCastNonNull(receiver, HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT)); + Object state = RawLoadNode.load(realReceiver, stateOffset(INJECTED_INTRINSIC_CONTEXT), JavaKind.Object, LocationIdentity.any()); Word bufAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(buf, ReplacementsUtil.getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Byte) + ofs)); Word stateAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(state, ReplacementsUtil.getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Int))); HotSpotBackend.sha2ImplCompressStub(bufAddr, stateAddr); } + + @Fold + static long stateOffset(@Fold.InjectedParameter IntrinsicContext context) { + return HotSpotReplacementsUtil.getFieldOffset(HotSpotReplacementsUtil.methodHolderClass(context), "state"); + } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA5Substitutions.java 2018-12-11 11:13:12.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA5Substitutions.java 2018-12-11 11:13:11.000000000 -0800 @@ -24,12 +24,12 @@ package org.graalvm.compiler.hotspot.replacements; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_INTRINSIC_CONTEXT; import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS; import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; import org.graalvm.compiler.api.replacements.ClassSubstitution; import org.graalvm.compiler.api.replacements.MethodSubstitution; -import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.hotspot.HotSpotBackend; import org.graalvm.compiler.nodes.ComputeObjectAddressNode; import org.graalvm.compiler.nodes.PiNode; @@ -44,31 +44,19 @@ @ClassSubstitution(className = "sun.security.provider.SHA5", optional = true) public class SHA5Substitutions { - static final long stateOffset; - - static final Class shaClass; - public static final String implCompressName = Java8OrEarlier ? "implCompress" : "implCompress0"; - static { - try { - // Need to use the system class loader as com.sun.crypto.provider.AESCrypt - // is normally loaded by the extension class loader which is not delegated - // to by the JVMCI class loader. - ClassLoader cl = ClassLoader.getSystemClassLoader(); - shaClass = Class.forName("sun.security.provider.SHA5", true, cl); - stateOffset = UnsafeAccess.UNSAFE.objectFieldOffset(shaClass.getDeclaredField("state")); - } catch (Exception ex) { - throw new GraalError(ex); - } - } - @MethodSubstitution(isStatic = false) static void implCompress0(Object receiver, byte[] buf, int ofs) { - Object realReceiver = PiNode.piCastNonNull(receiver, shaClass); - Object state = RawLoadNode.load(realReceiver, stateOffset, JavaKind.Object, LocationIdentity.any()); + Object realReceiver = PiNode.piCastNonNull(receiver, HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT)); + Object state = RawLoadNode.load(realReceiver, stateOffset(), JavaKind.Object, LocationIdentity.any()); Word bufAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(buf, ReplacementsUtil.getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Byte) + ofs)); Word stateAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(state, ReplacementsUtil.getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Int))); HotSpotBackend.sha5ImplCompressStub(bufAddr, stateAddr); } + + static long stateOffset() { + return HotSpotReplacementsUtil.getFieldOffset(HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT), "state"); + } + } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHASubstitutions.java 2018-12-11 11:13:12.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHASubstitutions.java 2018-12-11 11:13:12.000000000 -0800 @@ -24,12 +24,12 @@ package org.graalvm.compiler.hotspot.replacements; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_INTRINSIC_CONTEXT; import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS; import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; import org.graalvm.compiler.api.replacements.ClassSubstitution; import org.graalvm.compiler.api.replacements.MethodSubstitution; -import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.hotspot.HotSpotBackend; import org.graalvm.compiler.nodes.ComputeObjectAddressNode; import org.graalvm.compiler.nodes.PiNode; @@ -44,31 +44,19 @@ @ClassSubstitution(className = "sun.security.provider.SHA", optional = true) public class SHASubstitutions { - static final long stateOffset; - - static final Class shaClass; - public static final String implCompressName = Java8OrEarlier ? "implCompress" : "implCompress0"; - static { - try { - // Need to use the system class loader as com.sun.crypto.provider.AESCrypt - // is normally loaded by the extension class loader which is not delegated - // to by the JVMCI class loader. - ClassLoader cl = ClassLoader.getSystemClassLoader(); - shaClass = Class.forName("sun.security.provider.SHA", true, cl); - stateOffset = UnsafeAccess.UNSAFE.objectFieldOffset(shaClass.getDeclaredField("state")); - } catch (Exception ex) { - throw new GraalError(ex); - } - } - @MethodSubstitution(isStatic = false) static void implCompress0(Object receiver, byte[] buf, int ofs) { - Object realReceiver = PiNode.piCastNonNull(receiver, shaClass); - Object state = RawLoadNode.load(realReceiver, stateOffset, JavaKind.Object, LocationIdentity.any()); + Object realReceiver = PiNode.piCastNonNull(receiver, HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT)); + Object state = RawLoadNode.load(realReceiver, stateOffset(), JavaKind.Object, LocationIdentity.any()); Word bufAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(buf, ReplacementsUtil.getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Byte) + ofs)); Word stateAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(state, ReplacementsUtil.getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Int))); HotSpotBackend.shaImplCompressStub(bufAddr, stateAddr); } + + static long stateOffset() { + return HotSpotReplacementsUtil.getFieldOffset(HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT), "state"); + } + } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/StringToBytesSnippets.java 2018-12-11 11:13:13.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/StringToBytesSnippets.java 2018-12-11 11:13:13.000000000 -0800 @@ -24,16 +24,17 @@ package org.graalvm.compiler.hotspot.replacements; -import static org.graalvm.compiler.hotspot.replacements.UnsafeAccess.UNSAFE; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS; +import static org.graalvm.compiler.replacements.ReplacementsUtil.getArrayBaseOffset; import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER; -import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.compiler.api.replacements.Snippet; import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter; import org.graalvm.compiler.debug.DebugHandlersFactory; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; import org.graalvm.compiler.nodes.NamedLocationIdentity; import org.graalvm.compiler.nodes.debug.StringToBytesNode; +import org.graalvm.compiler.nodes.extended.RawStoreNode; import org.graalvm.compiler.nodes.java.NewArrayNode; import org.graalvm.compiler.nodes.spi.LoweringTool; import org.graalvm.compiler.options.OptionValues; @@ -56,11 +57,6 @@ public static final LocationIdentity CSTRING_LOCATION = NamedLocationIdentity.immutable("CString location"); - @Fold - static long arrayBaseOffset() { - return UNSAFE.arrayBaseOffset(char[].class); - } - @Snippet public static byte[] transform(@ConstantParameter String compilationTimeString) { int i = compilationTimeString.length(); @@ -68,7 +64,8 @@ Word cArray = CStringConstant.cstring(compilationTimeString); while (i-- > 0) { // array[i] = cArray.readByte(i); - UNSAFE.putByte(array, arrayBaseOffset() + i, cArray.readByte(i, CSTRING_LOCATION)); + RawStoreNode.storeByte(array, getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Byte) + i, cArray.readByte(i, CSTRING_LOCATION), JavaKind.Byte, + NamedLocationIdentity.getArrayLocation(JavaKind.Byte)); } return array; } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/UnsafeLoadSnippets.java 2018-12-11 11:13:14.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/UnsafeLoadSnippets.java 2018-12-11 11:13:14.000000000 -0800 @@ -24,6 +24,7 @@ package org.graalvm.compiler.hotspot.replacements; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_METAACCESS; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.referentOffset; import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER; @@ -48,7 +49,7 @@ @Snippet public static Object lowerUnsafeLoad(Object object, long offset) { Object fixedObject = FixedValueAnchorNode.getObject(object); - if (object instanceof java.lang.ref.Reference && referentOffset() == offset) { + if (object instanceof java.lang.ref.Reference && referentOffset(INJECTED_METAACCESS) == offset) { return Word.objectToTrackedPointer(fixedObject).readObject((int) offset, BarrierType.PRECISE); } else { return Word.objectToTrackedPointer(fixedObject).readObject((int) offset, BarrierType.NONE); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java 2018-12-11 11:13:15.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java 2018-12-11 11:13:15.000000000 -0800 @@ -69,6 +69,7 @@ import org.graalvm.compiler.nodes.NamedLocationIdentity; import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.PiNode; +import org.graalvm.compiler.nodes.SnippetAnchorNode; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.extended.FixedValueAnchorNode; @@ -313,7 +314,7 @@ private static void verifyNotArray(Object object) { if (object != null) { // Manually build the null check and cast because we're in snippet that's lowered late. - AssertionNode.assertion(false, !PiNode.piCastNonNull(object, Object.class).getClass().isArray(), "imprecise card mark used with array"); + AssertionNode.assertion(false, !PiNode.piCastNonNull(object, SnippetAnchorNode.anchor()).getClass().isArray(), "imprecise card mark used with array"); } } @@ -427,7 +428,7 @@ private final SnippetInfo serialPreciseWriteBarrier = snippet(WriteBarrierSnippets.class, "serialPreciseWriteBarrier", GC_CARD_LOCATION); private final SnippetInfo serialArrayRangeWriteBarrier = snippet(WriteBarrierSnippets.class, "serialArrayRangeWriteBarrier"); private final SnippetInfo g1PreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PreWriteBarrier", GC_INDEX_LOCATION, GC_LOG_LOCATION); - private final SnippetInfo g1ReferentReadBarrier = snippet(WriteBarrierSnippets.class, "g1PreWriteBarrier", GC_INDEX_LOCATION, GC_LOG_LOCATION); + private final SnippetInfo g1ReferentReadBarrier = g1PreWriteBarrier; private final SnippetInfo g1PostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PostWriteBarrier", GC_CARD_LOCATION, GC_INDEX_LOCATION, GC_LOG_LOCATION); private final SnippetInfo g1ArrayRangePreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePreWriteBarrier", GC_INDEX_LOCATION, GC_LOG_LOCATION); private final SnippetInfo g1ArrayRangePostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePostWriteBarrier", GC_CARD_LOCATION, GC_INDEX_LOCATION, GC_LOG_LOCATION); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProbabilisticProfileSnippets.java 2018-12-11 11:13:16.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProbabilisticProfileSnippets.java 2018-12-11 11:13:16.000000000 -0800 @@ -25,7 +25,10 @@ package org.graalvm.compiler.hotspot.replacements.profiling; import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.config; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.backedgeCounterOffset; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.invocationCounterIncrement; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.invocationCounterOffset; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.invocationCounterShift; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability; import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER; @@ -79,11 +82,11 @@ @Snippet public static void profileMethodEntryWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog, @ConstantParameter int probLog) { if (probability(1.0 / (1 << probLog), shouldProfile(probLog, random))) { - int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + ((config(INJECTED_VMCONFIG).invocationCounterIncrement * step) << probLog); - counters.writeInt(config(INJECTED_VMCONFIG).invocationCounterOffset, counterValue); + int counterValue = counters.readInt(invocationCounterOffset(INJECTED_VMCONFIG)) + ((invocationCounterIncrement(INJECTED_VMCONFIG) * step) << probLog); + counters.writeInt(invocationCounterOffset(INJECTED_VMCONFIG), counterValue); if (freqLog >= 0) { int mask = notificationMask(freqLog, probLog, stepLog); - if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) { + if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << invocationCounterShift(INJECTED_VMCONFIG))) == 0)) { methodInvocationEvent(HotSpotBackend.INVOCATION_EVENT, counters); } } @@ -97,10 +100,10 @@ public static void profileBackedgeWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog, @ConstantParameter int probLog, int bci, int targetBci) { if (probability(1.0 / (1 << probLog), shouldProfile(probLog, random))) { - int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + ((config(INJECTED_VMCONFIG).invocationCounterIncrement * step) << probLog); - counters.writeInt(config(INJECTED_VMCONFIG).backedgeCounterOffset, counterValue); + int counterValue = counters.readInt(backedgeCounterOffset(INJECTED_VMCONFIG)) + ((invocationCounterIncrement(INJECTED_VMCONFIG) * step) << probLog); + counters.writeInt(backedgeCounterOffset(INJECTED_VMCONFIG), counterValue); int mask = notificationMask(freqLog, probLog, stepLog); - if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) { + if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << invocationCounterShift(INJECTED_VMCONFIG))) == 0)) { methodBackedgeEvent(HotSpotBackend.BACKEDGE_EVENT, counters, bci, targetBci); } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProfileSnippets.java 2018-12-11 11:13:17.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProfileSnippets.java 2018-12-11 11:13:17.000000000 -0800 @@ -25,7 +25,10 @@ package org.graalvm.compiler.hotspot.replacements.profiling; import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.config; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.backedgeCounterOffset; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.invocationCounterIncrement; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.invocationCounterOffset; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.invocationCounterShift; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability; import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER; @@ -72,11 +75,11 @@ @Snippet public static void profileMethodEntry(MethodCountersPointer counters, int step, int stepLog, @ConstantParameter int freqLog) { - int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement * step; - counters.writeInt(config(INJECTED_VMCONFIG).invocationCounterOffset, counterValue); + int counterValue = counters.readInt(invocationCounterOffset(INJECTED_VMCONFIG)) + invocationCounterIncrement(INJECTED_VMCONFIG) * step; + counters.writeInt(invocationCounterOffset(INJECTED_VMCONFIG), counterValue); if (freqLog >= 0) { final int mask = notificationMask(freqLog, stepLog); - if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) { + if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << invocationCounterShift(INJECTED_VMCONFIG))) == 0)) { methodInvocationEvent(HotSpotBackend.INVOCATION_EVENT, counters); } } @@ -87,10 +90,10 @@ @Snippet public static void profileBackedge(MethodCountersPointer counters, int step, int stepLog, @ConstantParameter int freqLog, int bci, int targetBci) { - int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement * step; - counters.writeInt(config(INJECTED_VMCONFIG).backedgeCounterOffset, counterValue); + int counterValue = counters.readInt(backedgeCounterOffset(INJECTED_VMCONFIG)) + invocationCounterIncrement(INJECTED_VMCONFIG) * step; + counters.writeInt(backedgeCounterOffset(INJECTED_VMCONFIG), counterValue); final int mask = notificationMask(freqLog, stepLog); - if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) { + if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << invocationCounterShift(INJECTED_VMCONFIG))) == 0)) { methodBackedgeEvent(HotSpotBackend.BACKEDGE_EVENT, counters, bci, targetBci); } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/CreateExceptionStub.java 2018-12-11 11:13:18.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/CreateExceptionStub.java 2018-12-11 11:13:18.000000000 -0800 @@ -45,6 +45,7 @@ import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.replacements.nodes.CStringConstant; import org.graalvm.compiler.word.Word; +import jdk.internal.vm.compiler.word.WordFactory; import jdk.vm.ci.code.Register; @@ -67,7 +68,7 @@ } protected static Object createException(Register threadRegister, Class exception) { - Word message = null; + Word message = WordFactory.zero(); return createException(threadRegister, exception, message); } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ExceptionHandlerStub.java 2018-12-11 11:13:19.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ExceptionHandlerStub.java 2018-12-11 11:13:19.000000000 -0800 @@ -87,17 +87,17 @@ return providers.getRegisters().getThreadRegister(); } assert index == 3; - return options; + return StubOptions.TraceExceptionHandlerStub.getValue(options); } @Snippet - private static void exceptionHandler(Object exception, Word exceptionPc, @ConstantParameter Register threadRegister, @ConstantParameter OptionValues options) { + private static void exceptionHandler(Object exception, Word exceptionPc, @ConstantParameter Register threadRegister, @ConstantParameter boolean logging) { Word thread = registerAsWord(threadRegister); checkNoExceptionInThread(thread, assertionsEnabled(INJECTED_VMCONFIG)); checkExceptionNotNull(assertionsEnabled(INJECTED_VMCONFIG), exception); writeExceptionOop(thread, exception); writeExceptionPc(thread, exceptionPc); - if (logging(options)) { + if (logging) { printf("handling exception %p (", Word.objectToTrackedPointer(exception).rawValue()); decipher(Word.objectToTrackedPointer(exception).rawValue()); printf(") at %p (", exceptionPc.rawValue()); @@ -110,7 +110,7 @@ Word handlerPc = exceptionHandlerForPc(EXCEPTION_HANDLER_FOR_PC, thread); - if (logging(options)) { + if (logging) { printf("handler for exception %p at %p is at %p (", Word.objectToTrackedPointer(exception).rawValue(), exceptionPc.rawValue(), handlerPc.rawValue()); decipher(handlerPc.rawValue()); printf(")\n"); @@ -143,11 +143,6 @@ } } - @Fold - static boolean logging(OptionValues options) { - return StubOptions.TraceExceptionHandlerStub.getValue(options); - } - /** * Determines if either Java assertions are enabled for Graal or if this is a HotSpot build * where the ASSERT mechanism is enabled. --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ForeignCallStub.java 2018-12-11 11:13:20.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ForeignCallStub.java 2018-12-11 11:13:20.000000000 -0800 @@ -24,11 +24,14 @@ package org.graalvm.compiler.hotspot.stubs; +import static jdk.vm.ci.code.BytecodeFrame.UNKNOWN_BCI; import static jdk.vm.ci.hotspot.HotSpotCallingConventionType.JavaCall; import static jdk.vm.ci.hotspot.HotSpotCallingConventionType.JavaCallee; import static jdk.vm.ci.hotspot.HotSpotCallingConventionType.NativeCall; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.DESTROYS_REGISTERS; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.PRESERVES_REGISTERS; +import static org.graalvm.compiler.nodes.CallTargetNode.InvokeKind.Static; +import static org.graalvm.compiler.nodes.ConstantNode.forBoolean; import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.core.common.LIRKind; @@ -43,10 +46,10 @@ import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkageImpl; +import org.graalvm.compiler.hotspot.meta.HotSpotLoweringProvider; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; import org.graalvm.compiler.hotspot.nodes.StubForeignCallNode; -import org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil; -import org.graalvm.compiler.nodes.ConstantNode; +import org.graalvm.compiler.hotspot.stubs.ForeignCallSnippets.Templates; import org.graalvm.compiler.nodes.InvokeNode; import org.graalvm.compiler.nodes.ParameterNode; import org.graalvm.compiler.nodes.ReturnNode; @@ -76,8 +79,8 @@ * deoptimization while the call is in progress. And since these are foreign/runtime calls on slow * paths, we don't want to force the register allocator to spill around the call. As such, this stub * saves and restores all allocatable registers. It also - * {@linkplain StubUtil#handlePendingException(Word, boolean, boolean) handles} any exceptions - * raised during the foreign call. + * {@linkplain ForeignCallSnippets#handlePendingException handles} any exceptions raised during the + * foreign call. */ public class ForeignCallStub extends Stub { @@ -112,9 +115,10 @@ PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutability, killedLocations)); this.jvmciRuntime = runtime; this.prependThread = prependThread; + MetaAccessProvider metaAccess = providers.getMetaAccess(); Class[] targetParameterTypes = createTargetParameters(descriptor); ForeignCallDescriptor targetSig = new ForeignCallDescriptor(descriptor.getName() + ":C", descriptor.getResultType(), targetParameterTypes); - target = HotSpotForeignCallLinkageImpl.create(providers.getMetaAccess(), providers.getCodeCache(), providers.getWordTypes(), providers.getForeignCalls(), targetSig, address, + target = HotSpotForeignCallLinkageImpl.create(metaAccess, providers.getCodeCache(), providers.getWordTypes(), providers.getForeignCalls(), targetSig, address, DESTROYS_REGISTERS, NativeCall, NativeCall, transition, reexecutability, killedLocations); } @@ -234,16 +238,21 @@ // Do we want to clear the pending exception? boolean shouldClearException = linkage.isReexecutable() || linkage.isReexecutableOnlyAfterException(); try { - ResolvedJavaMethod thisMethod = providers.getMetaAccess().lookupJavaMethod(ForeignCallStub.class.getDeclaredMethod("getGraph", DebugContext.class, CompilationIdentifier.class)); + HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer(); + Templates foreignCallSnippets = lowerer.getForeignCallSnippets(); + ResolvedJavaMethod handlePendingException = foreignCallSnippets.handlePendingException.getMethod(); + ResolvedJavaMethod getAndClearObjectResult = foreignCallSnippets.getAndClearObjectResult.getMethod(); + ResolvedJavaMethod verifyObject = foreignCallSnippets.verifyObject.getMethod(); + ResolvedJavaMethod thisMethod = getGraphMethod(); GraphKit kit = new GraphKit(debug, thisMethod, providers, wordTypes, providers.getGraphBuilderPlugins(), compilationId, toString()); StructuredGraph graph = kit.getGraph(); ParameterNode[] params = createParameters(kit, args); ReadRegisterNode thread = kit.append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), wordTypes.getWordKind(), true, false)); ValueNode result = createTargetCall(kit, params, thread); - kit.createInvoke(StubUtil.class, "handlePendingException", thread, ConstantNode.forBoolean(shouldClearException, graph), ConstantNode.forBoolean(isObjectResult, graph)); + createStaticInvoke(kit, handlePendingException, thread, forBoolean(shouldClearException, graph), forBoolean(isObjectResult, graph)); if (isObjectResult) { - InvokeNode object = kit.createInvoke(HotSpotReplacementsUtil.class, "getAndClearObjectResult", thread); - result = kit.createInvoke(StubUtil.class, "verifyObject", object); + InvokeNode object = createStaticInvoke(kit, getAndClearObjectResult, thread); + result = createStaticInvoke(kit, verifyObject, object); } kit.append(new ReturnNode(linkage.getDescriptor().getResultType() == void.class ? null : result)); debug.dump(DebugContext.VERBOSE_LEVEL, graph, "Initial stub graph"); @@ -258,6 +267,27 @@ } } + private static InvokeNode createStaticInvoke(GraphKit kit, ResolvedJavaMethod method, ValueNode... args) { + return kit.createInvoke(method, Static, null, UNKNOWN_BCI, args); + } + + private ResolvedJavaMethod getGraphMethod() { + ResolvedJavaMethod thisMethod = null; + for (ResolvedJavaMethod method : providers.getMetaAccess().lookupJavaType(ForeignCallStub.class).getDeclaredMethods()) { + if (method.getName().equals("getGraph")) { + if (thisMethod == null) { + thisMethod = method; + } else { + throw new InternalError("getGraph is ambiguous"); + } + } + } + if (thisMethod == null) { + throw new InternalError("Can't find getGraph"); + } + return thisMethod; + } + private ParameterNode[] createParameters(GraphKit kit, Class[] args) { ParameterNode[] params = new ParameterNode[args.length]; ResolvedJavaType accessingClass = providers.getMetaAccess().lookupJavaType(getClass()); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/SnippetStub.java 2018-12-11 11:13:21.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/SnippetStub.java 2018-12-11 11:13:21.000000000 -0800 @@ -24,43 +24,30 @@ package org.graalvm.compiler.hotspot.stubs; -import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.INLINE_AFTER_PARSING; - -import java.lang.reflect.Method; - import org.graalvm.compiler.api.replacements.Snippet; import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter; import org.graalvm.compiler.api.replacements.Snippet.NonNullParameter; -import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; -import org.graalvm.compiler.bytecode.BytecodeProvider; import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; -import org.graalvm.compiler.java.GraphBuilderPhase; import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.ParameterNode; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage; -import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; -import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; -import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext; import org.graalvm.compiler.nodes.spi.LoweringTool; import org.graalvm.compiler.options.OptionValues; -import org.graalvm.compiler.phases.OptimisticOptimizations; import org.graalvm.compiler.phases.common.CanonicalizerPhase; import org.graalvm.compiler.phases.common.LoweringPhase; import org.graalvm.compiler.phases.common.RemoveValueProxyPhase; import org.graalvm.compiler.phases.tiers.PhaseContext; -import org.graalvm.compiler.replacements.ConstantBindingParameterPlugin; import org.graalvm.compiler.replacements.SnippetTemplate; import org.graalvm.compiler.replacements.Snippets; import jdk.vm.ci.meta.Local; import jdk.vm.ci.meta.LocalVariableTable; -import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; /** @@ -92,40 +79,21 @@ */ public SnippetStub(Class snippetDeclaringClass, String snippetMethodName, OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) { super(options, providers, linkage); - Method javaMethod = SnippetTemplate.AbstractTemplates.findMethod(snippetDeclaringClass == null ? getClass() : snippetDeclaringClass, snippetMethodName, null); - this.method = providers.getMetaAccess().lookupJavaMethod(javaMethod); + this.method = SnippetTemplate.AbstractTemplates.findMethod(providers.getMetaAccess(), snippetDeclaringClass == null ? getClass() : snippetDeclaringClass, snippetMethodName); + registerSnippet(); + } + + protected void registerSnippet() { + providers.getReplacements().registerSnippet(method, null, null, false); } @Override @SuppressWarnings("try") protected StructuredGraph getGraph(DebugContext debug, CompilationIdentifier compilationId) { - Plugins defaultPlugins = providers.getGraphBuilderPlugins(); - MetaAccessProvider metaAccess = providers.getMetaAccess(); - SnippetReflectionProvider snippetReflection = providers.getSnippetReflection(); - - Plugins plugins = new Plugins(defaultPlugins); - plugins.prependParameterPlugin(new ConstantBindingParameterPlugin(makeConstArgs(), metaAccess, snippetReflection)); - GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins); - - // @formatter:off // Stubs cannot have optimistic assumptions since they have // to be valid for the entire run of the VM. - final StructuredGraph graph = new StructuredGraph.Builder(options, debug). - method(method). - compilationId(compilationId). - setIsSubstitution(true). - build(); - // @formatter:on + final StructuredGraph graph = buildInitialGraph(debug, compilationId, makeConstArgs()); try (DebugContext.Scope outer = debug.scope("SnippetStub", graph)) { - graph.disableUnsafeAccessTracking(); - - IntrinsicContext initialIntrinsicContext = new IntrinsicContext(method, method, getReplacementsBytecodeProvider(), INLINE_AFTER_PARSING); - GraphBuilderPhase.Instance instance = new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), - providers.getConstantReflection(), providers.getConstantFieldProvider(), - config, OptimisticOptimizations.NONE, - initialIntrinsicContext); - instance.apply(graph); - for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) { int index = param.index(); if (method.getParameterAnnotation(NonNullParameter.class, index) != null) { @@ -146,8 +114,8 @@ return graph; } - protected BytecodeProvider getReplacementsBytecodeProvider() { - return providers.getReplacements().getDefaultReplacementBytecodeProvider(); + protected StructuredGraph buildInitialGraph(DebugContext debug, CompilationIdentifier compilationId, Object[] args) { + return providers.getReplacements().getSnippet(method, args, false, null).copyWithIdentifier(compilationId, debug); } protected boolean checkConstArg(int index, String expectedName) { @@ -191,4 +159,8 @@ public String toString() { return "Stub<" + getInstalledCodeOwner().format("%h.%n") + ">"; } + + public ResolvedJavaMethod getMethod() { + return method; + } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java 2018-12-11 11:13:22.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java 2018-12-11 11:13:22.000000000 -0800 @@ -24,13 +24,6 @@ package org.graalvm.compiler.hotspot.stubs; -import static jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint; -import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_VMCONFIG; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.clearPendingException; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.getPendingException; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.getAndClearObjectResult; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadHubIntrinsic; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.verifyOops; import static org.graalvm.compiler.replacements.nodes.CStringConstant.cstring; import java.lang.reflect.Method; @@ -44,20 +37,12 @@ import org.graalvm.compiler.graph.Node.ConstantNodeParameter; import org.graalvm.compiler.graph.Node.NodeIntrinsic; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; -import org.graalvm.compiler.hotspot.nodes.DeoptimizeCallerNode; import org.graalvm.compiler.hotspot.nodes.StubForeignCallNode; import org.graalvm.compiler.hotspot.nodes.VMErrorNode; -import org.graalvm.compiler.hotspot.word.KlassPointer; -import org.graalvm.compiler.nodes.PiNode; -import org.graalvm.compiler.nodes.SnippetAnchorNode; -import org.graalvm.compiler.nodes.extended.GuardingNode; import org.graalvm.compiler.replacements.Log; import org.graalvm.compiler.word.Word; -import jdk.internal.vm.compiler.word.Pointer; import jdk.internal.vm.compiler.word.WordFactory; -import jdk.vm.ci.meta.DeoptimizationAction; - //JaCoCo Exclude /** @@ -96,15 +81,6 @@ return new ForeignCallDescriptor(name, found.getReturnType(), cCallTypes); } - public static void handlePendingException(Word thread, boolean shouldClearException, boolean isObjectResult) { - if ((shouldClearException && clearPendingException(thread) != null) || (!shouldClearException && getPendingException(thread) != null)) { - if (isObjectResult) { - getAndClearObjectResult(thread); - } - DeoptimizeCallerNode.deopt(DeoptimizationAction.None, RuntimeConstraint); - } - } - /** * Determines if this is a HotSpot build where the ASSERT mechanism is enabled. */ @@ -232,46 +208,6 @@ } /** - * Verifies that a given object value is well formed if {@code -XX:+VerifyOops} is enabled. - */ - public static Object verifyObject(Object object) { - if (verifyOops(INJECTED_VMCONFIG)) { - Word verifyOopCounter = WordFactory.unsigned(verifyOopCounterAddress(INJECTED_VMCONFIG)); - verifyOopCounter.writeInt(0, verifyOopCounter.readInt(0) + 1); - - Pointer oop = Word.objectToTrackedPointer(object); - if (object != null) { - GuardingNode anchorNode = SnippetAnchorNode.anchor(); - // make sure object is 'reasonable' - if (!oop.and(WordFactory.unsigned(verifyOopMask(INJECTED_VMCONFIG))).equal(WordFactory.unsigned(verifyOopBits(INJECTED_VMCONFIG)))) { - fatal("oop not in heap: %p", oop.rawValue()); - } - - KlassPointer klass = loadHubIntrinsic(PiNode.piCastNonNull(object, anchorNode)); - if (klass.isNull()) { - fatal("klass for oop %p is null", oop.rawValue()); - } - } - } - return object; - } - - @Fold - static long verifyOopCounterAddress(@InjectedParameter GraalHotSpotVMConfig config) { - return config.verifyOopCounterAddress; - } - - @Fold - static long verifyOopMask(@InjectedParameter GraalHotSpotVMConfig config) { - return config.verifyOopMask; - } - - @Fold - static long verifyOopBits(@InjectedParameter GraalHotSpotVMConfig config) { - return config.verifyOopBits; - } - - /** * Print {@code number} as decimal string to {@code buffer}. * * @param buffer --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/UnwindExceptionToCallerStub.java 2018-12-11 11:13:23.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/UnwindExceptionToCallerStub.java 2018-12-11 11:13:23.000000000 -0800 @@ -24,6 +24,7 @@ package org.graalvm.compiler.hotspot.stubs; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_OPTIONVALUES; import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG; import static org.graalvm.compiler.hotspot.nodes.JumpToExceptionHandlerInCallerNode.jumpToExceptionHandlerInCaller; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord; @@ -77,14 +78,13 @@ if (index == 2) { return providers.getRegisters().getThreadRegister(); } - assert index == 3; - return options; + throw new InternalError(); } @Snippet - private static void unwindExceptionToCaller(Object exception, Word returnAddress, @ConstantParameter Register threadRegister, @ConstantParameter OptionValues options) { + private static void unwindExceptionToCaller(Object exception, Word returnAddress, @ConstantParameter Register threadRegister) { Pointer exceptionOop = Word.objectToTrackedPointer(exception); - if (logging(options)) { + if (logging(INJECTED_OPTIONVALUES)) { printf("unwinding exception %p (", exceptionOop.rawValue()); decipher(exceptionOop.rawValue()); printf(") at %p (", returnAddress.rawValue()); @@ -97,7 +97,7 @@ Word handlerInCallerPc = exceptionHandlerForReturnAddress(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, thread, returnAddress); - if (logging(options)) { + if (logging(INJECTED_OPTIONVALUES)) { printf("handler for exception %p at return address %p is at %p (", exceptionOop.rawValue(), returnAddress.rawValue(), handlerInCallerPc.rawValue()); decipher(handlerInCallerPc.rawValue()); printf(")\n"); @@ -107,7 +107,7 @@ } @Fold - static boolean logging(OptionValues options) { + static boolean logging(@Fold.InjectedParameter OptionValues options) { return StubOptions.TraceUnwindStub.getValue(options); } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/VerifyOopStub.java 2018-12-11 11:13:24.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/VerifyOopStub.java 2018-12-11 11:13:24.000000000 -0800 @@ -24,7 +24,7 @@ package org.graalvm.compiler.hotspot.stubs; -import static org.graalvm.compiler.hotspot.stubs.StubUtil.verifyObject; +import static org.graalvm.compiler.hotspot.stubs.ForeignCallSnippets.verifyObject; import org.graalvm.compiler.api.replacements.Snippet; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/EncodedGraph.java 2018-12-11 11:13:25.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/EncodedGraph.java 2018-12-11 11:13:25.000000000 -0800 @@ -38,11 +38,11 @@ * {@link GraphEncoder} for a description of the encoding format. Use {@link GraphDecoder} for * decoding. */ -public final class EncodedGraph { +public class EncodedGraph { private final byte[] encoding; private final int startOffset; - private final Object[] objects; + protected final Object[] objects; private final NodeClass[] types; private final Assumptions assumptions; private final List inlinedMethods; @@ -82,10 +82,18 @@ return startOffset; } - public Object[] getObjects() { + protected Object[] getObjects() { return objects; } + public int getNumObjects() { + return objects.length; + } + + public Object getObject(int i) { + return objects[i]; + } + public NodeClass[] getNodeClasses() { return types; } @@ -109,4 +117,9 @@ public boolean hasUnsafeAccess() { return hasUnsafeAccess; } + + @SuppressWarnings("unused") + public boolean isCallToOriginal(ResolvedJavaMethod callTarget) { + return false; + } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java 2018-12-11 11:13:26.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java 2018-12-11 11:13:26.000000000 -0800 @@ -27,8 +27,6 @@ import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.ResolvedJavaMethod; import org.graalvm.compiler.core.common.type.AbstractPointerStamp; import org.graalvm.compiler.core.common.type.ObjectStamp; import org.graalvm.compiler.core.common.type.Stamp; @@ -51,10 +49,12 @@ import org.graalvm.compiler.nodes.type.StampTool; import org.graalvm.compiler.nodes.virtual.VirtualObjectNode; -//JaCoCo Exclude - +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; +//JaCoCo Exclude + /** * A node that changes the type of its input, usually narrowing it. For example, a {@link PiNode} * refines the type of a receiver during type-guarded inlining to be the type tested by the guard. @@ -281,12 +281,12 @@ * Changes the stamp of an object to represent a given type and to indicate that the object is * not null. */ - public static Object piCastNonNull(Object object, @ConstantNodeParameter Class toType) { + public static Object piCastNonNull(Object object, @ConstantNodeParameter ResolvedJavaType toType) { return piCast(object, toType, false, true); } @NodeIntrinsic - public static native Object piCast(Object object, @ConstantNodeParameter Class toType, @ConstantNodeParameter boolean exactType, @ConstantNodeParameter boolean nonNull); + public static native Object piCast(Object object, @ConstantNodeParameter ResolvedJavaType toType, @ConstantNodeParameter boolean exactType, @ConstantNodeParameter boolean nonNull); /** * A placeholder node in a snippet that will be replaced with a {@link PiNode} when the snippet --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java 2018-12-11 11:13:27.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java 2018-12-11 11:13:27.000000000 -0800 @@ -83,6 +83,9 @@ @NodeIntrinsic public static native Object storeChar(Object object, long offset, char value, @ConstantNodeParameter JavaKind kind, @ConstantNodeParameter LocationIdentity locationIdentity); + @NodeIntrinsic + public static native Object storeByte(Object object, long offset, byte value, @ConstantNodeParameter JavaKind kind, @ConstantNodeParameter LocationIdentity locationIdentity); + public boolean needsBarrier() { return needsBarrier; } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java 2018-12-11 11:13:28.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java 2018-12-11 11:13:28.000000000 -0800 @@ -43,15 +43,20 @@ import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.UnaryOpLogicNode; import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.calc.ConditionalNode; import org.graalvm.compiler.nodes.calc.IsNullNode; import org.graalvm.compiler.nodes.extended.AnchoringNode; +import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; import org.graalvm.compiler.nodes.spi.Lowerable; import org.graalvm.compiler.nodes.spi.LoweringTool; import org.graalvm.compiler.nodes.spi.Virtualizable; import org.graalvm.compiler.nodes.spi.VirtualizerTool; import org.graalvm.compiler.nodes.type.StampTool; +import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaTypeProfile; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.TriState; /** @@ -218,6 +223,17 @@ return checkedStamp; } + @NodeIntrinsic + public static native boolean doInstanceof(@ConstantNodeParameter ResolvedJavaType type, Object object); + + @SuppressWarnings("unused") + static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ResolvedJavaType type, ValueNode object) { + InstanceOfNode node = new InstanceOfNode(StampFactory.objectNonNull(TypeReference.create(b.getAssumptions(), type)), object, null, null); + node = b.add(node); + b.addPush(JavaKind.Int, ConditionalNode.create(node, NodeView.DEFAULT)); + return true; + } + @Override public TriState implies(boolean thisNegated, LogicNode other) { if (other instanceof InstanceOfNode) { --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DelegatingReplacements.java 2018-12-11 11:13:29.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DelegatingReplacements.java 2018-12-11 11:13:29.000000000 -0800 @@ -32,6 +32,7 @@ import org.graalvm.compiler.graph.NodeSourcePosition; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; +import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderPlugin; import org.graalvm.compiler.options.OptionValues; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -57,6 +58,11 @@ } @Override + public Class getIntrinsifyingPlugin(ResolvedJavaMethod method) { + return delegate.getIntrinsifyingPlugin(method); + } + + @Override public StructuredGraph getSnippet(ResolvedJavaMethod method, Object[] args, boolean trackNodeSourcePosition, NodeSourcePosition replaceePosition) { return delegate.getSnippet(method, args, trackNodeSourcePosition, replaceePosition); } @@ -67,8 +73,8 @@ } @Override - public void registerSnippet(ResolvedJavaMethod method, boolean trackNodeSourcePosition) { - delegate.registerSnippet(method, trackNodeSourcePosition); + public void registerSnippet(ResolvedJavaMethod method, ResolvedJavaMethod original, Object receiver, boolean trackNodeSourcePosition) { + delegate.registerSnippet(method, original, receiver, trackNodeSourcePosition); } @Override --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/Replacements.java 2018-12-11 11:13:30.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/Replacements.java 2018-12-11 11:13:30.000000000 -0800 @@ -33,6 +33,7 @@ import org.graalvm.compiler.graph.NodeSourcePosition; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; +import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderPlugin; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; import org.graalvm.compiler.options.OptionValues; @@ -52,6 +53,11 @@ GraphBuilderConfiguration.Plugins getGraphBuilderPlugins(); /** + * Gets the plugin type that intrinsifies calls to {@code method}. + */ + Class getIntrinsifyingPlugin(ResolvedJavaMethod method); + + /** * Gets the snippet graph derived from a given method. * * @param args arguments to the snippet if available, otherwise {@code null} @@ -75,7 +81,7 @@ /** * Registers a method as snippet. */ - void registerSnippet(ResolvedJavaMethod method, boolean trackNodeSourcePosition); + void registerSnippet(ResolvedJavaMethod method, ResolvedJavaMethod original, Object receiver, boolean trackNodeSourcePosition); /** * Gets a graph that is a substitution for a given method. @@ -138,4 +144,13 @@ * {@link Replacements#registerSnippetTemplateCache(SnippetTemplateCache)}. */ T getSnippetTemplateCache(Class templatesClass); + + /** + * Notifies this method that no further snippets will be registered via {@link #registerSnippet} + * or {@link #registerSnippetTemplateCache}. + * + * This is a hook for an implementation to check for or forbid late registration. + */ + default void closeSnippetRegistration() { + } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java 2018-12-11 11:13:31.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java 2018-12-11 11:13:31.000000000 -0800 @@ -109,34 +109,42 @@ } public Providers copyWith(MetaAccessProvider substitution) { + assert this.getClass() == Providers.class : "must override"; return new Providers(substitution, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider); } public Providers copyWith(CodeCacheProvider substitution) { + assert this.getClass() == Providers.class : "must override"; return new Providers(metaAccess, substitution, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider); } public Providers copyWith(ConstantReflectionProvider substitution) { + assert this.getClass() == Providers.class : "must override"; return new Providers(metaAccess, codeCache, substitution, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider); } public Providers copyWith(ConstantFieldProvider substitution) { + assert this.getClass() == Providers.class : "must override"; return new Providers(metaAccess, codeCache, constantReflection, substitution, foreignCalls, lowerer, replacements, stampProvider); } public Providers copyWith(ForeignCallsProvider substitution) { + assert this.getClass() == Providers.class : "must override"; return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, substitution, lowerer, replacements, stampProvider); } public Providers copyWith(LoweringProvider substitution) { + assert this.getClass() == Providers.class : "must override"; return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, substitution, replacements, stampProvider); } public Providers copyWith(Replacements substitution) { + assert this.getClass() == Providers.class : "must override in " + getClass(); return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, substitution, stampProvider); } public Providers copyWith(StampProvider substitution) { + assert this.getClass() == Providers.class : "must override"; return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, substitution); } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/InjectedDependencies.java 2018-12-11 11:13:32.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/InjectedDependencies.java 2018-12-11 11:13:32.000000000 -0800 @@ -82,9 +82,12 @@ public enum WellKnownDependency { CONSTANT_REFLECTION("b.getConstantReflection()", "jdk.vm.ci.meta.ConstantReflectionProvider"), META_ACCESS("b.getMetaAccess()", "jdk.vm.ci.meta.MetaAccessProvider"), + ASSUMPTIONS("b.getAssumptions()", "jdk.vm.ci.meta.Assumptions"), + OPTIONVALUES("b.getOptions()", "org.graalvm.compiler.options.OptionValues"), INJECTED_STAMP(new InjectedStampDependency()), SNIPPET_REFLECTION(new InjectedDependency("snippetReflection", "org.graalvm.compiler.api.replacements.SnippetReflectionProvider")), STAMP_PROVIDER("b.getStampProvider()", "org.graalvm.compiler.nodes.spi.StampProvider"), + INTRINSIC_CONTEXT("b.getIntrinsic()", "org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext"), STRUCTURED_GRAPH("b.getGraph()", "org.graalvm.compiler.nodes.StructuredGraph"); private final String expr; --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/NodeIntrinsicHandler.java 2018-12-11 11:13:33.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/NodeIntrinsicHandler.java 2018-12-11 11:13:33.000000000 -0800 @@ -245,20 +245,29 @@ } if (method.getParameters().size() < 2) { + nonMatches.put(method, "Too few arguments"); continue; } VariableElement firstArg = method.getParameters().get(0); if (!isTypeCompatible(firstArg.asType(), processor.getType(GRAPH_BUILDER_CONTEXT_CLASS_NAME))) { + nonMatches.put(method, "First argument isn't of type GraphBuilderContext"); continue; } VariableElement secondArg = method.getParameters().get(1); if (!isTypeCompatible(secondArg.asType(), processor.getType(RESOLVED_JAVA_METHOD_CLASS_NAME))) { + nonMatches.put(method, "Second argument isn't of type ResolvedJavaMethod"); continue; } if (method.getReturnType().getKind() != TypeKind.BOOLEAN) { + nonMatches.put(method, "Doesn't return boolean"); + continue; + } + + if (!method.getModifiers().contains(Modifier.STATIC)) { + nonMatches.put(method, "Method is non-static"); continue; } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsTest.java 2018-12-11 11:13:34.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsTest.java 2018-12-11 11:13:34.000000000 -0800 @@ -38,7 +38,7 @@ */ protected final ClassfileBytecodeProvider getSystemClassLoaderBytecodeProvider() { ReplacementsImpl d = (ReplacementsImpl) getReplacements(); - MetaAccessProvider metaAccess = d.providers.getMetaAccess(); + MetaAccessProvider metaAccess = d.getProviders().getMetaAccess(); ClassfileBytecodeProvider bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, d.snippetReflection, ClassLoader.getSystemClassLoader()); return bytecodeProvider; } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SnippetsTest.java 2018-12-11 11:13:36.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SnippetsTest.java 2018-12-11 11:13:35.000000000 -0800 @@ -39,7 +39,7 @@ protected SnippetsTest() { ReplacementsImpl d = (ReplacementsImpl) getReplacements(); bytecodeProvider = getSystemClassLoaderBytecodeProvider(); - installer = new ReplacementsImpl(getInitialOptions(), null, d.providers, d.snippetReflection, bytecodeProvider, d.target); + installer = new ReplacementsImpl(getInitialOptions(), null, d.getProviders(), d.snippetReflection, bytecodeProvider, d.target); installer.setGraphBuilderPlugins(d.getGraphBuilderPlugins()); } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java 2018-12-11 11:13:37.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java 2018-12-11 11:13:36.000000000 -0800 @@ -93,6 +93,7 @@ needCheckNode = false; } else { List vmArgs = GraalServices.getInputArguments(); + Assume.assumeTrue(vmArgs != null); for (String vmArg : vmArgs) { if (vmArg.equals(DISABLE_COMPACTSTRINGS_FLAG)) { needCheckNode = false; --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java 2018-12-11 11:13:38.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java 2018-12-11 11:13:37.000000000 -0800 @@ -83,6 +83,7 @@ import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.Signature; /** @@ -218,11 +219,12 @@ } public ResolvedJavaMethod findMethod(Class declaringClass, String name, boolean isStatic) { + ResolvedJavaType type = providers.getMetaAccess().lookupJavaType(declaringClass); ResolvedJavaMethod method = null; - for (Method m : declaringClass.getDeclaredMethods()) { + for (ResolvedJavaMethod m : type.getDeclaredMethods()) { if (Modifier.isStatic(m.getModifiers()) == isStatic && m.getName().equals(name)) { assert method == null : "found more than one method in " + declaringClass + " named " + name; - method = providers.getMetaAccess().lookupJavaMethod(m); + method = m; } } GraalError.guarantee(method != null, "Could not find %s.%s (%s)", declaringClass, name, isStatic ? "static" : "non-static"); @@ -356,7 +358,8 @@ Plugins plugins = new Plugins(graphBuilderPlugins); GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins); - StructuredGraph calleeGraph = new StructuredGraph.Builder(invoke.getOptions(), invoke.getDebug()).method(method).trackNodeSourcePosition(invoke.graph().trackNodeSourcePosition()).build(); + StructuredGraph calleeGraph = new StructuredGraph.Builder(invoke.getOptions(), invoke.getDebug()).method(method).trackNodeSourcePosition( + invoke.graph().trackNodeSourcePosition()).setIsSubstitution(true).build(); IntrinsicContext initialReplacementContext = new IntrinsicContext(method, method, providers.getReplacements().getDefaultReplacementBytecodeProvider(), INLINE_AFTER_PARSING); GraphBuilderPhase.Instance instance = createGraphBuilderInstance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), providers.getConstantFieldProvider(), config, OptimisticOptimizations.NONE, --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/NodeIntrinsificationProvider.java 2018-12-11 11:13:39.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/NodeIntrinsificationProvider.java 2018-12-11 11:13:38.000000000 -0800 @@ -76,6 +76,8 @@ return type.cast(foreignCalls); } else if (type.equals(SnippetReflectionProvider.class)) { return type.cast(snippetReflection); + } else if (type.equals(WordTypes.class)) { + return type.cast(wordTypes); } else { throw new GraalError("Cannot handle injected argument of type %s.", type.getName()); } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java 2018-12-11 11:13:40.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java 2018-12-11 11:13:39.000000000 -0800 @@ -419,10 +419,18 @@ protected FixedWithNextNode lastInstr; protected ValueNode pushedNode; protected boolean invokeConsumed; + protected final InvokeKind invokeKind; + protected final JavaType invokeReturnType; public PEAppendGraphBuilderContext(PEMethodScope inlineScope, FixedWithNextNode lastInstr) { + this(inlineScope, lastInstr, null, null); + } + + public PEAppendGraphBuilderContext(PEMethodScope inlineScope, FixedWithNextNode lastInstr, InvokeKind invokeKind, JavaType invokeReturnType) { super(inlineScope, inlineScope.invokeData != null ? inlineScope.invokeData.invoke : null); this.lastInstr = lastInstr; + this.invokeKind = invokeKind; + this.invokeReturnType = invokeReturnType; } @Override @@ -483,6 +491,22 @@ } @Override + public InvokeKind getInvokeKind() { + if (invokeKind != null) { + return invokeKind; + } + return super.getInvokeKind(); + } + + @Override + public JavaType getInvokeReturnType() { + if (invokeReturnType != null) { + return invokeReturnType; + } + return super.getInvokeReturnType(); + } + + @Override public void handleReplacedInvoke(CallTargetNode callTarget, JavaKind resultType) { if (invokeConsumed) { throw unimplemented("handleReplacedInvoke can be called only once"); @@ -727,7 +751,9 @@ invoke.asNode().replaceAtPredecessor(null); PEMethodScope inlineScope = new PEMethodScope(graph, methodScope, loopScope, null, targetMethod, invokeData, methodScope.inliningDepth + 1, loopExplosionPlugin, arguments); - PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(inlineScope, invokePredecessor); + + JavaType returnType = targetMethod.getSignature().getReturnType(methodScope.method.getDeclaringClass()); + PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(inlineScope, invokePredecessor, callTarget.invokeKind(), returnType); InvocationPluginReceiver invocationPluginReceiver = new InvocationPluginReceiver(graphBuilderContext); if (invocationPlugin.execute(graphBuilderContext, targetMethod, invocationPluginReceiver.init(targetMethod, arguments), arguments)) { --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java 2018-12-11 11:13:41.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java 2018-12-11 11:13:40.000000000 -0800 @@ -24,6 +24,7 @@ package org.graalvm.compiler.replacements; +import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; import static org.graalvm.compiler.core.common.GraalOptions.UseSnippetGraphCache; import static org.graalvm.compiler.debug.DebugContext.DEFAULT_LOG_STREAM; import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing; @@ -72,6 +73,7 @@ import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; +import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderPlugin; import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin; import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; @@ -98,7 +100,16 @@ public class ReplacementsImpl implements Replacements, InlineInvokePlugin { protected final OptionValues options; - public final Providers providers; + + public Providers getProviders() { + return providers; + } + + public void setProviders(Providers providers) { + this.providers = providers.copyWith(this); + } + + protected Providers providers; public final SnippetReflectionProvider snippetReflection; public final TargetDescription target; private GraphBuilderConfiguration.Plugins graphBuilderPlugins; @@ -130,12 +141,15 @@ return graphBuilderPlugins; } - protected boolean hasGeneratedInvocationPluginAnnotation(ResolvedJavaMethod method) { - return method.getAnnotation(Node.NodeIntrinsic.class) != null || method.getAnnotation(Fold.class) != null; - } - - protected boolean hasGenericInvocationPluginAnnotation(ResolvedJavaMethod method) { - return method.getAnnotation(Word.Operation.class) != null; + @Override + public Class getIntrinsifyingPlugin(ResolvedJavaMethod method) { + if (method.getAnnotation(Node.NodeIntrinsic.class) != null || method.getAnnotation(Fold.class) != null) { + return GeneratedInvocationPlugin.class; + } + if (method.getAnnotation(Word.Operation.class) != null) { + return WordOperationPlugin.class; + } + return null; } private static final int MAX_GRAPH_INLINING_DEPTH = 100; // more than enough @@ -163,7 +177,8 @@ // Force inlining when parsing replacements return createIntrinsicInlineInfo(method, null, defaultBytecodeProvider); } else { - assert method.getAnnotation(NodeIntrinsic.class) == null : String.format("@%s method %s must only be called from within a replacement%n%s", NodeIntrinsic.class.getSimpleName(), + assert IS_BUILDING_NATIVE_IMAGE || method.getAnnotation(NodeIntrinsic.class) == null : String.format("@%s method %s must only be called from within a replacement%n%s", + NodeIntrinsic.class.getSimpleName(), method.format("%h.%n"), b); } return null; @@ -174,13 +189,15 @@ if (b.parsingIntrinsic()) { IntrinsicContext intrinsic = b.getIntrinsic(); if (!intrinsic.isCallToOriginal(method)) { - if (hasGeneratedInvocationPluginAnnotation(method)) { - throw new GraalError("%s should have been handled by a %s", method.format("%H.%n(%p)"), GeneratedInvocationPlugin.class.getSimpleName()); - } - if (hasGenericInvocationPluginAnnotation(method)) { - throw new GraalError("%s should have been handled by %s", method.format("%H.%n(%p)"), WordOperationPlugin.class.getSimpleName()); + Class pluginClass = getIntrinsifyingPlugin(method); + if (pluginClass != null) { + String methodDesc = method.format("%H.%n(%p)"); + throw new GraalError("Call to %s should have been intrinsified by a %s. " + + "This is typically caused by Eclipse failing to run an annotation " + + "processor. This can usually be fixed by forcing Eclipse to rebuild " + + "the source file in which %s is declared", + methodDesc, pluginClass.getSimpleName(), methodDesc); } - throw new GraalError("All non-recursive calls in the intrinsic %s must be inlined or intrinsified: found call to %s", intrinsic.getIntrinsicMethod().format("%H.%n(%p)"), method.format("%h.%n(%p)")); } @@ -213,7 +230,7 @@ private static final AtomicInteger nextDebugContextId = new AtomicInteger(); - protected DebugContext openDebugContext(String idPrefix, ResolvedJavaMethod method) { + public DebugContext openDebugContext(String idPrefix, ResolvedJavaMethod method) { DebugContext outer = DebugContext.forCurrentThread(); Description description = new Description(method, idPrefix + nextDebugContextId.incrementAndGet()); List factories = debugHandlersFactory == null ? Collections.emptyList() : Collections.singletonList(debugHandlersFactory); @@ -249,7 +266,7 @@ } @Override - public void registerSnippet(ResolvedJavaMethod method, boolean trackNodeSourcePosition) { + public void registerSnippet(ResolvedJavaMethod method, ResolvedJavaMethod original, Object receiver, boolean trackNodeSourcePosition) { // No initialization needed as snippet graphs are created on demand in getSnippet } @@ -386,7 +403,7 @@ */ protected final ResolvedJavaMethod substitutedMethod; - protected GraphMaker(ReplacementsImpl replacements, ResolvedJavaMethod substitute, ResolvedJavaMethod substitutedMethod) { + public GraphMaker(ReplacementsImpl replacements, ResolvedJavaMethod substitute, ResolvedJavaMethod substitutedMethod) { this.replacements = replacements; this.method = substitute; this.substitutedMethod = substitutedMethod; @@ -488,13 +505,15 @@ IntrinsicContext initialIntrinsicContext = null; Snippet snippetAnnotation = method.getAnnotation(Snippet.class); - if (snippetAnnotation == null) { + MethodSubstitution methodAnnotation = method.getAnnotation(MethodSubstitution.class); + if (methodAnnotation == null && snippetAnnotation == null) { // Post-parse inlined intrinsic initialIntrinsicContext = new IntrinsicContext(substitutedMethod, method, bytecodeProvider, INLINE_AFTER_PARSING); } else { // Snippet ResolvedJavaMethod original = substitutedMethod != null ? substitutedMethod : method; - initialIntrinsicContext = new IntrinsicContext(original, method, bytecodeProvider, INLINE_AFTER_PARSING, snippetAnnotation.allowPartialIntrinsicArgumentMismatch()); + initialIntrinsicContext = new IntrinsicContext(original, method, bytecodeProvider, INLINE_AFTER_PARSING, + snippetAnnotation != null ? snippetAnnotation.allowPartialIntrinsicArgumentMismatch() : true); } createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.providers.getConstantReflection(), replacements.providers.getConstantFieldProvider(), config, --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsUtil.java 2018-12-11 11:13:42.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsUtil.java 2018-12-11 11:13:41.000000000 -0800 @@ -51,6 +51,18 @@ } } + public static void staticAssert(boolean condition, String message, Object arg1) { + if (REPLACEMENTS_ASSERTIONS_ENABLED) { + AssertionNode.assertion(true, condition, message, arg1, ""); + } + } + + public static void staticAssert(boolean condition, String message, Object arg1, Object arg2) { + if (REPLACEMENTS_ASSERTIONS_ENABLED) { + AssertionNode.assertion(true, condition, message, arg1, arg2); + } + } + /** * Asserts that condition evaluates to true at runtime. This is intended to be used within * snippets or stubs, and will lead to a VM error if it fails. --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java 2018-12-11 11:13:43.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java 2018-12-11 11:13:42.000000000 -0800 @@ -64,6 +64,7 @@ import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.core.common.type.StampPair; import org.graalvm.compiler.core.common.type.TypeReference; +import org.graalvm.compiler.debug.Assertions; import org.graalvm.compiler.debug.CounterKey; import org.graalvm.compiler.debug.DebugCloseable; import org.graalvm.compiler.debug.DebugContext; @@ -170,7 +171,7 @@ public abstract static class SnippetInfo { protected final ResolvedJavaMethod method; - protected ResolvedJavaMethod original; + protected final ResolvedJavaMethod original; protected final LocationIdentity[] privateLocations; protected final Object receiver; @@ -269,8 +270,9 @@ protected abstract Lazy lazy(); - protected SnippetInfo(ResolvedJavaMethod method, LocationIdentity[] privateLocations, Object receiver) { + protected SnippetInfo(ResolvedJavaMethod method, ResolvedJavaMethod original, LocationIdentity[] privateLocations, Object receiver) { this.method = method; + this.original = original; this.privateLocations = privateLocations; instantiationCounter = DebugContext.counter("SnippetInstantiationCount[%s]", method.getName()); instantiationTimer = DebugContext.timer("SnippetInstantiationTime[%s]", method.getName()); @@ -285,10 +287,6 @@ return lazy().constantParameters.length; } - public void setOriginalMethod(ResolvedJavaMethod original) { - this.original = original; - } - public boolean isConstantParameter(int paramIdx) { return lazy().constantParameters[paramIdx]; } @@ -318,8 +316,8 @@ protected static class LazySnippetInfo extends SnippetInfo { protected final AtomicReference lazy = new AtomicReference<>(null); - protected LazySnippetInfo(ResolvedJavaMethod method, LocationIdentity[] privateLocations, Object receiver) { - super(method, privateLocations, receiver); + protected LazySnippetInfo(ResolvedJavaMethod method, ResolvedJavaMethod original, LocationIdentity[] privateLocations, Object receiver) { + super(method, original, privateLocations, receiver); } @Override @@ -334,8 +332,8 @@ protected static class EagerSnippetInfo extends SnippetInfo { protected final Lazy lazy; - protected EagerSnippetInfo(ResolvedJavaMethod method, LocationIdentity[] privateLocations, Object receiver) { - super(method, privateLocations, receiver); + protected EagerSnippetInfo(ResolvedJavaMethod method, ResolvedJavaMethod original, LocationIdentity[] privateLocations, Object receiver) { + super(method, original, privateLocations, receiver); lazy = new Lazy(method); } @@ -642,28 +640,45 @@ return null; } + public static ResolvedJavaMethod findMethod(MetaAccessProvider metaAccess, Class declaringClass, String methodName) { + ResolvedJavaType type = metaAccess.lookupJavaType(declaringClass); + ResolvedJavaMethod result = null; + for (ResolvedJavaMethod m : type.getDeclaredMethods()) { + if (m.getName().equals(methodName)) { + if (!Assertions.assertionsEnabled()) { + return m; + } else { + assert result == null : "multiple definitions found"; + result = m; + } + } + } + if (result == null) { + throw new GraalError("Could not find method in " + declaringClass + " named " + methodName); + } + return result; + } + protected SnippetInfo snippet(Class declaringClass, String methodName, LocationIdentity... initialPrivateLocations) { - return snippet(declaringClass, methodName, null, initialPrivateLocations); + return snippet(declaringClass, methodName, null, null, initialPrivateLocations); } /** * Finds the unique method in {@code declaringClass} named {@code methodName} annotated by * {@link Snippet} and returns a {@link SnippetInfo} value describing it. There must be - * exactly one snippet method in {@code declaringClass}. + * exactly one snippet method in {@code declaringClass} with a given name. */ - protected SnippetInfo snippet(Class declaringClass, String methodName, Object receiver, LocationIdentity... initialPrivateLocations) { + protected SnippetInfo snippet(Class declaringClass, String methodName, ResolvedJavaMethod original, Object receiver, LocationIdentity... initialPrivateLocations) { assert methodName != null; - Method method = findMethod(declaringClass, methodName, null); - assert method != null : "did not find @" + Snippet.class.getSimpleName() + " method in " + declaringClass + " named " + methodName; - assert method.getAnnotation(Snippet.class) != null : method + " must be annotated with @" + Snippet.class.getSimpleName(); - assert findMethod(declaringClass, methodName, method) == null : "found more than one method named " + methodName + " in " + declaringClass; - ResolvedJavaMethod javaMethod = providers.getMetaAccess().lookupJavaMethod(method); - providers.getReplacements().registerSnippet(javaMethod, GraalOptions.TrackNodeSourcePosition.getValue(options)); + ResolvedJavaMethod javaMethod = findMethod(providers.getMetaAccess(), declaringClass, methodName); + assert javaMethod != null : "did not find @" + Snippet.class.getSimpleName() + " method in " + declaringClass + " named " + methodName; + assert javaMethod.getAnnotation(Snippet.class) != null : javaMethod + " must be annotated with @" + Snippet.class.getSimpleName(); + providers.getReplacements().registerSnippet(javaMethod, original, receiver, GraalOptions.TrackNodeSourcePosition.getValue(options)); LocationIdentity[] privateLocations = GraalOptions.SnippetCounters.getValue(options) ? SnippetCounterNode.addSnippetCounters(initialPrivateLocations) : initialPrivateLocations; if (GraalOptions.EagerSnippets.getValue(options)) { - return new EagerSnippetInfo(javaMethod, privateLocations, receiver); + return new EagerSnippetInfo(javaMethod, original, privateLocations, receiver); } else { - return new LazySnippetInfo(javaMethod, privateLocations, receiver); + return new LazySnippetInfo(javaMethod, original, privateLocations, receiver); } } @@ -1038,7 +1053,7 @@ LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin); Mark mark = snippetCopy.getMark(); LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase()); - new CanonicalizerPhase().applyIncremental(snippetCopy, phaseContext, mark); + new CanonicalizerPhase().applyIncremental(snippetCopy, phaseContext, mark, false); loop.deleteUnusedNodes(); } GraphUtil.removeFixedWithUnusedInputs(explodeLoop); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopySnippets.java 2018-12-11 11:13:44.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopySnippets.java 2018-12-11 11:13:43.000000000 -0800 @@ -30,7 +30,6 @@ import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability; -import java.lang.reflect.Method; import java.util.EnumMap; import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap; @@ -290,7 +289,7 @@ DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } } else { - ReplacementsUtil.staticAssert(false, "unknown array type check"); + ReplacementsUtil.staticAssert(false, "unknown array type check ", arrayTypeCheck); } } @@ -384,8 +383,7 @@ } protected SnippetInfo snippet(ArrayCopySnippets receiver, String methodName) { - SnippetInfo info = snippet(ArrayCopySnippets.class, methodName, receiver, LocationIdentity.any()); - info.setOriginalMethod(originalArraycopy()); + SnippetInfo info = snippet(ArrayCopySnippets.class, methodName, originalArraycopy(), receiver, LocationIdentity.any()); return info; } @@ -577,13 +575,11 @@ private ResolvedJavaMethod originalArraycopy() throws GraalError { if (originalArraycopy == null) { - Method method; try { - method = System.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class); - } catch (NoSuchMethodException | SecurityException e) { + originalArraycopy = findMethod(providers.getMetaAccess(), System.class, "arraycopy"); + } catch (SecurityException e) { throw new GraalError(e); } - originalArraycopy = providers.getMetaAccess().lookupJavaMethod(method); } return originalArraycopy; } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/AssertionNode.java 2018-12-11 11:13:45.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/AssertionNode.java 2018-12-11 11:13:44.000000000 -0800 @@ -56,11 +56,11 @@ protected final boolean compileTimeAssertion; protected final String message; - public AssertionNode(boolean compileTimeAssertion, ValueNode condition, String message) { + public AssertionNode(boolean compileTimeAssertion, ValueNode condition, String message, Object arg1, Object arg2) { super(TYPE, StampFactory.forVoid()); this.condition = condition; this.compileTimeAssertion = compileTimeAssertion; - this.message = message; + this.message = message + arg1 + arg2; } public ValueNode condition() { @@ -112,5 +112,14 @@ } @NodeIntrinsic - public static native void assertion(@ConstantNodeParameter boolean compileTimeAssertion, boolean condition, @ConstantNodeParameter String message); + public static native void assertion(@ConstantNodeParameter boolean compileTimeAssertion, boolean condition, @ConstantNodeParameter String message, @ConstantNodeParameter Object arg1, + @ConstantNodeParameter Object arg2); + + public static void assertion(@ConstantNodeParameter boolean compileTimeAssertion, boolean condition, @ConstantNodeParameter String message) { + assertion(compileTimeAssertion, condition, message, "", ""); + } + + public static void assertion(@ConstantNodeParameter boolean compileTimeAssertion, boolean condition, @ConstantNodeParameter String message, @ConstantNodeParameter Object arg1) { + assertion(compileTimeAssertion, condition, message, arg1, ""); + } } --- /dev/null 2018-12-11 11:13:46.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ForeignCallSnippets.java 2018-12-11 11:13:45.000000000 -0800 @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2012, 2016, 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 org.graalvm.compiler.hotspot.stubs; + +import static jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_VMCONFIG; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.clearPendingException; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.getPendingException; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadHubIntrinsic; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.verifyOops; +import static org.graalvm.compiler.hotspot.stubs.StubUtil.fatal; + +import org.graalvm.compiler.api.replacements.Fold; +import org.graalvm.compiler.api.replacements.Fold.InjectedParameter; +import org.graalvm.compiler.api.replacements.Snippet; +import org.graalvm.compiler.debug.DebugHandlersFactory; +import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; +import org.graalvm.compiler.hotspot.meta.HotSpotProviders; +import org.graalvm.compiler.hotspot.nodes.DeoptimizeCallerNode; +import org.graalvm.compiler.hotspot.word.KlassPointer; +import org.graalvm.compiler.nodes.NamedLocationIdentity; +import org.graalvm.compiler.nodes.PiNode; +import org.graalvm.compiler.nodes.SnippetAnchorNode; +import org.graalvm.compiler.nodes.extended.GuardingNode; +import org.graalvm.compiler.options.OptionValues; +import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates; +import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo; +import org.graalvm.compiler.replacements.Snippets; +import org.graalvm.compiler.word.Word; +import jdk.internal.vm.compiler.word.LocationIdentity; +import jdk.internal.vm.compiler.word.Pointer; +import jdk.internal.vm.compiler.word.WordFactory; + +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.meta.DeoptimizationAction; + +public class ForeignCallSnippets implements Snippets { + + public static class Templates extends AbstractTemplates { + + final SnippetInfo handlePendingException = snippet(ForeignCallSnippets.class, "handlePendingException"); + final SnippetInfo getAndClearObjectResult = snippet(ForeignCallSnippets.class, "getAndClearObjectResult", OBJECT_RESULT_LOCATION); + final SnippetInfo verifyObject = snippet(ForeignCallSnippets.class, "verifyObject"); + + public Templates(OptionValues options, Iterable factories, HotSpotProviders providers, TargetDescription target) { + super(options, factories, providers, providers.getSnippetReflection(), target); + } + } + + /** + * See {@link ForeignCallStub#getGraph}. + */ + @Snippet + public static void handlePendingException(Word thread, boolean shouldClearException, boolean isObjectResult) { + if ((shouldClearException && clearPendingException(thread) != null) || (!shouldClearException && getPendingException(thread) != null)) { + if (isObjectResult) { + getAndClearObjectResult(thread); + } + DeoptimizeCallerNode.deopt(DeoptimizationAction.None, RuntimeConstraint); + } + } + + /** + * Verifies that a given object value is well formed if {@code -XX:+VerifyOops} is enabled. + */ + @Snippet + public static Object verifyObject(Object object) { + if (verifyOops(INJECTED_VMCONFIG)) { + Word verifyOopCounter = WordFactory.unsigned(verifyOopCounterAddress(INJECTED_VMCONFIG)); + verifyOopCounter.writeInt(0, verifyOopCounter.readInt(0) + 1); + + Pointer oop = Word.objectToTrackedPointer(object); + if (object != null) { + GuardingNode anchorNode = SnippetAnchorNode.anchor(); + // make sure object is 'reasonable' + if (!oop.and(WordFactory.unsigned(verifyOopMask(INJECTED_VMCONFIG))).equal(WordFactory.unsigned(verifyOopBits(INJECTED_VMCONFIG)))) { + fatal("oop not in heap: %p", oop.rawValue()); + } + + KlassPointer klass = loadHubIntrinsic(PiNode.piCastNonNull(object, anchorNode)); + if (klass.isNull()) { + fatal("klass for oop %p is null", oop.rawValue()); + } + } + } + return object; + } + + @Fold + static long verifyOopCounterAddress(@InjectedParameter GraalHotSpotVMConfig config) { + return config.verifyOopCounterAddress; + } + + @Fold + static long verifyOopMask(@InjectedParameter GraalHotSpotVMConfig config) { + return config.verifyOopMask; + } + + @Fold + static long verifyOopBits(@InjectedParameter GraalHotSpotVMConfig config) { + return config.verifyOopBits; + } + + /** + * Gets and clears the object result from a runtime call stored in a thread local. + * + * @return the object that was in the thread local + */ + @Snippet + public static Object getAndClearObjectResult(Word thread) { + Object result = thread.readObject(objectResultOffset(INJECTED_VMCONFIG), OBJECT_RESULT_LOCATION); + thread.writeObject(objectResultOffset(INJECTED_VMCONFIG), null, OBJECT_RESULT_LOCATION); + return result; + } + + public static final LocationIdentity OBJECT_RESULT_LOCATION = NamedLocationIdentity.mutable("ObjectResult"); + + @Fold + static int objectResultOffset(@InjectedParameter GraalHotSpotVMConfig config) { + return config.threadObjectResultOffset; + } +} --- /dev/null 2018-12-11 11:13:47.000000000 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/SuppressFBWarnings.java 2018-12-11 11:13:47.000000000 -0800 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 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 org.graalvm.compiler.options; + +/** + * Used to suppress FindBugs warnings. + */ +public @interface SuppressFBWarnings { + /** + * The set of FindBugs + * warnings that are to be + * suppressed in annotated element. The value can be a bug category, kind or pattern. + */ + String[] value(); + + /** + * Reason why the warning is suppressed. + */ + String justification(); +} --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/UnsafeAccess.java 2018-12-11 11:13:48.000000000 -0800 +++ /dev/null 2018-12-11 11:13:48.000000000 -0800 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2012, 2018, 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 org.graalvm.compiler.hotspot.replacements; - -import java.lang.reflect.Field; - -import sun.misc.Unsafe; - -/** - * Package private access to the {@link Unsafe} capability. - */ -class UnsafeAccess { - - static final Unsafe UNSAFE = initUnsafe(); - - private static Unsafe initUnsafe() { - try { - // Fast path when we are trusted. - return Unsafe.getUnsafe(); - } catch (SecurityException se) { - // Slow path when we are not trusted. - try { - Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafe.setAccessible(true); - return (Unsafe) theUnsafe.get(Unsafe.class); - } catch (Exception e) { - throw new RuntimeException("exception while trying to get Unsafe", e); - } - } - } -}