OpenJDK / jdk / jdk
changeset 52578:7dd81e82d083
8210777: Update Graal
Reviewed-by: kvn
line wrap: on
line diff
--- a/make/CompileJavaModules.gmk Thu Nov 15 21:05:47 2018 +0100 +++ b/make/CompileJavaModules.gmk Thu Nov 15 09:04:07 2018 -0800 @@ -450,21 +450,17 @@ jdk.internal.vm.compiler_EXCLUDES += \ jdk.internal.vm.compiler.collections.test \ - org.graalvm.compiler.processor \ - org.graalvm.compiler.core.match.processor \ - org.graalvm.compiler.nodeinfo.processor \ - org.graalvm.compiler.options.processor \ - org.graalvm.compiler.serviceprovider.processor \ - org.graalvm.compiler.replacements.processor \ - org.graalvm.compiler.replacements.jdk9.test \ + jdk.tools.jaotc.test \ org.graalvm.compiler.api.directives.test \ org.graalvm.compiler.api.test \ org.graalvm.compiler.asm.aarch64.test \ org.graalvm.compiler.asm.amd64.test \ org.graalvm.compiler.asm.sparc.test \ org.graalvm.compiler.asm.test \ + org.graalvm.compiler.core.aarch64.test \ org.graalvm.compiler.core.amd64.test \ - org.graalvm.compiler.core.sparc.test \ + org.graalvm.compiler.core.jdk9.test \ + org.graalvm.compiler.core.match.processor \ org.graalvm.compiler.core.test \ org.graalvm.compiler.debug.test \ org.graalvm.compiler.graph.test \ @@ -477,10 +473,18 @@ org.graalvm.compiler.lir.test \ org.graalvm.compiler.loop.test \ org.graalvm.compiler.microbenchmarks \ + org.graalvm.compiler.nodeinfo.processor \ org.graalvm.compiler.nodes.test \ + org.graalvm.compiler.options.processor \ org.graalvm.compiler.options.test \ org.graalvm.compiler.phases.common.test \ + org.graalvm.compiler.processor \ + org.graalvm.compiler.replacements.jdk12.test \ + org.graalvm.compiler.replacements.jdk9.test \ + org.graalvm.compiler.replacements.jdk9_11.test \ + org.graalvm.compiler.replacements.processor \ org.graalvm.compiler.replacements.test \ + org.graalvm.compiler.serviceprovider.processor \ org.graalvm.compiler.test \ org.graalvm.compiler.virtual.bench \ org.graalvm.micro.benchmarks \
--- a/make/test/JtregGraalUnit.gmk Thu Nov 15 21:05:47 2018 +0100 +++ b/make/test/JtregGraalUnit.gmk Thu Nov 15 09:04:07 2018 -0800 @@ -59,6 +59,7 @@ -Xlint:none \ -processorpath $(BUILDTOOLS_OUTPUTDIR)/jdk.vm.compiler.replacements.verifier.jar \ --add-exports jdk.unsupported/sun.misc=ALL-UNNAMED \ + --add-exports java.base/jdk.internal.misc=ALL-UNNAMED \ ### Copy 3rd party libs $(eval $(call SetupCopyFiles, COPY_GRAALUNIT_LIBS, \ @@ -81,6 +82,7 @@ $(SRC_DIR)/org.graalvm.compiler.asm.test/src \ $(SRC_DIR)/org.graalvm.compiler.core.amd64.test/src \ $(SRC_DIR)/org.graalvm.compiler.core.test/src \ + $(SRC_DIR)/org.graalvm.compiler.core.jdk9.test/src \ $(SRC_DIR)/org.graalvm.compiler.debug.test/src \ $(SRC_DIR)/org.graalvm.compiler.graph.test/src \ $(SRC_DIR)/org.graalvm.compiler.hotspot.amd64.test/src \ @@ -92,6 +94,9 @@ $(SRC_DIR)/org.graalvm.compiler.nodes.test/src \ $(SRC_DIR)/org.graalvm.compiler.options.test/src \ $(SRC_DIR)/org.graalvm.compiler.phases.common.test/src \ + $(SRC_DIR)/org.graalvm.compiler.replacements.jdk12.test/src \ + $(SRC_DIR)/org.graalvm.compiler.replacements.jdk9.test/src \ + $(SRC_DIR)/org.graalvm.compiler.replacements.jdk9_11.test/src \ $(SRC_DIR)/org.graalvm.compiler.replacements.test/src \ $(SRC_DIR)/org.graalvm.compiler.test/src \ $(SRC_DIR)/org.graalvm.util.test/src \
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTBackend.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTBackend.java Thu Nov 15 09:04:07 2018 -0800 @@ -33,8 +33,8 @@ import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.hotspot.HotSpotBackend; import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder; +import org.graalvm.compiler.hotspot.meta.HotSpotInvokeDynamicPlugin; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; -import org.graalvm.compiler.hotspot.meta.HotSpotInvokeDynamicPlugin; import org.graalvm.compiler.java.GraphBuilderPhase; import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory; import org.graalvm.compiler.lir.phases.LIRSuites; @@ -167,7 +167,7 @@ void printCompiledMethod(HotSpotResolvedJavaMethod resolvedMethod, CompilationResult compResult) { // This is really not installing the method. - InstalledCode installedCode = codeCache.addCode(resolvedMethod, HotSpotCompiledCodeBuilder.createCompiledCode(codeCache, resolvedMethod, null, compResult), null, null); + InstalledCode installedCode = codeCache.addCode(resolvedMethod, HotSpotCompiledCodeBuilder.createCompiledCode(codeCache, resolvedMethod, null, compResult, graalOptions), null, null); String disassembly = codeCache.disassemble(installedCode); if (disassembly != null) { main.printer.printlnDebug(disassembly);
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompilationTask.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompilationTask.java Thu Nov 15 09:04:07 2018 -0800 @@ -32,8 +32,8 @@ import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.core.GraalCompilerOptions; import org.graalvm.compiler.debug.DebugContext; +import org.graalvm.compiler.debug.DebugContext.Activation; import org.graalvm.compiler.debug.TTY; -import org.graalvm.compiler.debug.DebugContext.Activation; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.printer.GraalDebugHandlersFactory; import org.graalvm.compiler.serviceprovider.GraalServices; @@ -143,7 +143,7 @@ aotBackend.printCompiledMethod((HotSpotResolvedJavaMethod) method, compResult); } - result = new CompiledMethodInfo(compResult, new AOTHotSpotResolvedJavaMethod((HotSpotResolvedJavaMethod) method, aotBackend.getBackend())); + result = new CompiledMethodInfo(compResult, new AOTHotSpotResolvedJavaMethod((HotSpotResolvedJavaMethod) method, aotBackend.getBackend(), graalOptions)); } private String getMethodDescription() {
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTHotSpotResolvedJavaMethod.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTHotSpotResolvedJavaMethod.java Thu Nov 15 09:04:07 2018 -0800 @@ -28,6 +28,8 @@ import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.core.target.Backend; import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder; +import org.graalvm.compiler.options.OptionValues; + import jdk.vm.ci.hotspot.HotSpotCompiledCode; import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; @@ -35,10 +37,12 @@ private final HotSpotResolvedJavaMethod method; private final Backend backend; + private final OptionValues options; - AOTHotSpotResolvedJavaMethod(HotSpotResolvedJavaMethod method, Backend backend) { + AOTHotSpotResolvedJavaMethod(HotSpotResolvedJavaMethod method, Backend backend, OptionValues options) { this.method = method; this.backend = backend; + this.options = options; } @Override @@ -54,7 +58,7 @@ @Override public HotSpotCompiledCode compiledCode(CompilationResult result) { - return HotSpotCompiledCodeBuilder.createCompiledCode(backend.getCodeCache(), method, null, result); + return HotSpotCompiledCodeBuilder.createCompiledCode(backend.getCodeCache(), method, null, result, options); } }
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTStub.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTStub.java Thu Nov 15 09:04:07 2018 -0800 @@ -29,6 +29,7 @@ import org.graalvm.compiler.core.target.Backend; import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder; import org.graalvm.compiler.hotspot.stubs.Stub; +import org.graalvm.compiler.options.OptionValues; import jdk.vm.ci.hotspot.HotSpotCompiledCode; @@ -36,10 +37,12 @@ private final Stub stub; private final Backend backend; + private OptionValues options; - AOTStub(Stub stub, Backend backend) { + AOTStub(Stub stub, Backend backend, OptionValues options) { this.stub = stub; this.backend = backend; + this.options = options; } @Override @@ -54,7 +57,7 @@ @Override public HotSpotCompiledCode compiledCode(CompilationResult result) { - return HotSpotCompiledCodeBuilder.createCompiledCode(backend.getCodeCache(), null, null, result); + return HotSpotCompiledCodeBuilder.createCompiledCode(backend.getCodeCache(), null, null, result, options); } }
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/DataBuilder.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/DataBuilder.java Thu Nov 15 09:04:07 2018 -0800 @@ -30,16 +30,15 @@ import java.util.List; import java.util.Map.Entry; -import jdk.tools.jaotc.binformat.BinaryContainer; -import jdk.tools.jaotc.binformat.ByteContainer; -import jdk.tools.jaotc.binformat.HeaderContainer; - import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.hotspot.HotSpotHostBackend; import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider; import org.graalvm.compiler.hotspot.stubs.Stub; +import jdk.tools.jaotc.binformat.BinaryContainer; +import jdk.tools.jaotc.binformat.ByteContainer; +import jdk.tools.jaotc.binformat.HeaderContainer; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.hotspot.HotSpotVMConfigStore; import jdk.vm.ci.hotspot.VMField; @@ -190,7 +189,7 @@ for (Stub stub : foreignCallsProvider.getStubs()) { try (DebugContext.Scope scope = debug.scope("CompileStubs")) { CompilationResult result = stub.getCompilationResult(debug, backend); - CompiledMethodInfo cm = new CompiledMethodInfo(result, new AOTStub(stub, backend)); + CompiledMethodInfo cm = new CompiledMethodInfo(result, new AOTStub(stub, backend, debug.getOptions())); stubs.add(cm); } catch (Throwable e) { throw debug.handle(e);
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java Thu Nov 15 09:04:07 2018 -0800 @@ -150,10 +150,16 @@ */ synchronized void poll() { if (platformMBeanServer == null) { - ArrayList<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null); - if (!servers.isEmpty()) { - platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); - process(); + try { + ArrayList<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null); + if (!servers.isEmpty()) { + platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); + process(); + } + } catch (SecurityException e) { + // Without permission to find or create the MBeanServer, + // we cannot process any Graal mbeans. + deferred = null; } } else { process();
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapImplTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapImplTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections.test; import java.util.Arrays; @@ -117,7 +133,7 @@ Assert.assertTrue(set.add(newInteger(0))); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) private static Integer newInteger(int value) { return new Integer(value); }
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapLargeTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapLargeTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections.test; import java.util.Arrays;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections.test; import java.util.LinkedHashMap;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicSetTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicSetTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections.test; import java.util.ArrayList; @@ -145,7 +161,7 @@ Assert.assertEquals(newInteger(9), finalList.get(0)); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) private static Integer newInteger(int value) { return new Integer(value); }
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EquivalenceTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EquivalenceTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections.test; import jdk.internal.vm.compiler.collections.Equivalence;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/PairTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/PairTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections.test; import jdk.internal.vm.compiler.collections.Pair;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMap.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMap.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections; import java.util.Iterator;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMapImpl.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMapImpl.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections; import java.util.Iterator;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicSet.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicSet.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections; import java.util.Iterator;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Equivalence.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Equivalence.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections; /**
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/MapCursor.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/MapCursor.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections; /**
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Pair.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Pair.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections; import java.util.Objects;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicMap.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicMap.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections; /**
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicSet.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicSet.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections; /**
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableMapCursor.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableMapCursor.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections; /**
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/package-info.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/package-info.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -35,4 +35,20 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.collections;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/ComparableWord.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/ComparableWord.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.word; /**
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/LocationIdentity.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/LocationIdentity.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.word; // JaCoCo Exclude
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/Pointer.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/Pointer.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.word; /** @@ -959,7 +975,8 @@ void writeObject(WordBase offset, Object val); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * <p> * The offset is always treated as a {@link SignedWord} value. However, the static type is @@ -967,17 +984,19 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location - * @return The value after the atomic exchange + * @return The value that was read for comparison, which is {@code expectedValue} if the + * exchange was performed. * * @since 1.0 */ int compareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * <p> * The offset is always treated as a {@link SignedWord} value. However, the static type is @@ -985,17 +1004,19 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location - * @return The value after the atomic exchange + * @return The value that was read for comparison, which is {@code expectedValue} if the + * exchange was performed. * * @since 1.0 */ long compareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * <p> * The offset is always treated as a {@link SignedWord} value. However, the static type is @@ -1003,17 +1024,19 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location - * @return The value after the atomic exchange + * @return The value that was read for comparison, which is {@code expectedValue} if the + * exchange was performed. * * @since 1.0 */ <T extends WordBase> T compareAndSwapWord(WordBase offset, T expectedValue, T newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * <p> * The offset is always treated as a {@link SignedWord} value. However, the static type is @@ -1021,17 +1044,19 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location - * @return The value after the atomic exchange + * @return The value that was read for comparison, which is {@code expectedValue} if the + * exchange was performed. * * @since 1.0 */ Object compareAndSwapObject(WordBase offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * <p> * The offset is always treated as a {@link SignedWord} value. However, the static type is @@ -1039,8 +1064,8 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location * @return {@code true} if successful. False return indicates that the actual value was not * equal to the expected value. @@ -1050,7 +1075,8 @@ boolean logicCompareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * <p> * The offset is always treated as a {@link SignedWord} value. However, the static type is @@ -1058,8 +1084,8 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location * @return {@code true} if successful. False return indicates that the actual value was not * equal to the expected value. @@ -1069,7 +1095,8 @@ boolean logicCompareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * <p> * The offset is always treated as a {@link SignedWord} value. However, the static type is @@ -1077,8 +1104,8 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location * @return {@code true} if successful. False return indicates that the actual value was not * equal to the expected value. @@ -1088,7 +1115,8 @@ boolean logicCompareAndSwapWord(WordBase offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * <p> * The offset is always treated as a {@link SignedWord} value. However, the static type is @@ -1096,8 +1124,8 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location * @return {@code true} if successful. False return indicates that the actual value was not * equal to the expected value. @@ -1206,68 +1234,77 @@ void writeObject(int offset, Object val); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location - * @return The value after the atomic exchange + * @return The value that was read for comparison, which is {@code expectedValue} if the + * exchange was performed. * * @since 1.0 */ int compareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location - * @return The value after the atomic exchange + * @return The value that was read for comparison, which is {@code expectedValue} if the + * exchange was performed. * * @since 1.0 */ long compareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location - * @return The value after the atomic exchange + * @return The value that was read for comparison, which is {@code expectedValue} if the + * exchange was performed. * * @since 1.0 */ <T extends WordBase> T compareAndSwapWord(int offset, T expectedValue, T newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location - * @return The value after the atomic exchange + * @return The value that was read for comparison, which is {@code expectedValue} if the + * exchange was performed. * * @since 1.0 */ Object compareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location * @return {@code true} if successful. False return indicates that the actual value was not * equal to the expected value. @@ -1277,12 +1314,13 @@ boolean logicCompareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location * @return {@code true} if successful. False return indicates that the actual value was not * equal to the expected value. @@ -1292,12 +1330,13 @@ boolean logicCompareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location * @return {@code true} if successful. False return indicates that the actual value was not * equal to the expected value. @@ -1307,12 +1346,13 @@ boolean logicCompareAndSwapWord(int offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity); /** - * Atomically exchanges memory at address {@code (this + offset)}. Both the base address and + * In a single atomic step, compares the memory at address {@code (this + offset)} to the + * expected value, and if equal, exchanges it for the new value. Both the base address and * offset are in bytes. * * @param offset the signed offset for the memory access - * @param expectedValue the expected value of the atomic exchange - * @param newValue the new value of the atomic exchange + * @param expectedValue the expected current value at the memory address + * @param newValue the new value for the atomic exchange * @param locationIdentity the identity of the memory location * @return {@code true} if successful. False return indicates that the actual value was not * equal to the expected value.
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/PointerBase.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/PointerBase.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.word; /**
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/SignedWord.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/SignedWord.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.word; /**
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/UnsignedWord.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/UnsignedWord.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.word; /**
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordBase.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordBase.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.word; /**
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordFactory.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordFactory.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.word; import jdk.internal.vm.compiler.word.impl.WordBoxFactory;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/impl/WordBoxFactory.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/impl/WordBoxFactory.java Thu Nov 15 09:04:07 2018 -0800 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.word.impl; import jdk.internal.vm.compiler.word.WordBase;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/impl/WordFactoryOpcode.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/impl/WordFactoryOpcode.java Thu Nov 15 09:04:07 2018 -0800 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.word.impl; /**
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/impl/WordFactoryOperation.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/impl/WordFactoryOperation.java Thu Nov 15 09:04:07 2018 -0800 @@ -22,6 +22,22 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.word.impl; import java.lang.annotation.ElementType;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/package-info.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/package-info.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -33,4 +33,20 @@ */ + + + + + + + + + + + + + + + + package jdk.internal.vm.compiler.word; \ No newline at end of file
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java Thu Nov 15 09:04:07 2018 -0800 @@ -2775,7 +2775,8 @@ WFE(0x2), WFI(0x3), SEV(0x4), - SEVL(0x5); + SEVL(0x5), + CSDB(0x14); private final int encoding;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java Thu Nov 15 09:04:07 2018 -0800 @@ -1476,6 +1476,14 @@ } /** + * Consumption of Speculative Data Barrier. This is a memory barrier that controls speculative + * execution and data value prediction. + */ + public void csdb() { + super.hint(SystemHint.CSDB); + } + + /** * Same as {@link #nop()}. */ @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java Thu Nov 15 09:04:07 2018 -0800 @@ -43,6 +43,7 @@ import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp.NOT; import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.B0; import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.Z0; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.Z1; import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.BYTE; import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD; import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.PD; @@ -1023,7 +1024,7 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src) { assert assertion.check((AMD64) asm.target.arch, size, dst, null, src); assert op != 0x1A || op != 0x5A; - asm.vexPrefix(dst, Register.None, src, size, pp, mmmmm, w); + asm.vexPrefix(dst, Register.None, src, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitModRM(dst, src); } @@ -1084,7 +1085,7 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, AMD64Address src) { assert assertion.check((AMD64) asm.target.arch, size, dst, null, null); - asm.vexPrefix(dst, Register.None, src, size, pp, mmmmm, w); + asm.vexPrefix(dst, Register.None, src, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitOperandHelper(dst, src, 0); } @@ -1123,14 +1124,14 @@ public void emit(AMD64Assembler asm, AVXSize size, AMD64Address dst, Register src) { assert assertion.check((AMD64) asm.target.arch, size, src, null, null); - asm.vexPrefix(src, Register.None, dst, size, pp, mmmmm, w); + asm.vexPrefix(src, Register.None, dst, size, pp, mmmmm, w, false); asm.emitByte(opReverse); asm.emitOperandHelper(src, dst, 0); } public void emitReverse(AMD64Assembler asm, AVXSize size, Register dst, Register src) { assert assertion.check((AMD64) asm.target.arch, size, src, null, dst); - asm.vexPrefix(src, Register.None, dst, size, pp, mmmmm, w); + asm.vexPrefix(src, Register.None, dst, size, pp, mmmmm, w, false); asm.emitByte(opReverse); asm.emitModRM(src, dst); } @@ -1158,7 +1159,7 @@ @Override public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src, int imm8) { assert assertion.check((AMD64) asm.target.arch, size, dst, null, src); - asm.vexPrefix(dst, Register.None, src, size, pp, mmmmm, w); + asm.vexPrefix(dst, Register.None, src, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitModRM(dst, src); asm.emitByte(imm8); @@ -1166,7 +1167,7 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, AMD64Address src, int imm8) { assert assertion.check((AMD64) asm.target.arch, size, dst, null, null); - asm.vexPrefix(dst, Register.None, src, size, pp, mmmmm, w); + asm.vexPrefix(dst, Register.None, src, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitOperandHelper(dst, src, 1); asm.emitByte(imm8); @@ -1193,7 +1194,7 @@ @Override public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src, int imm8) { assert assertion.check((AMD64) asm.target.arch, size, src, null, dst); - asm.vexPrefix(src, Register.None, dst, size, pp, mmmmm, w); + asm.vexPrefix(src, Register.None, dst, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitModRM(src, dst); asm.emitByte(imm8); @@ -1201,7 +1202,7 @@ public void emit(AMD64Assembler asm, AVXSize size, AMD64Address dst, Register src, int imm8) { assert assertion.check((AMD64) asm.target.arch, size, src, null, null); - asm.vexPrefix(src, Register.None, dst, size, pp, mmmmm, w); + asm.vexPrefix(src, Register.None, dst, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitOperandHelper(src, dst, 1); asm.emitByte(imm8); @@ -1224,7 +1225,7 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register mask, Register src1, Register src2) { assert assertion.check((AMD64) asm.target.arch, size, dst, mask, src1, src2); - asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitModRM(dst, src2); asm.emitByte(mask.encoding() << 4); @@ -1232,7 +1233,7 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register mask, Register src1, AMD64Address src2) { assert assertion.check((AMD64) asm.target.arch, size, dst, mask, src1, null); - asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitOperandHelper(dst, src2, 0); asm.emitByte(mask.encoding() << 4); @@ -1320,20 +1321,20 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2) { assert assertion.check((AMD64) asm.target.arch, size, dst, src1, src2); - asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitModRM(dst, src2); } public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2) { assert assertion.check((AMD64) asm.target.arch, size, dst, src1, null); - asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitOperandHelper(dst, src2, 0); } } - public static final class VexGeneralPurposeRVMOp extends VexOp { + public static final class VexGeneralPurposeRVMOp extends VexRVMOp { // @formatter:off public static final VexGeneralPurposeRVMOp ANDN = new VexGeneralPurposeRVMOp("ANDN", P_, M_0F38, WIG, 0xF2, VEXOpAssertion.BMI1); public static final VexGeneralPurposeRVMOp MULX = new VexGeneralPurposeRVMOp("MULX", P_F2, M_0F38, WIG, 0xF6, VEXOpAssertion.BMI2); @@ -1345,18 +1346,20 @@ super(opcode, pp, mmmmm, w, op, assertion); } + @Override public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2) { assert assertion.check((AMD64) asm.target.arch, LZ, dst, src1, src2, null); assert size == AVXSize.DWORD || size == AVXSize.QWORD; - asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1, false); asm.emitByte(op); asm.emitModRM(dst, src2); } + @Override public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2) { assert assertion.check((AMD64) asm.target.arch, LZ, dst, src1, null, null); assert size == AVXSize.DWORD || size == AVXSize.QWORD; - asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1, false); asm.emitByte(op); asm.emitOperandHelper(dst, src2, 0); } @@ -1378,7 +1381,7 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2) { assert assertion.check((AMD64) asm.target.arch, LZ, dst, src2, src1, null); assert size == AVXSize.DWORD || size == AVXSize.QWORD; - asm.vexPrefix(dst, src2, src1, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1); + asm.vexPrefix(dst, src2, src1, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1, false); asm.emitByte(op); asm.emitModRM(dst, src1); } @@ -1386,12 +1389,42 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, AMD64Address src1, Register src2) { assert assertion.check((AMD64) asm.target.arch, LZ, dst, src2, null, null); assert size == AVXSize.DWORD || size == AVXSize.QWORD; - asm.vexPrefix(dst, src2, src1, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1); + asm.vexPrefix(dst, src2, src1, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1, false); asm.emitByte(op); asm.emitOperandHelper(dst, src1, 0); } } + public static final class VexGeneralPurposeRMOp extends VexRMOp { + // @formatter:off + public static final VexGeneralPurposeRMOp BLSI = new VexGeneralPurposeRMOp("BLSI", P_, M_0F38, WIG, 0xF3, 3, VEXOpAssertion.BMI1); + public static final VexGeneralPurposeRMOp BLSMSK = new VexGeneralPurposeRMOp("BLSMSK", P_, M_0F38, WIG, 0xF3, 2, VEXOpAssertion.BMI1); + public static final VexGeneralPurposeRMOp BLSR = new VexGeneralPurposeRMOp("BLSR", P_, M_0F38, WIG, 0xF3, 1, VEXOpAssertion.BMI1); + // @formatter:on + private final int ext; + + private VexGeneralPurposeRMOp(String opcode, int pp, int mmmmm, int w, int op, int ext, VEXOpAssertion assertion) { + super(opcode, pp, mmmmm, w, op, assertion); + this.ext = ext; + } + + @Override + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src) { + assert assertion.check((AMD64) asm.target.arch, size, dst, null, null); + asm.vexPrefix(AMD64.cpuRegisters[ext], dst, src, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1, false); + asm.emitByte(op); + asm.emitModRM(ext, src); + } + + @Override + public void emit(AMD64Assembler asm, AVXSize size, Register dst, AMD64Address src) { + assert assertion.check((AMD64) asm.target.arch, size, dst, null, null); + asm.vexPrefix(AMD64.cpuRegisters[ext], dst, src, size, pp, mmmmm, size == AVXSize.DWORD ? W0 : W1, false); + asm.emitByte(op); + asm.emitOperandHelper(ext, src, 0); + } + } + /** * VEX-encoded shift instructions with an operand order of either RVM or VMI. */ @@ -1419,7 +1452,7 @@ @Override public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src, int imm8) { assert assertion.check((AMD64) asm.target.arch, size, null, dst, src); - asm.vexPrefix(null, dst, src, size, pp, mmmmm, w); + asm.vexPrefix(null, dst, src, size, pp, mmmmm, w, false); asm.emitByte(immOp); asm.emitModRM(r, src); asm.emitByte(imm8); @@ -1447,14 +1480,14 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register mask, AMD64Address src) { assert assertion.check((AMD64) asm.target.arch, size, dst, mask, null); - asm.vexPrefix(dst, mask, src, size, pp, mmmmm, w); + asm.vexPrefix(dst, mask, src, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitOperandHelper(dst, src, 0); } public void emit(AMD64Assembler asm, AVXSize size, AMD64Address dst, Register mask, Register src) { assert assertion.check((AMD64) asm.target.arch, size, src, mask, null); - asm.vexPrefix(src, mask, dst, size, pp, mmmmm, w); + asm.vexPrefix(src, mask, dst, size, pp, mmmmm, w, false); asm.emitByte(opReverse); asm.emitOperandHelper(src, dst, 0); } @@ -1482,7 +1515,7 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2, int imm8) { assert assertion.check((AMD64) asm.target.arch, size, dst, src1, src2); assert (imm8 & 0xFF) == imm8; - asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitModRM(dst, src2); asm.emitByte(imm8); @@ -1491,7 +1524,7 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2, int imm8) { assert assertion.check((AMD64) asm.target.arch, size, dst, src1, null); assert (imm8 & 0xFF) == imm8; - asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitOperandHelper(dst, src2, 1); asm.emitByte(imm8); @@ -1595,7 +1628,7 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2, Predicate p) { assert assertion.check((AMD64) asm.target.arch, size, dst, src1, src2); - asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitModRM(dst, src2); asm.emitByte(p.imm8); @@ -1603,7 +1636,7 @@ public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2, Predicate p) { assert assertion.check((AMD64) asm.target.arch, size, dst, src1, null); - asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w, false); asm.emitByte(op); asm.emitOperandHelper(dst, src2, 1); asm.emitByte(p.imm8); @@ -1943,14 +1976,14 @@ } public final void movapd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, Register.None, src, PD, P_0F, false); emitByte(0x28); emitModRM(dst, src); } public final void movaps(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, Register.None, src, PS, P_0F, false); emitByte(0x28); emitModRM(dst, src); @@ -1964,7 +1997,7 @@ } public final void movb(AMD64Address dst, Register src) { - assert src.getRegisterCategory().equals(CPU) : "must have byte register"; + assert inRC(CPU, src) : "must have byte register"; prefixb(dst, src); emitByte(0x88); emitOperandHelper(src, dst, 0); @@ -2027,14 +2060,14 @@ * {@link AMD64MacroAssembler#movflt(Register, Register)}. */ public final void movlpd(Register dst, AMD64Address src) { - assert dst.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst); simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0x12); emitOperandHelper(dst, src, 0); } public final void movlhps(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, src, src, PS, P_0F, false); emitByte(0x16); emitModRM(dst, src); @@ -2044,28 +2077,39 @@ movq(dst, src, false); } - public final void movq(Register dst, AMD64Address src, boolean wide) { - if (dst.getRegisterCategory().equals(XMM)) { + public final void movq(Register dst, AMD64Address src, boolean force4BytesDisplacement) { + if (inRC(XMM, dst)) { + // Insn: MOVQ xmm, r/m64 + // Code: F3 0F 7E /r + // An alternative instruction would be 66 REX.W 0F 6E /r. We prefer the REX.W free + // format, because it would allow us to emit 2-bytes-prefixed vex-encoding instruction + // when applicable. simdPrefix(dst, Register.None, src, SS, P_0F, false); emitByte(0x7E); - emitOperandHelper(dst, src, wide, 0); + emitOperandHelper(dst, src, force4BytesDisplacement, 0); } else { // gpr version of movq prefixq(src, dst); emitByte(0x8B); - emitOperandHelper(dst, src, wide, 0); + emitOperandHelper(dst, src, force4BytesDisplacement, 0); } } public final void movq(Register dst, Register src) { + assert inRC(CPU, dst) && inRC(CPU, src); prefixq(dst, src); emitByte(0x8B); emitModRM(dst, src); } public final void movq(AMD64Address dst, Register src) { - if (src.getRegisterCategory().equals(XMM)) { - simdPrefix(src, Register.None, dst, PD, P_0F, true); + if (inRC(XMM, src)) { + // Insn: MOVQ r/m64, xmm + // Code: 66 0F D6 /r + // An alternative instruction would be 66 REX.W 0F 7E /r. We prefer the REX.W free + // format, because it would allow us to emit 2-bytes-prefixed vex-encoding instruction + // when applicable. + simdPrefix(src, Register.None, dst, PD, P_0F, false); emitByte(0xD6); emitOperandHelper(src, dst, 0); } else { @@ -2426,6 +2470,18 @@ OR.getMIOpcode(DWORD, isByte(imm32)).emit(this, DWORD, dst, imm32); } + // Insn: VPACKUSWB xmm1, xmm2, xmm3/m128 + // ----- + // Insn: VPACKUSWB xmm1, xmm1, xmm2 + + public final void packuswb(Register dst, Register src) { + assert inRC(XMM, dst) && inRC(XMM, src); + // Code: VEX.NDS.128.66.0F.WIG 67 /r + simdPrefix(dst, dst, src, PD, P_0F, false); + emitByte(0x67); + emitModRM(dst, src); + } + public final void pop(Register dst) { prefix(dst); emitByte(0x58 + encode(dst)); @@ -2437,7 +2493,7 @@ public final void ptest(Register dst, Register src) { assert supports(CPUFeature.SSE4_1); - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, Register.None, src, PD, P_0F38, false); emitByte(0x17); emitModRM(dst, src); @@ -2445,7 +2501,7 @@ public final void pcmpeqb(Register dst, Register src) { assert supports(CPUFeature.SSE2); - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0x74); emitModRM(dst, src); @@ -2453,15 +2509,23 @@ public final void pcmpeqw(Register dst, Register src) { assert supports(CPUFeature.SSE2); - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0x75); emitModRM(dst, src); } + public final void pcmpeqd(Register dst, Register src) { + assert supports(CPUFeature.SSE2); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, src, PD, P_0F, false); + emitByte(0x76); + emitModRM(dst, src); + } + public final void pcmpestri(Register dst, AMD64Address src, int imm8) { assert supports(CPUFeature.SSE4_2); - assert dst.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst); simdPrefix(dst, Register.None, src, PD, P_0F3A, false); emitByte(0x61); emitOperandHelper(dst, src, 0); @@ -2470,7 +2534,7 @@ public final void pcmpestri(Register dst, Register src, int imm8) { assert supports(CPUFeature.SSE4_2); - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, Register.None, src, PD, P_0F3A, false); emitByte(0x61); emitModRM(dst, src); @@ -2479,21 +2543,30 @@ public final void pmovmskb(Register dst, Register src) { assert supports(CPUFeature.SSE2); - assert dst.getRegisterCategory().equals(CPU) && src.getRegisterCategory().equals(XMM); + assert inRC(CPU, dst) && inRC(XMM, src); simdPrefix(dst, Register.None, src, PD, P_0F, false); emitByte(0xD7); emitModRM(dst, src); } + // Insn: VPMOVZXBW xmm1, xmm2/m64 + public final void pmovzxbw(Register dst, AMD64Address src) { - assert supports(CPUFeature.SSE4_2); - assert dst.getRegisterCategory().equals(XMM); - // XXX legacy_mode should be: _legacy_mode_bw + assert supports(CPUFeature.SSE4_1); + assert inRC(XMM, dst); simdPrefix(dst, Register.None, src, PD, P_0F38, false); emitByte(0x30); emitOperandHelper(dst, src, 0); } + public final void pmovzxbw(Register dst, Register src) { + assert supports(CPUFeature.SSE4_1); + assert inRC(XMM, dst) && inRC(XMM, src); + simdPrefix(dst, Register.None, src, PD, P_0F38, false); + emitByte(0x30); + emitModRM(dst, src); + } + public final void push(Register src) { prefix(src); emitByte(0x50 + encode(src)); @@ -2504,21 +2577,21 @@ } public final void paddd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xFE); emitModRM(dst, src); } public final void paddq(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xD4); emitModRM(dst, src); } public final void pextrw(Register dst, Register src, int imm8) { - assert dst.getRegisterCategory().equals(CPU) && src.getRegisterCategory().equals(XMM); + assert inRC(CPU, dst) && inRC(XMM, src); simdPrefix(dst, Register.None, src, PD, P_0F, false); emitByte(0xC5); emitModRM(dst, src); @@ -2526,7 +2599,7 @@ } public final void pinsrw(Register dst, Register src, int imm8) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(CPU); + assert inRC(XMM, dst) && inRC(CPU, src); simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xC4); emitModRM(dst, src); @@ -2534,21 +2607,21 @@ } public final void por(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xEB); emitModRM(dst, src); } public final void pand(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xDB); emitModRM(dst, src); } public final void pxor(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xEF); emitModRM(dst, src); @@ -2556,7 +2629,7 @@ public final void pslld(Register dst, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst); // XMM6 is for /6 encoding: 66 0F 72 /6 ib simdPrefix(AMD64.xmm6, dst, dst, PD, P_0F, false); emitByte(0x72); @@ -2565,7 +2638,7 @@ } public final void psllq(Register dst, Register shift) { - assert dst.getRegisterCategory().equals(XMM) && shift.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, shift); simdPrefix(dst, dst, shift, PD, P_0F, false); emitByte(0xF3); emitModRM(dst, shift); @@ -2573,7 +2646,7 @@ public final void psllq(Register dst, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst); // XMM6 is for /6 encoding: 66 0F 73 /6 ib simdPrefix(AMD64.xmm6, dst, dst, PD, P_0F, false); emitByte(0x73); @@ -2583,7 +2656,7 @@ public final void psrad(Register dst, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst); // XMM4 is for /4 encoding: 66 0F 72 /4 ib simdPrefix(AMD64.xmm4, dst, dst, PD, P_0F, false); emitByte(0x72); @@ -2593,7 +2666,7 @@ public final void psrld(Register dst, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst); // XMM2 is for /2 encoding: 66 0F 72 /2 ib simdPrefix(AMD64.xmm2, dst, dst, PD, P_0F, false); emitByte(0x72); @@ -2603,7 +2676,7 @@ public final void psrlq(Register dst, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst); // XMM2 is for /2 encoding: 66 0F 73 /2 ib simdPrefix(AMD64.xmm2, dst, dst, PD, P_0F, false); emitByte(0x73); @@ -2613,7 +2686,7 @@ public final void psrldq(Register dst, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst); simdPrefix(AMD64.xmm3, dst, dst, PD, P_0F, false); emitByte(0x73); emitModRM(3, dst); @@ -2622,7 +2695,7 @@ public final void pshufb(Register dst, Register src) { assert supports(CPUFeature.SSSE3); - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, dst, src, PD, P_0F38, false); emitByte(0x00); emitModRM(dst, src); @@ -2631,7 +2704,7 @@ public final void pshuflw(Register dst, Register src, int imm8) { assert supports(CPUFeature.SSE2); assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, Register.None, src, SD, P_0F, false); emitByte(0x70); emitModRM(dst, src); @@ -2640,7 +2713,7 @@ public final void pshufd(Register dst, Register src, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, Register.None, src, PD, P_0F, false); emitByte(0x70); emitModRM(dst, src); @@ -2648,14 +2721,22 @@ } public final void psubd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xFA); emitModRM(dst, src); } + public final void punpcklbw(Register dst, Register src) { + assert supports(CPUFeature.SSE2); + assert inRC(XMM, dst) && inRC(XMM, src); + simdPrefix(dst, dst, src, PD, P_0F, false); + emitByte(0x60); + emitModRM(dst, src); + } + public final void rcpps(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, Register.None, src, PS, P_0F, false); emitByte(0x53); emitModRM(dst, src); @@ -2703,6 +2784,12 @@ emitModRM(4, dst); } + // Insn: SHLX r32a, r/m32, r32b + + public final void shlxl(Register dst, Register src1, Register src2) { + VexGeneralPurposeRMVOp.SHLX.emit(this, AVXSize.DWORD, dst, src1, src2); + } + public final void shrl(Register dst, int imm8) { assert isShiftCount(imm8 >> 1) : "illegal shift count"; prefix(dst); @@ -2769,14 +2856,14 @@ } public final void unpckhpd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0x15); emitModRM(dst, src); } public final void unpcklpd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0x14); emitModRM(dst, src); @@ -2887,7 +2974,7 @@ } public final void cvtdq2pd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, Register.None, src, SS, P_0F, false); emitByte(0xE6); emitModRM(dst, src); @@ -2902,14 +2989,14 @@ } public final void cvttpd2dq(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, Register.None, src, PD, P_0F, false); emitByte(0xE6); emitModRM(dst, src); } public final void decq(Register dst) { - // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) + // Use two-byte form (one-byte form is a REX prefix in 64-bit mode) prefixq(dst); emitByte(0xFF); emitModRM(1, dst); @@ -2970,9 +3057,9 @@ } public final void movdq(Register dst, Register src) { - if (dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(CPU)) { + if (inRC(XMM, dst) && inRC(CPU, src)) { AMD64RMOp.MOVQ.emit(this, QWORD, dst, src); - } else if (src.getRegisterCategory().equals(XMM) && dst.getRegisterCategory().equals(CPU)) { + } else if (inRC(XMM, src) && inRC(CPU, dst)) { AMD64MROp.MOVQ.emit(this, QWORD, dst, src); } else { throw new InternalError("should not reach here"); @@ -2980,9 +3067,9 @@ } public final void movdl(Register dst, Register src) { - if (dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(CPU)) { + if (inRC(XMM, dst) && inRC(CPU, src)) { AMD64RMOp.MOVD.emit(this, DWORD, dst, src); - } else if (src.getRegisterCategory().equals(XMM) && dst.getRegisterCategory().equals(CPU)) { + } else if (inRC(XMM, src) && inRC(CPU, dst)) { AMD64MROp.MOVD.emit(this, DWORD, dst, src); } else { throw new InternalError("should not reach here"); @@ -2995,26 +3082,36 @@ public final void movddup(Register dst, Register src) { assert supports(CPUFeature.SSE3); - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, Register.None, src, SD, P_0F, false); emitByte(0x12); emitModRM(dst, src); } public final void movdqu(Register dst, AMD64Address src) { - assert dst.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst); simdPrefix(dst, Register.None, src, SS, P_0F, false); emitByte(0x6F); emitOperandHelper(dst, src, 0); } public final void movdqu(Register dst, Register src) { - assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst) && inRC(XMM, src); simdPrefix(dst, Register.None, src, SS, P_0F, false); emitByte(0x6F); emitModRM(dst, src); } + // Insn: VMOVDQU xmm2/m128, xmm1 + + public final void movdqu(AMD64Address dst, Register src) { + assert inRC(XMM, src); + // Code: VEX.128.F3.0F.WIG 7F /r + simdPrefix(src, Register.None, dst, SS, P_0F, false); + emitByte(0x7F); + emitOperandHelper(src, dst, 0); + } + public final void movslq(AMD64Address dst, int imm32) { prefixq(dst); emitByte(0xC7); @@ -3195,8 +3292,7 @@ protected final void patchJumpTarget(int branch, int branchTarget) { int op = getByte(branch); assert op == 0xE8 // call - || - op == 0x00 // jump table entry + || op == 0x00 // jump table entry || op == 0xE9 // jmp || op == 0xEB // short jmp || (op & 0xF0) == 0x70 // short jcc @@ -3457,46 +3553,73 @@ VexMoveOp.VMOVDQU.emit(this, AVXSize.YMM, dst, src); } + public final void vmovdqu(AMD64Address dst, Register src) { + assert inRC(XMM, src); + VexMoveOp.VMOVDQU.emit(this, AVXSize.YMM, dst, src); + } + public final void vpmovzxbw(Register dst, AMD64Address src) { + assert supports(CPUFeature.AVX2); VexRMOp.VPMOVZXBW.emit(this, AVXSize.YMM, dst, src); } public final void vzeroupper() { - emitVEX(L128, P_, M_0F, W0, 0, 0); + emitVEX(L128, P_, M_0F, W0, 0, 0, true); emitByte(0x77); } + // Insn: KORTESTD k1, k2 + + // This instruction produces ZF or CF flags + public final void kortestd(Register src1, Register src2) { + assert supports(CPUFeature.AVX512BW); + assert inRC(MASK, src1) && inRC(MASK, src2); + // Code: VEX.L0.66.0F.W1 98 /r + vexPrefix(src1, Register.None, src2, AVXSize.XMM, P_66, M_0F, W1, true); + emitByte(0x98); + emitModRM(src1, src2); + } + + // Insn: KORTESTQ k1, k2 + // This instruction produces ZF or CF flags public final void kortestq(Register src1, Register src2) { assert supports(CPUFeature.AVX512BW); - assert src1.getRegisterCategory().equals(MASK) && src2.getRegisterCategory().equals(MASK); - vexPrefix(src1, Register.None, src2, AVXSize.XMM, P_, M_0F, W1); + assert inRC(MASK, src1) && inRC(MASK, src2); + // Code: VEX.L0.0F.W1 98 /r + vexPrefix(src1, Register.None, src2, AVXSize.XMM, P_, M_0F, W1, true); emitByte(0x98); emitModRM(src1, src2); } - public final void kmovq(Register dst, Register src) { + public final void kmovd(Register dst, Register src) { assert supports(CPUFeature.AVX512BW); - assert dst.getRegisterCategory().equals(MASK) || dst.getRegisterCategory().equals(CPU); - assert src.getRegisterCategory().equals(MASK) || src.getRegisterCategory().equals(CPU); - assert !(dst.getRegisterCategory().equals(CPU) && src.getRegisterCategory().equals(CPU)); - - if (dst.getRegisterCategory().equals(MASK)) { - if (src.getRegisterCategory().equals(MASK)) { - // kmovq(KRegister dst, KRegister src) - vexPrefix(dst, Register.None, src, AVXSize.XMM, P_, M_0F, W1); + assert inRC(MASK, dst) || inRC(CPU, dst); + assert inRC(MASK, src) || inRC(CPU, src); + assert !(inRC(CPU, dst) && inRC(CPU, src)); + + if (inRC(MASK, dst)) { + if (inRC(MASK, src)) { + // kmovd(KRegister dst, KRegister src): + // Insn: KMOVD k1, k2/m32 + // Code: VEX.L0.66.0F.W1 90 /r + vexPrefix(dst, Register.None, src, AVXSize.XMM, P_66, M_0F, W1, true); emitByte(0x90); emitModRM(dst, src); } else { - // kmovq(KRegister dst, Register src) - vexPrefix(dst, Register.None, src, AVXSize.XMM, P_F2, M_0F, W1); + // kmovd(KRegister dst, Register src) + // Insn: KMOVD k1, r32 + // Code: VEX.L0.F2.0F.W0 92 /r + vexPrefix(dst, Register.None, src, AVXSize.XMM, P_F2, M_0F, W0, true); emitByte(0x92); emitModRM(dst, src); } } else { - if (src.getRegisterCategory().equals(MASK)) { - // kmovq(Register dst, KRegister src) - vexPrefix(dst, Register.None, src, AVXSize.XMM, P_F2, M_0F, W1); + if (inRC(MASK, src)) { + // kmovd(Register dst, KRegister src) + // Insn: KMOVD r32, k1 + // Code: VEX.L0.F2.0F.W0 93 /r + vexPrefix(dst, Register.None, src, AVXSize.XMM, P_F2, M_0F, W0, true); emitByte(0x93); emitModRM(dst, src); } else { @@ -3505,17 +3628,67 @@ } } + public final void kmovq(Register dst, Register src) { + assert supports(CPUFeature.AVX512BW); + assert inRC(MASK, dst) || inRC(CPU, dst); + assert inRC(MASK, src) || inRC(CPU, src); + assert !(inRC(CPU, dst) && inRC(CPU, src)); + + if (inRC(MASK, dst)) { + if (inRC(MASK, src)) { + // kmovq(KRegister dst, KRegister src): + // Insn: KMOVQ k1, k2/m64 + // Code: VEX.L0.0F.W1 90 /r + vexPrefix(dst, Register.None, src, AVXSize.XMM, P_, M_0F, W1, true); + emitByte(0x90); + emitModRM(dst, src); + } else { + // kmovq(KRegister dst, Register src) + // Insn: KMOVQ k1, r64 + // Code: VEX.L0.F2.0F.W1 92 /r + vexPrefix(dst, Register.None, src, AVXSize.XMM, P_F2, M_0F, W1, true); + emitByte(0x92); + emitModRM(dst, src); + } + } else { + if (inRC(MASK, src)) { + // kmovq(Register dst, KRegister src) + // Insn: KMOVQ r64, k1 + // Code: VEX.L0.F2.0F.W1 93 /r + vexPrefix(dst, Register.None, src, AVXSize.XMM, P_F2, M_0F, W1, true); + emitByte(0x93); + emitModRM(dst, src); + } else { + throw GraalError.shouldNotReachHere(); + } + } + } + + // Insn: KTESTD k1, k2 + + public final void ktestd(Register src1, Register src2) { + assert supports(CPUFeature.AVX512BW); + assert inRC(MASK, src1) && inRC(MASK, src2); + // Code: VEX.L0.66.0F.W1 99 /r + vexPrefix(src1, Register.None, src2, AVXSize.XMM, P_66, M_0F, W1, true); + emitByte(0x99); + emitModRM(src1, src2); + } + public final void evmovdqu64(Register dst, AMD64Address src) { assert supports(CPUFeature.AVX512F); - assert dst.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst); evexPrefix(dst, Register.None, Register.None, src, AVXSize.ZMM, P_F3, M_0F, W1, Z0, B0); emitByte(0x6F); emitEVEXOperandHelper(dst, src, 0, EVEXTuple.FVM.getDisp8ScalingFactor(AVXSize.ZMM)); } + // Insn: VPMOVZXBW zmm1, m256 + public final void evpmovzxbw(Register dst, AMD64Address src) { assert supports(CPUFeature.AVX512BW); - assert dst.getRegisterCategory().equals(XMM); + assert inRC(XMM, dst); + // Code: EVEX.512.66.0F38.WIG 30 /r evexPrefix(dst, Register.None, Register.None, src, AVXSize.ZMM, P_66, M_0F38, WIG, Z0, B0); emitByte(0x30); emitEVEXOperandHelper(dst, src, 0, EVEXTuple.HVM.getDisp8ScalingFactor(AVXSize.ZMM)); @@ -3523,9 +3696,137 @@ public final void evpcmpeqb(Register kdst, Register nds, AMD64Address src) { assert supports(CPUFeature.AVX512BW); - assert kdst.getRegisterCategory().equals(MASK) && nds.getRegisterCategory().equals(XMM); + assert inRC(MASK, kdst) && inRC(XMM, nds); evexPrefix(kdst, Register.None, nds, src, AVXSize.ZMM, P_66, M_0F, WIG, Z0, B0); emitByte(0x74); emitEVEXOperandHelper(kdst, src, 0, EVEXTuple.FVM.getDisp8ScalingFactor(AVXSize.ZMM)); } + + // Insn: VMOVDQU16 zmm1 {k1}{z}, zmm2/m512 + // ----- + // Insn: VMOVDQU16 zmm1, m512 + + public final void evmovdqu16(Register dst, AMD64Address src) { + assert supports(CPUFeature.AVX512BW); + assert inRC(XMM, dst); + // Code: EVEX.512.F2.0F.W1 6F /r + evexPrefix(dst, Register.None, Register.None, src, AVXSize.ZMM, P_F2, M_0F, W1, Z0, B0); + emitByte(0x6F); + emitEVEXOperandHelper(dst, src, 0, EVEXTuple.FVM.getDisp8ScalingFactor(AVXSize.ZMM)); + } + + // Insn: VMOVDQU16 zmm1, k1:z, m512 + + public final void evmovdqu16(Register dst, Register mask, AMD64Address src) { + assert supports(CPUFeature.AVX512BW); + assert inRC(XMM, dst) && inRC(MASK, mask); + // Code: EVEX.512.F2.0F.W1 6F /r + evexPrefix(dst, mask, Register.None, src, AVXSize.ZMM, P_F2, M_0F, W1, Z1, B0); + emitByte(0x6F); + emitEVEXOperandHelper(dst, src, 0, EVEXTuple.FVM.getDisp8ScalingFactor(AVXSize.ZMM)); + } + + // Insn: VMOVDQU16 zmm2/m512 {k1}{z}, zmm1 + // ----- + // Insn: VMOVDQU16 m512, zmm1 + + public final void evmovdqu16(AMD64Address dst, Register src) { + assert supports(CPUFeature.AVX512BW); + assert inRC(XMM, src); + // Code: EVEX.512.F2.0F.W1 7F /r + evexPrefix(src, Register.None, Register.None, dst, AVXSize.ZMM, P_F2, M_0F, W1, Z0, B0); + emitByte(0x7F); + emitEVEXOperandHelper(src, dst, 0, EVEXTuple.FVM.getDisp8ScalingFactor(AVXSize.ZMM)); + } + + // Insn: VMOVDQU16 m512, k1, zmm1 + + public final void evmovdqu16(AMD64Address dst, Register mask, Register src) { + assert supports(CPUFeature.AVX512BW); + assert inRC(MASK, mask) && inRC(XMM, src); + // Code: EVEX.512.F2.0F.W1 7F /r + evexPrefix(src, mask, Register.None, dst, AVXSize.ZMM, P_F2, M_0F, W1, Z0, B0); + emitByte(0x7F); + emitEVEXOperandHelper(src, dst, 0, EVEXTuple.FVM.getDisp8ScalingFactor(AVXSize.ZMM)); + } + + // Insn: VPBROADCASTW zmm1 {k1}{z}, reg + // ----- + // Insn: VPBROADCASTW zmm1, reg + + public final void evpbroadcastw(Register dst, Register src) { + assert supports(CPUFeature.AVX512BW); + assert inRC(XMM, dst) && inRC(CPU, src); + // Code: EVEX.512.66.0F38.W0 7B /r + evexPrefix(dst, Register.None, Register.None, src, AVXSize.ZMM, P_66, M_0F38, W0, Z0, B0); + emitByte(0x7B); + emitModRM(dst, src); + } + + // Insn: VPCMPUW k1 {k2}, zmm2, zmm3/m512, imm8 + // ----- + // Insn: VPCMPUW k1, zmm2, zmm3, imm8 + + public final void evpcmpuw(Register kdst, Register nds, Register src, int vcc) { + assert supports(CPUFeature.AVX512BW); + assert inRC(MASK, kdst) && inRC(XMM, nds) && inRC(XMM, src); + // Code: EVEX.NDS.512.66.0F3A.W1 3E /r ib + evexPrefix(kdst, Register.None, nds, src, AVXSize.ZMM, P_66, M_0F3A, W1, Z0, B0); + emitByte(0x3E); + emitModRM(kdst, src); + emitByte(vcc); + } + + // Insn: VPCMPUW k1 {k2}, zmm2, zmm3/m512, imm8 + // ----- + // Insn: VPCMPUW k1, k2, zmm2, zmm3, imm8 + + public final void evpcmpuw(Register kdst, Register mask, Register nds, Register src, int vcc) { + assert supports(CPUFeature.AVX512BW); + assert inRC(MASK, kdst) && inRC(MASK, mask); + assert inRC(XMM, nds) && inRC(XMM, src); + // Code: EVEX.NDS.512.66.0F3A.W1 3E /r ib + evexPrefix(kdst, mask, nds, src, AVXSize.ZMM, P_66, M_0F3A, W1, Z0, B0); + emitByte(0x3E); + emitModRM(kdst, src); + emitByte(vcc); + } + + // Insn: VPMOVWB ymm1/m256 {k1}{z}, zmm2 + // ----- + // Insn: VPMOVWB m256, zmm2 + + public final void evpmovwb(AMD64Address dst, Register src) { + assert supports(CPUFeature.AVX512BW); + assert inRC(XMM, src); + // Code: EVEX.512.F3.0F38.W0 30 /r + evexPrefix(src, Register.None, Register.None, dst, AVXSize.ZMM, P_F3, M_0F38, W0, Z0, B0); + emitByte(0x30); + emitEVEXOperandHelper(src, dst, 0, EVEXTuple.HVM.getDisp8ScalingFactor(AVXSize.ZMM)); + } + + // Insn: VPMOVWB m256, k1, zmm2 + + public final void evpmovwb(AMD64Address dst, Register mask, Register src) { + assert supports(CPUFeature.AVX512BW); + assert inRC(MASK, mask) && inRC(XMM, src); + // Code: EVEX.512.F3.0F38.W0 30 /r + evexPrefix(src, mask, Register.None, dst, AVXSize.ZMM, P_F3, M_0F38, W0, Z0, B0); + emitByte(0x30); + emitEVEXOperandHelper(src, dst, 0, EVEXTuple.HVM.getDisp8ScalingFactor(AVXSize.ZMM)); + } + + // Insn: VPMOVZXBW zmm1 {k1}{z}, ymm2/m256 + // ----- + // Insn: VPMOVZXBW zmm1, k1, m256 + + public final void evpmovzxbw(Register dst, Register mask, AMD64Address src) { + assert supports(CPUFeature.AVX512BW); + assert inRC(MASK, mask) && inRC(XMM, dst); + // Code: EVEX.512.66.0F38.WIG 30 /r + evexPrefix(dst, mask, Register.None, src, AVXSize.ZMM, P_66, M_0F38, WIG, Z0, B0); + emitByte(0x30); + emitEVEXOperandHelper(dst, src, 0, EVEXTuple.HVM.getDisp8ScalingFactor(AVXSize.ZMM)); + } + }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64BaseAssembler.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64BaseAssembler.java Thu Nov 15 09:04:07 2018 -0800 @@ -59,6 +59,7 @@ import jdk.vm.ci.amd64.AMD64.CPUFeature; import jdk.vm.ci.amd64.AMD64Kind; import jdk.vm.ci.code.Register; +import jdk.vm.ci.code.Register.RegisterCategory; import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.PlatformKind; @@ -269,8 +270,12 @@ return ((AMD64) target.arch).getFeatures().contains(feature); } + protected static boolean inRC(RegisterCategory rc, Register r) { + return r.getRegisterCategory().equals(rc); + } + protected static int encode(Register r) { - assert r.encoding >= 0 && (r.getRegisterCategory().equals(XMM) ? r.encoding < 32 : r.encoding < 16) : "encoding out of range: " + r.encoding; + assert r.encoding >= 0 && (inRC(XMM, r) ? r.encoding < 32 : r.encoding < 16) : "encoding out of range: " + r.encoding; return r.encoding & 0x7; } @@ -296,6 +301,10 @@ private static final int REXWRB = 0x4D; private static final int REXWRX = 0x4E; private static final int REXWRXB = 0x4F; + + private static final int VEX2 = 0xC5; + private static final int VEX3 = 0xC4; + private static final int EVEX = 0x62; } protected final void rexw() { @@ -797,12 +806,17 @@ @Override public void simdPrefix(Register reg, Register nds, AMD64Address rm, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) { - emitVEX(L128, sizePrefixToPP(sizePrefix), opcodeEscapePrefixToMMMMM(opcodeEscapePrefix), isRexW ? W1 : W0, getRXB(reg, rm), nds.isValid() ? nds.encoding : 0); + assert reg.encoding < 16 : "encoding out of range: " + reg.encoding; + assert nds.encoding < 16 : "encoding out of range: " + nds.encoding; + emitVEX(L128, sizePrefixToPP(sizePrefix), opcodeEscapePrefixToMMMMM(opcodeEscapePrefix), isRexW ? W1 : W0, getRXB(reg, rm), nds.isValid() ? nds.encoding : 0, true); } @Override public void simdPrefix(Register dst, Register nds, Register src, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) { - emitVEX(L128, sizePrefixToPP(sizePrefix), opcodeEscapePrefixToMMMMM(opcodeEscapePrefix), isRexW ? W1 : W0, getRXB(dst, src), nds.isValid() ? nds.encoding : 0); + assert dst.encoding < 16 : "encoding out of range: " + dst.encoding; + assert src.encoding < 16 : "encoding out of range: " + src.encoding; + assert nds.encoding < 16 : "encoding out of range: " + nds.encoding; + emitVEX(L128, sizePrefixToPP(sizePrefix), opcodeEscapePrefixToMMMMM(opcodeEscapePrefix), isRexW ? W1 : W0, getRXB(dst, src), nds.isValid() ? nds.encoding : 0, true); } } @@ -822,6 +836,46 @@ simdEncoder.simdPrefix(dst, nds, src, size.sizePrefix, opcodeEscapePrefix, isRexW); } + // @formatter:off + // + // Instruction Format and VEX illustrated below (optional []): + // + // #of bytes: 2,3 1 1 1 1,2,4 1 + // [Prefixes] VEX OpCode ModR/M [SIB] [Disp8*N] [Immediate] + // [Disp16,32] + // + // VEX: 0xC4 | P1 | P2 + // + // 7 6 5 4 3 2 1 0 + // P1 R X B m m m m m P[ 7:0] + // P2 W v v v v L p p P[15:8] + // + // VEX: 0xC5 | B1 + // + // 7 6 5 4 3 2 1 0 + // P1 R v v v v L p p P[7:0] + // + // Figure. Bit Field Layout of the VEX Prefix + // + // Table. VEX Prefix Bit Field Functional Grouping + // + // Notation Bit field Group Position Comment + // ---------- ------------------------- -------- ------------------- + // VEX.RXB Next-8 register specifier P[7:5] Combine with ModR/M.reg, ModR/M.rm (base, index/vidx). + // VEX.R REX.R inverse P[7] Combine with EVEX.R and ModR/M.reg. + // VEX.X REX.X inverse P[6] Combine with EVEX.B and ModR/M.rm, when SIB/VSIB absent. + // VEX.B REX.B inverse P[5] + // VEX.mmmmmm 0F, 0F_38, 0F_3A encoding P[4:0] b01/0x0F, b10/0F_38, b11/0F_3A (all other reserved) + // + // VEX.W Opcode specific P[15] + // VEX.vvvv A register specifier P[14:11] In inverse form, b1111 if not used. + // P[6:3] + // VEX.L Vector length/RC P[10] b0/scalar or 128b vec, b1/256b vec. + // P[2] + // VEX.pp Compressed legacy prefix P[9:8] b00/None, b01/0x66, b10/0xF3, b11/0xF2 + // P[1:0] + // @formatter:on + /** * Low-level function to encode and emit the VEX prefix. * <p> @@ -846,8 +900,8 @@ * This function automatically chooses the 2 or 3 byte encoding, based on the XBW flags and the * m-mmmm field. */ - protected final void emitVEX(int l, int pp, int mmmmm, int w, int rxb, int vvvv) { - assert ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX) : "emitting VEX prefix on a CPU without AVX support"; + protected final void emitVEX(int l, int pp, int mmmmm, int w, int rxb, int vvvv, boolean checkAVX) { + assert !checkAVX || ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX) : "emitting VEX prefix on a CPU without AVX support"; assert l == L128 || l == L256 : "invalid value for VEX.L"; assert pp == P_ || pp == P_66 || pp == P_F3 || pp == P_F2 : "invalid value for VEX.pp"; @@ -867,7 +921,7 @@ byte2 |= l << 2; byte2 |= pp; - emitByte(0xC5); + emitByte(Prefix.VEX2); emitByte(byte2); } else { // 3 byte encoding @@ -881,7 +935,7 @@ byte3 |= l << 2; byte3 |= pp; - emitByte(0xC4); + emitByte(Prefix.VEX3); emitByte(byte2); emitByte(byte3); } @@ -900,12 +954,12 @@ } } - public final void vexPrefix(Register dst, Register nds, Register src, AVXSize size, int pp, int mmmmm, int w) { - emitVEX(getLFlag(size), pp, mmmmm, w, getRXB(dst, src), nds.isValid() ? nds.encoding() : 0); + public final void vexPrefix(Register dst, Register nds, Register src, AVXSize size, int pp, int mmmmm, int w, boolean checkAVX) { + emitVEX(getLFlag(size), pp, mmmmm, w, getRXB(dst, src), nds.isValid() ? nds.encoding() : 0, checkAVX); } - public final void vexPrefix(Register dst, Register nds, AMD64Address src, AVXSize size, int pp, int mmmmm, int w) { - emitVEX(getLFlag(size), pp, mmmmm, w, getRXB(dst, src), nds.isValid() ? nds.encoding() : 0); + public final void vexPrefix(Register dst, Register nds, AMD64Address src, AVXSize size, int pp, int mmmmm, int w, boolean checkAVX) { + emitVEX(getLFlag(size), pp, mmmmm, w, getRXB(dst, src), nds.isValid() ? nds.encoding() : 0, checkAVX); } protected static final class EVEXPrefixConfig { @@ -986,6 +1040,51 @@ } } + // @formatter:off + // + // Instruction Format and EVEX illustrated below (optional []): + // + // #of bytes: 4 1 1 1 1,2,4 1 + // [Prefixes] EVEX OpCode ModR/M [SIB] [Disp8*N] [Immediate] + // [Disp16,32] + // + // The EVEX prefix is a 4-byte prefix, with the first two bytes derived from unused encoding + // form of the 32-bit-mode-only BOUND instruction. The layout of the EVEX prefix is shown in + // the figure below. The first byte must be 0x62, followed by three pay-load bytes, denoted + // as P1, P2, and P3 individually or collectively as P[23:0] (see below). + // + // EVEX: 0x62 | P1 | P2 | P3 + // + // 7 6 5 4 3 2 1 0 + // P1 R X B R' 0 0 m m P[ 7: 0] + // P2 W v v v v 1 p p P[15: 8] + // P3 z L' L b V' a a a P[23:16] + // + // Figure. Bit Field Layout of the EVEX Prefix + // + // Table. EVEX Prefix Bit Field Functional Grouping + // + // Notation Bit field Group Position Comment + // --------- -------------------------- -------- ----------------------- + // EVEX.RXB Next-8 register specifier P[7:5] Combine with ModR/M.reg, ModR/M.rm (base, index/vidx). + // EVEX.X High-16 register specifier P[6] Combine with EVEX.B and ModR/M.rm, when SIB/VSIB absent. + // EVEX.R' High-16 register specifier P[4] Combine with EVEX.R and ModR/M.reg. + // -- Reserved P[3:2] Must be 0. + // EVEX.mm Compressed legacy escape P[1:0] Identical to low two bits of VEX.mmmmm. + // + // EVEX.W Osize promotion/Opcode ext P[15] + // EVEX.vvvv NDS register specifier P[14:11] Same as VEX.vvvv. + // -- Fixed Value P[10] Must be 1. + // EVEX.pp Compressed legacy prefix P[9:8] Identical to VEX.pp. + // + // EVEX.z Zeroing/Merging P[23] + // EVEX.L'L Vector length/RC P[22:21] + // EVEX.b Broadcast/RC/SAE Context P[20] + // EVEX.V' High-16 NDS/VIDX register P[19] Combine with EVEX.vvvv or VSIB when present. + // EVEX.aaa Embedded opmask register P[18:16] + // + // @formatter:on + /** * Low-level function to encode and emit the EVEX prefix. * <p> @@ -1021,13 +1120,13 @@ assert (rxb & 0x07) == rxb : "invalid value for EVEX.RXB"; assert (reg & 0x1F) == reg : "invalid value for EVEX.R'"; - assert (vvvvv & 0x1F) == vvvvv : "invalid value for EVEX.vvvvv"; + assert (vvvvv & 0x1F) == vvvvv : "invalid value for EVEX.V'vvvv"; assert z == Z0 || z == Z1 : "invalid value for EVEX.z"; assert b == B0 || b == B1 : "invalid value for EVEX.b"; assert (aaa & 0x07) == aaa : "invalid value for EVEX.aaa"; - emitByte(0x62); + emitByte(Prefix.EVEX); int p1 = 0; p1 |= ((rxb ^ 0x07) & 0x07) << 5; p1 |= reg < 16 ? 0x10 : 0; @@ -1037,7 +1136,7 @@ int p2 = 0; p2 |= w << 7; p2 |= ((vvvvv ^ 0x0F) & 0x0F) << 3; - p2 |= 0x4; + p2 |= 0x04; p2 |= pp; emitByte(p2); @@ -1050,6 +1149,11 @@ emitByte(p3); } + /** + * Get RXB bits for register-register instructions in EVEX-encoding, where ModRM.rm contains a + * register index. The R bit extends the ModRM.reg field and the X and B bits extends the + * ModRM.rm field. + */ private static int getRXBForEVEX(Register reg, Register rm) { int rxb = (reg == null ? 0 : reg.encoding & 0x08) >> 1; rxb |= (rm == null ? 0 : rm.encoding & 0x018) >> 3; @@ -1060,7 +1164,7 @@ * Helper method for emitting EVEX prefix in the form of RRRR. */ protected final void evexPrefix(Register dst, Register mask, Register nds, Register src, AVXSize size, int pp, int mm, int w, int z, int b) { - assert !mask.isValid() || mask.getRegisterCategory().equals(MASK); + assert !mask.isValid() || inRC(MASK, mask); emitEVEX(getLFlag(size), pp, mm, w, getRXBForEVEX(dst, src), dst.encoding, nds.isValid() ? nds.encoding() : 0, z, b, mask.isValid() ? mask.encoding : 0); } @@ -1071,7 +1175,7 @@ * {@link #emitEVEXOperandHelper(Register, AMD64Address, int, int)}. */ protected final void evexPrefix(Register dst, Register mask, Register nds, AMD64Address src, AVXSize size, int pp, int mm, int w, int z, int b) { - assert !mask.isValid() || mask.getRegisterCategory().equals(MASK); + assert !mask.isValid() || inRC(MASK, mask); emitEVEX(getLFlag(size), pp, mm, w, getRXB(dst, src), dst.encoding, nds.isValid() ? nds.encoding() : 0, z, b, mask.isValid() ? mask.encoding : 0); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -24,6 +24,8 @@ package org.graalvm.compiler.asm.amd64; +import static jdk.vm.ci.amd64.AMD64.rbp; +import static jdk.vm.ci.amd64.AMD64.rsp; import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseIncDec; import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseXmmLoadAndClearUpper; import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseXmmRegToRegMoveAll; @@ -82,6 +84,20 @@ } } + public final void enter(int frameSize) { + if (NumUtil.isUShort(frameSize)) { + // Can use enter instruction only for frame size that fits in 16 bits. + emitByte(0xC8); + emitShort(frameSize); + emitByte(0x00); + } else { + // Fall back to manual sequence. + push(rbp); + movq(rbp, rsp); + decrementq(rsp, frameSize); + } + } + public void incrementq(Register reg, int value) { if (value == Integer.MIN_VALUE) { addq(reg, value);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java Thu Nov 15 09:04:07 2018 -0800 @@ -191,6 +191,10 @@ private StackSlot customStackArea = null; + /** + * A customized name that is unrelated to {@link #compilationId}. Can be null if + * {@link #compilationId} fully describes the compilation. + */ private final String name; private final CompilationIdentifier compilationId; @@ -228,7 +232,7 @@ private boolean isImmutablePIC; public CompilationResult(CompilationIdentifier compilationId) { - this(compilationId, compilationId.toString(CompilationIdentifier.Verbosity.NAME), false); + this(compilationId, null, false); } public CompilationResult(CompilationIdentifier compilationId, String name) { @@ -677,6 +681,10 @@ return unmodifiableList(sourceMapping); } + /** + * Gets the name for this compilation result. This will only be non-null when it provides a + * value unrelated to {@link #getCompilationId()}. + */ public String getName() { return name; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64AddSubShiftTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, Arm Limited and 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.core.aarch64.test; + +import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp; +import org.junit.Assert; +import org.junit.Test; + +public class AArch64AddSubShiftTest extends AArch64MatchRuleTest { + /** + * addSubShift match rule test for add operation with int type. + */ + private static int addLeftShiftInt(int input) { + int output = (input << 5) + input; + output += output << -5; + output += output << 32; + return output; + } + + private static int addRightShiftInt(int input) { + int output = (input >> 5) + input; + output += output >> -5; + output += output >> 32; + return output; + } + + private static int addUnsignedRightShiftInt(int input) { + int output = (input >>> 5) + input; + output += output >>> -5; + output += output >>> 32; + return output; + } + + private static int addShiftInt(int input) { + return addLeftShiftInt(input) + addRightShiftInt(input) + addUnsignedRightShiftInt(input); + } + + /** + * Check whether the addSubShift match rule in AArch64NodeMatchRules does work for add operation + * with int type and check if the expected LIR instructions show up. + */ + @Test + public void testAddShiftInt() { + int expected = addShiftInt(123); + + Result result = executeActual(getResolvedJavaMethod("addShiftInt"), null, 123); + int actual = (int) result.returnValue; + Assert.assertEquals(expected, actual); + + checkLIR(AArch64ArithmeticOp.AddSubShiftOp.class, 6); + } + + /** + * addSubShift match rule test for add operation with long type. + */ + private static long addLeftShiftLong(long input) { + long output = (input << 5) + input; + output += output << -5; + output += output << 64; + return output; + } + + private static long addRightShiftLong(long input) { + long output = (input >> 5) + input; + output += output >> -5; + output += output >> 64; + return output; + } + + private static long addUnsignedRightShiftLong(long input) { + long output = (input >>> 5) + input; + output += output >>> -5; + output += output >>> 64; + return output; + } + + private static long addShiftLong(long input) { + return addLeftShiftLong(input) + addRightShiftLong(input) + addUnsignedRightShiftLong(input); + } + + /** + * Check whether the addSubShift match rule in AArch64NodeMatchRules does work for add operation + * with long type and check if the expected LIR instructions show up. + */ + @Test + public void testAddShiftLong() { + long expected = addShiftLong(1234567); + + Result result = executeActual(getResolvedJavaMethod("addShiftLong"), null, (long) 1234567); + long actual = (long) result.returnValue; + Assert.assertEquals(expected, actual); + + checkLIR(AArch64ArithmeticOp.AddSubShiftOp.class, 6); + } + + /** + * addSubShift match rule test for sub operation with int type. + */ + private static int subLeftShiftInt(int input0, int input1) { + return input0 - (input1 << 5); + } + + private static int subRightShiftInt(int input0, int input1) { + return input0 - (input1 >> 5); + } + + private static int subUnsignedRightShiftInt(int input0, int input1) { + return input0 - (input1 >>> 5); + } + + private static int subShiftInt(int input0, int input1) { + return subLeftShiftInt(input0, input1) + subRightShiftInt(input0, input1) + subUnsignedRightShiftInt(input0, input1); + } + + /** + * Check whether the addSubShift match rule in AArch64NodeMatchRules does work for sub operation + * with int type and check if the expected LIR instructions show up. + */ + @Test + public void testSubShiftInt() { + int expected = subShiftInt(123, 456); + + Result result = executeActual(getResolvedJavaMethod("subShiftInt"), null, 123, 456); + int actual = (int) result.returnValue; + Assert.assertEquals(expected, actual); + + checkLIR(AArch64ArithmeticOp.AddSubShiftOp.class, 3); + } + + /** + * addSubShift match rule test for sub operation with long type. + */ + private static long subLeftShiftLong(long input0, long input1) { + return input0 - (input1 << 5); + } + + private static long subRightShiftLong(long input0, long input1) { + return input0 - (input1 >> 5); + } + + private static long subUnsignedRightShiftLong(long input0, long input1) { + return input0 - (input1 >>> 5); + } + + private static long subShiftLong(long input0, long input1) { + return subLeftShiftLong(input0, input1) + subRightShiftLong(input0, input1) + subUnsignedRightShiftLong(input0, input1); + } + + /** + * Check whether the addSubShift match rule in AArch64NodeMatchRules does work for sub operation + * with long type and check if the expected LIR instructions show up. + */ + @Test + public void testSubShiftLong() { + long expected = subShiftLong(1234567, 123); + + Result result = executeActual(getResolvedJavaMethod("subShiftLong"), null, (long) 1234567, (long) 123); + long actual = (long) result.returnValue; + Assert.assertEquals(expected, actual); + + checkLIR(AArch64ArithmeticOp.AddSubShiftOp.class, 3); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64MatchRuleTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, Arm Limited and 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.core.aarch64.test; + +import jdk.vm.ci.aarch64.AArch64; +import jdk.vm.ci.code.TargetDescription; +import org.graalvm.compiler.core.test.GraalCompilerTest; +import org.graalvm.compiler.lir.LIR; +import org.graalvm.compiler.lir.LIRInstruction; +import org.graalvm.compiler.lir.aarch64.AArch64LIRInstruction; +import org.graalvm.compiler.lir.gen.LIRGenerationResult; +import org.graalvm.compiler.lir.phases.LIRPhase; +import org.graalvm.compiler.lir.phases.LIRSuites; +import org.graalvm.compiler.lir.phases.PreAllocationOptimizationPhase; +import org.graalvm.compiler.options.OptionValues; +import org.junit.Assert; +import org.junit.Before; + +import static org.junit.Assume.assumeTrue; + +public abstract class AArch64MatchRuleTest extends GraalCompilerTest { + private LIR lir; + + @Before + public void checkAArch64() { + assumeTrue("skipping AArch64 specific test", getTarget().arch instanceof AArch64); + } + + @Override + protected LIRSuites createLIRSuites(OptionValues options) { + LIRSuites suites = super.createLIRSuites(options); + suites.getPreAllocationOptimizationStage().appendPhase(new CheckPhase()); + return suites; + } + + private class CheckPhase extends LIRPhase<PreAllocationOptimizationPhase.PreAllocationOptimizationContext> { + @Override + protected void run(TargetDescription target, LIRGenerationResult lirGenRes, + PreAllocationOptimizationPhase.PreAllocationOptimizationContext context) { + lir = lirGenRes.getLIR(); + } + } + + protected void checkLIR(Class<? extends AArch64LIRInstruction> op, int expected) { + int actualOpNum = 0; + for (LIRInstruction ins : lir.getLIRforBlock(lir.codeEmittingOrder()[0])) { + if (ins.getClass() == op) { + actualOpNum++; + } + } + Assert.assertEquals(expected, actualOpNum); + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java Thu Nov 15 09:04:07 2018 -0800 @@ -201,6 +201,16 @@ return result; } + public Value emitAddSubShift(AArch64ArithmeticOp op, Value a, Value b, AArch64MacroAssembler.ShiftType shiftType, int shiftAmount) { + assert isNumericInteger(a.getPlatformKind()); + assert isNumericInteger(b.getPlatformKind()); + Variable result = getLIRGen().newVariable(LIRKind.combine(a, b)); + AllocatableValue x = moveSp(asAllocatable(a)); + AllocatableValue y = moveSp(asAllocatable(b)); + getLIRGen().append(new AArch64ArithmeticOp.AddSubShiftOp(op, result, x, y, shiftType, shiftAmount)); + return result; + } + private static PlatformKind getFloatConvertResultKind(FloatConvert op) { switch (op) { case F2I:
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java Thu Nov 15 09:04:07 2018 -0800 @@ -61,6 +61,7 @@ import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndWriteOp; import org.graalvm.compiler.lir.aarch64.AArch64Move.MembarOp; import org.graalvm.compiler.lir.aarch64.AArch64PauseOp; +import org.graalvm.compiler.lir.aarch64.AArch64SpeculativeBarrier; import org.graalvm.compiler.lir.gen.LIRGenerationResult; import org.graalvm.compiler.lir.gen.LIRGenerator; import org.graalvm.compiler.phases.util.Providers; @@ -465,9 +466,9 @@ } @Override - public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length) { + public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length, int constantLength, boolean directPointers) { Variable result = newVariable(LIRKind.value(AArch64Kind.DWORD)); - append(new AArch64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length))); + append(new AArch64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length), directPointers)); return result; } @@ -513,4 +514,9 @@ } public abstract void emitCCall(long address, CallingConvention nativeCallingConvention, Value[] args); + + @Override + public void emitSpeculationFence() { + append(new AArch64SpeculativeBarrier()); + } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64MoveFactory.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64MoveFactory.java Thu Nov 15 09:04:07 2018 -0800 @@ -34,6 +34,7 @@ import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.lir.LIRInstruction; import org.graalvm.compiler.lir.aarch64.AArch64AddressValue; +import org.graalvm.compiler.lir.aarch64.AArch64LIRInstruction; import org.graalvm.compiler.lir.aarch64.AArch64Move; import org.graalvm.compiler.lir.aarch64.AArch64Move.LoadAddressOp; import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory; @@ -69,7 +70,7 @@ } @Override - public LIRInstruction createLoad(AllocatableValue dst, Constant src) { + public AArch64LIRInstruction createLoad(AllocatableValue dst, Constant src) { if (src instanceof JavaConstant) { JavaConstant javaConstant = (JavaConstant) src; if (canInlineConstant(javaConstant)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java Thu Nov 15 09:04:07 2018 -0800 @@ -25,11 +25,22 @@ package org.graalvm.compiler.core.aarch64; +import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler; import org.graalvm.compiler.core.gen.NodeMatchRules; +import org.graalvm.compiler.core.match.ComplexMatchResult; +import org.graalvm.compiler.core.match.MatchRule; import org.graalvm.compiler.lir.LIRFrameState; +import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp; import org.graalvm.compiler.lir.gen.LIRGeneratorTool; +import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.DeoptimizingNode; import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.calc.AddNode; +import org.graalvm.compiler.nodes.calc.BinaryNode; +import org.graalvm.compiler.nodes.calc.LeftShiftNode; +import org.graalvm.compiler.nodes.calc.RightShiftNode; +import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode; import org.graalvm.compiler.nodes.memory.Access; import jdk.vm.ci.aarch64.AArch64Kind; @@ -51,6 +62,36 @@ return (AArch64Kind) gen.getLIRKind(access.asNode().stamp(NodeView.DEFAULT)).getPlatformKind(); } + private ComplexMatchResult emitAddSubShift(AArch64ArithmeticOp op, ValueNode value, BinaryNode shift) { + assert shift.getY() instanceof ConstantNode; + int shiftAmount = shift.getY().asJavaConstant().asInt(); + + if (shift instanceof LeftShiftNode) { + return builder -> getArithmeticLIRGenerator().emitAddSubShift(op, operand(value), operand(shift.getX()), + AArch64MacroAssembler.ShiftType.LSL, shiftAmount); + } else if (shift instanceof RightShiftNode) { + return builder -> getArithmeticLIRGenerator().emitAddSubShift(op, operand(value), operand(shift.getX()), + AArch64MacroAssembler.ShiftType.ASR, shiftAmount); + } else { + assert shift instanceof UnsignedRightShiftNode; + return builder -> getArithmeticLIRGenerator().emitAddSubShift(op, operand(value), operand(shift.getX()), + AArch64MacroAssembler.ShiftType.LSR, shiftAmount); + } + } + + @MatchRule("(Add=binary a (LeftShift=shift b Constant))") + @MatchRule("(Add=binary a (RightShift=shift b Constant))") + @MatchRule("(Add=binary a (UnsignedRightShift=shift b Constant))") + @MatchRule("(Sub=binary a (LeftShift=shift b Constant))") + @MatchRule("(Sub=binary a (RightShift=shift b Constant))") + @MatchRule("(Sub=binary a (UnsignedRightShift=shift b Constant))") + public ComplexMatchResult addSubShift(BinaryNode binary, ValueNode a, BinaryNode shift) { + if (binary instanceof AddNode) { + return emitAddSubShift(AArch64ArithmeticOp.ADD, a, shift); + } + return emitAddSubShift(AArch64ArithmeticOp.SUB, a, shift); + } + @Override public AArch64LIRGenerator getLIRGeneratorTool() { return (AArch64LIRGenerator) gen;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java Thu Nov 15 09:04:07 2018 -0800 @@ -84,7 +84,10 @@ import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64Shift; import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexGeneralPurposeRVMOp; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexGeneralPurposeRMOp; import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; +import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.core.common.calc.FloatConvert; @@ -106,6 +109,8 @@ import org.graalvm.compiler.lir.amd64.AMD64ShiftOp; import org.graalvm.compiler.lir.amd64.AMD64SignExtendOp; import org.graalvm.compiler.lir.amd64.AMD64Unary; +import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary; +import org.graalvm.compiler.lir.amd64.vector.AMD64VectorUnary; import org.graalvm.compiler.lir.gen.ArithmeticLIRGenerator; import org.graalvm.compiler.lir.gen.LIRGenerator; @@ -932,6 +937,57 @@ } @Override + public Value emitLogicalAndNot(Value value1, Value value2) { + Variable result = getLIRGen().newVariable(LIRKind.combine(value1, value2)); + + if (value1.getPlatformKind() == AMD64Kind.QWORD) { + getLIRGen().append(new AMD64VectorBinary.AVXBinaryOp(VexGeneralPurposeRVMOp.ANDN, AVXSize.QWORD, result, asAllocatable(value1), asAllocatable(value2))); + } else { + getLIRGen().append(new AMD64VectorBinary.AVXBinaryOp(VexGeneralPurposeRVMOp.ANDN, AVXSize.DWORD, result, asAllocatable(value1), asAllocatable(value2))); + } + return result; + } + + @Override + public Value emitLowestSetIsolatedBit(Value value) { + Variable result = getLIRGen().newVariable(LIRKind.combine(value)); + + if (value.getPlatformKind() == AMD64Kind.QWORD) { + getLIRGen().append(new AMD64VectorUnary.AVXUnaryOp(VexGeneralPurposeRMOp.BLSI, AVXSize.QWORD, result, asAllocatable(value))); + } else { + getLIRGen().append(new AMD64VectorUnary.AVXUnaryOp(VexGeneralPurposeRMOp.BLSI, AVXSize.DWORD, result, asAllocatable(value))); + } + + return result; + } + + @Override + public Value emitGetMaskUpToLowestSetBit(Value value) { + Variable result = getLIRGen().newVariable(LIRKind.combine(value)); + + if (value.getPlatformKind() == AMD64Kind.QWORD) { + getLIRGen().append(new AMD64VectorUnary.AVXUnaryOp(VexGeneralPurposeRMOp.BLSMSK, AVXSize.QWORD, result, asAllocatable(value))); + } else { + getLIRGen().append(new AMD64VectorUnary.AVXUnaryOp(VexGeneralPurposeRMOp.BLSMSK, AVXSize.DWORD, result, asAllocatable(value))); + } + + return result; + } + + @Override + public Value emitResetLowestSetBit(Value value) { + Variable result = getLIRGen().newVariable(LIRKind.combine(value)); + + if (value.getPlatformKind() == AMD64Kind.QWORD) { + getLIRGen().append(new AMD64VectorUnary.AVXUnaryOp(VexGeneralPurposeRMOp.BLSR, AVXSize.QWORD, result, asAllocatable(value))); + } else { + getLIRGen().append(new AMD64VectorUnary.AVXUnaryOp(VexGeneralPurposeRMOp.BLSR, AVXSize.DWORD, result, asAllocatable(value))); + } + + return result; + } + + @Override public Value emitMathAbs(Value input) { Variable result = getLIRGen().newVariable(LIRKind.combine(input)); switch ((AMD64Kind) input.getPlatformKind()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java Thu Nov 15 09:04:07 2018 -0800 @@ -87,7 +87,8 @@ import org.graalvm.compiler.lir.amd64.AMD64Move.MembarOp; import org.graalvm.compiler.lir.amd64.AMD64Move.StackLeaOp; import org.graalvm.compiler.lir.amd64.AMD64PauseOp; -import org.graalvm.compiler.lir.amd64.AMD64StringIndexOfOp; +import org.graalvm.compiler.lir.amd64.AMD64StringLatin1InflateOp; +import org.graalvm.compiler.lir.amd64.AMD64StringUTF16CompressOp; import org.graalvm.compiler.lir.amd64.AMD64ZapRegistersOp; import org.graalvm.compiler.lir.amd64.AMD64ZapStackOp; import org.graalvm.compiler.lir.gen.LIRGenerationResult; @@ -262,8 +263,8 @@ public void emitCompareAndSwapBranch(ValueKind<?> kind, AMD64AddressValue address, Value expectedValue, Value newValue, Condition condition, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) { - assert kind.equals(expectedValue.getValueKind()); - assert kind.equals(newValue.getValueKind()); + assert kind.getPlatformKind().getSizeInBytes() <= expectedValue.getValueKind().getPlatformKind().getSizeInBytes(); + assert kind.getPlatformKind().getSizeInBytes() <= newValue.getValueKind().getPlatformKind().getSizeInBytes(); assert condition == Condition.EQ || condition == Condition.NE; AMD64Kind memKind = (AMD64Kind) kind.getPlatformKind(); RegisterValue raxValue = AMD64.rax.asValue(kind); @@ -542,9 +543,9 @@ } @Override - public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length) { + public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length, int constantLength, boolean directPointers) { Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD)); - append(new AMD64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length))); + append(new AMD64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length), constantLength, directPointers, getMaxVectorSize())); return result; } @@ -555,22 +556,56 @@ return 4096; } + /** + * Return the maximum size of vector registers used in SSE/AVX instructions. + */ + protected int getMaxVectorSize() { + // default for "unlimited" + return -1; + } + @Override - public Variable emitStringIndexOf(Value source, Value sourceCount, Value target, Value targetCount, int constantTargetCount) { - Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD)); - RegisterValue cnt1 = AMD64.rdx.asValue(sourceCount.getValueKind()); - emitMove(cnt1, sourceCount); - RegisterValue cnt2 = AMD64.rax.asValue(targetCount.getValueKind()); - emitMove(cnt2, targetCount); - append(new AMD64StringIndexOfOp(this, result, source, target, cnt1, cnt2, AMD64.rcx.asValue(), AMD64.xmm0.asValue(), constantTargetCount, getVMPageSize())); + public Variable emitArrayIndexOf(JavaKind kind, boolean findTwoConsecutive, Value arrayPointer, Value arrayLength, Value... searchValues) { + Variable result = newVariable(LIRKind.value(AMD64Kind.QWORD)); + Value[] allocatableSearchValues = new Value[searchValues.length]; + for (int i = 0; i < searchValues.length; i++) { + allocatableSearchValues[i] = asAllocatable(searchValues[i]); + } + append(new AMD64ArrayIndexOfOp(kind, findTwoConsecutive, getVMPageSize(), getMaxVectorSize(), this, result, asAllocatable(arrayPointer), asAllocatable(arrayLength), allocatableSearchValues)); return result; } @Override - public Variable emitArrayIndexOf(JavaKind kind, Value arrayPointer, Value arrayLength, Value charValue) { - Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD)); - append(new AMD64ArrayIndexOfOp(kind, getVMPageSize(), this, result, asAllocatable(arrayPointer), asAllocatable(arrayLength), asAllocatable(charValue))); - return result; + public void emitStringLatin1Inflate(Value src, Value dst, Value len) { + RegisterValue rsrc = AMD64.rsi.asValue(src.getValueKind()); + RegisterValue rdst = AMD64.rdi.asValue(dst.getValueKind()); + RegisterValue rlen = AMD64.rdx.asValue(len.getValueKind()); + + emitMove(rsrc, src); + emitMove(rdst, dst); + emitMove(rlen, len); + + append(new AMD64StringLatin1InflateOp(this, rsrc, rdst, rlen)); + } + + @Override + public Variable emitStringUTF16Compress(Value src, Value dst, Value len) { + RegisterValue rsrc = AMD64.rsi.asValue(src.getValueKind()); + RegisterValue rdst = AMD64.rdi.asValue(dst.getValueKind()); + RegisterValue rlen = AMD64.rdx.asValue(len.getValueKind()); + + emitMove(rsrc, src); + emitMove(rdst, dst); + emitMove(rlen, len); + + LIRKind reskind = LIRKind.value(AMD64Kind.DWORD); + RegisterValue rres = AMD64.rax.asValue(reskind); + + append(new AMD64StringUTF16CompressOp(this, rres, rsrc, rdst, rlen)); + + Variable res = newVariable(reskind); + emitMove(res, rres); + return res; } @Override @@ -614,7 +649,8 @@ return new AMD64ZapStackOp(zappedStack, zapValues); } - public void emitLFence() { + @Override + public void emitSpeculationFence() { append(new AMD64LFenceOp()); } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeLIRBuilder.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeLIRBuilder.java Thu Nov 15 09:04:07 2018 -0800 @@ -25,8 +25,6 @@ package org.graalvm.compiler.core.amd64; -import static org.graalvm.compiler.core.amd64.AMD64NodeLIRBuilder.Options.MitigateSpeculativeExecutionAttacks; - import org.graalvm.compiler.core.gen.NodeLIRBuilder; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.lir.LIRFrameState; @@ -41,11 +39,6 @@ import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.calc.IntegerDivRemNode; import org.graalvm.compiler.nodes.calc.IntegerDivRemNode.Op; -import org.graalvm.compiler.nodes.cfg.Block; -import org.graalvm.compiler.options.Option; -import org.graalvm.compiler.options.OptionKey; -import org.graalvm.compiler.options.OptionType; -import org.graalvm.compiler.options.OptionValues; import jdk.vm.ci.amd64.AMD64; import jdk.vm.ci.meta.AllocatableValue; @@ -53,13 +46,6 @@ public abstract class AMD64NodeLIRBuilder extends NodeLIRBuilder { - public static class Options { - // @formatter:off - @Option(help = "AMD64: Emit lfence instructions at the beginning of basic blocks", type = OptionType.Expert) - public static final OptionKey<Boolean> MitigateSpeculativeExecutionAttacks = new OptionKey<>(false); - // @formatter:on - } - public AMD64NodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool gen, AMD64NodeMatchRules nodeMatchRules) { super(graph, gen, nodeMatchRules); } @@ -137,21 +123,4 @@ public AMD64LIRGenerator getLIRGeneratorTool() { return (AMD64LIRGenerator) gen; } - - @Override - public void doBlockPrologue(Block block, OptionValues options) { - if (MitigateSpeculativeExecutionAttacks.getValue(options)) { - boolean hasControlSplitPredecessor = false; - for (Block b : block.getPredecessors()) { - if (b.getSuccessorCount() > 1) { - hasControlSplitPredecessor = true; - break; - } - } - boolean isStartBlock = block.getPredecessorCount() == 0; - if (hasControlSplitPredecessor || isStartBlock) { - getLIRGeneratorTool().emitLFence(); - } - } - } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java Thu Nov 15 09:04:07 2018 -0800 @@ -78,9 +78,12 @@ import org.graalvm.compiler.nodes.memory.WriteNode; import org.graalvm.compiler.nodes.util.GraphUtil; +import jdk.vm.ci.amd64.AMD64; +import jdk.vm.ci.amd64.AMD64.CPUFeature; import jdk.vm.ci.amd64.AMD64Kind; import jdk.vm.ci.meta.AllocatableValue; import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.PlatformKind; import jdk.vm.ci.meta.Value; import jdk.vm.ci.meta.ValueKind; @@ -272,6 +275,81 @@ return getArithmeticLIRGenerator().emitLoad(to, address, state); } + private boolean supports(CPUFeature feature) { + return ((AMD64) getLIRGeneratorTool().target().arch).getFeatures().contains(feature); + } + + @MatchRule("(And (Not a) b)") + public ComplexMatchResult logicalAndNot(ValueNode a, ValueNode b) { + if (!supports(CPUFeature.BMI1)) { + return null; + } + return builder -> getArithmeticLIRGenerator().emitLogicalAndNot(operand(a), operand(b)); + } + + @MatchRule("(And a (Negate a))") + public ComplexMatchResult lowestSetIsolatedBit(ValueNode a) { + if (!supports(CPUFeature.BMI1)) { + return null; + } + return builder -> getArithmeticLIRGenerator().emitLowestSetIsolatedBit(operand(a)); + } + + @MatchRule("(Xor a (Add a b))") + public ComplexMatchResult getMaskUpToLowestSetBit(ValueNode a, ValueNode b) { + if (!supports(CPUFeature.BMI1)) { + return null; + } + + // Make sure that the pattern matches a subtraction by one. + if (!b.isJavaConstant()) { + return null; + } + + JavaConstant bCst = b.asJavaConstant(); + long bValue; + if (bCst.getJavaKind() == JavaKind.Int) { + bValue = bCst.asInt(); + } else if (bCst.getJavaKind() == JavaKind.Long) { + bValue = bCst.asLong(); + } else { + return null; + } + + if (bValue == -1) { + return builder -> getArithmeticLIRGenerator().emitGetMaskUpToLowestSetBit(operand(a)); + } else { + return null; + } + } + + @MatchRule("(And a (Add a b))") + public ComplexMatchResult resetLowestSetBit(ValueNode a, ValueNode b) { + if (!supports(CPUFeature.BMI1)) { + return null; + } + // Make sure that the pattern matches a subtraction by one. + if (!b.isJavaConstant()) { + return null; + } + + JavaConstant bCst = b.asJavaConstant(); + long bValue; + if (bCst.getJavaKind() == JavaKind.Int) { + bValue = bCst.asInt(); + } else if (bCst.getJavaKind() == JavaKind.Long) { + bValue = bCst.asLong(); + } else { + return null; + } + + if (bValue == -1) { + return builder -> getArithmeticLIRGenerator().emitResetLowestSetBit(operand(a)); + } else { + return null; + } + } + @MatchRule("(If (IntegerTest Read=access value))") @MatchRule("(If (IntegerTest FloatingRead=access value))") public ComplexMatchResult integerTestBranchMemory(IfNode root, LIRLowerableAccess access, ValueNode value) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/NumUtil.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/NumUtil.java Thu Nov 15 09:04:07 2018 -0800 @@ -215,14 +215,14 @@ } public static long maxUnsigned(long a, long b) { - if (Long.compareUnsigned(a, b) > 0) { + if (Long.compareUnsigned(a, b) < 0) { return b; } return a; } public static long minUnsigned(long a, long b) { - if (Long.compareUnsigned(a, b) > 0) { + if (Long.compareUnsigned(a, b) < 0) { return a; } return b;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/SpeculativeExecutionAttacksMitigations.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018, 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.core.common; + +import org.graalvm.compiler.options.EnumOptionKey; +import org.graalvm.compiler.options.Option; +import org.graalvm.compiler.options.OptionKey; +import org.graalvm.compiler.options.OptionType; + +public enum SpeculativeExecutionAttacksMitigations { + None, + AllTargets, + GuardTargets, + NonDeoptGuardTargets; + + public static class Options { + // @formatter:off + @Option(help = "Select a strategy to mitigate speculative execution attacks (e.g., SPECTRE)", type = OptionType.User) + public static final EnumOptionKey<SpeculativeExecutionAttacksMitigations> MitigateSpeculativeExecutionAttacks = new EnumOptionKey<>(None); + @Option(help = "Use index masking after bounds check to mitigate speculative execution attacks", type = OptionType.User) + public static final OptionKey<Boolean> UseIndexMasking = new OptionKey<>(false); + // @formatter:on + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/BiDirectionalTraceBuilder.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/BiDirectionalTraceBuilder.java Thu Nov 15 09:04:07 2018 -0800 @@ -63,7 +63,7 @@ } private static int compare(AbstractBlockBase<?> a, AbstractBlockBase<?> b) { - return Double.compare(b.probability(), a.probability()); + return Double.compare(b.getRelativeFrequency(), a.getRelativeFrequency()); } private boolean processed(AbstractBlockBase<?> b) { @@ -132,7 +132,7 @@ } private void addBlockToTrace(DebugContext debug, AbstractBlockBase<?> block) { - debug.log("add %s (prob: %f)", block, block.probability()); + debug.log("add %s (freq: %f)", block, block.getRelativeFrequency()); processed.set(block.getId()); } @@ -142,7 +142,7 @@ private AbstractBlockBase<?> selectPredecessor(AbstractBlockBase<?> block) { AbstractBlockBase<?> next = null; for (AbstractBlockBase<?> pred : block.getPredecessors()) { - if (!processed(pred) && !isBackEdge(pred, block) && (next == null || pred.probability() > next.probability())) { + if (!processed(pred) && !isBackEdge(pred, block) && (next == null || pred.getRelativeFrequency() > next.getRelativeFrequency())) { next = pred; } } @@ -160,7 +160,7 @@ private AbstractBlockBase<?> selectSuccessor(AbstractBlockBase<?> block) { AbstractBlockBase<?> next = null; for (AbstractBlockBase<?> succ : block.getSuccessors()) { - if (!processed(succ) && (next == null || succ.probability() > next.probability())) { + if (!processed(succ) && (next == null || succ.getRelativeFrequency() > next.getRelativeFrequency())) { next = succ; } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/ComputeBlockOrder.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/ComputeBlockOrder.java Thu Nov 15 09:04:07 2018 -0800 @@ -143,11 +143,11 @@ double unscheduledSum = 0.0; for (T pred : mostLikelySuccessor.getPredecessors()) { if (pred.getLinearScanNumber() == -1) { - unscheduledSum += pred.probability(); + unscheduledSum += pred.getRelativeFrequency(); } } - if (unscheduledSum > block.probability() / PENALTY_VERSUS_UNSCHEDULED) { + if (unscheduledSum > block.getRelativeFrequency() / PENALTY_VERSUS_UNSCHEDULED) { // Add this merge only after at least one additional predecessor gets scheduled. visitedBlocks.clear(mostLikelySuccessor.getId()); return null; @@ -212,8 +212,8 @@ private static <T extends AbstractBlockBase<T>> T findAndMarkMostLikelySuccessor(T block, BitSet visitedBlocks) { T result = null; for (T successor : block.getSuccessors()) { - assert successor.probability() >= 0.0 : "Probabilities must be positive"; - if (!visitedBlocks.get(successor.getId()) && successor.getLoopDepth() >= block.getLoopDepth() && (result == null || successor.probability() >= result.probability())) { + assert successor.getRelativeFrequency() >= 0.0 : "Relative frequencies must be positive"; + if (!visitedBlocks.get(successor.getId()) && successor.getLoopDepth() >= block.getLoopDepth() && (result == null || successor.getRelativeFrequency() >= result.getRelativeFrequency())) { result = successor; } } @@ -261,7 +261,7 @@ public int compare(T a, T b) { // Loop blocks before any loop exit block. The only exception are blocks that are // (almost) impossible to reach. - if (a.probability() > EPSILON && b.probability() > EPSILON) { + if (a.getRelativeFrequency() > EPSILON && b.getRelativeFrequency() > EPSILON) { int diff = b.getLoopDepth() - a.getLoopDepth(); if (diff != 0) { return diff; @@ -269,7 +269,7 @@ } // Blocks with high probability before blocks with low probability. - if (a.probability() > b.probability()) { + if (a.getRelativeFrequency() > b.getRelativeFrequency()) { return -1; } else { return 1;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/TraceStatisticsPrinter.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/TraceStatisticsPrinter.java Thu Nov 15 09:04:07 2018 -0800 @@ -59,13 +59,13 @@ double max = Double.NEGATIVE_INFINITY; double min = Double.POSITIVE_INFINITY; for (AbstractBlockBase<?> block : t) { - double probability = block.probability(); - total += probability; - if (probability < min) { - min = probability; + double frequency = block.getRelativeFrequency(); + total += frequency; + if (frequency < min) { + min = frequency; } - if (probability > max) { - max = probability; + if (frequency > max) { + max = frequency; } } printLine(debug, i, total, min, max, t.length);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/UniDirectionalTraceBuilder.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/UniDirectionalTraceBuilder.java Thu Nov 15 09:04:07 2018 -0800 @@ -65,7 +65,7 @@ } private static int compare(AbstractBlockBase<?> a, AbstractBlockBase<?> b) { - return Double.compare(b.probability(), a.probability()); + return Double.compare(b.getRelativeFrequency(), a.getRelativeFrequency()); } private boolean processed(AbstractBlockBase<?> b) { @@ -110,7 +110,7 @@ int blockNumber = 0; try (Indent i = debug.logAndIndent("StartTrace: %s", traceStart)) { for (AbstractBlockBase<?> block = traceStart; block != null; block = selectNext(block)) { - debug.log("add %s (prob: %f)", block, block.probability()); + debug.log("add %s (freq: %f)", block, block.getRelativeFrequency()); processed.set(block.getId()); trace.add(block); unblock(block); @@ -149,7 +149,7 @@ private AbstractBlockBase<?> selectNext(AbstractBlockBase<?> block) { AbstractBlockBase<?> next = null; for (AbstractBlockBase<?> successor : block.getSuccessors()) { - if (!processed(successor) && (next == null || successor.probability() > next.probability())) { + if (!processed(successor) && (next == null || successor.getRelativeFrequency() > next.getRelativeFrequency())) { next = successor; } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/AbstractBlockBase.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/AbstractBlockBase.java Thu Nov 15 09:04:07 2018 -0800 @@ -163,7 +163,7 @@ public abstract T getPostdominator(); - public abstract double probability(); + public abstract double getRelativeFrequency(); public abstract T getDominator(int distance);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ArrayOffsetProvider.java Thu Nov 15 21:05:47 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2018, 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.core.common.spi; - -import jdk.vm.ci.meta.JavaKind; - -public interface ArrayOffsetProvider { - - int arrayBaseOffset(JavaKind elementKind); - - int arrayScalingFactor(JavaKind elementKind); -}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/CodeGenProviders.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/CodeGenProviders.java Thu Nov 15 09:04:07 2018 -0800 @@ -41,6 +41,4 @@ ForeignCallsProvider getForeignCalls(); ConstantReflectionProvider getConstantReflection(); - - ArrayOffsetProvider getArrayOffsetProvider(); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/AbstractPointerStamp.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/AbstractPointerStamp.java Thu Nov 15 09:04:07 2018 -0800 @@ -142,10 +142,13 @@ @Override public Constant asConstant() { if (alwaysNull) { - return JavaConstant.NULL_POINTER; - } else { - return null; + return nullConstant(); } + return super.asConstant(); + } + + public JavaConstant nullConstant() { + return JavaConstant.NULL_POINTER; } @Override
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.jdk9.test/src/org/graalvm/compiler/core/test/ea/AtomicVirtualizationTests.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2018, 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.core.jdk9.test.ea; + +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; +import org.graalvm.compiler.core.test.ea.EATestBase; + +import org.junit.Test; + +import jdk.vm.ci.meta.JavaConstant; + +public class AtomicVirtualizationTests extends EATestBase { + private static final TestObject OBJ1 = new TestObject(1); + private static final TestObject OBJ2 = new TestObject(2); + private static TestObject obj6 = new TestObject(6); + private static TestObject obj7 = new TestObject(7); + private static TestObject obj8 = new TestObject(8); + + private static final class TestObject { + final int id; + + private TestObject(int id) { + this.id = id; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TestObject that = (TestObject) o; + return id == that.id; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "TestObject{id=" + id + '}'; + } + } + + // c = constant (heap-allocated); v = virtual; u = unknown (heap-allocated) + + public static boolean cvvNoMatchCAS() { + AtomicReference<TestObject> a = new AtomicReference<>(null); + return a.compareAndSet(new TestObject(3), new TestObject(4)); + } + + @Test + public void testcvvNoMatchCAS() { + testAtomicVirtualization("cvvNoMatchCAS", JavaConstant.INT_0); + } + + public static Object cvvNoMatchCAE() { + AtomicReference<TestObject> a = new AtomicReference<>(null); + return a.compareAndExchange(new TestObject(3), new TestObject(4)); + } + + @Test + public void testcvvNoMatchCAE() { + testAtomicVirtualization("cvvNoMatchCAE", JavaConstant.NULL_POINTER); + } + + public static boolean ccvNoMatchCAS() { + AtomicReference<TestObject> a = new AtomicReference<>(null); + return a.compareAndSet(OBJ1, new TestObject(3)); + } + + @Test + public void testccvNoMatchCAS() { + testAtomicVirtualization("ccvNoMatchCAS", JavaConstant.INT_0); + } + + public static Object ccvNoMatchCAE() { + AtomicReference<TestObject> a = new AtomicReference<>(null); + return a.compareAndExchange(OBJ1, new TestObject(3)); + } + + @Test + public void testccvNoMatchCAE() { + testAtomicVirtualization("ccvNoMatchCAE", JavaConstant.NULL_POINTER); + } + + public static boolean cccNoMatchCAS() { + AtomicReference<TestObject> a = new AtomicReference<>(null); + return a.compareAndSet(OBJ1, OBJ2); + } + + @Test + public void testcccNoMatchCAS() { + testAtomicVirtualization("cccNoMatchCAS", JavaConstant.INT_0); + } + + public static Object cccNoMatchCAE() { + AtomicReference<TestObject> a = new AtomicReference<>(null); + return a.compareAndExchange(OBJ1, OBJ2); + } + + @Test + public void testcccNoMatchCAE() { + testAtomicVirtualization("cccNoMatchCAE", JavaConstant.NULL_POINTER); + } + + public static boolean ccvCAS() { + AtomicReference<TestObject> a = new AtomicReference<>(null); + return a.compareAndSet(null, new TestObject(3)); + } + + @Test + public void testccvCAS() { + testAtomicVirtualization("ccvCAS", JavaConstant.INT_1); + } + + public static Object ccvCAE() { + AtomicReference<TestObject> a = new AtomicReference<>(null); + return a.compareAndExchange(null, new TestObject(3)); + } + + @Test + public void testccvCAE() { + testAtomicVirtualization("ccvCAE", null, 0); + } + + public static boolean cccCAS() { + AtomicReference<TestObject> a = new AtomicReference<>(null); + return a.compareAndSet(null, OBJ2); + } + + @Test + public void testcccCAS() { + testAtomicVirtualization("cccCAS", JavaConstant.INT_1); + } + + public static Object cccCAE() { + AtomicReference<TestObject> a = new AtomicReference<>(null); + return a.compareAndExchange(null, OBJ2); + } + + @Test + public void testcccCAE() { + testAtomicVirtualization("cccCAE", null); + } + + public static boolean vvvNoMatchCAS() { + AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3)); + return a.compareAndSet(new TestObject(4), new TestObject(5)); + } + + @Test + public void testvvvNoMatchCAS() { + testAtomicVirtualization("vvvNoMatchCAS", JavaConstant.INT_0); + } + + public static Object vvvNoMatchCAE() { + AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3)); + return a.compareAndExchange(new TestObject(4), new TestObject(5)); + } + + @Test + public void testvvvNoMatchCAE() { + testAtomicVirtualization("vvvNoMatchCAE", null, 1); + } + + public static boolean vcvNoMatchCAS() { + AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3)); + return a.compareAndSet(OBJ1, new TestObject(4)); + } + + @Test + public void testvcvNoMatchCAS() { + testAtomicVirtualization("vcvNoMatchCAS", JavaConstant.INT_0); + } + + public static Object vcvNoMatchCAE() { + AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3)); + return a.compareAndExchange(OBJ1, new TestObject(4)); + } + + @Test + public void testvcvNoMatchCAE() { + testAtomicVirtualization("vcvNoMatchCAE", null, 1); + } + + public static boolean vccNoMatchCAS() { + AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3)); + return a.compareAndSet(OBJ1, OBJ2); + } + + @Test + public void testvccNoMatchCAS() { + testAtomicVirtualization("vccNoMatchCAS", JavaConstant.INT_0); + } + + public static Object vccNoMatchCAE() { + AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3)); + return a.compareAndExchange(OBJ1, OBJ2); + } + + @Test + public void testvccNoMatchCAE() { + testAtomicVirtualization("vccNoMatchCAE", null, 1); + } + + public static boolean uvvCAS() { + AtomicReference<TestObject> a = new AtomicReference<>(obj6); + return a.compareAndSet(new TestObject(3), new TestObject(4)); + } + + @Test + public void testuvvCAS() { + testAtomicVirtualization("uvvCAS", JavaConstant.INT_0); + } + + public static Object uvvCAE() { + AtomicReference<TestObject> a = new AtomicReference<>(obj6); + return a.compareAndExchange(new TestObject(3), new TestObject(4)); + } + + @Test + public void testuvvCAE() { + testAtomicVirtualization("uvvCAE", null); + } + + public static boolean uuvCAS() { + AtomicReference<TestObject> a = new AtomicReference<>(obj6); + return a.compareAndSet(obj7, new TestObject(3)); + } + + @Test + public void testuuvCAS() { + testAtomicVirtualization("uuvCAS", null, 2); + } + + public static Object uuvCAE() { + AtomicReference<TestObject> a = new AtomicReference<>(obj6); + return a.compareAndExchange(obj7, new TestObject(3)); + } + + @Test + public void testuuvCAE() { + testAtomicVirtualization("uuvCAE", null, 2); + } + + public static boolean uuuCAS() { + AtomicReference<TestObject> a = new AtomicReference<>(obj6); + return a.compareAndSet(obj7, obj8); + } + + @Test + public void testuuuCAS() { + testAtomicVirtualization("uuuCAS", null); + } + + public static Object uuuCAE() { + AtomicReference<TestObject> a = new AtomicReference<>(obj6); + return a.compareAndExchange(obj7, obj8); + } + + @Test + public void testuuuCAE() { + testAtomicVirtualization("uuuCAE", null); + } + + public static boolean vuvCAS() { + AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3)); + return a.compareAndSet(obj6, new TestObject(4)); + } + + @Test + public void testvuvCAS() { + testAtomicVirtualization("vuvCAS", JavaConstant.INT_0); + } + + public static Object vuvCAE() { + AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3)); + return a.compareAndExchange(obj6, new TestObject(4)); + } + + @Test + public void testvuvCAE() { + testAtomicVirtualization("vuvCAE", null, 1); + } + + public static boolean vuuCAS() { + AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3)); + return a.compareAndSet(obj6, obj7); + } + + @Test + public void testvuuCAS() { + testAtomicVirtualization("vuuCAS", JavaConstant.INT_0); + } + + public static Object vuuCAE() { + AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3)); + return a.compareAndExchange(obj6, obj7); + } + + @Test + public void testvuuCAE() { + testAtomicVirtualization("vuuCAE", null, 1); + } + + private void testAtomicVirtualization(String snippet, JavaConstant expectedValue) { + testAtomicVirtualization(snippet, expectedValue, 0); + } + + protected void testAtomicVirtualization(String snippet, JavaConstant expectedValue, int expectedAllocations) { + testEscapeAnalysis(snippet, expectedValue, false, expectedAllocations); + test(snippet); + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java Thu Nov 15 09:04:07 2018 -0800 @@ -692,7 +692,7 @@ private RoundEnvironment currentRound; @Override - public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { + public boolean doProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (roundEnv.processingOver()) { return true; }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCLIRGenerator.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCLIRGenerator.java Thu Nov 15 09:04:07 2018 -0800 @@ -420,9 +420,9 @@ } @Override - public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length) { + public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length, int constantLength, boolean directPointers) { Variable result = newVariable(LIRKind.value(SPARCKind.WORD)); - append(new SPARCArrayEqualsOp(this, kind, result, load(array1), load(array2), asAllocatable(length))); + append(new SPARCArrayEqualsOp(this, kind, result, load(array1), load(array2), asAllocatable(length), directPointers)); return result; } @@ -477,4 +477,9 @@ public void emitPause() { append(new SPARCPauseOp()); } + + @Override + public void emitSpeculationFence() { + throw GraalError.unimplemented(); + } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Thu Nov 15 09:04:07 2018 -0800 @@ -181,6 +181,7 @@ @Test @SuppressWarnings("try") public void test() { + assumeManagementLibraryIsLoadable(); runTest(new InvariantsTool()); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest2.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest2.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -24,56 +24,74 @@ package org.graalvm.compiler.core.test; -import static org.graalvm.compiler.graph.test.matchers.NodeIterableIsEmpty.isNotEmpty; - import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; -import org.graalvm.compiler.nodes.calc.IntegerLessThanNode; import org.graalvm.compiler.phases.common.CanonicalizerPhase; import org.graalvm.compiler.phases.tiers.PhaseContext; -import org.junit.Assert; import org.junit.Test; public class CompareCanonicalizerTest2 extends GraalCompilerTest { - @SuppressWarnings("unused") private static int sink0; - @SuppressWarnings("unused") private static int sink1; + @SuppressWarnings("unused") private static boolean sink; private StructuredGraph getCanonicalizedGraph(String name) { - StructuredGraph graph = parseEager(name, AllowAssumptions.YES); + StructuredGraph graph = getRegularGraph(name); new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); return graph; } - public void testIntegerTestCanonicalization(String name) { - StructuredGraph graph = getCanonicalizedGraph(name); - Assert.assertThat(graph.getNodes().filter(IntegerLessThanNode.class), isNotEmpty()); + private StructuredGraph getRegularGraph(String name) { + StructuredGraph graph = parseEager(name, AllowAssumptions.YES); + return graph; } @Test public void test0() { - testIntegerTestCanonicalization("integerTestCanonicalization0"); + assertEquals(getCanonicalizedGraph("integerTestCanonicalization0"), getRegularGraph("integerTestCanonicalization0")); + } + + public static void integerTestCanonicalization0(int a) { + sink = 1 < a + 1; } @Test public void test1() { - testIntegerTestCanonicalization("integerTestCanonicalization1"); - } - - public static void integerTestCanonicalization0(int a) { - if (1 < a + 1) { - sink1 = 0; - } else { - sink0 = -1; - } + assertEquals(getCanonicalizedGraph("integerTestCanonicalization1"), getRegularGraph("integerTestCanonicalization1")); } public static void integerTestCanonicalization1(int a) { - if (a - 1 < -1) { - sink1 = 0; - } else { - sink0 = -1; - } + sink = a - 1 < -1; + } + + @Test + public void test2() { + assertEquals(getCanonicalizedGraph("integerTestCanonicalization2a"), getCanonicalizedGraph("integerTestCanonicalization2Reference")); + assertEquals(getCanonicalizedGraph("integerTestCanonicalization2b"), getCanonicalizedGraph("integerTestCanonicalization2Reference")); + } + + public static boolean integerTestCanonicalization2a(Object[] arr) { + return arr.length - 1 < 0; + } + + public static boolean integerTestCanonicalization2b(Object[] arr) { + return arr.length < 1; + } + + public static boolean integerTestCanonicalization2Reference(Object[] arr) { + return arr.length == 0; + } + + @Test + public void test3() { + assertEquals(getCanonicalizedGraph("integerTestCanonicalization3"), getCanonicalizedGraph("integerTestCanonicalization3Reference")); + } + + public static boolean integerTestCanonicalization3(Object[] arr) { + return ((long) (arr.length - 1)) - 1 < 0; + } + + public static boolean integerTestCanonicalization3Reference(Object[] arr) { + return arr.length < 2; } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest3.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest3.java Thu Nov 15 09:04:07 2018 -0800 @@ -92,16 +92,18 @@ assertCanonicallyEqual("integerTestCanonicalization1", "referenceSnippet1"); } - public static void integerTestCanonicalization1(char a) { - if (Integer.compareUnsigned(a - 2, a) < 0) { + public static void integerTestCanonicalization1(char[] a) { + int len = a.length; + if (Integer.compareUnsigned(len - 2, len) < 0) { sink1 = 0; } else { sink0 = -1; } } - public static void referenceSnippet1(char a) { - if (Integer.compareUnsigned(a, 2) >= 0) { + public static void referenceSnippet1(char[] a) { + int len = a.length; + if (Integer.compareUnsigned(len, 2) >= 0) { sink1 = 0; } else { sink0 = -1; @@ -238,12 +240,18 @@ StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); PhaseContext context = new PhaseContext(getProviders()); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); + canonicalizer.apply(graph, context); new GuardLoweringPhase().apply(graph, new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo())); new FrameStateAssignmentPhase().apply(graph); canonicalizer.apply(graph, context); + StructuredGraph referenceGraph = parseEager(reference, AllowAssumptions.YES); canonicalizer.apply(referenceGraph, context); + new GuardLoweringPhase().apply(referenceGraph, new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo())); + new FrameStateAssignmentPhase().apply(referenceGraph); + canonicalizer.apply(referenceGraph, context); + canonicalizer.apply(referenceGraph, context); assertEquals(referenceGraph, graph, true, true); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest13.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest13.java Thu Nov 15 09:04:07 2018 -0800 @@ -31,6 +31,7 @@ import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin; import org.graalvm.compiler.phases.common.CanonicalizerPhase; import org.graalvm.compiler.phases.tiers.PhaseContext; +import org.junit.Ignore; import org.junit.Test; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -282,6 +283,7 @@ testConditionalElimination("testSnippet9", "referenceSnippet9"); } + @Ignore("Need better unsigned stamps for this conditional elimination to work.") @Test public void test10() { testConditionalElimination("testSnippet10", "referenceSnippet4");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DumpPathTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DumpPathTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -47,6 +47,7 @@ @Test public void testDump() throws IOException { + assumeManagementLibraryIsLoadable(); Path dumpDirectoryPath = Files.createTempDirectory("DumpPathTest"); String[] extensions = new String[]{".cfg", ".bgv", ".graph-strings"}; EconomicMap<OptionKey<?>, Object> overrides = OptionValues.newOptionMap();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphResetDebugTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphResetDebugTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -43,6 +43,7 @@ @SuppressWarnings("try") @Test public void test1() { + assumeManagementLibraryIsLoadable(); EconomicMap<OptionKey<?>, Object> map = EconomicMap.create(); // Configure with an option that enables scopes map.put(DebugOptions.DumpOnError, true);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardedIntrinsicTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardedIntrinsicTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -34,7 +34,7 @@ import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; import org.graalvm.compiler.nodes.ValueNode; -import org.graalvm.compiler.nodes.debug.OpaqueNode; +import org.graalvm.compiler.nodes.extended.OpaqueNode; import org.graalvm.compiler.nodes.extended.LoadHubNode; import org.graalvm.compiler.nodes.extended.LoadMethodNode; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LongNodeChainTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LongNodeChainTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -35,7 +35,7 @@ import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.calc.AddNode; -import org.graalvm.compiler.nodes.debug.OpaqueNode; +import org.graalvm.compiler.nodes.extended.OpaqueNode; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.common.CanonicalizerPhase; import org.graalvm.compiler.phases.schedule.SchedulePhase; @@ -71,7 +71,7 @@ addNode.setY(newAddNode); addNode = newAddNode; } - opaque.replaceAndDelete(opaque.getValue()); + opaque.remove(); } else { value = constant; for (int i = 0; i < N; ++i) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java Thu Nov 15 09:04:07 2018 -0800 @@ -24,6 +24,8 @@ package org.graalvm.compiler.core.test.ea; +import static org.graalvm.compiler.graph.iterators.NodePredicates.isA; + import java.util.List; import org.graalvm.compiler.core.test.GraalCompilerTest; @@ -33,6 +35,7 @@ import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; import org.graalvm.compiler.nodes.java.NewArrayNode; import org.graalvm.compiler.nodes.java.NewInstanceNode; +import org.graalvm.compiler.nodes.virtual.AllocatedObjectNode; import org.graalvm.compiler.nodes.virtual.CommitAllocationNode; import org.graalvm.compiler.phases.common.CanonicalizerPhase; import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase; @@ -139,6 +142,10 @@ * iteration */ protected void testEscapeAnalysis(String snippet, JavaConstant expectedConstantResult, boolean iterativeEscapeAnalysis) { + testEscapeAnalysis(snippet, expectedConstantResult, iterativeEscapeAnalysis, 0); + } + + protected void testEscapeAnalysis(String snippet, JavaConstant expectedConstantResult, boolean iterativeEscapeAnalysis, int expectedAllocationCount) { prepareGraph(snippet, iterativeEscapeAnalysis); if (expectedConstantResult != null) { for (ReturnNode returnNode : returnNodes) { @@ -146,9 +153,11 @@ Assert.assertEquals(expectedConstantResult, returnNode.result().asConstant()); } } - int newInstanceCount = graph.getNodes().filter(NewInstanceNode.class).count() + graph.getNodes().filter(NewArrayNode.class).count() + - graph.getNodes().filter(CommitAllocationNode.class).count(); - Assert.assertEquals(0, newInstanceCount); + int newInstanceCount = graph.getNodes().filter(isA(NewInstanceNode.class).or(NewArrayNode.class).or(AllocatedObjectNode.class)).count(); + Assert.assertEquals("Expected allocation count does not match", expectedAllocationCount, newInstanceCount); + if (expectedAllocationCount == 0) { + Assert.assertTrue("Unexpected CommitAllocationNode", graph.getNodes().filter(CommitAllocationNode.class).isEmpty()); + } } @SuppressWarnings("try")
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PEAAssertionsTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PEAAssertionsTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -45,7 +45,7 @@ public static Object field; - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) public static void snippet1(int i) { Integer object = new Integer(i); GraalDirectives.ensureVirtualized(object); @@ -56,7 +56,7 @@ test("snippet1", 1); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) public static void snippet2(int i) { Integer object = new Integer(i); GraalDirectives.ensureVirtualized(object); @@ -68,7 +68,7 @@ test("snippet2", 1); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) public static void snippet3(int i) { Integer object = new Integer(i); field = object; @@ -80,7 +80,7 @@ test("snippet3", 1); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) public static void snippetHere1(int i) { Integer object = new Integer(i); GraalDirectives.ensureVirtualizedHere(object); @@ -91,7 +91,7 @@ test("snippetHere1", 1); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) public static void snippetHere2(int i) { Integer object = new Integer(i); GraalDirectives.ensureVirtualizedHere(object); @@ -103,7 +103,7 @@ test("snippetHere2", 1); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) public static void snippetHere3(int i) { Integer object = new Integer(i); field = object; @@ -136,7 +136,7 @@ test("snippetBoxing2", 1); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) public static void snippetControlFlow1(boolean b, int i) { Integer object = new Integer(i); if (b) { @@ -151,7 +151,7 @@ test("snippetControlFlow1", true, 1); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) public static void snippetControlFlow2(boolean b, int i) { Integer object = new Integer(i); if (b) { @@ -168,7 +168,7 @@ test("snippetControlFlow2", true, 1); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) public static void snippetControlFlow3(boolean b, int i) { Integer object = new Integer(i); GraalDirectives.ensureVirtualized(object); @@ -186,7 +186,7 @@ test("snippetControlFlow3", true, 1); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) public static void snippetControlFlow4(boolean b, int i) { Integer object = new Integer(i); if (b) { @@ -202,7 +202,7 @@ test("snippetControlFlow4", true, 1); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) public static void snippetControlFlow5(boolean b, int i) { Integer object = new Integer(i); if (b) { @@ -223,7 +223,7 @@ Object b; } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) public static void snippetIndirect1(boolean b, int i) { Integer object = new Integer(i); TestClass t = new TestClass(); @@ -242,7 +242,7 @@ test("snippetIndirect1", true, 1); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) public static void snippetIndirect2(boolean b, int i) { Integer object = new Integer(i); TestClass t = new TestClass();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -293,14 +293,14 @@ Assert.assertTrue("partial escape analysis should have removed all NewArrayNode allocations", graph.getNodes().filter(NewArrayNode.class).isEmpty()); ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, false, false); - double probabilitySum = 0; + double frequencySum = 0; int materializeCount = 0; for (CommitAllocationNode materialize : graph.getNodes().filter(CommitAllocationNode.class)) { - probabilitySum += cfg.blockFor(materialize).probability() * materialize.getVirtualObjects().size(); + frequencySum += cfg.blockFor(materialize).getRelativeFrequency() * materialize.getVirtualObjects().size(); materializeCount += materialize.getVirtualObjects().size(); } Assert.assertEquals("unexpected number of MaterializeObjectNodes", expectedCount, materializeCount); - Assert.assertEquals("unexpected probability of MaterializeObjectNodes", expectedProbability, probabilitySum, 0.01); + Assert.assertEquals("unexpected frequency of MaterializeObjectNodes", expectedProbability, frequencySum, 0.01); for (Node node : graph.getNodes()) { for (Class<? extends Node> clazz : invalidNodeClasses) { Assert.assertFalse("instance of invalid class: " + clazz.getSimpleName(), clazz.isInstance(node) && node.usages().isNotEmpty());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/UnsafeCompareAndSwapVirtualizationTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2018, 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.core.test.ea; + +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.atomic.AtomicReferenceArray; + +import org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode; +import org.junit.Test; + +import jdk.vm.ci.meta.JavaConstant; + +public class UnsafeCompareAndSwapVirtualizationTest extends EATestBase { + + private static Object obj1 = new Object(); + private static Object obj2 = new Object(); + private static final Object OBJ1 = new Object(); + + public static boolean bothVirtualNoMatch() { + AtomicReference<Object> a = new AtomicReference<>(); + return a.compareAndSet(new Object(), new Object()); + } + + @Test + public void bothVirtualNoMatchTest() { + testEscapeAnalysis("bothVirtualNoMatch", JavaConstant.INT_0, true); + assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty()); + } + + public static boolean bothVirtualMatch() { + Object expect = new Object(); + AtomicReference<Object> a = new AtomicReference<>(expect); + return a.compareAndSet(expect, new Object()); + } + + @Test + public void bothVirtualMatchTest() { + testEscapeAnalysis("bothVirtualMatch", JavaConstant.INT_1, true); + assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty()); + } + + public static boolean expectedVirtualMatch() { + Object o = new Object(); + AtomicReference<Object> a = new AtomicReference<>(o); + return a.compareAndSet(o, obj1); + } + + @Test + public void expectedVirtualMatchTest() { + testEscapeAnalysis("expectedVirtualMatch", JavaConstant.INT_1, true); + assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty()); + } + + public static boolean expectedVirtualNoMatch() { + Object o = new Object(); + AtomicReference<Object> a = new AtomicReference<>(); + return a.compareAndSet(o, obj1); + } + + @Test + public void expectedVirtualNoMatchTest() { + testEscapeAnalysis("expectedVirtualNoMatch", JavaConstant.INT_0, true); + assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty()); + } + + public static boolean bothNonVirtualNoMatch() { + AtomicReference<Object> a = new AtomicReference<>(); + return a.compareAndSet(OBJ1, obj2); + } + + @Test + public void bothNonVirtualNoMatchTest() { + testEscapeAnalysis("bothNonVirtualNoMatch", JavaConstant.INT_0, true); + assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty()); + } + + public static boolean bothNonVirtualMatch() { + AtomicReference<Object> a = new AtomicReference<>(OBJ1); + return a.compareAndSet(OBJ1, obj2); + } + + @Test + public void bothNonVirtualMatchTest() { + testEscapeAnalysis("bothNonVirtualMatch", JavaConstant.INT_1, true); + assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty()); + } + + public static boolean onlyInitialValueVirtualNoMatch() { + AtomicReference<Object> a = new AtomicReference<>(new Object()); + return a.compareAndSet(obj1, obj2); + } + + @Test + public void onlyInitialValueVirtualNoMatchTest() { + testEscapeAnalysis("onlyInitialValueVirtualNoMatch", JavaConstant.INT_0, true); + assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty()); + } + + public static boolean onlyInitialValueVirtualMatch() { + Object o = new Object(); + AtomicReference<Object> a = new AtomicReference<>(o); + return a.compareAndSet(o, obj2); + } + + @Test + public void onlyInitialValueVirtualMatchTest() { + testEscapeAnalysis("onlyInitialValueVirtualMatch", JavaConstant.INT_1, true); + assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty()); + } + + public static boolean bothVirtualNoMatchArray() { + AtomicReferenceArray<Object> array = new AtomicReferenceArray<>(1); + return array.compareAndSet(0, new Object(), new Object()); + } + + @Test + public void bothVirtualNoMatchArrayTest() { + testEscapeAnalysis("bothVirtualNoMatchArray", JavaConstant.INT_0, true); + assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty()); + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/PolymorphicInliningTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/PolymorphicInliningTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -48,6 +48,8 @@ import org.graalvm.compiler.phases.tiers.HighTierContext; import org.graalvm.compiler.test.SubprocessUtil; import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; import org.junit.Test; import java.io.IOException; @@ -55,6 +57,11 @@ public class PolymorphicInliningTest extends GraalCompilerTest { + @Before + public void checkJavaAgent() { + Assume.assumeFalse("Java Agent found -> skipping", SubprocessUtil.isJavaAgentAttached()); + } + @Test public void testInSubprocess() throws InterruptedException, IOException { String recursionPropName = getClass().getName() + ".recursion";
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysisTests.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysisTests.java Thu Nov 15 09:04:07 2018 -0800 @@ -120,7 +120,7 @@ assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class)); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) static void test03Entry() { Data data = new Data(); data.f = new Integer(42); @@ -148,7 +148,7 @@ assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class), t(Integer.class)); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) static void test04Entry() { Data data = null; for (int i = 0; i < 2; i++) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java Thu Nov 15 09:04:07 2018 -0800 @@ -41,7 +41,6 @@ import java.io.PrintStream; import java.util.Map; -import org.graalvm.compiler.debug.DebugCloseable; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DiagnosticsOutputDirectory; import org.graalvm.compiler.debug.PathUtilities; @@ -163,8 +162,9 @@ * Creates the {@link DebugContext} to use when retrying a compilation. * * @param options the options for configuring the debug context + * @param logStream the log stream to use in the debug context */ - protected abstract DebugContext createRetryDebugContext(OptionValues options); + protected abstract DebugContext createRetryDebugContext(OptionValues options, PrintStream logStream); @SuppressWarnings("try") public final T run(DebugContext initialDebug) { @@ -227,22 +227,27 @@ return handleException(cause); } - String dir = this.outputDirectory.getPath(); - if (dir == null) { - return handleException(cause); - } - String dumpName = PathUtilities.sanitizeFileName(toString()); - File dumpPath = new File(dir, dumpName); - dumpPath.mkdirs(); - if (!dumpPath.exists()) { - TTY.println("Warning: could not create diagnostics directory " + dumpPath); - return handleException(cause); + File dumpPath = null; + try { + String dir = this.outputDirectory.getPath(); + if (dir != null) { + String dumpName = PathUtilities.sanitizeFileName(toString()); + dumpPath = new File(dir, dumpName); + dumpPath.mkdirs(); + if (!dumpPath.exists()) { + TTY.println("Warning: could not create diagnostics directory " + dumpPath); + dumpPath = null; + } + } + } catch (Throwable t) { + TTY.println("Warning: could not create Graal diagnostic directory"); + t.printStackTrace(TTY.out); } String message; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try (PrintStream ps = new PrintStream(baos)) { - ps.printf("%s: Compilation of %s failed: ", Thread.currentThread(), this); + ps.printf("%s: Compilation of %s failed:%n", Thread.currentThread(), this); cause.printStackTrace(ps); ps.printf("To disable compilation %s notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n", causeType, @@ -253,11 +258,19 @@ causeType, actionKey.getName(), ExceptionAction.Print, actionKey.getName(), ExceptionAction.Print); - ps.println("Retrying compilation of " + this); + if (dumpPath != null) { + ps.println("Retrying compilation of " + this); + } else { + ps.println("Not retrying compilation of " + this + " as the dump path could not be created."); + } message = baos.toString(); } TTY.print(message); + if (dumpPath == null) { + return handleException(cause); + } + File retryLogFile = new File(dumpPath, "retry.log"); try (PrintStream ps = new PrintStream(new FileOutputStream(retryLogFile))) { ps.print(message); @@ -270,15 +283,27 @@ MethodFilter, null, DumpPath, dumpPath.getPath()); - try (DebugContext retryDebug = createRetryDebugContext(retryOptions); DebugCloseable s = retryDebug.disableIntercept()) { + ByteArrayOutputStream logBaos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(logBaos); + try (DebugContext retryDebug = createRetryDebugContext(retryOptions, ps)) { T res = performCompilation(retryDebug); + ps.println("There was no exception during retry."); maybeExitVM(action); return res; - } catch (Throwable ignore) { + } catch (Throwable e) { + ps.println("Exception during retry:"); + e.printStackTrace(ps); // Failures during retry are silent T res = handleException(cause); maybeExitVM(action); return res; + } finally { + ps.close(); + try (FileOutputStream fos = new FileOutputStream(retryLogFile, true)) { + fos.write(logBaos.toByteArray()); + } catch (Throwable e) { + TTY.printf("Error writing to %s: %s%n", retryLogFile, e); + } } } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java Thu Nov 15 09:04:07 2018 -0800 @@ -27,6 +27,8 @@ import static jdk.vm.ci.code.ValueUtil.asRegister; import static jdk.vm.ci.code.ValueUtil.isLegal; import static jdk.vm.ci.code.ValueUtil.isRegister; +import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.AllTargets; +import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.Options.MitigateSpeculativeExecutionAttacks; import static org.graalvm.compiler.core.common.GraalOptions.MatchExpressions; import static org.graalvm.compiler.debug.DebugOptions.LogVerbose; import static org.graalvm.compiler.lir.LIR.verifyBlock; @@ -312,6 +314,19 @@ public void doBlockPrologue(@SuppressWarnings("unused") Block block, @SuppressWarnings("unused") OptionValues options) { + if (MitigateSpeculativeExecutionAttacks.getValue(options) == AllTargets) { + boolean hasControlSplitPredecessor = false; + for (Block b : block.getPredecessors()) { + if (b.getSuccessorCount() > 1) { + hasControlSplitPredecessor = true; + break; + } + } + boolean isStartBlock = block.getPredecessorCount() == 0; + if (hasControlSplitPredecessor || isStartBlock) { + getLIRGeneratorTool().emitSpeculationFence(); + } + } } @Override @@ -372,6 +387,8 @@ debug.log("interior match for %s", valueNode); } else if (operand instanceof ComplexMatchValue) { debug.log("complex match for %s", valueNode); + // Set current position to the position of the root matched node. + setSourcePosition(node.getNodeSourcePosition()); ComplexMatchValue match = (ComplexMatchValue) operand; operand = match.evaluate(this); if (operand != null) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeMatchRules.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeMatchRules.java Thu Nov 15 09:04:07 2018 -0800 @@ -47,10 +47,13 @@ import org.graalvm.compiler.nodes.calc.LeftShiftNode; import org.graalvm.compiler.nodes.calc.MulNode; import org.graalvm.compiler.nodes.calc.NarrowNode; +import org.graalvm.compiler.nodes.calc.NegateNode; +import org.graalvm.compiler.nodes.calc.NotNode; import org.graalvm.compiler.nodes.calc.ObjectEqualsNode; import org.graalvm.compiler.nodes.calc.OrNode; import org.graalvm.compiler.nodes.calc.PointerEqualsNode; import org.graalvm.compiler.nodes.calc.ReinterpretNode; +import org.graalvm.compiler.nodes.calc.RightShiftNode; import org.graalvm.compiler.nodes.calc.SignExtendNode; import org.graalvm.compiler.nodes.calc.SubNode; import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode; @@ -78,6 +81,8 @@ @MatchableNode(nodeClass = WriteNode.class, inputs = {"address", "value"}) @MatchableNode(nodeClass = ZeroExtendNode.class, inputs = {"value"}) @MatchableNode(nodeClass = AndNode.class, inputs = {"x", "y"}, commutative = true) +@MatchableNode(nodeClass = NegateNode.class, inputs = {"value"}) +@MatchableNode(nodeClass = NotNode.class, inputs = {"value"}) @MatchableNode(nodeClass = FloatEqualsNode.class, inputs = {"x", "y"}, commutative = true) @MatchableNode(nodeClass = FloatLessThanNode.class, inputs = {"x", "y"}, commutative = true) @MatchableNode(nodeClass = PointerEqualsNode.class, inputs = {"x", "y"}, commutative = true) @@ -93,6 +98,7 @@ @MatchableNode(nodeClass = PiNode.class, inputs = {"object"}) @MatchableNode(nodeClass = LogicCompareAndSwapNode.class, inputs = {"address", "expectedValue", "newValue"}) @MatchableNode(nodeClass = ValueCompareAndSwapNode.class, inputs = {"address", "expectedValue", "newValue"}) +@MatchableNode(nodeClass = RightShiftNode.class, inputs = {"x", "y"}) public abstract class NodeMatchRules { NodeLIRBuilder lirBuilder;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/GraphChangeMonitoringPhase.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/GraphChangeMonitoringPhase.java Thu Nov 15 09:04:07 2018 -0800 @@ -34,7 +34,7 @@ import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.phases.BasePhase; import org.graalvm.compiler.phases.PhaseSuite; -import org.graalvm.compiler.phases.common.util.HashSetNodeEventListener; +import org.graalvm.compiler.phases.common.util.EconomicSetNodeEventListener; import org.graalvm.compiler.phases.tiers.PhaseContext; /** @@ -68,7 +68,7 @@ * Phase may add nodes but not end up using them so ignore additions. Nodes going dead and * having their inputs change are the main interesting differences. */ - HashSetNodeEventListener listener = new HashSetNodeEventListener().exclude(NodeEvent.NODE_ADDED); + EconomicSetNodeEventListener listener = new EconomicSetNodeEventListener().exclude(NodeEvent.NODE_ADDED); StructuredGraph graphCopy = (StructuredGraph) graph.copy(graph.getDebug()); DebugContext debug = graph.getDebug(); try (NodeEventScope s = graphCopy.trackNodeEvents(listener)) { @@ -90,7 +90,7 @@ } if (!filteredNodes.isEmpty()) { /* rerun it on the real graph in a new Debug scope so Dump and Log can find it. */ - listener = new HashSetNodeEventListener(); + listener = new EconomicSetNodeEventListener(); try (NodeEventScope s = graph.trackNodeEvents(listener)) { try (DebugContext.Scope s2 = debug.scope("WithGraphChangeMonitoring")) { if (debug.isDumpEnabled(DebugContext.DETAILED_LEVEL)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/MidTier.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/MidTier.java Thu Nov 15 09:04:07 2018 -0800 @@ -24,6 +24,9 @@ package org.graalvm.compiler.core.phases; +import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.GuardTargets; +import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.NonDeoptGuardTargets; +import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.Options.MitigateSpeculativeExecutionAttacks; import static org.graalvm.compiler.core.common.GraalOptions.ConditionalElimination; import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode; import static org.graalvm.compiler.core.common.GraalOptions.OptDeoptimizationGrouping; @@ -47,6 +50,7 @@ import org.graalvm.compiler.phases.common.FrameStateAssignmentPhase; import org.graalvm.compiler.phases.common.GuardLoweringPhase; import org.graalvm.compiler.phases.common.IncrementalCanonicalizerPhase; +import org.graalvm.compiler.phases.common.InsertGuardFencesPhase; import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase; import org.graalvm.compiler.phases.common.LockEliminationPhase; import org.graalvm.compiler.phases.common.LoopSafepointInsertionPhase; @@ -78,6 +82,10 @@ appendPhase(new GuardLoweringPhase()); + if (MitigateSpeculativeExecutionAttacks.getValue(options) == GuardTargets || MitigateSpeculativeExecutionAttacks.getValue(options) == NonDeoptGuardTargets) { + appendPhase(new InsertGuardFencesPhase()); + } + if (VerifyHeapAtReturn.getValue(options)) { appendPhase(new VerifyHeapAtReturnPhase()); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java Thu Nov 15 09:04:07 2018 -0800 @@ -44,6 +44,7 @@ import org.graalvm.compiler.lir.gen.LIRGeneratorTool; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; +import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.tiers.SuitesProvider; import org.graalvm.compiler.phases.tiers.TargetProvider; import org.graalvm.compiler.phases.util.Providers; @@ -153,7 +154,7 @@ * Turns a Graal {@link CompilationResult} into a {@link CompiledCode} object that can be passed * to the VM for code installation. */ - protected abstract CompiledCode createCompiledCode(ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult); + protected abstract CompiledCode createCompiledCode(ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult, boolean isDefault, OptionValues options); /** * @see #createInstalledCode(DebugContext, ResolvedJavaMethod, CompilationRequest, @@ -192,6 +193,9 @@ * @param context a custom debug context to use for the code installation * @return a reference to the compiled and ready-to-run installed code * @throws BailoutException if the code installation failed + * @throws IllegalArgumentException if {@code installedCode != null} and this platform does not + * {@linkplain CodeCacheProvider#installCode support} a predefined + * {@link InstalledCode} object */ @SuppressWarnings("try") public InstalledCode createInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult, @@ -209,8 +213,8 @@ InstalledCode installedCode; try { - preCodeInstallationTasks(tasks, compilationResult, predefinedInstalledCode); - CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult); + preCodeInstallationTasks(tasks, compilationResult); + CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult, isDefault, debug.getOptions()); installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault); assert predefinedInstalledCode == null || installedCode == predefinedInstalledCode; } catch (Throwable t) { @@ -218,7 +222,7 @@ throw t; } - postCodeInstallationTasks(tasks, installedCode); + postCodeInstallationTasks(tasks, compilationResult, installedCode); return installedCode; } catch (Throwable e) { @@ -232,16 +236,16 @@ } } - private static void preCodeInstallationTasks(CodeInstallationTask[] tasks, CompilationResult compilationResult, InstalledCode predefinedInstalledCode) { + private static void preCodeInstallationTasks(CodeInstallationTask[] tasks, CompilationResult compilationResult) { for (CodeInstallationTask task : tasks) { - task.preProcess(compilationResult, predefinedInstalledCode); + task.preProcess(compilationResult); } } - private static void postCodeInstallationTasks(CodeInstallationTask[] tasks, InstalledCode installedCode) { + private static void postCodeInstallationTasks(CodeInstallationTask[] tasks, CompilationResult compilationResult, InstalledCode installedCode) { try { for (CodeInstallationTask task : tasks) { - task.postProcess(installedCode); + task.postProcess(compilationResult, installedCode); } } catch (Throwable t) { installedCode.invalidate(); @@ -310,19 +314,18 @@ * Task to run before code installation. * * @param compilationResult the code about to be installed - * @param predefinedInstalledCode a pre-allocated {@link InstalledCode} object that will be - * used as a reference to the installed code. May be {@code null}. * */ - public void preProcess(CompilationResult compilationResult, InstalledCode predefinedInstalledCode) { + public void preProcess(CompilationResult compilationResult) { } /** * Task to run after the code is installed. * + * @param compilationResult the code about to be installed * @param installedCode a reference to the installed code */ - public void postProcess(InstalledCode installedCode) { + public void postProcess(CompilationResult compilationResult, InstalledCode installedCode) { } /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/DebugContextTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/DebugContextTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -197,6 +197,7 @@ @Test public void testEnabledSandbox() { + TimerKeyTest.assumeManagementLibraryIsLoadable(); EconomicMap<OptionKey<?>, Object> map = EconomicMap.create(); // Configure with an option that enables scopes map.put(DebugOptions.DumpOnError, true); @@ -226,6 +227,7 @@ @Test public void testDisabledSandbox() { + TimerKeyTest.assumeManagementLibraryIsLoadable(); EconomicMap<OptionKey<?>, Object> map = EconomicMap.create(); // Configure with an option that enables scopes map.put(DebugOptions.DumpOnError, true); @@ -283,6 +285,7 @@ @Test public void testDisableIntercept() { + TimerKeyTest.assumeManagementLibraryIsLoadable(); EconomicMap<OptionKey<?>, Object> map = EconomicMap.create(); // Configure with an option that enables scopes map.put(DebugOptions.DumpOnError, true);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/TimerKeyTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/TimerKeyTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -39,6 +39,7 @@ import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.serviceprovider.GraalServices; import org.junit.Assume; +import org.junit.AssumptionViolatedException; import org.junit.Before; import org.junit.Test; @@ -47,9 +48,20 @@ @Before public void checkCapabilities() { + assumeManagementLibraryIsLoadable(); Assume.assumeTrue("skipping management interface test", GraalServices.isCurrentThreadCpuTimeSupported()); } + /** @see <a href="https://bugs.openjdk.java.net/browse/JDK-8076557">JDK-8076557</a> */ + static void assumeManagementLibraryIsLoadable() { + try { + /* Trigger loading of the management library using the bootstrap class loader. */ + GraalServices.getCurrentThreadAllocatedBytes(); + } catch (UnsatisfiedLinkError | NoClassDefFoundError | UnsupportedOperationException e) { + throw new AssumptionViolatedException("Management interface is unavailable: " + e); + } + } + /** * Actively spins the current thread for at least a given number of milliseconds in such a way * that timers for the current thread keep ticking over.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java Thu Nov 15 09:04:07 2018 -0800 @@ -80,7 +80,7 @@ */ public final class DebugContext implements AutoCloseable { - public static final Description NO_DESCRIPTION = null; + public static final Description NO_DESCRIPTION = new Description(null, "NO_DESCRIPTION"); public static final GlobalMetrics NO_GLOBAL_METRIC_VALUES = null; public static final Iterable<DebugHandlersFactory> NO_CONFIG_CUSTOMIZERS = Collections.emptyList(); @@ -404,6 +404,18 @@ return new DebugContext(NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, Immutable.create(options), factories); } + public static DebugContext create(OptionValues options, PrintStream logStream, DebugHandlersFactory factory) { + return new DebugContext(NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, logStream, Immutable.create(options), Collections.singletonList(factory)); + } + + /** + * Creates a {@link DebugContext} based on a given set of option values and {@code factories}. + * The {@link DebugHandlersFactory#LOADER} can be used for the latter. + */ + public static DebugContext create(OptionValues options, Description description, Iterable<DebugHandlersFactory> factories) { + return new DebugContext(description, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, Immutable.create(options), factories); + } + /** * Creates a {@link DebugContext}. */
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java Thu Nov 15 09:04:07 2018 -0800 @@ -127,8 +127,6 @@ @Option(help = "Enable dumping LIR, register allocation and code generation info to the C1Visualizer.", type = OptionType.Debug) public static final OptionKey<Boolean> PrintBackendCFG = new OptionKey<>(true); - @Option(help = "Output probabilities for fixed nodes during binary graph dumping.", type = OptionType.Debug) - public static final OptionKey<Boolean> PrintGraphProbabilities = new OptionKey<>(false); @Option(help = "Enable dumping to the IdealGraphVisualizer.", type = OptionType.Debug) public static final OptionKey<Boolean> PrintGraph = new OptionKey<>(true); @Option(help = "Print graphs to files instead of sending them over the network.", type = OptionType.Debug)
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DiagnosticsOutputDirectory.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DiagnosticsOutputDirectory.java Thu Nov 15 09:04:07 2018 -0800 @@ -86,6 +86,7 @@ } if (CLOSED.equals(path)) { TTY.println("Warning: Graal diagnostic directory already closed"); + return null; } return path; } @@ -129,6 +130,7 @@ Path dir = Paths.get(outDir); if (dir.toFile().exists()) { + String prefix = new File(outDir).getName() + "/"; File zip = new File(outDir + ".zip").getAbsoluteFile(); List<Path> toDelete = new ArrayList<>(); try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip))) { @@ -137,7 +139,7 @@ @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if (attrs.isRegularFile()) { - String name = dir.relativize(file).toString(); + String name = prefix + dir.relativize(file).toString(); ZipEntry ze = new ZipEntry(name); zos.putNextEntry(ze); Files.copy(file, zos);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphSnippetTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphSnippetTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -31,7 +31,7 @@ import org.junit.Test; public class GraphSnippetTest { - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "unused"}) @Test public void dumpTheFile() throws Exception { Class<?> snippets = null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeSourcePosition.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeSourcePosition.java Thu Nov 15 09:04:07 2018 -0800 @@ -28,6 +28,7 @@ import static org.graalvm.compiler.graph.NodeSourcePosition.Marker.Placeholder; import static org.graalvm.compiler.graph.NodeSourcePosition.Marker.Substitution; +import java.util.Iterator; import java.util.Objects; import org.graalvm.compiler.bytecode.BytecodeDisassembler; @@ -40,7 +41,7 @@ import jdk.vm.ci.meta.MetaUtil; import jdk.vm.ci.meta.ResolvedJavaMethod; -public class NodeSourcePosition extends BytecodePosition { +public class NodeSourcePosition extends BytecodePosition implements Iterable<NodeSourcePosition> { private static final boolean STRICT_SOURCE_POSITION = Boolean.getBoolean("debug.graal.SourcePositionStrictChecks"); private static final boolean SOURCE_POSITION_BYTECODES = Boolean.getBoolean("debug.graal.SourcePositionDisassemble"); @@ -53,17 +54,16 @@ * Remove marker frames. */ public NodeSourcePosition trim() { - if (marker != None) { - return null; + NodeSourcePosition lastMarker = null; + for (NodeSourcePosition current = this; current != null; current = current.getCaller()) { + if (current.marker != None) { + lastMarker = current; + } } - NodeSourcePosition caller = getCaller(); - if (caller != null) { - caller = caller.trim(); + if (lastMarker == null) { + return this; } - if (caller != getCaller()) { - return new NodeSourcePosition(caller, getMethod(), getBCI()); - } - return this; + return lastMarker.getCaller(); } public ResolvedJavaMethod getRootMethod() { @@ -81,6 +81,25 @@ return true; } + @Override + public Iterator<NodeSourcePosition> iterator() { + return new Iterator<NodeSourcePosition>() { + private NodeSourcePosition currentPosition = NodeSourcePosition.this; + + @Override + public boolean hasNext() { + return currentPosition != null; + } + + @Override + public NodeSourcePosition next() { + NodeSourcePosition current = currentPosition; + currentPosition = currentPosition.getCaller(); + return current; + } + }; + } + enum Marker { None, Placeholder, @@ -124,11 +143,19 @@ } public static NodeSourcePosition substitution(ResolvedJavaMethod method) { - return substitution(null, method); + return substitution(null, method, BytecodeFrame.INVALID_FRAMESTATE_BCI); + } + + public static NodeSourcePosition substitution(ResolvedJavaMethod method, int bci) { + return substitution(null, method, bci); } public static NodeSourcePosition substitution(NodeSourcePosition caller, ResolvedJavaMethod method) { - return new NodeSourcePosition(caller, method, BytecodeFrame.INVALID_FRAMESTATE_BCI, Substitution); + return substitution(caller, method, BytecodeFrame.INVALID_FRAMESTATE_BCI); + } + + public static NodeSourcePosition substitution(NodeSourcePosition caller, ResolvedJavaMethod method, int bci) { + return new NodeSourcePosition(caller, method, bci, Substitution); } public boolean isSubstitution() { @@ -195,10 +222,10 @@ return new NodeSourcePosition(newSourceLanguagePosition, link, getMethod(), 0); } assert link == null || isSubstitution || verifyCaller(this, link) : link; - - return new NodeSourcePosition(newSourceLanguagePosition, link, getMethod(), getBCI()); + assert !isSubstitution || marker == None; + return new NodeSourcePosition(newSourceLanguagePosition, link, getMethod(), getBCI(), isSubstitution ? Substitution : None); } else { - return new NodeSourcePosition(getCaller().addCaller(newSourceLanguagePosition, link, isSubstitution), getMethod(), getBCI()); + return new NodeSourcePosition(getCaller().addCaller(newSourceLanguagePosition, link, isSubstitution), getMethod(), getBCI(), marker); } } @@ -221,6 +248,9 @@ private static void format(StringBuilder sb, NodeSourcePosition pos) { MetaUtil.appendLocation(sb.append("at "), pos.getMethod(), pos.getBCI()); + if (pos.marker != None) { + sb.append(" " + pos.marker); + } if (SOURCE_POSITION_BYTECODES) { String disassembly = BytecodeDisassembler.disassembleOne(pos.getMethod(), pos.getBCI()); if (disassembly != null && disassembly.length() > 0) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Thu Nov 15 09:04:07 2018 -0800 @@ -56,7 +56,6 @@ import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider; import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; -import org.graalvm.compiler.nodes.spi.LoweringProvider; import org.graalvm.compiler.nodes.spi.Replacements; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.Phase; @@ -148,7 +147,7 @@ replacements = createReplacements(graalRuntime.getOptions(), p, snippetReflection, bytecodeProvider); } try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { - plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, lowerer, metaAccess, snippetReflection, replacements, wordTypes, stampProvider); + plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes); replacements.setGraphBuilderPlugins(plugins); } try (InitTimer rt = timer("create Suites provider")) { @@ -164,10 +163,9 @@ } protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection, - HotSpotHostForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, - HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) { - Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider, - replacements); + HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, + HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) { + Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, replacements); AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false); return plugins; }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotMoveFactory.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotMoveFactory.java Thu Nov 15 09:04:07 2018 -0800 @@ -29,7 +29,7 @@ import static jdk.vm.ci.meta.JavaConstant.LONG_0; import org.graalvm.compiler.core.aarch64.AArch64MoveFactory; -import org.graalvm.compiler.lir.LIRInstruction; +import org.graalvm.compiler.lir.aarch64.AArch64LIRInstruction; import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant; import jdk.vm.ci.hotspot.HotSpotConstant; @@ -52,7 +52,7 @@ } @Override - public LIRInstruction createLoad(AllocatableValue dst, Constant src) { + public AArch64LIRInstruction createLoad(AllocatableValue dst, Constant src) { Constant usedSource; if (COMPRESSED_NULL.equals(src)) { usedSource = INT_0;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/BmiAndn.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 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.amd64.test; + +import org.junit.Test; +import org.junit.Assert; + +/** + * Tests Bit Manipulation Instruction andn pattern matching and result. + */ +public class BmiAndn extends BmiCompilerTest { + // from Intel manual VEX.NDS.LZ.0F38.W0 F2 /r, example c4e260f2c2 + private final byte[] instrMask = new byte[]{ + (byte) 0xFF, + (byte) 0x1F, + (byte) 0x00, + (byte) 0xFF}; + private final byte[] instrPattern = new byte[]{ + (byte) 0xC4, // prefix for 3-byte VEX instruction + (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes + (byte) 0x00, + (byte) 0xF2}; + + public int andni(int n1, int n2) { + return (n1 & (~n2)); + } + + public long andnl(long n1, long n2) { + return (n1 & (~n2)); + } + + // Pattern matching check for andni + @Test + public void test1() { + Assert.assertTrue(verifyPositive("andni", instrMask, instrPattern)); + } + + // Pattern matching check for andnl + @Test + public void test2() { + Assert.assertTrue(verifyPositive("andnl", instrMask, instrPattern)); + } + + // Result correctness check + @Test + public void test3() { + int n1 = 42; + int n2 = 100; + test("andni", n1, n2); + } + + @Test + public void test4() { + long n1 = 420000000; + long n2 = 1000000000; + test("andnl", n1, n2); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/BmiBlsi.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 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.amd64.test; + +import org.junit.Test; +import org.junit.Assert; + +/** + * Tests Bit Manipulation Instruction blsi pattern matching and result. + */ +public class BmiBlsi extends BmiCompilerTest { + // from Intel manual VEX.NDD.LZ.0F38.W0 F3 /3, example c4e260f2c2 + private final byte[] instrMask = new byte[]{ + (byte) 0xFF, + (byte) 0x1F, + (byte) 0x00, + (byte) 0xFF, + (byte) 0b0011_1000}; + private final byte[] instrPattern = new byte[]{ + (byte) 0xC4, // prefix for 3-byte VEX instruction + (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes + (byte) 0x00, + (byte) 0xF3, + (byte) 0b0001_1000}; // bits 543 == 011 (3) + + public int blsii(int n1) { + return (n1 & (-n1)); + } + + public long blsil(long n1) { + return (n1 & (-n1)); + } + + // Pattern matching check for blsii + @Test + public void test1() { + Assert.assertTrue(verifyPositive("blsii", instrMask, instrPattern)); + } + + // Pattern matching check for blsil + @Test + public void test2() { + Assert.assertTrue(verifyPositive("blsil", instrMask, instrPattern)); + } + + // Result correctness check + @Test + public void test3() { + int n1 = 42; + test("blsii", n1); + } + + @Test + public void test4() { + long n1 = 420000000; + test("blsil", n1); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/BmiBlsmsk.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 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.amd64.test; + +import org.junit.Test; +import org.junit.Assert; + +/** + * Tests Bit Manipulation Instruction blsmsk pattern matching and result. + */ +public class BmiBlsmsk extends BmiCompilerTest { + // from Intel manual VEX.NDD.LZ.0F38.W0 F3 /2, example c4e260f2c2 + private final byte[] instrMask = new byte[]{ + (byte) 0xFF, + (byte) 0x1F, + (byte) 0x00, + (byte) 0xFF, + (byte) 0b0011_1000}; + private final byte[] instrPattern = new byte[]{ + (byte) 0xC4, // prefix for 3-byte VEX instruction + (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes + (byte) 0x00, + (byte) 0xF3, + (byte) 0b0001_0000}; // bits 543 == 010 (2) + + public int blsmski(int n1) { + return (n1 ^ (n1 - 1)); + } + + public long blsmskl(long n1) { + return (n1 ^ (n1 - 1)); + } + + // Pattern matching check for blsmski + @Test + public void test1() { + Assert.assertTrue(verifyPositive("blsmski", instrMask, instrPattern)); + } + + // Pattern matching check for blsmskl + @Test + public void test2() { + Assert.assertTrue(verifyPositive("blsmskl", instrMask, instrPattern)); + } + + // Result correctness check + @Test + public void test3() { + int n1 = 42; + test("blsmski", n1); + } + + @Test + public void test4() { + long n1 = 420000000; + test("blsmskl", n1); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/BmiBlsr.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 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.amd64.test; + +import org.junit.Test; +import org.junit.Assert; + +/** + * Tests Bit Manipulation Instruction blsr pattern matching and result. + */ +public class BmiBlsr extends BmiCompilerTest { + // from Intel manual VEX.NDD.LZ.0F38.W0 F3 /3, example c4e260f2c2 + private final byte[] instrMask = new byte[]{ + (byte) 0xFF, + (byte) 0x1F, + (byte) 0x00, + (byte) 0xFF, + (byte) 0b0011_1000}; + private final byte[] instrPattern = new byte[]{ + (byte) 0xC4, // prefix for 3-byte VEX instruction + (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes + (byte) 0x00, + (byte) 0xF3, + (byte) 0b0000_1000}; // bits 543 == 011 (3) + + public int blsri(int n1) { + return (n1 & (n1 - 1)); + } + + public long blsrl(long n1) { + return (n1 & (n1 - 1)); + } + + // Pattern matching check for blsri + @Test + public void test1() { + Assert.assertTrue(verifyPositive("blsri", instrMask, instrPattern)); + } + + // Pattern matching check for blsrl + @Test + public void test2() { + Assert.assertTrue(verifyPositive("blsrl", instrMask, instrPattern)); + } + + // Result correctness check + @Test + public void test3() { + int n1 = 42; + test("blsri", n1); + } + + @Test + public void test4() { + long n1 = 420000000; + test("blsrl", n1); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/BmiCompilerTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 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.amd64.test; + +import static org.junit.Assume.assumeTrue; + +import org.graalvm.compiler.api.test.Graal; +import org.graalvm.compiler.code.CompilationResult; +import org.graalvm.compiler.core.test.GraalCompilerTest; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.runtime.RuntimeProvider; +import org.junit.Assert; +import org.junit.Before; + +import jdk.vm.ci.amd64.AMD64; +import jdk.vm.ci.code.Architecture; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +public abstract class BmiCompilerTest extends GraalCompilerTest { + + @Before + public void checkAMD64() { + Architecture arch = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getTarget().arch; + assumeTrue("skipping AMD64 specific test", arch instanceof AMD64); + assumeTrue("skipping BMI1 specific test", ((AMD64) arch).getFeatures().contains(AMD64.CPUFeature.BMI1)); + } + + public boolean verifyPositive(String methodName, byte[] instrMask, byte[] instrPattern) { + ResolvedJavaMethod method = getResolvedJavaMethod(methodName); + StructuredGraph graph = parseForCompile(method); + + CompilationResult c = compile(method, graph); + byte[] targetCode = c.getTargetCode(); + + return countCpuInstructions(targetCode, instrMask, instrPattern) >= 1; + } + + public static int countCpuInstructions(byte[] nativeCode, byte[] instrMask, byte[] instrPattern) { + int count = 0; + int patternSize = Math.min(instrMask.length, instrPattern.length); + boolean found; + Assert.assertTrue(patternSize > 0); + for (int i = 0, n = nativeCode.length - patternSize; i < n;) { + found = true; + for (int j = 0; j < patternSize; j++) { + if ((nativeCode[i + j] & instrMask[j]) != instrPattern[j]) { + found = false; + break; + } + } + if (found) { + ++count; + i += patternSize - 1; + } + i++; + } + return count; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayIndexOfStub.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2018, 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.amd64; + +import jdk.vm.ci.meta.JavaKind; +import org.graalvm.compiler.api.replacements.Snippet; +import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; +import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; +import org.graalvm.compiler.hotspot.meta.HotSpotProviders; +import org.graalvm.compiler.hotspot.stubs.SnippetStub; +import org.graalvm.compiler.options.OptionValues; +import org.graalvm.compiler.replacements.amd64.AMD64ArrayIndexOfNode; +import jdk.internal.vm.compiler.word.Pointer; + +public class AMD64ArrayIndexOfStub extends SnippetStub { + + public AMD64ArrayIndexOfStub(ForeignCallDescriptor foreignCallDescriptor, OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) { + super(foreignCallDescriptor.getName(), options, providers, linkage); + } + + @Snippet + private static int indexOfTwoConsecutiveBytes(Pointer arrayPointer, int arrayLength, int searchValue) { + return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, true, arrayPointer, arrayLength, searchValue); + } + + @Snippet + private static int indexOfTwoConsecutiveChars(Pointer arrayPointer, int arrayLength, int searchValue) { + return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, true, arrayPointer, arrayLength, searchValue); + } + + @Snippet + private static int indexOf1Byte(Pointer arrayPointer, int arrayLength, byte b) { + return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, arrayPointer, arrayLength, b); + } + + @Snippet + private static int indexOf2Bytes(Pointer arrayPointer, int arrayLength, byte b1, byte b2) { + return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, arrayPointer, arrayLength, b1, b2); + } + + @Snippet + private static int indexOf3Bytes(Pointer arrayPointer, int arrayLength, byte b1, byte b2, byte b3) { + return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, arrayPointer, arrayLength, b1, b2, b3); + } + + @Snippet + private static int indexOf4Bytes(Pointer arrayPointer, int arrayLength, byte b1, byte b2, byte b3, byte b4) { + return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, arrayPointer, arrayLength, b1, b2, b3, b4); + } + + @Snippet + private static int indexOf1Char(Pointer arrayPointer, int arrayLength, char c) { + return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, arrayPointer, arrayLength, c); + } + + @Snippet + private static int indexOf2Chars(Pointer arrayPointer, int arrayLength, char c1, char c2) { + return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, arrayPointer, arrayLength, c1, c2); + } + + @Snippet + private static int indexOf3Chars(Pointer arrayPointer, int arrayLength, char c1, char c2, char c3) { + return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, arrayPointer, arrayLength, c1, c2, c3); + } + + @Snippet + private static int indexOf4Chars(Pointer arrayPointer, int arrayLength, char c1, char c2, char c3, char c4) { + return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, arrayPointer, arrayLength, c1, c2, c3, c4); + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java Thu Nov 15 09:04:07 2018 -0800 @@ -52,7 +52,6 @@ import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider; import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; -import org.graalvm.compiler.nodes.spi.LoweringProvider; import org.graalvm.compiler.nodes.spi.Replacements; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.common.AddressLoweringPhase; @@ -142,8 +141,7 @@ replacements = createReplacements(options, p, snippetReflection, bytecodeProvider); } try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { - plugins = createGraphBuilderPlugins(compilerConfiguration, config, options, target, constantReflection, foreignCalls, lowerer, metaAccess, snippetReflection, replacements, wordTypes, - stampProvider); + plugins = createGraphBuilderPlugins(compilerConfiguration, config, options, target, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes); replacements.setGraphBuilderPlugins(plugins); } try (InitTimer rt = timer("create Suites provider")) { @@ -159,10 +157,9 @@ } protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, OptionValues options, TargetDescription target, - HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotMetaAccessProvider metaAccess, - HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) { - Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider, - replacements); + HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, + HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) { + Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, replacements); AMD64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), (AMD64) target.arch, GraalArithmeticStubs.getValue(options), false); return plugins; }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotCounterOp.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotCounterOp.java Thu Nov 15 09:04:07 2018 -0800 @@ -24,18 +24,21 @@ package org.graalvm.compiler.hotspot.amd64; -import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant; -import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant; import static jdk.vm.ci.amd64.AMD64.rax; import static jdk.vm.ci.amd64.AMD64.rbx; import static jdk.vm.ci.code.ValueUtil.asRegister; import static jdk.vm.ci.code.ValueUtil.isRegister; +import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant; +import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant; +import org.graalvm.compiler.asm.Label; import org.graalvm.compiler.asm.amd64.AMD64Address; +import org.graalvm.compiler.asm.amd64.AMD64Assembler; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.HotSpotCounterOp; -import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; +import org.graalvm.compiler.hotspot.debug.BenchmarkCounters; import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider; import org.graalvm.compiler.lir.LIRInstructionClass; import org.graalvm.compiler.lir.Opcode; @@ -90,7 +93,7 @@ // load counters array masm.movptr(countersArrayReg, countersArrayAddr); - CounterProcedure emitProcedure = (counterIndex, increment, displacement) -> emitIncrement(masm, countersArrayReg, increment, displacement); + CounterProcedure emitProcedure = (counterIndex, increment, displacement) -> emitIncrement(crb, masm, countersArrayReg, increment, displacement); forEachCounter(emitProcedure, target); // restore scratch register @@ -109,7 +112,7 @@ return false; } - private static void emitIncrement(AMD64MacroAssembler masm, Register countersArrayReg, Value incrementValue, int displacement) { + private static void emitIncrement(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register countersArrayReg, Value incrementValue, int displacement) { // address for counter value AMD64Address counterAddr = new AMD64Address(countersArrayReg, displacement); // increment counter (in memory) @@ -119,6 +122,12 @@ } else { masm.addq(counterAddr, asRegister(incrementValue)); } - + if (BenchmarkCounters.Options.AbortOnBenchmarkCounterOverflow.getValue(crb.getOptions())) { + Label target = new Label(); + masm.jccb(AMD64Assembler.ConditionFlag.NoOverflow, target); + crb.blockComment("[BENCHMARK COUNTER OVERFLOW]"); + masm.illegal(); + masm.bind(target); + } } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Thu Nov 15 09:04:07 2018 -0800 @@ -48,6 +48,7 @@ import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; import org.graalvm.compiler.options.OptionValues; +import org.graalvm.compiler.replacements.amd64.AMD64ArrayIndexOf; import org.graalvm.compiler.word.WordTypes; import jdk.vm.ci.code.CallingConvention; @@ -108,6 +109,27 @@ registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); } + link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_BYTES, options, providers, + registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_BYTES, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS, options, providers, + registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_1_BYTE, options, providers, + registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_1_BYTE, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_2_BYTES, options, providers, + registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_2_BYTES, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_3_BYTES, options, providers, + registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_3_BYTES, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_4_BYTES, options, providers, + registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_4_BYTES, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_1_CHAR, options, providers, + registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_1_CHAR, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_2_CHARS, options, providers, + registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_2_CHARS, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_3_CHARS, options, providers, + registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_3_CHARS, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_4_CHARS, options, providers, + registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_4_CHARS, LEAF, REEXECUTABLE, NO_LOCATIONS))); + super.initialize(providers, options); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Nov 15 09:04:07 2018 -0800 @@ -133,6 +133,11 @@ return (HotSpotProviders) super.getProviders(); } + @Override + protected int getMaxVectorSize() { + return config.maxVectorSize; + } + /** * Utility for emitting the instruction to save RBP. */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.lir.test/src/org/graalvm/compiler/hotspot/lir/test/BenchmarkCounterOverflowTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2018, 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.lir.test; + +import static org.graalvm.compiler.test.SubprocessUtil.getVMCommandLine; +import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.graalvm.compiler.api.directives.GraalDirectives; +import org.graalvm.compiler.core.common.LIRKind; +import org.graalvm.compiler.hotspot.HotSpotBackend; +import org.graalvm.compiler.hotspot.debug.BenchmarkCounters; +import org.graalvm.compiler.lir.ConstantValue; +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.test.SubprocessUtil; +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; + +import jdk.vm.ci.amd64.AMD64; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +public class BenchmarkCounterOverflowTest extends LIRTest { + private static final String SUBPROCESS_PROPERTY = BenchmarkCounterOverflowTest.class.getSimpleName() + ".subprocess.call"; + private static final boolean VERBOSE = Boolean.getBoolean(BenchmarkCounterOverflowTest.class.getSimpleName() + ".verbose"); + + private static LIRKind intKind; + + @Before + public void checkAMD64() { + Assume.assumeTrue("skipping AMD64 specific test", getTarget().arch instanceof AMD64); + Assume.assumeTrue("skipping HotSpot specific test", getBackend() instanceof HotSpotBackend); + } + + @Before + public void setUp() { + intKind = LIRKind.fromJavaKind(getBackend().getTarget().arch, JavaKind.Long); + } + + private static final LIRTestSpecification constCounterIncrement = new LIRTestSpecification() { + @Override + public void generate(LIRGeneratorTool gen) { + gen.append(gen.createBenchmarkCounter("counter", "test", new ConstantValue(intKind, JavaConstant.forLong(Integer.MAX_VALUE)))); + } + }; + + @SuppressWarnings("unused") + @LIRIntrinsic + public static void counterInc(LIRTestSpecification spec) { + } + + public static void test(long count) { + for (long i = 0; i < count; i++) { + counterInc(constCounterIncrement); + GraalDirectives.blackhole(i); + } + } + + @Test + public void incrementCounter() { + Assume.assumeTrue("not a subprocess -> skip", Boolean.getBoolean(SUBPROCESS_PROPERTY)); + BenchmarkCounters.enabled = true; + + Object[] args = new Object[]{Integer.MAX_VALUE * 4L}; + ResolvedJavaMethod method = getResolvedJavaMethod("test"); + executeActualCheckDeopt(getInitialOptions(), method, EMPTY, null, args); + } + + @Test + public void spawnSubprocess() throws Throwable { + Assume.assumeFalse("subprocess already spawned -> skip", Boolean.getBoolean(SUBPROCESS_PROPERTY)); + List<String> vmArgs = withoutDebuggerArguments(getVMCommandLine()); + vmArgs.add("-XX:JVMCICounterSize=1"); + vmArgs.add("-Dgraal." + BenchmarkCounters.Options.AbortOnBenchmarkCounterOverflow.getName() + "=true"); + vmArgs.add("-D" + SUBPROCESS_PROPERTY + "=true"); + + // Disable increment range checks (e.g. HotSpotCounterOp.checkIncrements()) + vmArgs.add("-dsa"); + vmArgs.add("-da"); + + List<String> mainClassAndArgs = new ArrayList<>(); + mainClassAndArgs.add("com.oracle.mxtool.junit.MxJUnitWrapper"); + mainClassAndArgs.add(BenchmarkCounterOverflowTest.class.getName()); + + SubprocessUtil.Subprocess proc = SubprocessUtil.java(vmArgs, mainClassAndArgs); + + if (VERBOSE) { + System.out.println(proc); + } + + Assert.assertNotEquals("Expected non-zero exit status", 0, proc.exitCode); + + Iterator<String> it = proc.output.iterator(); + while (it.hasNext()) { + String line = it.next(); + if (line.contains("Problematic frame:")) { + if (!it.hasNext()) { + // no more line + break; + } + line = it.next(); + if (line.contains(BenchmarkCounterOverflowTest.class.getName() + ".test")) { + return; + } + Assert.fail("Unexpected stack trace: " + line); + } + } + Assert.fail(String.format("Could not find method in output:%n%s", proc)); + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc.test/src/org/graalvm/compiler/core/sparc/test/SPARCAllocatorTest.java Thu Nov 15 21:05:47 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2013, 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.core.sparc.test; - -import static org.graalvm.compiler.core.common.GraalOptions.RegisterPressure; -import static org.graalvm.compiler.core.common.GraalOptions.TraceRA; -import static org.junit.Assume.assumeTrue; - -import org.graalvm.compiler.core.test.backend.AllocatorTest; -import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; -import org.graalvm.compiler.hotspot.HotSpotBackend; -import org.junit.Before; -import org.junit.Test; - -import jdk.vm.ci.sparc.SPARC; - -public class SPARCAllocatorTest extends AllocatorTest { - - private final GraalHotSpotVMConfig config = ((HotSpotBackend) getBackend()).getRuntime().getVMConfig(); - - @Before - public void checkSPARC() { - assumeTrue("skipping SPARC specific test", getTarget().arch instanceof SPARC); - assumeTrue("RegisterPressure is set -> skip", RegisterPressure.getValue(getInitialOptions()) == null); - assumeTrue("TraceRA is set -> skip", !TraceRA.getValue(getInitialOptions())); - } - - @Test - public void test1() { - testAllocation("test1snippet", config.threadLocalHandshakes ? 1 : 2, 0, 0); - } - - public static long test1snippet(long x) { - return x + 41; - } - - @Test - public void test2() { - testAllocation("test2snippet", config.threadLocalHandshakes ? 1 : 2, 0, 0); - } - - public static long test2snippet(long x) { - return x * 41; - } - - @Test - public void test3() { - testAllocation("test3snippet", config.threadLocalHandshakes ? 3 : 4, 0, 0); - } - - public static long test3snippet(long x) { - return x / 41 + x % 41; - } - -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc.test/src/org/graalvm/compiler/hotspot/sparc/test/SPARCAllocatorTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013, 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.sparc.test; + +import static org.graalvm.compiler.core.common.GraalOptions.RegisterPressure; +import static org.graalvm.compiler.core.common.GraalOptions.TraceRA; +import static org.junit.Assume.assumeTrue; + +import org.graalvm.compiler.core.test.backend.AllocatorTest; +import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; +import org.graalvm.compiler.hotspot.HotSpotBackend; +import org.junit.Before; +import org.junit.Test; + +import jdk.vm.ci.sparc.SPARC; + +public class SPARCAllocatorTest extends AllocatorTest { + + private final GraalHotSpotVMConfig config = ((HotSpotBackend) getBackend()).getRuntime().getVMConfig(); + + @Before + public void checkSPARC() { + assumeTrue("skipping SPARC specific test", getTarget().arch instanceof SPARC); + assumeTrue("RegisterPressure is set -> skip", RegisterPressure.getValue(getInitialOptions()) == null); + assumeTrue("TraceRA is set -> skip", !TraceRA.getValue(getInitialOptions())); + } + + @Test + public void test1() { + testAllocation("test1snippet", config.threadLocalHandshakes ? 1 : 2, 0, 0); + } + + public static long test1snippet(long x) { + return x + 41; + } + + @Test + public void test2() { + testAllocation("test2snippet", config.threadLocalHandshakes ? 1 : 2, 0, 0); + } + + public static long test2snippet(long x) { + return x * 41; + } + + @Test + public void test3() { + testAllocation("test3snippet", config.threadLocalHandshakes ? 3 : 4, 0, 0); + } + + public static long test3snippet(long x) { + return x / 41 + x % 41; + } + +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackend.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackend.java Thu Nov 15 09:04:07 2018 -0800 @@ -193,19 +193,19 @@ @Override public void enter(CompilationResultBuilder crb) { final int frameSize = crb.frameMap.totalFrameSize(); - final int stackpoinerChange = -frameSize; + final int stackpointerChange = -frameSize; SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; if (!isStub) { emitStackOverflowCheck(crb); } - if (SPARCAssembler.isSimm13(stackpoinerChange)) { - masm.save(sp, stackpoinerChange, sp); + if (SPARCAssembler.isSimm13(stackpointerChange)) { + masm.save(sp, stackpointerChange, sp); } else { try (ScratchRegister sc = masm.getScratchRegister()) { Register scratch = sc.getRegister(); assert isGlobalRegister(scratch) : "Only global registers are allowed before save. Got register " + scratch; - masm.setx(stackpoinerChange, scratch, false); + masm.setx(stackpointerChange, scratch, false); masm.save(sp, scratch, sp); } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java Thu Nov 15 09:04:07 2018 -0800 @@ -104,7 +104,7 @@ HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes); BytecodeProvider bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection); HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(runtime.getOptions(), p, snippetReflection, bytecodeProvider, target); - Plugins plugins = createGraphBuilderPlugins(compilerConfiguration, config, metaAccess, constantReflection, foreignCalls, lowerer, stampProvider, snippetReflection, replacements, wordTypes); + Plugins plugins = createGraphBuilderPlugins(compilerConfiguration, config, metaAccess, constantReflection, foreignCalls, snippetReflection, replacements, wordTypes); replacements.setGraphBuilderPlugins(plugins); HotSpotSuitesProvider suites = createSuites(config, runtime, compilerConfiguration, plugins, replacements); HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers, @@ -115,10 +115,9 @@ } protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotMetaAccessProvider metaAccess, - HotSpotConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotStampProvider stampProvider, + HotSpotConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) { - Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider, - replacements); + Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, replacements); SPARCGraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false); return plugins; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/BigIntegerIntrinsicsTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -0,0 +1,217 @@ +/* + * Copyright (c) 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.test; + +import java.math.BigInteger; +import java.util.Random; + +import org.graalvm.compiler.api.test.Graal; +import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; +import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; +import org.graalvm.compiler.replacements.test.MethodSubstitutionTest; +import org.graalvm.compiler.runtime.RuntimeProvider; + +import org.junit.Test; + +import jdk.vm.ci.amd64.AMD64; +import jdk.vm.ci.code.InstalledCode; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +/* + * Indirectly test intrinsic/call substitutions for (innate) methods: + * + * BigInteger.implMultiplyToLen + * BigInteger.implMulAdd + * BigInteger.implMontgomeryMultiply + * BigInteger.implMontgomerySquare + * BigInteger.implSquareToLen + * + * via BigInteger.multiply() and .modPow(). Note that the actual substitution + * is not tested per se (only execution based on admissible intrinsics). + * + */ +public final class BigIntegerIntrinsicsTest extends MethodSubstitutionTest { + + static final int N = 100; + + @Test + public void testMultiplyToLen() throws ClassNotFoundException { + + // Intrinsic must be available. + org.junit.Assume.assumeTrue(config.useMultiplyToLenIntrinsic()); + // Test case is (currently) AMD64 only. + org.junit.Assume.assumeTrue(getTarget().arch instanceof AMD64); + + Class<?> javaclass = Class.forName("java.math.BigInteger"); + + TestIntrinsic tin = new TestIntrinsic("testMultiplyAux", javaclass, + "multiply", BigInteger.class); + + for (int i = 0; i < N; i++) { + + BigInteger big1 = randomBig(i); + BigInteger big2 = randomBig(i); + + // Invoke BigInteger BigInteger.multiply(BigInteger) + BigInteger res1 = (BigInteger) tin.invokeJava(big1, big2); + + // Invoke BigInteger testMultiplyAux(BigInteger) + BigInteger res2 = (BigInteger) tin.invokeTest(big1, big2); + + assertDeepEquals(res1, res2); + + // Invoke BigInteger testMultiplyAux(BigInteger) through code handle. + BigInteger res3 = (BigInteger) tin.invokeCode(big1, big2); + + assertDeepEquals(res1, res3); + } + } + + @Test + public void testMulAdd() throws ClassNotFoundException { + + // Intrinsic must be available. + org.junit.Assume.assumeTrue(config.useMulAddIntrinsic() || + config.useSquareToLenIntrinsic()); + // Test case is (currently) AMD64 only. + org.junit.Assume.assumeTrue(getTarget().arch instanceof AMD64); + + Class<?> javaclass = Class.forName("java.math.BigInteger"); + + TestIntrinsic tin = new TestIntrinsic("testMultiplyAux", javaclass, + "multiply", BigInteger.class); + + for (int i = 0; i < N; i++) { + + BigInteger big1 = randomBig(i); + + // Invoke BigInteger BigInteger.multiply(BigInteger) + BigInteger res1 = (BigInteger) tin.invokeJava(big1, big1); + + // Invoke BigInteger testMultiplyAux(BigInteger) + BigInteger res2 = (BigInteger) tin.invokeTest(big1, big1); + + assertDeepEquals(res1, res2); + + // Invoke BigInteger testMultiplyAux(BigInteger) through code handle. + BigInteger res3 = (BigInteger) tin.invokeCode(big1, big1); + + assertDeepEquals(res1, res3); + } + } + + @Test + public void testMontgomery() throws ClassNotFoundException { + + // Intrinsic must be available. + org.junit.Assume.assumeTrue(config.useMontgomeryMultiplyIntrinsic() || + config.useMontgomerySquareIntrinsic()); + // Test case is (currently) AMD64 only. + org.junit.Assume.assumeTrue(getTarget().arch instanceof AMD64); + + Class<?> javaclass = Class.forName("java.math.BigInteger"); + + TestIntrinsic tin = new TestIntrinsic("testMontgomeryAux", javaclass, + "modPow", BigInteger.class, BigInteger.class); + + for (int i = 0; i < N; i++) { + + BigInteger big1 = randomBig(i); + BigInteger big2 = randomBig(i); + + // Invoke BigInteger BigInteger.modPow(BigExp, BigInteger) + BigInteger res1 = (BigInteger) tin.invokeJava(big1, bigTwo, big2); + + // Invoke BigInteger testMontgomeryAux(BigInteger, BigExp, BigInteger) + BigInteger res2 = (BigInteger) tin.invokeTest(big1, bigTwo, big2); + + assertDeepEquals(res1, res2); + + // Invoke BigInteger testMontgomeryAux(BigInteger, BigExp, BigInteger) through code + // handle. + BigInteger res3 = (BigInteger) tin.invokeCode(big1, bigTwo, big2); + + assertDeepEquals(res1, res3); + } + } + + public static BigInteger testMultiplyAux(BigInteger a, BigInteger b) { + return a.multiply(b); + } + + public static BigInteger testMontgomeryAux(BigInteger a, BigInteger exp, BigInteger b) { + return a.modPow(exp, b); + } + + private class TestIntrinsic { + + TestIntrinsic(String testmname, Class<?> javaclass, String javamname, Class<?>... params) { + + javamethod = getResolvedJavaMethod(javaclass, javamname, params); + testmethod = getResolvedJavaMethod(testmname); + + assert javamethod != null; + assert testmethod != null; + + // Force the test method to be compiled. + testcode = getCode(testmethod); + + assert testcode != null; + } + + Object invokeJava(BigInteger big, Object... args) { + + return invokeSafe(javamethod, big, args); + } + + Object invokeTest(Object... args) { + + return invokeSafe(testmethod, null, args); + } + + Object invokeCode(Object... args) { + + return executeVarargsSafe(testcode, args); + } + + // Private data section: + private ResolvedJavaMethod javamethod; + private ResolvedJavaMethod testmethod; + private InstalledCode testcode; + } + + private static GraalHotSpotVMConfig config = ((HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class)).getVMConfig(); + + private static BigInteger bigTwo = BigInteger.valueOf(2); + private static Random rnd = new Random(17); + + private static BigInteger randomBig(int i) { + return new BigInteger(rnd.nextInt(4096) + i2sz(i), rnd); + } + + private static int i2sz(int i) { + return i * 3 + 1; + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Thu Nov 15 09:04:07 2018 -0800 @@ -260,6 +260,9 @@ // Stub based intrinsics but implementation seems complex in C2 "sun/security/provider/DigestBase.implCompressMultiBlock([BII)I"); + // See JDK-8207146. + String oopName = isJDK12OrHigher() ? "Reference" : "Object"; + if (isJDK9OrHigher()) { // Relevant for Java flight recorder add(toBeInvestigated, @@ -304,6 +307,7 @@ * explicitly as the more generic method might be more restrictive and therefore slower * than necessary. */ + add(toBeInvestigated, // Mapped to compareAndExchange* "jdk/internal/misc/Unsafe.compareAndExchangeByteAcquire(Ljava/lang/Object;JBB)B", @@ -312,8 +316,8 @@ "jdk/internal/misc/Unsafe.compareAndExchangeIntRelease(Ljava/lang/Object;JII)I", "jdk/internal/misc/Unsafe.compareAndExchangeLongAcquire(Ljava/lang/Object;JJJ)J", "jdk/internal/misc/Unsafe.compareAndExchangeLongRelease(Ljava/lang/Object;JJJ)J", - "jdk/internal/misc/Unsafe.compareAndExchangeReferenceAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - "jdk/internal/misc/Unsafe.compareAndExchangeReferenceRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + "jdk/internal/misc/Unsafe.compareAndExchange" + oopName + "Acquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + "jdk/internal/misc/Unsafe.compareAndExchange" + oopName + "Release(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", "jdk/internal/misc/Unsafe.compareAndExchangeShortAcquire(Ljava/lang/Object;JSS)S", "jdk/internal/misc/Unsafe.compareAndExchangeShortRelease(Ljava/lang/Object;JSS)S", @@ -330,10 +334,10 @@ "jdk/internal/misc/Unsafe.weakCompareAndSetLongAcquire(Ljava/lang/Object;JJJ)Z", "jdk/internal/misc/Unsafe.weakCompareAndSetLongPlain(Ljava/lang/Object;JJJ)Z", "jdk/internal/misc/Unsafe.weakCompareAndSetLongRelease(Ljava/lang/Object;JJJ)Z", - "jdk/internal/misc/Unsafe.weakCompareAndSetReference(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", - "jdk/internal/misc/Unsafe.weakCompareAndSetReferenceAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", - "jdk/internal/misc/Unsafe.weakCompareAndSetReferencePlain(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", - "jdk/internal/misc/Unsafe.weakCompareAndSetReferenceRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", + "jdk/internal/misc/Unsafe.weakCompareAndSet" + oopName + "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", + "jdk/internal/misc/Unsafe.weakCompareAndSet" + oopName + "Acquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", + "jdk/internal/misc/Unsafe.weakCompareAndSet" + oopName + "Plain(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", + "jdk/internal/misc/Unsafe.weakCompareAndSet" + oopName + "Release(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", "jdk/internal/misc/Unsafe.weakCompareAndSetShort(Ljava/lang/Object;JSS)Z", "jdk/internal/misc/Unsafe.weakCompareAndSetShortAcquire(Ljava/lang/Object;JSS)Z", "jdk/internal/misc/Unsafe.weakCompareAndSetShortPlain(Ljava/lang/Object;JSS)Z", @@ -344,10 +348,6 @@ "java/lang/StringCoding.hasNegatives([BII)Z", "java/lang/StringCoding.implEncodeISOArray([BI[BII)I", "java/lang/StringLatin1.indexOf([B[B)I", - "java/lang/StringLatin1.inflate([BI[BII)V", - "java/lang/StringLatin1.inflate([BI[CII)V", - "java/lang/StringUTF16.compress([BI[BII)I", - "java/lang/StringUTF16.compress([CI[BII)I", "java/lang/StringUTF16.getChar([BI)C", "java/lang/StringUTF16.getChars([BII[CI)V", "java/lang/StringUTF16.indexOf([BI[BII)I", @@ -387,6 +387,10 @@ // Can we implement these on non-AMD64 platforms? C2 seems to. add(toBeInvestigated, "java/lang/String.compareTo(Ljava/lang/String;)I", + "java/lang/StringLatin1.inflate([BI[BII)V", + "java/lang/StringLatin1.inflate([BI[CII)V", + "java/lang/StringUTF16.compress([BI[BII)I", + "java/lang/StringUTF16.compress([CI[BII)I", "jdk/internal/misc/Unsafe.compareAndExchangeByte(Ljava/lang/Object;JBB)B", "jdk/internal/misc/Unsafe.compareAndExchangeShort(Ljava/lang/Object;JSS)S", "jdk/internal/misc/Unsafe.compareAndSetByte(Ljava/lang/Object;JBB)Z", @@ -399,7 +403,7 @@ "sun/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J", "sun/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I", "sun/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J", - "sun/misc/Unsafe.getAndSetReference(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;"); + "sun/misc/Unsafe.getAndSet" + oopName + "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;"); if (isJDK9OrHigher()) { if (!(arch instanceof AArch64)) { @@ -412,7 +416,7 @@ "jdk/internal/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J", "jdk/internal/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I", "jdk/internal/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J", - "jdk/internal/misc/Unsafe.getAndSetReference(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;"); + "jdk/internal/misc/Unsafe.getAndSet" + oopName + "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;"); } add(toBeInvestigated, "jdk/internal/misc/Unsafe.getCharUnaligned(Ljava/lang/Object;J)C", @@ -527,6 +531,10 @@ return GraalServices.JAVA_SPECIFICATION_VERSION >= 11; } + private static boolean isJDK12OrHigher() { + return GraalServices.JAVA_SPECIFICATION_VERSION >= 12; + } + public interface Refiner { void refine(CheckGraalIntrinsics checker); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -54,6 +54,7 @@ */ @Test public void testVMCompilation1() throws IOException, InterruptedException { + assumeManagementLibraryIsLoadable(); testHelper(Collections.emptyList(), Arrays.asList("-XX:-TieredCompilation", "-XX:+UseJVMCICompiler", "-Dgraal.CompilationFailureAction=ExitVM", @@ -69,6 +70,7 @@ */ @Test public void testVMCompilation2() throws IOException, InterruptedException { + assumeManagementLibraryIsLoadable(); testHelper(Collections.emptyList(), Arrays.asList("-XX:-TieredCompilation", "-XX:+UseJVMCICompiler", "-Dgraal.ExitVMOnException=true", @@ -109,6 +111,7 @@ */ @Test public void testVMCompilation3() throws IOException, InterruptedException { + assumeManagementLibraryIsLoadable(); final int maxProblems = 2; Probe retryingProbe = new Probe("Retrying compilation of", maxProblems) { @Override @@ -146,6 +149,7 @@ */ @Test public void testTruffleCompilation1() throws IOException, InterruptedException { + assumeManagementLibraryIsLoadable(); testHelper(Collections.emptyList(), Arrays.asList( "-Dgraal.CompilationFailureAction=ExitVM", @@ -175,6 +179,7 @@ */ @Test public void testTruffleCompilation3() throws IOException, InterruptedException { + assumeManagementLibraryIsLoadable(); Probe[] probes = { new Probe("Exiting VM due to TrufflePerformanceWarningsAreFatal=true", 1), };
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ConstantPoolSubstitutionsTests.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ConstantPoolSubstitutionsTests.java Thu Nov 15 09:04:07 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -76,7 +76,7 @@ private static Object getConstantPoolForObject() { String miscPackage = Java8OrEarlier ? "sun.misc" - : (Java11OrEarlier ? "jdk.internal.misc" : "jdk.internal.access"); + : (Java11OrEarlier ? "jdk.internal.misc" : "jdk.internal.access"); try { Class<?> sharedSecretsClass = Class.forName(miscPackage + ".SharedSecrets"); Class<?> javaLangAccessClass = Class.forName(miscPackage + ".JavaLangAccess"); @@ -115,10 +115,11 @@ Object javaBaseModule = JLModule.fromClass(String.class); Object cModule = JLModule.fromClass(c); uncheckedAddExports(javaBaseModule, "jdk.internal.reflect", cModule); - if (Java11OrEarlier) + if (Java11OrEarlier) { uncheckedAddExports(javaBaseModule, "jdk.internal.misc", cModule); - else + } else { uncheckedAddExports(javaBaseModule, "jdk.internal.access", cModule); + } } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/DataPatchTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/DataPatchTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -28,7 +28,7 @@ import org.graalvm.compiler.core.common.CompressEncoding; import org.graalvm.compiler.hotspot.nodes.HotSpotCompressionNode; import org.graalvm.compiler.nodes.ValueNode; -import org.graalvm.compiler.nodes.debug.OpaqueNode; +import org.graalvm.compiler.nodes.extended.OpaqueNode; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -60,6 +60,7 @@ @BeforeClass public static void checkVMArguments() { + assumeManagementLibraryIsLoadable(); /* * Note: The -Xcomp execution mode of the VM will stop most of the OSR test cases from * working as every method is compiled at level3 (followed by level4 on the second
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalCompilerTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalCompilerTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -28,7 +28,6 @@ import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.core.test.GraalCompilerTest; import org.graalvm.compiler.hotspot.HotSpotBackend; -import org.graalvm.compiler.hotspot.HotSpotGraalCompiler; import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; import org.graalvm.compiler.nodes.StructuredGraph; @@ -37,7 +36,6 @@ import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.runtime.JVMCI; /** * A Graal compiler test that needs access to the {@link HotSpotGraalRuntimeProvider}. @@ -53,12 +51,11 @@ protected InstalledCode compileAndInstallSubstitution(Class<?> c, String methodName) { ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(getMethod(c, methodName)); - HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) JVMCI.getRuntime().getCompiler(); HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class); HotSpotProviders providers = rt.getHostBackend().getProviders(); CompilationIdentifier compilationId = runtime().getHostBackend().getCompilationIdentifier(method); OptionValues options = getInitialOptions(); - StructuredGraph graph = compiler.getIntrinsicGraph(method, providers, compilationId, options, getDebugContext(options)); + StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, compilationId, getDebugContext(options)); if (graph != null) { return getCode(method, graph, true, true, graph.getOptions()); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalManagementTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalManagementTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -73,8 +73,10 @@ public HotSpotGraalManagementTest() { try { + /* Trigger loading of the management library using the bootstrap class loader. */ + ManagementFactory.getThreadMXBean(); MBeanServerFactory.findMBeanServer(null); - } catch (NoClassDefFoundError e) { + } catch (UnsatisfiedLinkError | NoClassDefFoundError e) { throw new AssumptionViolatedException("Management classes/module(s) not available: " + e); } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotStackIntrospectionTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotStackIntrospectionTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -26,8 +26,6 @@ import java.util.function.Function; -import org.graalvm.compiler.test.GraalTest; -import org.junit.Assume; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; @@ -80,15 +78,11 @@ @Test public void run() throws InvalidInstalledCodeException { - // The JDK9 bits are currently broken - Assume.assumeTrue(GraalTest.Java8OrEarlier); test("testSnippet"); } @Test public void runSynchronized() throws InvalidInstalledCodeException { - // The JDK9 bits are currently broken - Assume.assumeTrue(GraalTest.Java8OrEarlier); test("testSynchronizedSnippet"); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/JVMCIInfopointErrorTest.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/JVMCIInfopointErrorTest.java Thu Nov 15 09:04:07 2018 -0800 @@ -148,7 +148,7 @@ CompilationResult compResult = compile(method, graph); CodeCacheProvider codeCache = getCodeCache(); - HotSpotCompiledCode compiledCode = HotSpotCompiledCodeBuilder.createCompiledCode(codeCache, method, null, compResult); + HotSpotCompiledCode compiledCode = HotSpotCompiledCodeBuilder.createCompiledCode(codeCache, method, null, compResult, getInitialOptions()); codeCache.addCode(method, compiledCode, null, null); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java Thu Nov 15 09:04:07 2018 -0800 @@ -32,7 +32,6 @@ import org.graalvm.compiler.api.test.Graal; import org.graalvm.compiler.core.test.GraalCompilerTest; import org.graalvm.compiler.debug.DebugContext; -import org.graalvm.compiler.hotspot.HotSpotGraalCompiler; import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; import org.graalvm.compiler.nodes.StructuredGraph; @@ -48,7 +47,6 @@ import jdk.vm.ci.hotspot.HotSpotVMConfigStore; import jdk.vm.ci.hotspot.VMIntrinsicMethod; import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.runtime.JVMCI; /** * Exercise the compilation of intrinsic method substitutions. @@ -58,7 +56,6 @@ @Test @SuppressWarnings("try") public void test() throws ClassNotFoundException { - HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) JVMCI.getRuntime().getCompiler(); HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class); HotSpotProviders providers = rt.getHostBackend().getProviders(); Plugins graphBuilderPlugins = providers.getGraphBuilderPlugins(); @@ -75,7 +72,7 @@ if (plugin instanceof MethodSubstitutionPlugin) { ResolvedJavaMethod method = CheckGraalIntrinsics.resolveIntrinsic(getMetaAccess(), intrinsic); if (!method.isNative()) { - StructuredGraph graph = compiler.getIntrinsicGraph(method, providers, INVALID_COMPILATION_ID, options, debug); + StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, INVALID_COMPILATION_ID, debug); getCode(method, graph); } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationStatistics.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationStatistics.java Thu Nov 15 09:04:07 2018 -0800 @@ -24,8 +24,6 @@ package org.graalvm.compiler.hotspot; -import static java.lang.Thread.currentThread; - import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream; @@ -37,7 +35,6 @@ import java.lang.reflect.Modifier; import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Arrays; import java.util.Date; import java.util.Deque; import java.util.Locale;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java Thu Nov 15 09:04:07 2018 -0800 @@ -31,6 +31,7 @@ import static org.graalvm.compiler.core.phases.HighTier.Options.Inline; import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing; +import java.io.PrintStream; import java.util.List; import jdk.internal.vm.compiler.collections.EconomicMap; @@ -105,9 +106,9 @@ } @Override - protected DebugContext createRetryDebugContext(OptionValues retryOptions) { + protected DebugContext createRetryDebugContext(OptionValues retryOptions, PrintStream logStream) { SnippetReflectionProvider snippetReflection = compiler.getGraalRuntime().getHostProviders().getSnippetReflection(); - return DebugContext.create(retryOptions, new GraalDebugHandlersFactory(snippetReflection)); + return DebugContext.create(retryOptions, logStream, new GraalDebugHandlersFactory(snippetReflection)); } @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Thu Nov 15 09:04:07 2018 -0800 @@ -652,11 +652,13 @@ public final long newInstanceAddress = getAddress("JVMCIRuntime::new_instance"); public final long newArrayAddress = getAddress("JVMCIRuntime::new_array"); public final long newMultiArrayAddress = getAddress("JVMCIRuntime::new_multi_array"); + public final long dynamicNewInstanceAddress = getAddress("JVMCIRuntime::dynamic_new_instance"); // Allocation stubs that return null when allocation fails public final long newInstanceOrNullAddress = getAddress("JVMCIRuntime::new_instance_or_null", 0L); public final long newArrayOrNullAddress = getAddress("JVMCIRuntime::new_array_or_null", 0L); public final long newMultiArrayOrNullAddress = getAddress("JVMCIRuntime::new_multi_array_or_null", 0L); + public final long dynamicNewInstanceOrNullAddress = getAddress("JVMCIRuntime::dynamic_new_instance_or_null", 0L); public boolean areNullAllocationStubsAvailable() { return newInstanceOrNullAddress != 0L; @@ -669,9 +671,11 @@ if (newInstanceOrNullAddress == 0L) { assert newArrayOrNullAddress == 0L; assert newMultiArrayOrNullAddress == 0L; + assert dynamicNewInstanceOrNullAddress == 0L; } else { assert newArrayOrNullAddress != 0L; assert newMultiArrayOrNullAddress != 0L; + assert dynamicNewInstanceOrNullAddress != 0L; } return true; }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigVersioned.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigVersioned.java Thu Nov 15 09:04:07 2018 -0800 @@ -34,7 +34,7 @@ * * Fields are grouped according to the most recent JBS issue showing why they are versioned. * - * JDK Version: 11+ + * JDK Version: 12+ */ final class GraalHotSpotVMConfigVersioned extends HotSpotVMConfigAccess { @@ -42,13 +42,8 @@ super(store); } - private boolean initInlineNotify() { - String syncKnobs = getFlag("SyncKnobs", String.class, ""); - return syncKnobs == null || !syncKnobs.contains("InlineNotify=0"); - } - - // JSK-8132287 - boolean inlineNotify = initInlineNotify(); + // JDK-8210848 + boolean inlineNotify = true; // JDK-8073583 boolean useCRC32CIntrinsics = getFlag("UseCRC32CIntrinsics", Boolean.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java Thu Nov 15 09:04:07 2018 -0800 @@ -441,9 +441,14 @@ } @Override - public CompiledCode createCompiledCode(ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compResult) { + public CompiledCode createCompiledCode(ResolvedJavaMethod method, + CompilationRequest compilationRequest, + CompilationResult compResult, + boolean isDefault, + OptionValues options) { + assert !isDefault || compResult.getName() == null : "a default nmethod should have a null name since it is associated with a Method*"; HotSpotCompilationRequest compRequest = compilationRequest instanceof HotSpotCompilationRequest ? (HotSpotCompilationRequest) compilationRequest : null; - return HotSpotCompiledCodeBuilder.createCompiledCode(getCodeCache(), method, compRequest, compResult); + return HotSpotCompiledCodeBuilder.createCompiledCode(getCodeCache(), method, compRequest, compResult, options); } @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java Thu Nov 15 09:04:07 2018 -0800 @@ -24,6 +24,7 @@ package org.graalvm.compiler.hotspot; +import static org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder.Options.ShowSubstitutionSourceInfo; import static org.graalvm.util.CollectionsUtil.anyMatch; import java.nio.ByteBuffer; @@ -33,10 +34,13 @@ import java.util.Comparator; import java.util.EnumMap; 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; import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.code.CompilationResult.CodeAnnotation; import org.graalvm.compiler.code.CompilationResult.CodeComment; @@ -45,6 +49,9 @@ import org.graalvm.compiler.code.SourceMapping; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.graph.NodeSourcePosition; +import org.graalvm.compiler.options.Option; +import org.graalvm.compiler.options.OptionKey; +import org.graalvm.compiler.options.OptionValues; import jdk.vm.ci.code.CodeCacheProvider; import jdk.vm.ci.code.DebugInfo; @@ -64,14 +71,20 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; public class HotSpotCompiledCodeBuilder { + public static class Options { + // @formatter:off + @Option(help = "Controls whether the source position information of snippets and method substitutions" + + " are exposed to HotSpot. Can be useful when profiling to get more precise position information.") + public static final OptionKey<Boolean> ShowSubstitutionSourceInfo = new OptionKey<>(false); + } - public static HotSpotCompiledCode createCompiledCode(CodeCacheProvider codeCache, ResolvedJavaMethod method, HotSpotCompilationRequest compRequest, CompilationResult compResult) { + public static HotSpotCompiledCode createCompiledCode(CodeCacheProvider codeCache, ResolvedJavaMethod method, HotSpotCompilationRequest compRequest, CompilationResult compResult, OptionValues options) { String name = compResult.getName(); byte[] targetCode = compResult.getTargetCode(); int targetCodeSize = compResult.getTargetCodeSize(); - Site[] sites = getSortedSites(codeCache, compResult); + Site[] sites = getSortedSites(compResult, options, codeCache.shouldDebugNonSafepoints() && method != null); Assumption[] assumptions = compResult.getAssumptions(); @@ -205,7 +218,7 @@ * {@code DebugInformationRecorder::add_new_pc_offset}). In addition, it expects * {@link Infopoint} PCs to be unique. */ - private static Site[] getSortedSites(CodeCacheProvider codeCache, CompilationResult target) { + private static Site[] getSortedSites(CompilationResult target, OptionValues options, boolean includeSourceInfo) { List<Site> sites = new ArrayList<>( target.getExceptionHandlers().size() + target.getInfopoints().size() + target.getDataPatches().size() + target.getMarks().size() + target.getSourceMappings().size()); sites.addAll(target.getExceptionHandlers()); @@ -213,39 +226,89 @@ sites.addAll(target.getDataPatches()); sites.addAll(target.getMarks()); - if (codeCache.shouldDebugNonSafepoints()) { + if (includeSourceInfo) { /* * Translate the source mapping into appropriate info points. In HotSpot only one * position can really be represented and recording the end PC seems to give the best * results and corresponds with what C1 and C2 do. HotSpot doesn't like to see these * unless -XX:+DebugNonSafepoints is enabled, so don't emit them in that case. */ - List<Site> sourcePositionSites = new ArrayList<>(); - for (SourceMapping source : target.getSourceMappings()) { - NodeSourcePosition sourcePosition = source.getSourcePosition(); - if (sourcePosition.isPlaceholder() || sourcePosition.isSubstitution()) { - // HotSpot doesn't understand any of the special positions so just drop them. - continue; + + List<SourceMapping> sourceMappings = new ArrayList<>(); + ListIterator<SourceMapping> sourceMappingListIterator = target.getSourceMappings().listIterator(); + if (sourceMappingListIterator.hasNext()) { + SourceMapping currentSource = sourceMappingListIterator.next(); + NodeSourcePosition sourcePosition = currentSource.getSourcePosition(); + if (!sourcePosition.isPlaceholder() && !sourcePosition.isSubstitution()) { + sourceMappings.add(currentSource); } - assert sourcePosition.verify(); - sourcePosition = sourcePosition.trim(); - /* - * Don't add BYTECODE_POSITION info points that would potentially create conflicts. - * Under certain conditions the site's pc is not the pc that gets recorded by - * HotSpot (see @code {CodeInstaller::site_Call}). So, avoid adding any source - * positions that can potentially map to the same pc. To do that make sure that the - * source mapping doesn't contain a pc of any important Site. - */ - if (sourcePosition != null && !anyMatch(sites, s -> source.contains(s.pcOffset))) { - sourcePositionSites.add(new Infopoint(source.getEndOffset(), new DebugInfo(sourcePosition), InfopointReason.BYTECODE_POSITION)); - + while (sourceMappingListIterator.hasNext()) { + SourceMapping nextSource = sourceMappingListIterator.next(); + assert currentSource.getStartOffset() <= nextSource.getStartOffset() : "Must be presorted"; + currentSource = nextSource; + sourcePosition = currentSource.getSourcePosition(); + if (!sourcePosition.isPlaceholder() && !sourcePosition.isSubstitution()) { + sourceMappings.add(currentSource); + } } } + + /* + * Don't add BYTECODE_POSITION info points that would potentially create conflicts. + * Under certain conditions the site's pc is not the pc that gets recorded by HotSpot + * (see @code {CodeInstaller::site_Call}). So, avoid adding any source positions that + * can potentially map to the same pc. To do that the following code makes sure that the + * source mapping doesn't contain a pc of any important Site. + */ + sites.sort(new SiteComparator()); + + ListIterator<Site> siteListIterator = sites.listIterator(); + sourceMappingListIterator = sourceMappings.listIterator(); + + List<Site> sourcePositionSites = new ArrayList<>(); + Site site = null; + + // Iterate over sourceMappings and sites in parallel. Create source position infopoints + // only for source mappings that don't have any sites inside their intervals. + while (sourceMappingListIterator.hasNext()) { + SourceMapping source = sourceMappingListIterator.next(); + + // Skip sites before the current source mapping + if (site == null || site.pcOffset < source.getStartOffset()) { + while (siteListIterator.hasNext()) { + site = siteListIterator.next(); + if (site.pcOffset >= source.getStartOffset()) { + break; + } + } + } + assert !siteListIterator.hasNext() || site.pcOffset >= source.getStartOffset(); + if (site != null && source.getStartOffset() <= site.pcOffset && site.pcOffset <= source.getEndOffset()) { + // Conflicting source mapping, skip it. + continue; + } else { + // Since the sites are sorted there can not be any more sites in this interval. + } + assert !siteListIterator.hasNext() || site.pcOffset > source.getEndOffset(); + // Good source mapping. Create an infopoint and add it to the list. + NodeSourcePosition sourcePosition = source.getSourcePosition(); + assert sourcePosition.verify(); + if (!ShowSubstitutionSourceInfo.getValue(options)) { + sourcePosition = sourcePosition.trim(); + assert verifyTrim(sourcePosition); + } + if (sourcePosition != null) { + assert !anyMatch(sites, s -> source.getStartOffset() <= s.pcOffset && s.pcOffset <= source.getEndOffset()); + sourcePositionSites.add(new Infopoint(source.getEndOffset(), new DebugInfo(sourcePosition), InfopointReason.BYTECODE_POSITION)); + } + } + sites.addAll(sourcePositionSites); } SiteComparator c = new SiteComparator(); Collections.sort(sites, c); + if (c.sawCollidingInfopoints) { Infopoint lastInfopoint = null; List<Site> copy = new ArrayList<>(sites.size()); @@ -265,6 +328,14 @@ } sites = copy; } + return sites.toArray(new Site[sites.size()]); } + + private static boolean verifyTrim(NodeSourcePosition sourcePosition) { + for (NodeSourcePosition sp = sourcePosition; sp != null; sp = sp.getCaller()) { + assert (sp.getMethod().getAnnotation(Snippet.class) == null && sp.getMethod().getAnnotation(MethodSubstitution.class) == null); + } + return true; + } }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCounterOp.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCounterOp.java Thu Nov 15 09:04:07 2018 -0800 @@ -27,6 +27,8 @@ import static jdk.vm.ci.code.ValueUtil.isRegister; import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant; import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant; +import static org.graalvm.compiler.nodes.debug.DynamicCounterNode.MAX_INCREMENT; +import static org.graalvm.compiler.nodes.debug.DynamicCounterNode.MIN_INCREMENT; import java.util.Arrays; @@ -69,6 +71,21 @@ this.increments = increments; this.thread = registers.getThreadRegister(); this.config = config; + checkIncrements(); + } + + private boolean checkIncrements() { + for (int i = 0; i < increments.length; i++) { + Value increment = increments[i]; + if (isJavaConstant(increment)) { + long incValue = asLong(asJavaConstant(increment)); + if (incValue < MIN_INCREMENT || incValue > MAX_INCREMENT) { + String message = String.format("Benchmark counter %s:%s has increment out of range [%d .. %d]: %d", groups[i], names[i], MIN_INCREMENT, MAX_INCREMENT, incValue); + assert false : message; + } + } + } + return true; } protected static int getDisplacementForLongIndex(TargetDescription target, long index) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Thu Nov 15 09:04:07 2018 -0800 @@ -25,7 +25,6 @@ package org.graalvm.compiler.hotspot; import static org.graalvm.compiler.core.common.GraalOptions.OptAssumptions; -import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.ROOT_COMPILATION; import java.io.ByteArrayOutputStream; import java.io.PrintStream; @@ -35,8 +34,6 @@ import java.util.List; import org.graalvm.compiler.api.runtime.GraalJVMCICompiler; -import org.graalvm.compiler.bytecode.Bytecode; -import org.graalvm.compiler.bytecode.BytecodeProvider; import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.core.GraalCompiler; import org.graalvm.compiler.core.common.CompilationIdentifier; @@ -54,9 +51,6 @@ import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; 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.Replacements; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.OptimisticOptimizations; import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization; @@ -139,7 +133,7 @@ } CompilationTask task = new CompilationTask(jvmciRuntime, this, hsRequest, true, installAsDefault, options); CompilationRequestResult r = null; - try (DebugContext debug = graalRuntime.openDebugContext(options, task.getCompilationIdentifier(), method, getDebugHandlersFactories()); + try (DebugContext debug = graalRuntime.openDebugContext(options, task.getCompilationIdentifier(), method, getDebugHandlersFactories(), DebugContext.DEFAULT_LOG_STREAM); Activation a = debug.activate()) { r = task.runCompilation(debug); } @@ -152,7 +146,7 @@ HotSpotBackend backend = graalRuntime.getHostBackend(); HotSpotProviders providers = backend.getProviders(); final boolean isOSR = entryBCI != JVMCICompiler.INVOCATION_ENTRY_BCI; - StructuredGraph graph = method.isNative() || isOSR ? null : getIntrinsicGraph(method, providers, compilationId, options, debug); + StructuredGraph graph = method.isNative() || isOSR ? null : providers.getReplacements().getIntrinsicGraph(method, compilationId, debug); if (graph == null) { SpeculationLog speculationLog = method.getSpeculationLog(); @@ -204,47 +198,6 @@ return compileHelper(CompilationResultBuilderFactory.Default, result, graph, method, entryBCI, useProfilingInfo, options); } - /** - * Gets a graph produced from the intrinsic for a given method that can be compiled and - * installed for the method. - * - * @param method - * @param compilationId - * @param options - * @param debug - * @return an intrinsic graph that can be compiled and installed for {@code method} or null - */ - @SuppressWarnings("try") - public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, HotSpotProviders providers, CompilationIdentifier compilationId, OptionValues options, DebugContext debug) { - Replacements replacements = providers.getReplacements(); - Bytecode subst = replacements.getSubstitutionBytecode(method); - if (subst != null) { - ResolvedJavaMethod substMethod = subst.getMethod(); - assert !substMethod.equals(method); - BytecodeProvider bytecodeProvider = subst.getOrigin(); - // @formatter:off - StructuredGraph graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.YES). - method(substMethod). - compilationId(compilationId). - recordInlinedMethods(bytecodeProvider.shouldRecordMethodDependencies()). - setIsSubstitution(true). - build(); - // @formatter:on - try (DebugContext.Scope scope = debug.scope("GetIntrinsicGraph", graph)) { - Plugins plugins = new Plugins(providers.getGraphBuilderPlugins()); - GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins); - IntrinsicContext initialReplacementContext = new IntrinsicContext(method, substMethod, bytecodeProvider, ROOT_COMPILATION); - new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), providers.getConstantFieldProvider(), config, - OptimisticOptimizations.NONE, initialReplacementContext).apply(graph); - assert !graph.isFrozen(); - return graph; - } catch (Throwable e) { - debug.handle(e); - } - } - return null; - } - protected OptimisticOptimizations getOptimisticOpts(ProfilingInfo profilingInfo, OptionValues options) { return new OptimisticOptimizations(profilingInfo, options); }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java Thu Nov 15 09:04:07 2018 -0800 @@ -28,8 +28,8 @@ import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; import static org.graalvm.compiler.core.common.GraalOptions.HotSpotPrintInlining; -import static org.graalvm.compiler.debug.DebugContext.DEFAULT_LOG_STREAM; +import java.io.PrintStream; import java.util.ArrayList; import java.util.EnumMap; import java.util.List; @@ -276,7 +276,7 @@ } @Override - public DebugContext openDebugContext(OptionValues compilationOptions, CompilationIdentifier compilationId, Object compilable, Iterable<DebugHandlersFactory> factories) { + public DebugContext openDebugContext(OptionValues compilationOptions, CompilationIdentifier compilationId, Object compilable, Iterable<DebugHandlersFactory> factories, PrintStream logStream) { if (management != null && management.poll(false) != null) { if (compilable instanceof HotSpotResolvedJavaMethod) { HotSpotResolvedObjectType type = ((HotSpotResolvedJavaMethod) compilable).getDeclaringClass(); @@ -294,7 +294,7 @@ } } Description description = new Description(compilable, compilationId.toString(CompilationIdentifier.Verbosity.ID)); - return DebugContext.create(compilationOptions, description, metricValues, DEFAULT_LOG_STREAM, factories); + return DebugContext.create(compilationOptions, description, metricValues, logStream, factories); } @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntimeProvider.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntimeProvider.java Thu Nov 15 09:04:07 2018 -0800 @@ -24,6 +24,7 @@ package org.graalvm.compiler.hotspot; +import java.io.PrintStream; import java.util.Map; import org.graalvm.compiler.api.runtime.GraalRuntime; @@ -69,8 +70,9 @@ * @param compilationOptions the options used to configure the compilation debug context * @param compilationId a system wide unique compilation id * @param compilable the input to the compilation + * @param logStream the log stream to use in this context */ - DebugContext openDebugContext(OptionValues compilationOptions, CompilationIdentifier compilationId, Object compilable, Iterable<DebugHandlersFactory> factories); + DebugContext openDebugContext(OptionValues compilationOptions, CompilationIdentifier compilationId, Object compilable, Iterable<DebugHandlersFactory> factories, PrintStream logStream); /** * Gets the option values associated with this runtime.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java Thu Nov 15 09:04:07 2018 -0800 @@ -42,6 +42,7 @@ import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.printer.GraalDebugHandlersFactory; +import org.graalvm.compiler.word.Word; import jdk.vm.ci.code.CallingConvention; import jdk.vm.ci.common.InitTimer; @@ -50,7 +51,6 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.runtime.JVMCICompiler; -import org.graalvm.compiler.word.Word; /** * Common functionality of HotSpot host backends.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java Thu Nov 15 21:05:47 2018 +0100 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java Thu Nov 15 09:04:07 2018 -0800 @@ -75,7 +75,7 @@ */ public class BenchmarkCounters { - static class Options { + public static class Options { //@formatter:off @Option(help = "Turn on the benchmark counters, and displays the results on VM shutdown", type = OptionType.Debug) @@ -95,6 +95,8 @@ public static final OptionKey<Boolean> BenchmarkCountersDumpDynamic = new OptionKey<>(true); @Option(help = "Dump static counters", type = OptionType.Debug) public static final OptionKey<Boolean> BenchmarkCountersDumpStatic = new OptionKey<>(false); + @Option(help = "file:doc-files/AbortOnBenchmarkCounterOverflowHelp.txt", type = OptionType.Debug) + public static final OptionKey<Boolean> AbortOnBenchmarkCounterOverflow = new OptionKey<>(false); //@formatter:on }