--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMap.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMap.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicSet.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicSet.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Equivalence.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Equivalence.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/MapCursor.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/MapCursor.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Pair.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Pair.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicMap.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicMap.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicSet.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicSet.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableMapCursor.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableMapCursor.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/package-info.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/package-info.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/ComparableWord.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/ComparableWord.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/LocationIdentity.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/LocationIdentity.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/Pointer.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/Pointer.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/PointerBase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/PointerBase.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/SignedWord.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/SignedWord.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/UnsignedWord.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/UnsignedWord.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordBase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordBase.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordFactory.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordFactory.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/package-info.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/package-info.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/MethodSubstitution.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/MethodSubstitution.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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,9 +35,7 @@
/**
* Denotes a method whose body is used by a compiler as the substitute (or intrinsification) of
* another method. The exact mechanism used to do the substitution is compiler dependent but every
- * compiler should require substitute methods to be annotated with {@link MethodSubstitution}. In
- * addition, a compiler is recommended to implement {@link MethodSubstitutionRegistry} to advertise
- * the mechanism by which it supports registration of method substitutes.
+ * compiler should require substitute methods to be annotated with {@link MethodSubstitution}.
*
* A compiler may support partial intrinsification where only a part of a method is implemented by
* the compiler. The unsupported path is expressed by a call to either the original or substitute
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/MethodSubstitutionRegistry.java Thu Oct 31 14:23:06 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +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.api.replacements;
-
-import java.lang.reflect.Type;
-
-/**
- * A registry for {@link MethodSubstitution}s.
- */
-public interface MethodSubstitutionRegistry {
-
- /**
- * Gets the type representing the receiver (i.e., {@code this}) argument in a non-static method.
- */
- Class<?> getReceiverType();
-
- /**
- * Registers a substitution method.
- *
- * @param substituteDeclaringClass the class declaring the substitute method
- * @param name the name of both the original and substitute method
- * @param argumentTypes the argument types of the method. Element 0 of this array must be
- * {@link #getReceiverType()} iff the method is non-static. Upon returning, element 0
- * will have been rewritten to {@code declaringClass}.
- */
- default void registerMethodSubstitution(Class<?> substituteDeclaringClass, String name, Type... argumentTypes) {
- registerMethodSubstitution(substituteDeclaringClass, name, name, argumentTypes);
- }
-
- /**
- * Registers a substitution method.
- *
- * @param substituteDeclaringClass the class declaring the substitute method
- * @param name the name of both the original method
- * @param substituteName the name of the substitute method
- * @param argumentTypes the argument types of the method. Element 0 of this array must be
- * {@link #getReceiverType()} iff the method is non-static. Upon returning, element 0
- * will have been rewritten to {@code declaringClass}.
- */
- void registerMethodSubstitution(Class<?> substituteDeclaringClass, String name, String substituteName, Type... argumentTypes);
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.test/src/org/graalvm/compiler/api/test/ExportingClassLoader.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, 2019, 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.api.test;
+
+/**
+ * A class loader that exports all packages in the module defining the class loader to all classes
+ * in the unnamed module associated with the loader.
+ */
+public class ExportingClassLoader extends ClassLoader {
+ public ExportingClassLoader() {
+ ModuleSupport.exportAllPackagesTo(getClass(), this);
+ }
+
+ public ExportingClassLoader(ClassLoader parent) {
+ super(parent);
+ ModuleSupport.exportAllPackagesTo(getClass(), this);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.test/src/org/graalvm/compiler/api/test/ModuleSupport.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2019, 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.api.test;
+
+import java.io.IOException;
+import java.lang.module.ModuleDescriptor.Requires;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.graalvm.compiler.debug.DebugOptions;
+
+import jdk.internal.module.Modules;
+
+public class ModuleSupport {
+
+ public static void exportPackageTo(Class<?> moduleMember, String packageName, Class<?> requestor) {
+ Module moduleToExport = moduleMember.getModule();
+ Module requestorModule = requestor.getModule();
+ if (moduleToExport != requestorModule) {
+ Modules.addExports(moduleToExport, packageName, requestorModule);
+ }
+ }
+
+ public static void exportAllPackagesTo(Class<?> moduleMember, Class<?> requestor) {
+ Module moduleToExport = moduleMember.getModule();
+ Module requestorModule = requestor.getModule();
+ if (moduleToExport != requestorModule) {
+ for (String packageName : moduleToExport.getPackages()) {
+ Modules.addExports(moduleToExport, packageName, requestorModule);
+ }
+ }
+ }
+
+ public static void exportAllPackagesTo(Class<?> moduleMember, ClassLoader cl) {
+ Module moduleToExport = moduleMember.getModule();
+ Module unnamedModule = cl.getUnnamedModule();
+ for (String packageName : moduleToExport.getPackages()) {
+ Modules.addExports(moduleToExport, packageName, unnamedModule);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public static void exportAndOpenAllPackagesToUnnamed(String name) {
+ Module module = ModuleLayer.boot().findModule(name).orElseThrow();
+ Set<String> packages = module.getPackages();
+ for (String pkg : packages) {
+ Modules.addExportsToAllUnnamed(module, pkg);
+ Modules.addOpensToAllUnnamed(module, pkg);
+ }
+ }
+
+ public static List<String> getJRTGraalClassNames() throws IOException {
+ List<String> classNames = new ArrayList<>();
+ FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), Collections.emptyMap());
+ Module graalModule = DebugOptions.class.getModule();
+ Set<String> graalModuleSet = new HashSet<>();
+ graalModuleSet.add(graalModule.getName());
+ for (Module module : graalModule.getLayer().modules()) {
+ if (requires(module, graalModule)) {
+ graalModuleSet.add(module.getName());
+ }
+ }
+
+ Path top = fs.getPath("/modules/");
+ Files.find(top, Integer.MAX_VALUE,
+ (path, attrs) -> attrs.isRegularFile()).forEach(p -> {
+ int nameCount = p.getNameCount();
+ if (nameCount > 2) {
+ String base = p.getName(nameCount - 1).toString();
+ if (base.endsWith(".class") && !base.equals("module-info.class")) {
+ String module = p.getName(1).toString();
+ if (graalModuleSet.contains(module)) {
+ // Strip module prefix and convert to dotted
+ // form
+ String className = p.subpath(2, nameCount).toString().replace('/', '.');
+ // Strip ".class" suffix
+ className = className.replace('/', '.').substring(0, className.length() - ".class".length());
+ classNames.add(className);
+ }
+ }
+ }
+ });
+ return classNames;
+ }
+
+ private static boolean requires(Module module, Module graalModule) {
+ ModuleLayer graalLayer = graalModule.getLayer();
+ for (Requires r : module.getDescriptor().requires()) {
+ if (r.name().equals(graalModule.getName())) {
+ return true;
+ }
+ Module dep = graalLayer.findModule(r.name()).get();
+ if (requires(dep, graalModule)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java Thu Oct 31 16:54:16 2019 -0700
@@ -471,6 +471,7 @@
private static final int AddSubExtendedOp = 0x0B200000;
private static final int MulOp = 0x1B000000;
+ private static final int SignedMulLongOp = 0x9B200000;
private static final int DataProcessing1SourceOp = 0x5AC00000;
private static final int DataProcessing2SourceOp = 0x1AC00000;
@@ -2313,7 +2314,7 @@
}
/**
- * unsigned multiply high. dst = (src1 * src2)[127:64]
+ * Unsigned multiply high. dst = (src1 * src2)[127:64]
*
* @param dst general purpose register. May not be null or the stackpointer.
* @param src1 general purpose register. May not be null or the stackpointer.
@@ -2327,7 +2328,7 @@
}
/**
- * unsigned multiply add-long. xDst = xSrc3 + (wSrc1 * wSrc2)
+ * Unsigned multiply add-long. xDst = xSrc3 + (wSrc1 * wSrc2)
*
* @param dst general purpose register. May not be null or the stackpointer.
* @param src1 general purpose register. May not be null or the stackpointer.
@@ -2343,7 +2344,7 @@
}
/**
- * signed multiply add-long. xDst = xSrc3 + (wSrc1 * wSrc2)
+ * Signed multiply-add long. xDst = xSrc3 + (wSrc1 * wSrc2)
*
* @param dst general purpose register. May not be null or the stackpointer.
* @param src1 general purpose register. May not be null or the stackpointer.
@@ -2351,11 +2352,19 @@
* @param src3 general purpose register. May not be null or the stackpointer.
*/
public void smaddl(Register dst, Register src1, Register src2, Register src3) {
- assert !dst.equals(sp);
- assert !src1.equals(sp);
- assert !src2.equals(sp);
- assert !src3.equals(sp);
- emitInt(0b10011011001 << 21 | dst.encoding | rs1(src1) | rs2(src2) | rs3(src3));
+ smullInstruction(MADD, dst, src1, src2, src3);
+ }
+
+ /**
+ * Signed multiply-sub long. xDst = xSrc3 - (wSrc1 * wSrc2)
+ *
+ * @param dst general purpose register. May not be null or the stackpointer.
+ * @param src1 general purpose register. May not be null or the stackpointer.
+ * @param src2 general purpose register. May not be null or the stackpointer.
+ * @param src3 general purpose register. May not be null or the stackpointer.
+ */
+ public void smsubl(Register dst, Register src1, Register src2, Register src3) {
+ smullInstruction(MSUB, dst, src1, src2, src3);
}
private void mulInstruction(Instruction instr, Register dst, Register src1, Register src2, Register src3, InstructionType type) {
@@ -2366,6 +2375,14 @@
emitInt(type.encoding | instr.encoding | MulOp | rd(dst) | rs1(src1) | rs2(src2) | rs3(src3));
}
+ private void smullInstruction(Instruction instr, Register dst, Register src1, Register src2, Register src3) {
+ assert !dst.equals(sp);
+ assert !src1.equals(sp);
+ assert !src2.equals(sp);
+ assert !src3.equals(sp);
+ emitInt(instr.encoding | SignedMulLongOp | rd(dst) | rs1(src1) | rs2(src2) | rs3(src3));
+ }
+
/**
* Signed divide. dst = src1 / src2.
*
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java Thu Oct 31 16:54:16 2019 -0700
@@ -817,7 +817,7 @@
}
/**
- * unsigned multiply high. dst = (src1 * src2) >> size
+ * Unsigned multiply high. dst = (src1 * src2) >> size
*
* @param size register size. Has to be 32 or 64.
* @param dst general purpose register. May not be null or the stackpointer.
@@ -838,7 +838,7 @@
}
/**
- * signed multiply high. dst = (src1 * src2) >> size
+ * Signed multiply high. dst = (src1 * src2) >> size
*
* @param size register size. Has to be 32 or 64.
* @param dst general purpose register. May not be null or the stackpointer.
@@ -859,6 +859,60 @@
}
/**
+ * Signed multiply long. xDst = wSrc1 * wSrc2
+ *
+ * @param size destination register size. Has to be 64.
+ * @param dst 64-bit general purpose register. May not be null or the stackpointer.
+ * @param src1 32-bit general purpose register. May not be null or the stackpointer.
+ * @param src2 32-bit general purpose register. May not be null or the stackpointer.
+ */
+ public void smull(int size, Register dst, Register src1, Register src2) {
+ this.smaddl(size, dst, src1, src2, zr);
+ }
+
+ /**
+ * Signed multiply-negate long. xDst = -(wSrc1 * wSrc2)
+ *
+ * @param size destination register size. Has to be 64.
+ * @param dst 64-bit general purpose register. May not be null or the stackpointer.
+ * @param src1 32-bit general purpose register. May not be null or the stackpointer.
+ * @param src2 32-bit general purpose register. May not be null or the stackpointer.
+ */
+ public void smnegl(int size, Register dst, Register src1, Register src2) {
+ this.smsubl(size, dst, src1, src2, zr);
+ }
+
+ /**
+ * Signed multiply-add long. xDst = xSrc3 + (wSrc1 * wSrc2)
+ *
+ * @param size destination register size. Has to be 64.
+ * @param dst 64-bit general purpose register. May not be null or the stackpointer.
+ * @param src1 32-bit general purpose register. May not be null or the stackpointer.
+ * @param src2 32-bit general purpose register. May not be null or the stackpointer.
+ * @param src3 64-bit general purpose register. May not be null or the stackpointer.
+ */
+ public void smaddl(int size, Register dst, Register src1, Register src2, Register src3) {
+ assert (!dst.equals(sp) && !src1.equals(sp) && !src2.equals(sp) && !src3.equals(sp));
+ assert size == 64;
+ super.smaddl(dst, src1, src2, src3);
+ }
+
+ /**
+ * Signed multiply-sub long. xDst = xSrc3 - (wSrc1 * wSrc2)
+ *
+ * @param size destination register size. Has to be 64.
+ * @param dst 64-bit general purpose register. May not be null or the stackpointer.
+ * @param src1 32-bit general purpose register. May not be null or the stackpointer.
+ * @param src2 32-bit general purpose register. May not be null or the stackpointer.
+ * @param src3 64-bit general purpose register. May not be null or the stackpointer.
+ */
+ public void smsubl(int size, Register dst, Register src1, Register src2, Register src3) {
+ assert (!dst.equals(sp) && !src1.equals(sp) && !src2.equals(sp) && !src3.equals(sp));
+ assert size == 64;
+ super.smsubl(dst, src1, src2, src3);
+ }
+
+ /**
* dst = src1 % src2. Signed.
*
* @param size register size. Has to be 32 or 64.
--- /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/AArch64MultiplyLongTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Arm Limited. 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.junit.Test;
+
+public class AArch64MultiplyLongTest extends AArch64MatchRuleTest {
+
+ public long signedMulLong(int a, int b) {
+ return a * (long) b;
+ }
+
+ public long signedMulLongFromShort(short a, short b) {
+ return (long) a * b;
+ }
+
+ public long signedMulLongFromChar(char a, char b) {
+ return a * (long) b;
+ }
+
+ public long signedMulLongFromByte(byte a, byte b) {
+ return (long) a * b;
+ }
+
+ @Test
+ public void testSignedMulLong() {
+ test("signedMulLong", 0x12345678, 0x87654321);
+ checkLIR("signedMulLong", op -> op.name().equals("SMULL"), 1);
+ test("signedMulLongFromShort", (short) 32767, (short) -32768);
+ checkLIR("signedMulLongFromShort", op -> op.name().equals("SMULL"), 1);
+ test("signedMulLongFromChar", (char) 59999, (char) 65535);
+ checkLIR("signedMulLongFromChar", op -> op.name().equals("SMULL"), 1);
+ test("signedMulLongFromByte", (byte) 10, (byte) -256);
+ checkLIR("signedMulLongFromByte", op -> op.name().equals("SMULL"), 1);
+ }
+
+ public long signedMNegLong1(int a, int b) {
+ return -(a * (long) b);
+ }
+
+ public long signedMNegLong2(int a, int b) {
+ return a * (-(long) b);
+ }
+
+ @Test
+ public void testSignedMNegLong() {
+ test("signedMNegLong1", 0x89abcdef, 0xfedcba98);
+ checkLIR("signedMNegLong1", op -> op.name().equals("SMNEGL"), 1);
+ test("signedMNegLong2", 0x89abcdef, 0xfedcba98);
+ checkLIR("signedMNegLong2", op -> op.name().equals("SMNEGL"), 1);
+ }
+
+ public long signedMAddLong1(int a, int b, long c) {
+ return c + a * (long) b;
+ }
+
+ public long signedMAddLong2(int a, int b, long c) {
+ return a * (long) b + c;
+ }
+
+ @Test
+ public void testSignedMAddLong() {
+ test("signedMAddLong1", 0x22228888, 0xaaaacccc, 0x123456789abcdL);
+ checkLIR("signedMAddLong1", op -> op.name().equals("SMADDL"), 1);
+ test("signedMAddLong2", 0x22228888, 0xaaaacccc, 0x123456789abcdL);
+ checkLIR("signedMAddLong2", op -> op.name().equals("SMADDL"), 1);
+ }
+
+ public long signedMSubLong(int a, int b, long c) {
+ return c - a * (long) b;
+ }
+
+ @Test
+ public void testSignedMSubLong() {
+ test("signedMSubLong", 0x99995555, 0xeeeebbbb, 0x3456789abcdefL);
+ checkLIR("signedMSubLong", op -> op.name().equals("SMSUBL"), 1);
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java Thu Oct 31 16:54:16 2019 -0700
@@ -220,23 +220,34 @@
return result;
}
- public Value emitMAdd(Value a, Value b, Value c) {
- return emitMultiplyAddSub(AArch64ArithmeticOp.ADD, a, b, c);
+ Value emitIntegerMAdd(Value a, Value b, Value c, boolean isI2L) {
+ return emitMultiplyAddSub(isI2L ? AArch64ArithmeticOp.SMADDL : AArch64ArithmeticOp.MADD, a, b, c);
}
- public Value emitMSub(Value a, Value b, Value c) {
- return emitMultiplyAddSub(AArch64ArithmeticOp.SUB, a, b, c);
+ Value emitIntegerMSub(Value a, Value b, Value c, boolean isI2L) {
+ return emitMultiplyAddSub(isI2L ? AArch64ArithmeticOp.SMSUBL : AArch64ArithmeticOp.MSUB, a, b, c);
}
private Value emitMultiplyAddSub(AArch64ArithmeticOp op, Value a, Value b, Value c) {
- assert a.getPlatformKind() == b.getPlatformKind() && b.getPlatformKind() == c.getPlatformKind();
- if (op == AArch64ArithmeticOp.ADD || op == AArch64ArithmeticOp.SUB) {
- assert isNumericInteger(a.getPlatformKind());
- } else if (op == AArch64ArithmeticOp.FADD) {
- assert a.getPlatformKind() == AArch64Kind.SINGLE || a.getPlatformKind() == AArch64Kind.DOUBLE;
+ assert a.getPlatformKind() == b.getPlatformKind();
+ Variable result;
+ if (op == AArch64ArithmeticOp.SMADDL || op == AArch64ArithmeticOp.SMSUBL) {
+ // For signed multiply int and then add/sub long.
+ assert a.getPlatformKind() != c.getPlatformKind();
+ result = getLIRGen().newVariable(LIRKind.combine(c));
+ } else {
+ assert a.getPlatformKind() == c.getPlatformKind();
+ if (op == AArch64ArithmeticOp.FADD) {
+ // For floating-point Math.fma intrinsic.
+ assert a.getPlatformKind() == AArch64Kind.SINGLE || a.getPlatformKind() == AArch64Kind.DOUBLE;
+ } else {
+ // For int/long multiply add or sub.
+ assert op == AArch64ArithmeticOp.MADD || op == AArch64ArithmeticOp.MSUB;
+ assert isNumericInteger(a.getPlatformKind());
+ }
+ result = getLIRGen().newVariable(LIRKind.combine(a, b, c));
}
- Variable result = getLIRGen().newVariable(LIRKind.combine(a, b, c));
AllocatableValue x = moveSp(asAllocatable(a));
AllocatableValue y = moveSp(asAllocatable(b));
AllocatableValue z = moveSp(asAllocatable(c));
@@ -451,7 +462,7 @@
@Override
public Value emitFusedMultiplyAdd(Value a, Value b, Value c) {
- return emitMultiplyAddSub(AArch64ArithmeticOp.FADD, a, b, c);
+ return emitMultiplyAddSub(AArch64ArithmeticOp.FMADD, a, b, c);
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java Thu Oct 31 16:54:16 2019 -0700
@@ -57,6 +57,7 @@
import org.graalvm.compiler.nodes.calc.BinaryNode;
import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
import org.graalvm.compiler.nodes.calc.LeftShiftNode;
+import org.graalvm.compiler.nodes.calc.MulNode;
import org.graalvm.compiler.nodes.calc.NotNode;
import org.graalvm.compiler.nodes.calc.OrNode;
import org.graalvm.compiler.nodes.calc.RightShiftNode;
@@ -224,6 +225,33 @@
return emitBinaryShift(op, a, shift, isShiftNot);
}
+ @MatchRule("(Add=binary (Mul (SignExtend a) (SignExtend b)) c)")
+ @MatchRule("(Sub=binary c (Mul (SignExtend a) (SignExtend b)))")
+ public ComplexMatchResult signedMultiplyAddSubLong(BinaryNode binary, ValueNode a, ValueNode b, ValueNode c) {
+ assert a.getStackKind() == JavaKind.Int && b.getStackKind() == JavaKind.Int && c.getStackKind() == JavaKind.Long;
+ if (binary instanceof AddNode) {
+ return builder -> getArithmeticLIRGenerator().emitIntegerMAdd(operand(a), operand(b), operand(c), true);
+ }
+ return builder -> getArithmeticLIRGenerator().emitIntegerMSub(operand(a), operand(b), operand(c), true);
+ }
+
+ @MatchRule("(Negate (Mul=mul (SignExtend a) (SignExtend b)))")
+ @MatchRule("(Mul=mul (Negate (SignExtend a)) (SignExtend b))")
+ public ComplexMatchResult signedMultiplyNegLong(MulNode mul, ValueNode a, ValueNode b) {
+ assert a.getStackKind() == JavaKind.Int && b.getStackKind() == JavaKind.Int;
+ LIRKind resultKind = LIRKind.fromJavaKind(gen.target().arch, mul.getStackKind());
+ return builder -> getArithmeticLIRGenerator().emitBinary(
+ resultKind, AArch64ArithmeticOp.SMNEGL, true, operand(a), operand(b));
+ }
+
+ @MatchRule("(Mul=mul (SignExtend a) (SignExtend b))")
+ public ComplexMatchResult signedMultiplyLong(MulNode mul, ValueNode a, ValueNode b) {
+ assert a.getStackKind() == JavaKind.Int && b.getStackKind() == JavaKind.Int;
+ LIRKind resultKind = LIRKind.fromJavaKind(gen.target().arch, mul.getStackKind());
+ return builder -> getArithmeticLIRGenerator().emitBinary(
+ resultKind, AArch64ArithmeticOp.SMULL, true, operand(a), operand(b));
+ }
+
@MatchRule("(Mul (Negate a) b)")
@MatchRule("(Negate (Mul a b))")
public ComplexMatchResult multiplyNegate(ValueNode a, ValueNode b) {
@@ -244,9 +272,9 @@
}
if (binary instanceof AddNode) {
- return builder -> getArithmeticLIRGenerator().emitMAdd(operand(a), operand(b), operand(c));
+ return builder -> getArithmeticLIRGenerator().emitIntegerMAdd(operand(a), operand(b), operand(c), false);
}
- return builder -> getArithmeticLIRGenerator().emitMSub(operand(a), operand(b), operand(c));
+ return builder -> getArithmeticLIRGenerator().emitIntegerMSub(operand(a), operand(b), operand(c), false);
}
/**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java Thu Oct 31 16:54:16 2019 -0700
@@ -359,6 +359,7 @@
@MatchRule("(If (IntegerTest Read=access value))")
@MatchRule("(If (IntegerTest FloatingRead=access value))")
+ @MatchRule("(If (IntegerTest VolatileRead=access value))")
public ComplexMatchResult integerTestBranchMemory(IfNode root, LIRLowerableAccess access, ValueNode value) {
return emitIntegerTestBranchMemory(root, value, access);
}
@@ -369,14 +370,21 @@
@MatchRule("(If (IntegerEquals=compare value FloatingRead=access))")
@MatchRule("(If (IntegerLessThan=compare value FloatingRead=access))")
@MatchRule("(If (IntegerBelow=compare value FloatingRead=access))")
+ @MatchRule("(If (IntegerEquals=compare value VolatileRead=access))")
+ @MatchRule("(If (IntegerLessThan=compare value VolatileRead=access))")
+ @MatchRule("(If (IntegerBelow=compare value VolatileRead=access))")
@MatchRule("(If (FloatEquals=compare value Read=access))")
@MatchRule("(If (FloatEquals=compare value FloatingRead=access))")
+ @MatchRule("(If (FloatEquals=compare value VolatileRead=access))")
@MatchRule("(If (FloatLessThan=compare value Read=access))")
@MatchRule("(If (FloatLessThan=compare value FloatingRead=access))")
+ @MatchRule("(If (FloatLessThan=compare value VolatileRead=access))")
@MatchRule("(If (PointerEquals=compare value Read=access))")
@MatchRule("(If (PointerEquals=compare value FloatingRead=access))")
+ @MatchRule("(If (PointerEquals=compare value VolatileRead=access))")
@MatchRule("(If (ObjectEquals=compare value Read=access))")
@MatchRule("(If (ObjectEquals=compare value FloatingRead=access))")
+ @MatchRule("(If (ObjectEquals=compare value VolatileRead=access))")
public ComplexMatchResult ifCompareMemory(IfNode root, CompareNode compare, ValueNode value, LIRLowerableAccess access) {
return emitCompareBranchMemory(root, compare, value, access);
}
@@ -478,6 +486,7 @@
@MatchRule("(Add value Read=access)")
@MatchRule("(Add value FloatingRead=access)")
+ @MatchRule("(Add value VolatileRead=access)")
public ComplexMatchResult addMemory(ValueNode value, LIRLowerableAccess access) {
OperandSize size = getMemorySize(access);
if (size.isXmmType()) {
@@ -493,6 +502,7 @@
@MatchRule("(Sub value Read=access)")
@MatchRule("(Sub value FloatingRead=access)")
+ @MatchRule("(Sub value VolatileRead=access)")
public ComplexMatchResult subMemory(ValueNode value, LIRLowerableAccess access) {
OperandSize size = getMemorySize(access);
if (size.isXmmType()) {
@@ -508,6 +518,7 @@
@MatchRule("(Mul value Read=access)")
@MatchRule("(Mul value FloatingRead=access)")
+ @MatchRule("(Mul value VolatileRead=access)")
public ComplexMatchResult mulMemory(ValueNode value, LIRLowerableAccess access) {
OperandSize size = getMemorySize(access);
if (size.isXmmType()) {
@@ -523,6 +534,7 @@
@MatchRule("(And value Read=access)")
@MatchRule("(And value FloatingRead=access)")
+ @MatchRule("(And value VolatileRead=access)")
public ComplexMatchResult andMemory(ValueNode value, LIRLowerableAccess access) {
OperandSize size = getMemorySize(access);
if (size.isXmmType()) {
@@ -534,6 +546,7 @@
@MatchRule("(Or value Read=access)")
@MatchRule("(Or value FloatingRead=access)")
+ @MatchRule("(Or value VolatileRead=access)")
public ComplexMatchResult orMemory(ValueNode value, LIRLowerableAccess access) {
OperandSize size = getMemorySize(access);
if (size.isXmmType()) {
@@ -545,6 +558,7 @@
@MatchRule("(Xor value Read=access)")
@MatchRule("(Xor value FloatingRead=access)")
+ @MatchRule("(Xor value VolatileRead=access)")
public ComplexMatchResult xorMemory(ValueNode value, LIRLowerableAccess access) {
OperandSize size = getMemorySize(access);
if (size.isXmmType()) {
@@ -565,12 +579,14 @@
@MatchRule("(SignExtend Read=access)")
@MatchRule("(SignExtend FloatingRead=access)")
+ @MatchRule("(SignExtend VolatileRead=access)")
public ComplexMatchResult signExtend(SignExtendNode root, LIRLowerableAccess access) {
return emitSignExtendMemory(access, root.getInputBits(), root.getResultBits(), null);
}
@MatchRule("(ZeroExtend Read=access)")
@MatchRule("(ZeroExtend FloatingRead=access)")
+ @MatchRule("(ZeroExtend VolatileRead=access)")
public ComplexMatchResult zeroExtend(ZeroExtendNode root, LIRLowerableAccess access) {
AMD64Kind memoryKind = getMemoryKind(access);
return builder -> getArithmeticLIRGenerator().emitZeroExtendMemory(memoryKind, root.getResultBits(), (AMD64AddressValue) operand(access.getAddress()), getState(access));
@@ -578,6 +594,7 @@
@MatchRule("(Narrow Read=access)")
@MatchRule("(Narrow FloatingRead=access)")
+ @MatchRule("(Narrow VolatileRead=access)")
public ComplexMatchResult narrowRead(NarrowNode root, LIRLowerableAccess access) {
return new ComplexMatchResult() {
@Override
@@ -595,6 +612,7 @@
@MatchRule("(SignExtend (Narrow=narrow Read=access))")
@MatchRule("(SignExtend (Narrow=narrow FloatingRead=access))")
+ @MatchRule("(SignExtend (Narrow=narrow VolatileRead=access))")
public ComplexMatchResult signExtendNarrowRead(SignExtendNode root, NarrowNode narrow, LIRLowerableAccess access) {
LIRKind kind = getLIRGeneratorTool().getLIRKind(narrow.stamp(NodeView.DEFAULT));
return emitSignExtendMemory(access, narrow.getResultBits(), root.getResultBits(), kind);
@@ -602,6 +620,7 @@
@MatchRule("(FloatConvert Read=access)")
@MatchRule("(FloatConvert FloatingRead=access)")
+ @MatchRule("(FloatConvert VolatileRead=access)")
public ComplexMatchResult floatConvert(FloatConvertNode root, LIRLowerableAccess access) {
switch (root.getFloatConvert()) {
case D2F:
@@ -631,6 +650,7 @@
@MatchRule("(Reinterpret Read=access)")
@MatchRule("(Reinterpret FloatingRead=access)")
+ @MatchRule("(Reinterpret VolatileRead=access)")
public ComplexMatchResult reinterpret(ReinterpretNode root, LIRLowerableAccess access) {
return builder -> {
LIRKind kind = getLIRGeneratorTool().getLIRKind(root.stamp(NodeView.DEFAULT));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java Thu Oct 31 16:54:16 2019 -0700
@@ -115,7 +115,7 @@
public static final OptionKey<Boolean> PartialUnroll = new OptionKey<>(true);
@Option(help = "", type = OptionType.Expert)
- public static final OptionKey<Float> MinimumPeelProbability = new OptionKey<>(0.35f);
+ public static final OptionKey<Float> MinimumPeelFrequency = new OptionKey<>(0.35f);
@Option(help = "", type = OptionType.Expert)
public static final OptionKey<Integer> LoopMaxUnswitch = new OptionKey<>(3);
@@ -242,9 +242,6 @@
public static final OptionKey<Boolean> OptImplicitNullChecks = new OptionKey<>(true);
@Option(help = "", type = OptionType.Debug)
- public static final OptionKey<Boolean> OptLoopTransform = new OptionKey<>(true);
-
- @Option(help = "", type = OptionType.Debug)
public static final OptionKey<Boolean> OptFloatingReads = new OptionKey<>(true);
@Option(help = "", type = OptionType.Debug)
@@ -291,4 +288,7 @@
@Option(help = "Alignment in bytes for loop header blocks.", type = OptionType.Expert)
public static final OptionKey<Integer> LoopHeaderAlignment = new OptionKey<>(16);
+
+ @Option(help = "Do not include membars for volatile accesses until the end of optimizations.", type = OptionType.Expert)
+ public static final OptionKey<Boolean> LateMembars = new OptionKey<>(true);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/AbstractBlockBase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/AbstractBlockBase.java Thu Oct 31 16:54:16 2019 -0700
@@ -94,6 +94,38 @@
return dominator;
}
+ /**
+ * Returns the next dominator of this block that is either in the same loop of this block or in
+ * an outer loop.
+ *
+ * @return the next dominator while skipping over loops
+ */
+ public T getDominatorSkipLoops() {
+ T d = getDominator();
+
+ if (d == null) {
+ // We are at the start block and don't have a dominator.
+ return null;
+ }
+
+ if (isLoopHeader()) {
+ // We are moving out of current loop => just return dominator.
+ assert d.getLoopDepth() == getLoopDepth() - 1;
+ assert d.getLoop() != getLoop();
+ return d;
+ }
+
+ while (d.getLoop() != getLoop()) {
+ // We have a case where our dominator is in a different loop. Move further along
+ // the domiantor tree until we hit our loop again.
+ d = d.getDominator();
+ }
+
+ assert d.getLoopDepth() <= getLoopDepth();
+
+ return d;
+ }
+
public void setDominator(T dominator) {
this.dominator = dominator;
this.domDepth = dominator.domDepth + 1;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/AbstractControlFlowGraph.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/AbstractControlFlowGraph.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -46,7 +46,7 @@
T getStartBlock();
/**
- * True if block {@code a} is dominated by block {@code b}.
+ * True if block {@code a} is dominated by block {@code b} or {@code a} is equal to {@code b}.
*/
static boolean isDominatedBy(AbstractBlockBase<?> a, AbstractBlockBase<?> b) {
int domNumberA = a.getDominatorNumber();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/Loop.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/Loop.java Thu Oct 31 16:54:16 2019 -0700
@@ -177,25 +177,6 @@
return true;
}
- /**
- * Determines if one loop is a transitive parent of another loop.
- *
- * @param childLoop The loop for which parentLoop might be a transitive parent loop.
- * @param parentLoop The loop which might be a transitive parent loop of child loop.
- * @return {@code true} if parentLoop is a (transitive) parent loop of childLoop, {@code false}
- * otherwise
- */
- public static <T extends AbstractBlockBase<T>> boolean transitiveParentLoop(Loop<T> childLoop, Loop<T> parentLoop) {
- Loop<T> curr = childLoop;
- while (curr != null) {
- if (curr == parentLoop) {
- return true;
- }
- curr = curr.getParent();
- }
- return false;
- }
-
@Override
public int hashCode() {
return index + depth * 31;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java Thu Oct 31 16:54:16 2019 -0700
@@ -167,8 +167,15 @@
@Override
public Stamp constant(Constant c, MetaAccessProvider meta) {
if (c instanceof PrimitiveConstant) {
- long value = ((PrimitiveConstant) c).asLong();
- return StampFactory.forInteger(getBits(), value, value);
+ PrimitiveConstant primitiveConstant = (PrimitiveConstant) c;
+ long value = primitiveConstant.asLong();
+ if (primitiveConstant.getJavaKind() == JavaKind.Boolean && value == 1) {
+ // Need to special case booleans as integer stamps are always signed values.
+ value = -1;
+ }
+ Stamp returnedStamp = StampFactory.forInteger(getBits(), value, value);
+ assert returnedStamp.hasValues();
+ return returnedStamp;
}
return this;
}
@@ -1605,7 +1612,10 @@
long newUpMask = stamp.upMask() & defaultMask;
long newLowerBound = CodeUtil.signExtend((lowerBound | newDownMask) & newUpMask, resultBits);
long newUpperBound = CodeUtil.signExtend((upperBound | newDownMask) & newUpMask, resultBits);
- return new IntegerStamp(resultBits, newLowerBound, newUpperBound, newDownMask, newUpMask);
+
+ IntegerStamp result = new IntegerStamp(resultBits, newLowerBound, newUpperBound, newDownMask, newUpMask);
+ assert result.hasValues();
+ return result;
}
},
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCNodeMatchRules.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCNodeMatchRules.java Thu Oct 31 16:54:16 2019 -0700
@@ -134,12 +134,14 @@
@MatchRule("(SignExtend Read=access)")
@MatchRule("(SignExtend FloatingRead=access)")
+ @MatchRule("(SignExtend VolatileRead=access)")
public ComplexMatchResult signExtend(SignExtendNode root, Access access) {
return emitSignExtendMemory(access, root.getInputBits(), root.getResultBits());
}
@MatchRule("(ZeroExtend Read=access)")
@MatchRule("(ZeroExtend FloatingRead=access)")
+ @MatchRule("(ZeroExtend VolatileRead=access)")
public ComplexMatchResult zeroExtend(ZeroExtendNode root, Access access) {
return emitZeroExtendMemory(access, root.getInputBits(), root.getResultBits());
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/BoxingEliminationTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/BoxingEliminationTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -313,7 +313,7 @@
graph = parseEager(snippet, AllowAssumptions.NO);
HighTierContext context = getDefaultHighTierContext();
createInliningPhase().apply(graph, context);
- new PartialEscapePhase(false, new CanonicalizerPhase(), graph.getOptions()).apply(graph, context);
+ new PartialEscapePhase(false, createCanonicalizerPhase(), graph.getOptions()).apply(graph, context);
}
private void compareGraphs(final String snippet, final String referenceSnippet) {
@@ -323,7 +323,7 @@
private void compareGraphs(final String snippet, final String referenceSnippet, final boolean loopPeeling, final boolean excludeVirtual) {
graph = parseEager(snippet, AllowAssumptions.NO);
HighTierContext context = getDefaultHighTierContext();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = this.createCanonicalizerPhase();
canonicalizer.apply(graph, context);
createInliningPhase().apply(graph, context);
if (loopPeeling) {
@@ -339,7 +339,7 @@
StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.YES);
createInliningPhase().apply(referenceGraph, context);
new DeadCodeEliminationPhase().apply(referenceGraph);
- new CanonicalizerPhase().apply(referenceGraph, context);
+ this.createCanonicalizerPhase().apply(referenceGraph, context);
assertEquals(referenceGraph, graph, excludeVirtual, true);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Thu Oct 31 16:54:16 2019 -0700
@@ -78,7 +78,7 @@
import org.graalvm.compiler.runtime.RuntimeProvider;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.graalvm.compiler.test.AddExports;
-import org.graalvm.compiler.test.ModuleSupport;
+import org.graalvm.compiler.api.test.ModuleSupport;
import jdk.internal.vm.compiler.word.LocationIdentity;
import org.junit.Assert;
import org.junit.Assume;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -31,14 +31,13 @@
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.ConditionalNode;
import org.graalvm.compiler.nodes.calc.IntegerTestNode;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
public class CompareCanonicalizerTest extends GraalCompilerTest {
private StructuredGraph getCanonicalizedGraph(String name) {
StructuredGraph graph = parseEager(name, AllowAssumptions.YES);
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
return graph;
}
@@ -55,7 +54,7 @@
StructuredGraph graph = parseEager("canonicalCompare" + i, AllowAssumptions.NO);
assertEquals(referenceGraph, graph);
}
- new CanonicalizerPhase().apply(referenceGraph, getProviders());
+ createCanonicalizerPhase().apply(referenceGraph, getProviders());
for (int i = 1; i < 4; i++) {
StructuredGraph graph = getCanonicalizedGraph("canonicalCompare" + i);
assertEquals(referenceGraph, graph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest2.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest2.java Thu Oct 31 16:54:16 2019 -0700
@@ -26,7 +26,6 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
public class CompareCanonicalizerTest2 extends GraalCompilerTest {
@@ -35,7 +34,7 @@
private StructuredGraph getCanonicalizedGraph(String name) {
StructuredGraph graph = getRegularGraph(name);
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
return graph;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest3.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest3.java Thu Oct 31 16:54:16 2019 -0700
@@ -239,7 +239,7 @@
protected void assertCanonicallyEqual(String snippet, String reference) {
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
CoreProviders context = getProviders();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = this.createCanonicalizerPhase();
canonicalizer.apply(graph, context);
new GuardLoweringPhase().apply(graph, new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo()));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationMulTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationMulTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -78,7 +78,7 @@
StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
HighTierContext context = getDefaultHighTierContext();
new ConditionalEliminationPhase(false).apply(graph, context);
- CanonicalizerPhase c = new CanonicalizerPhase();
+ CanonicalizerPhase c = createCanonicalizerPhase();
c.apply(graph, context);
new ConditionalEliminationPhase(false).apply(graph, context);
c.apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest10.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest10.java Thu Oct 31 16:54:16 2019 -0700
@@ -30,7 +30,6 @@
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.ConditionalEliminationPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.junit.Assert;
@@ -95,7 +94,7 @@
private void test(String snippet, int guardCount) {
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
CoreProviders context = getProviders();
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+ new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
new ConditionalEliminationPhase(true).apply(graph, context);
Assert.assertEquals(guardCount, graph.getNodes().filter(GuardNode.class).count());
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest14.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest14.java Thu Oct 31 16:54:16 2019 -0700
@@ -70,7 +70,7 @@
@Test
public void test1() {
StructuredGraph graph = parseEager("test1Snippet", AllowAssumptions.YES);
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
CoreProviders context = getProviders();
/* Convert the LoadIndexNode to ReadNode with floating guards. */
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest15.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest15.java Thu Oct 31 16:54:16 2019 -0700
@@ -47,10 +47,10 @@
private void checkNodeCount(String methodName, Class<? extends Node> nodeClass, int count) {
StructuredGraph graph = parseEager(methodName, AllowAssumptions.YES);
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = this.createCanonicalizerPhase();
CoreProviders context = getProviders();
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+ new LoweringPhase(this.createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
canonicalizer.apply(graph, context);
// Merge arr.length reads.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest16.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest16.java Thu Oct 31 16:54:16 2019 -0700
@@ -31,7 +31,6 @@
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Before;
import org.junit.Test;
@@ -69,7 +68,7 @@
break;
}
}
- new CanonicalizerPhase().apply(graph, getDefaultHighTierContext());
+ this.createCanonicalizerPhase().apply(graph, getDefaultHighTierContext());
}
super.checkHighTierGraph(graph);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest2.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest2.java Thu Oct 31 16:54:16 2019 -0700
@@ -109,7 +109,7 @@
@Test
public void testRedundantCompares() {
StructuredGraph graph = parseEager("testRedundantComparesSnippet", AllowAssumptions.YES);
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
CoreProviders context = getProviders();
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
@@ -132,7 +132,7 @@
public void testInstanceOfCheckCastLowered() {
StructuredGraph graph = parseEager("testInstanceOfCheckCastSnippet", AllowAssumptions.YES);
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
CoreProviders context = getProviders();
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
@@ -146,7 +146,7 @@
private void checkInstanceOfCount(String methodName, int count) {
StructuredGraph graph = parseEager(methodName, AllowAssumptions.YES);
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = this.createCanonicalizerPhase();
CoreProviders context = getProviders();
canonicalizer.apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTestBase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTestBase.java Thu Oct 31 16:54:16 2019 -0700
@@ -69,8 +69,8 @@
DebugContext debug = graph.getDebug();
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
CoreProviders context = getProviders();
- CanonicalizerPhase canonicalizer1 = new CanonicalizerPhase();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer1 = createCanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
try (DebugContext.Scope scope = debug.scope("ConditionalEliminationTest", graph)) {
prepareGraph(graph, canonicalizer1, context, applyLowering);
new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context);
@@ -106,10 +106,9 @@
public void testProxies(String snippet, int expectedProxiesCreated) {
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
CoreProviders context = getProviders();
- CanonicalizerPhase canonicalizer1 = new CanonicalizerPhase();
- canonicalizer1.disableSimplification();
+ CanonicalizerPhase canonicalizer1 = CanonicalizerPhase.createWithoutCFGSimplification();
canonicalizer1.apply(graph, context);
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
canonicalizer.apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -43,6 +43,7 @@
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
import org.graalvm.compiler.nodes.spi.LIRLowerable;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.phases.OptimisticOptimizations;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.junit.Test;
@@ -559,7 +560,7 @@
}
public void rewrite(LoopsData loops) {
- InductionVariable inductionVariable = loops.getInductionVariable(iv);
+ InductionVariable inductionVariable = loops.getInductionVariable(GraphUtil.unproxify(iv));
ValueNode node = null;
if (inductionVariable == null) {
assert loopCanBeRemoved;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DeMorganCanonicalizationTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DeMorganCanonicalizationTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -29,7 +29,6 @@
import org.graalvm.compiler.nodes.calc.AndNode;
import org.graalvm.compiler.nodes.calc.NotNode;
import org.graalvm.compiler.nodes.calc.OrNode;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Assert;
import org.junit.Test;
@@ -46,7 +45,7 @@
@Test
public void testAnd() {
StructuredGraph g = parseEager("and", AllowAssumptions.NO, getInitialOptions());
- new CanonicalizerPhase().apply(g, getDefaultHighTierContext());
+ createCanonicalizerPhase().apply(g, getDefaultHighTierContext());
Assert.assertEquals(1, g.getNodes().filter(OrNode.class).count());
Assert.assertEquals(1, g.getNodes().filter(NotNode.class).count());
@@ -59,7 +58,7 @@
@Test
public void testOr() {
StructuredGraph g = parseEager("or", AllowAssumptions.NO, getInitialOptions());
- new CanonicalizerPhase().apply(g, getDefaultHighTierContext());
+ createCanonicalizerPhase().apply(g, getDefaultHighTierContext());
Assert.assertEquals(1, g.getNodes().filter(AndNode.class).count());
Assert.assertEquals(1, g.getNodes().filter(NotNode.class).count());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DegeneratedLoopsTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DegeneratedLoopsTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -28,7 +28,6 @@
import org.graalvm.compiler.debug.DebugDumpScope;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.junit.Test;
@@ -85,7 +84,7 @@
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
HighTierContext context = getDefaultHighTierContext();
createInliningPhase().apply(graph, context);
- new CanonicalizerPhase().apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.YES);
debug.dump(DebugContext.BASIC_LEVEL, referenceGraph, "ReferenceGraph");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/EnumSwitchTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/EnumSwitchTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -29,7 +29,6 @@
import org.graalvm.compiler.nodes.java.LoadIndexedNode;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.Phase;
-import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
import org.graalvm.compiler.phases.tiers.Suites;
import org.junit.Assume;
import org.junit.Test;
@@ -157,7 +156,7 @@
return "CheckGraphPhase";
}
});
- ret.getHighTier().findPhase(RemoveValueProxyPhase.class).add(new Phase() {
+ ret.getHighTier().addBeforeLast(new Phase() {
@Override
protected void run(StructuredGraph graph) {
/* Re-writing of the switch cases eliminates the array load. */
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FinalizableSubclassTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FinalizableSubclassTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -38,7 +38,6 @@
import org.graalvm.compiler.nodes.java.RegisterFinalizerNode;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.OptimisticOptimizations;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.junit.Assert;
import org.junit.Test;
@@ -80,7 +79,7 @@
new GraphBuilderPhase.Instance(getProviders(), conf, OptimisticOptimizations.ALL, null).apply(graph);
HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
createInliningPhase().apply(graph, context);
- new CanonicalizerPhase().apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
return graph;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FloatingReadTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FloatingReadTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -34,7 +34,6 @@
import org.graalvm.compiler.nodes.memory.FloatingReadNode;
import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.FloatingReadPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.junit.Assert;
@@ -68,7 +67,7 @@
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
CoreProviders context = getProviders();
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+ new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
new FloatingReadPhase().apply(graph);
ReturnNode returnNode = null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -126,7 +126,7 @@
import org.graalvm.compiler.runtime.RuntimeProvider;
import org.graalvm.compiler.test.AddExports;
import org.graalvm.compiler.test.GraalTest;
-import org.graalvm.compiler.test.ModuleSupport;
+import org.graalvm.compiler.api.test.ModuleSupport;
import org.junit.After;
import org.junit.Assert;
import org.junit.BeforeClass;
@@ -643,7 +643,7 @@
}
protected final BasePhase<HighTierContext> createInliningPhase() {
- return createInliningPhase(new CanonicalizerPhase());
+ return createInliningPhase(this.createCanonicalizerPhase());
}
protected BasePhase<HighTierContext> createInliningPhase(CanonicalizerPhase canonicalizer) {
@@ -1119,6 +1119,12 @@
return graph;
}
+ protected StructuredGraph getFinalGraph(ResolvedJavaMethod method, OptionValues options) {
+ StructuredGraph graph = parseForCompile(method, options);
+ applyFrontEnd(graph);
+ return graph;
+ }
+
@SuppressWarnings("try")
protected void applyFrontEnd(StructuredGraph graph) {
DebugContext debug = graph.getDebug();
@@ -1515,4 +1521,8 @@
protected boolean isArchitecture(String name) {
return name.equals(backend.getTarget().arch.getName());
}
+
+ protected CanonicalizerPhase createCanonicalizerPhase() {
+ return CanonicalizerPhase.create();
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphEncoderTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphEncoderTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -35,7 +35,6 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.spi.CoreProviders;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -61,7 +60,7 @@
StructuredGraph originalGraph = parseEager(javaMethod, AllowAssumptions.YES);
if (canonicalize) {
CoreProviders context = getProviders();
- new CanonicalizerPhase().apply(originalGraph, context);
+ createCanonicalizerPhase().apply(originalGraph, context);
}
originalGraphs.add(originalGraph);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardPrioritiesTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardPrioritiesTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -86,7 +86,7 @@
private StructuredGraph prepareGraph(String method) {
StructuredGraph graph = parseEager(method, StructuredGraph.AllowAssumptions.YES);
HighTierContext highTierContext = getDefaultHighTierContext();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
new ConvertDeoptimizeToGuardPhase().apply(graph, highTierContext);
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext);
new FloatingReadPhase().apply(graph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IfCanonicalizerTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IfCanonicalizerTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -35,7 +35,6 @@
import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.phases.OptimisticOptimizations;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.FloatingReadPhase;
import org.graalvm.compiler.phases.common.GuardLoweringPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
@@ -227,12 +226,12 @@
private void testCombinedIf(String snippet, int count) {
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
CoreProviders context = getProviders();
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+ new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
new FloatingReadPhase().apply(graph);
MidTierContext midContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
new GuardLoweringPhase().apply(graph, midContext);
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
- new CanonicalizerPhase().apply(graph, context);
+ new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
+ createCanonicalizerPhase().apply(graph, context);
assertDeepEquals(count, graph.getNodes().filter(IfNode.class).count());
}
@@ -247,7 +246,7 @@
}
}
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
for (FrameState fs : param.usages().filter(FrameState.class).snapshot()) {
fs.replaceFirstInput(param, null);
param.safeDelete();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ImplicitNullCheckTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ImplicitNullCheckTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -34,7 +34,6 @@
import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.phases.OptimisticOptimizations;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.FloatingReadPhase;
import org.graalvm.compiler.phases.common.GuardLoweringPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
@@ -72,7 +71,7 @@
try (DebugContext.Scope s = debug.scope("FloatingReadTest", new DebugDumpScope(snippet))) {
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES, debug);
CoreProviders context = getProviders();
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+ new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
new FloatingReadPhase().apply(graph);
MidTierContext midTierContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
new GuardLoweringPhase().apply(graph, midTierContext);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IntegerEqualsCanonicalizerTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IntegerEqualsCanonicalizerTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -27,7 +27,6 @@
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
public class IntegerEqualsCanonicalizerTest extends GraalCompilerTest {
@@ -166,7 +165,7 @@
private StructuredGraph getCanonicalizedGraph(String snippet) {
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
for (FrameState state : graph.getNodes(FrameState.TYPE).snapshot()) {
state.replaceAtUsages(null);
state.safeDelete();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InterfaceMethodHandleTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InterfaceMethodHandleTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -30,7 +30,7 @@
import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.test.ExportingClassLoader;
+import org.graalvm.compiler.api.test.ExportingClassLoader;
import org.junit.Test;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InvokeExceptionTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InvokeExceptionTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -30,7 +30,6 @@
import org.graalvm.compiler.nodes.Invoke;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.junit.Test;
@@ -69,8 +68,8 @@
hints.put(invoke, 1000d);
}
HighTierContext context = getDefaultHighTierContext();
- createInliningPhase(hints, new CanonicalizerPhase()).apply(graph, context);
- new CanonicalizerPhase().apply(graph, context);
+ createInliningPhase(hints, createCanonicalizerPhase()).apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
new DeadCodeEliminationPhase().apply(graph);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InvokeHintsTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InvokeHintsTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -30,7 +30,6 @@
import org.graalvm.compiler.nodes.Invoke;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.junit.Test;
@@ -80,8 +79,8 @@
}
HighTierContext context = getDefaultHighTierContext();
- createInliningPhase(hints, new CanonicalizerPhase()).apply(graph, context);
- new CanonicalizerPhase().apply(graph, context);
+ createInliningPhase(hints, createCanonicalizerPhase()).apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
new DeadCodeEliminationPhase().apply(graph);
StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.NO);
assertEquals(referenceGraph, graph);
--- /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/LateMembarInsertionTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Red Hat Inc. 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;
+
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.internal.vm.compiler.collections.EconomicMap;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.cfg.Block;
+import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
+import org.graalvm.compiler.nodes.memory.FixedAccessNode;
+import org.graalvm.compiler.nodes.memory.MemoryAccess;
+import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionValues;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.graalvm.compiler.core.common.GraalOptions.StressTestEarlyReads;
+
+public class LateMembarInsertionTest extends GraalCompilerTest {
+
+ private final ResolvedJavaType volatileAccessType = getMetaAccess().lookupJavaType(VolatileAccess.class);
+ private final ResolvedJavaType regularAccessField = getMetaAccess().lookupJavaType(RegularAccess.class);
+ private final ResolvedJavaType volatileAccess2Type = getMetaAccess().lookupJavaType(VolatileAccess2.class);
+
+ static class VolatileAccess {
+ static volatile int field;
+ }
+
+ static class VolatileAccess2 {
+ static volatile int field;
+ }
+
+ static class RegularAccess {
+ static int field;
+ }
+
+ public static int volatileFieldLoadFieldLoad() {
+ int v1 = VolatileAccess.field;
+ int v2 = RegularAccess.field;
+ return v1 + v2;
+ }
+
+ @Test
+ public void test01() {
+ List<TypePair> accesses = compile("volatileFieldLoadFieldLoad", stressTestEarlyReads());
+
+ Assert.assertEquals(accesses.size(), 2);
+ Assert.assertEquals(accesses.get(0).getType(), volatileAccessType);
+ Assert.assertEquals(accesses.get(1).getType(), regularAccessField);
+ Assert.assertTrue(accesses.get(0).isRead());
+ Assert.assertTrue(accesses.get(1).isRead());
+ }
+
+ public static int volatileFieldLoadVolatileFieldLoad() {
+ int v1 = VolatileAccess.field;
+ int v2 = VolatileAccess2.field;
+ return v1 + v2;
+ }
+
+ @Test
+ public void test02() {
+ List<TypePair> accesses = compile("volatileFieldLoadVolatileFieldLoad", stressTestEarlyReads());
+
+ Assert.assertEquals(accesses.size(), 2);
+ Assert.assertEquals(accesses.get(0).getType(), volatileAccessType);
+ Assert.assertEquals(accesses.get(1).getType(), volatileAccess2Type);
+ Assert.assertTrue(accesses.get(0).isRead());
+ Assert.assertTrue(accesses.get(1).isRead());
+ }
+
+ public static int volatileFieldLoadVolatileFieldStore(int v2) {
+ int v1 = VolatileAccess.field;
+ VolatileAccess2.field = v2;
+ return v1;
+ }
+
+ @Test
+ public void test03() {
+ List<TypePair> accesses = compile("volatileFieldLoadVolatileFieldStore");
+
+ Assert.assertEquals(accesses.size(), 2);
+ Assert.assertEquals(accesses.get(0).getType(), volatileAccessType);
+ Assert.assertEquals(accesses.get(1).getType(), volatileAccess2Type);
+ Assert.assertTrue(accesses.get(0).isRead());
+ Assert.assertTrue(accesses.get(1).isWrite());
+ }
+
+ public static int volatileFieldStoreVolatileFieldLoad(int v2) {
+ VolatileAccess.field = v2;
+ return VolatileAccess2.field;
+ }
+
+ @Test
+ public void test04() {
+ List<TypePair> accesses = compile("volatileFieldStoreVolatileFieldLoad", stressTestEarlyReads());
+
+ Assert.assertEquals(accesses.size(), 2);
+ Assert.assertEquals(accesses.get(0).getType(), volatileAccessType);
+ Assert.assertEquals(accesses.get(1).getType(), volatileAccess2Type);
+ Assert.assertTrue(accesses.get(0).isWrite());
+ Assert.assertTrue(accesses.get(1).isRead());
+ }
+
+ public static int fieldLoadVolatileFieldStore(int v2) {
+ int v1 = RegularAccess.field;
+ VolatileAccess2.field = v2;
+ return v1;
+ }
+
+ @Test
+ public void test05() {
+ List<TypePair> accesses = compile("fieldLoadVolatileFieldStore");
+
+ Assert.assertEquals(accesses.size(), 2);
+ Assert.assertEquals(accesses.get(0).getType(), regularAccessField);
+ Assert.assertEquals(accesses.get(1).getType(), volatileAccess2Type);
+ Assert.assertTrue(accesses.get(0).isRead());
+ Assert.assertTrue(accesses.get(1).isWrite());
+ }
+
+ public static void volatileFieldStoreVolatileFieldStore(int v1, int v2) {
+ VolatileAccess.field = v1;
+ VolatileAccess2.field = v2;
+ }
+
+ @Test
+ public void test06() {
+ List<TypePair> accesses = compile("volatileFieldStoreVolatileFieldStore");
+
+ Assert.assertEquals(accesses.size(), 2);
+ Assert.assertEquals(accesses.get(0).getType(), volatileAccessType);
+ Assert.assertEquals(accesses.get(1).getType(), volatileAccess2Type);
+ Assert.assertTrue(accesses.get(0).isWrite());
+ Assert.assertTrue(accesses.get(1).isWrite());
+ }
+
+ private static OptionValues stressTestEarlyReads() {
+ EconomicMap<OptionKey<?>, Object> overrides = OptionValues.newOptionMap();
+ overrides.put(StressTestEarlyReads, true);
+ return new OptionValues(getInitialOptions(), overrides);
+ }
+
+ static class TypePair {
+ private boolean isRead;
+ private ResolvedJavaType type;
+
+ TypePair(boolean isRead, ResolvedJavaType type) {
+ this.isRead = isRead;
+ this.type = type;
+ }
+
+ public boolean isRead() {
+ return isRead;
+ }
+
+ public boolean isWrite() {
+ return !isRead;
+ }
+
+ public ResolvedJavaType getType() {
+ return type;
+ }
+ }
+
+ private List<TypePair> compile(String test, OptionValues options) {
+ StructuredGraph graph = getFinalGraph(getResolvedJavaMethod(test), options);
+ return getAccesses(graph);
+ }
+
+ private List<TypePair> getAccesses(StructuredGraph graph) {
+ StructuredGraph.ScheduleResult schedule = graph.getLastSchedule();
+ ControlFlowGraph cfg = schedule.getCFG();
+ Block[] blocks = cfg.getBlocks();
+
+ return Arrays.stream(blocks).flatMap(b -> schedule.nodesFor(b).stream()).filter(n -> n instanceof MemoryAccess).map(
+ n -> new TypePair(n instanceof ReadNode, classForAccess((FixedAccessNode) n))).collect(Collectors.toList());
+ }
+
+ private List<TypePair> compile(String test) {
+ StructuredGraph graph = getFinalGraph(getResolvedJavaMethod(test));
+ return getAccesses(graph);
+ }
+
+ private ResolvedJavaType classForAccess(FixedAccessNode n) {
+ AddressNode address = n.getAddress();
+ ValueNode base = address.getBase();
+ Stamp stamp = base.stamp(NodeView.DEFAULT);
+ MetaAccessProvider metaAccess = getMetaAccess();
+ ResolvedJavaType javaType = stamp.javaType(metaAccess);
+ if (javaType == metaAccess.lookupJavaType(Class.class) && base instanceof ConstantNode) {
+ ConstantReflectionProvider constantReflection = getConstantReflection();
+ javaType = constantReflection.asJavaType(base.asConstant());
+ }
+ return javaType;
+ }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LockEliminationTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LockEliminationTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -69,7 +69,7 @@
test("testSynchronizedSnippet", new A(), new A());
StructuredGraph graph = getGraph("testSynchronizedSnippet", false);
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
new LockEliminationPhase().apply(graph);
assertDeepEquals(1, graph.getNodes().filter(RawMonitorEnterNode.class).count());
assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
@@ -87,7 +87,7 @@
test("testSynchronizedMethodSnippet", new A());
StructuredGraph graph = getGraph("testSynchronizedMethodSnippet", false);
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
new LockEliminationPhase().apply(graph);
assertDeepEquals(1, graph.getNodes().filter(RawMonitorEnterNode.class).count());
assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
@@ -104,7 +104,7 @@
@Test
public void testUnrolledSync() {
StructuredGraph graph = getGraph("testUnrolledSyncSnippet", false);
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
canonicalizer.apply(graph, getProviders());
HighTierContext context = getDefaultHighTierContext();
new LoopFullUnrollPhase(canonicalizer, new DefaultLoopPolicies()).apply(graph, context);
@@ -117,15 +117,15 @@
ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
StructuredGraph graph = parseEager(method, AllowAssumptions.YES);
HighTierContext context = getDefaultHighTierContext();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
canonicalizer.apply(graph, context);
createInliningPhase().apply(graph, context);
- new CanonicalizerPhase().apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
new DeadCodeEliminationPhase().apply(graph);
if (doEscapeAnalysis) {
new PartialEscapePhase(true, canonicalizer, graph.getOptions()).apply(graph, context);
}
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+ new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
return graph;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LongNodeChainTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LongNodeChainTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -37,7 +37,6 @@
import org.graalvm.compiler.nodes.calc.AddNode;
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;
import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
import org.graalvm.compiler.phases.tiers.HighTierContext;
@@ -85,7 +84,7 @@
new SchedulePhase(s).apply(graph);
}
- new CanonicalizerPhase().apply(graph, context);
+ this.createCanonicalizerPhase().apply(graph, context);
JavaConstant asConstant = (JavaConstant) returnNode.result().asConstant();
Assert.assertEquals(N + 1, asConstant.asInt());
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LoopFullUnrollTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LoopFullUnrollTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -32,7 +32,6 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.spi.CoreProviders;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
public class LoopFullUnrollTest extends GraalCompilerTest {
@@ -89,7 +88,7 @@
final StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO, debug);
CoreProviders context = getProviders();
- new LoopFullUnrollPhase(new CanonicalizerPhase(), new DefaultLoopPolicies()).apply(graph, context);
+ new LoopFullUnrollPhase(createCanonicalizerPhase(), new DefaultLoopPolicies()).apply(graph, context);
assertTrue(graph.getNodes().filter(LoopBeginNode.class).count() == loopCount);
} catch (Throwable e) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LoopUnswitchTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LoopUnswitchTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -30,7 +30,6 @@
import org.graalvm.compiler.loop.phases.LoopUnswitchingPhase;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
public class LoopUnswitchTest extends GraalCompilerTest {
@@ -133,8 +132,8 @@
graph.clearAllStateAfter();
referenceGraph.clearAllStateAfter();
- new CanonicalizerPhase().apply(graph, getProviders());
- new CanonicalizerPhase().apply(referenceGraph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(referenceGraph, getProviders());
try (DebugContext.Scope s = debug.scope("Test", new DebugDumpScope("Test:" + snippet))) {
assertEquals(referenceGraph, graph);
} catch (Throwable e) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MarkUnsafeAccessTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MarkUnsafeAccessTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -37,7 +37,6 @@
import java.nio.file.Path;
import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.inlining.InliningPhase;
import org.graalvm.compiler.phases.common.inlining.policy.InlineEverythingPolicy;
import org.graalvm.compiler.phases.tiers.HighTierContext;
@@ -125,8 +124,8 @@
Assert.assertNotNull(getMethodImpl);
StructuredGraph graph = parseForCompile(getMethodImpl);
HighTierContext highContext = getDefaultHighTierContext();
- new CanonicalizerPhase().apply(graph, highContext);
- new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase()).apply(graph, highContext);
+ createCanonicalizerPhase().apply(graph, highContext);
+ new InliningPhase(new InlineEverythingPolicy(), createCanonicalizerPhase()).apply(graph, highContext);
InstalledCode compiledCode = getCode(getMethodImpl, graph);
testMappedByteBuffer(mbb -> {
try {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MemoryGraphCanonicalizeTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MemoryGraphCanonicalizeTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -28,7 +28,6 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.memory.WriteNode;
import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.FloatingReadPhase;
import org.graalvm.compiler.phases.common.IncrementalCanonicalizerPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
@@ -76,10 +75,9 @@
public void testGraph(String name, int expectedWrites) {
StructuredGraph graph = parseEager(name, StructuredGraph.AllowAssumptions.YES);
HighTierContext context = getDefaultHighTierContext();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
- new IncrementalCanonicalizerPhase<>(canonicalizer, new FloatingReadPhase()).apply(graph, context);
- new CanonicalizerPhase().apply(graph, context);
+ new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+ new IncrementalCanonicalizerPhase<>(createCanonicalizerPhase(), new FloatingReadPhase()).apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
int writes = graph.getNodes().filter(WriteNode.class).count();
assertTrue(writes == expectedWrites, "Expected %d writes, found %d", expectedWrites, writes);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MemoryScheduleTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MemoryScheduleTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -38,7 +38,6 @@
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.nodes.ReturnNode;
-import org.graalvm.compiler.nodes.StartNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
@@ -177,7 +176,6 @@
@Test
public void testLoop1() {
ScheduleResult schedule = getFinalSchedule("testLoop1Snippet", TestMode.WITHOUT_FRAMESTATES);
- assertDeepEquals(6, schedule.getCFG().getBlocks().length);
assertReadWithinStartBlock(schedule, true);
assertReadWithinAllReturnBlocks(schedule, false);
}
@@ -202,7 +200,6 @@
@Test
public void testLoop2() {
ScheduleResult schedule = getFinalSchedule("testLoop2Snippet", TestMode.WITHOUT_FRAMESTATES);
- assertDeepEquals(6, schedule.getCFG().getBlocks().length);
assertReadWithinStartBlock(schedule, false);
assertReadWithinAllReturnBlocks(schedule, true);
}
@@ -224,7 +221,6 @@
@Test
public void testLoop3() {
ScheduleResult schedule = getFinalSchedule("testLoop3Snippet", TestMode.WITHOUT_FRAMESTATES);
- assertDeepEquals(6, schedule.getCFG().getBlocks().length);
assertReadWithinStartBlock(schedule, true);
assertReadWithinAllReturnBlocks(schedule, false);
}
@@ -260,7 +256,6 @@
@Test
public void testLoop5() {
ScheduleResult schedule = getFinalSchedule("testLoop5Snippet", TestMode.WITHOUT_FRAMESTATES);
- assertDeepEquals(10, schedule.getCFG().getBlocks().length);
assertReadWithinStartBlock(schedule, false);
assertReadWithinAllReturnBlocks(schedule, false);
}
@@ -289,7 +284,6 @@
@Test
public void testLoop6() {
ScheduleResult schedule = getFinalSchedule("testLoop6Snippet", TestMode.WITHOUT_FRAMESTATES);
- assertDeepEquals(13, schedule.getCFG().getBlocks().length);
assertReadWithinStartBlock(schedule, false);
assertReadWithinAllReturnBlocks(schedule, false);
}
@@ -322,7 +316,6 @@
@Test
public void testLoop7() {
ScheduleResult schedule = getFinalSchedule("testLoop7Snippet", TestMode.WITHOUT_FRAMESTATES);
- assertDeepEquals(18, schedule.getCFG().getBlocks().length);
assertReadWithinStartBlock(schedule, false);
assertReadWithinAllReturnBlocks(schedule, false);
}
@@ -349,7 +342,6 @@
@Test
public void testLoop8() {
ScheduleResult schedule = getFinalSchedule("testLoop8Snippet", TestMode.WITHOUT_FRAMESTATES);
- assertDeepEquals(10, schedule.getCFG().getBlocks().length);
assertReadWithinStartBlock(schedule, true);
assertReadWithinAllReturnBlocks(schedule, false);
}
@@ -391,7 +383,6 @@
@Test
public void testIfRead1() {
ScheduleResult schedule = getFinalSchedule("testIfRead1Snippet", TestMode.WITHOUT_FRAMESTATES);
- assertDeepEquals(3, schedule.getCFG().getBlocks().length);
assertReadWithinStartBlock(schedule, true);
assertReadAndWriteInSameBlock(schedule, false);
}
@@ -412,7 +403,6 @@
@Test
public void testIfRead2() {
ScheduleResult schedule = getFinalSchedule("testIfRead2Snippet", TestMode.WITHOUT_FRAMESTATES);
- assertDeepEquals(3, schedule.getCFG().getBlocks().length);
assertDeepEquals(1, schedule.getCFG().graph.getNodes().filter(FloatingReadNode.class).count());
assertReadWithinStartBlock(schedule, false);
assertReadWithinAllReturnBlocks(schedule, false);
@@ -434,7 +424,6 @@
@Test
public void testIfRead3() {
ScheduleResult schedule = getFinalSchedule("testIfRead3Snippet", TestMode.WITHOUT_FRAMESTATES);
- assertDeepEquals(4, schedule.getCFG().getBlocks().length);
assertReadWithinStartBlock(schedule, false);
assertReadWithinAllReturnBlocks(schedule, true);
}
@@ -455,7 +444,6 @@
@Test
public void testIfRead4() {
ScheduleResult schedule = getFinalSchedule("testIfRead4Snippet", TestMode.WITHOUT_FRAMESTATES);
- assertDeepEquals(3, schedule.getCFG().getBlocks().length);
assertReadWithinStartBlock(schedule, false);
assertReadWithinAllReturnBlocks(schedule, false);
assertReadAndWriteInSameBlock(schedule, true);
@@ -474,7 +462,6 @@
@Test
public void testIfRead5() {
ScheduleResult schedule = getFinalSchedule("testIfRead5Snippet", TestMode.WITHOUT_FRAMESTATES);
- assertDeepEquals(4, schedule.getCFG().getBlocks().length);
assertReadWithinStartBlock(schedule, false);
assertReadWithinAllReturnBlocks(schedule, true);
assertReadAndWriteInSameBlock(schedule, false);
@@ -500,7 +487,6 @@
@Test
public void testAntiDependency() {
ScheduleResult schedule = getFinalSchedule("testAntiDependencySnippet", TestMode.WITHOUT_FRAMESTATES);
- assertDeepEquals(4, schedule.getCFG().getBlocks().length);
assertReadBeforeAllWritesInStartBlock(schedule);
}
@@ -527,7 +513,6 @@
StructuredGraph graph = schedule.getCFG().graph;
NodeIterable<WriteNode> writeNodes = graph.getNodes().filter(WriteNode.class);
- assertDeepEquals(1, schedule.getCFG().getBlocks().length);
assertDeepEquals(8, writeNodes.count());
assertDeepEquals(1, graph.getNodes().filter(FloatingReadNode.class).count());
@@ -708,7 +693,7 @@
DebugContext debug = graph.getDebug();
try (DebugContext.Scope d = debug.scope("FloatingReadTest", graph)) {
HighTierContext context = getDefaultHighTierContext();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
canonicalizer.apply(graph, context);
if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
createInliningPhase(canonicalizer).apply(graph, context);
@@ -729,7 +714,6 @@
SchedulePhase schedule = new SchedulePhase(schedulingStrategy);
schedule.apply(graph);
- assertDeepEquals(1, graph.getNodes().filter(StartNode.class).count());
return graph.getLastSchedule();
} catch (Throwable e) {
throw debug.handle(e);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MergeCanonicalizerTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MergeCanonicalizerTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -30,7 +30,6 @@
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.phases.OptimisticOptimizations;
import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.junit.Test;
@@ -70,8 +69,8 @@
private void testReturnCount(String snippet, int returnCount) {
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
- new CanonicalizerPhase().apply(graph, getProviders());
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
graph.getDebug().dump(DebugContext.BASIC_LEVEL, graph, "Graph");
assertDeepEquals(returnCount, graph.getNodes(ReturnNode.TYPE).count());
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MonitorGraphTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MonitorGraphTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -36,7 +36,6 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.java.MonitorExitNode;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.junit.Assert;
@@ -103,8 +102,8 @@
hints.put(invoke, 1000d);
}
HighTierContext context = getDefaultHighTierContext();
- createInliningPhase(hints, new CanonicalizerPhase()).apply(graph, context);
- new CanonicalizerPhase().apply(graph, context);
+ createInliningPhase(hints, createCanonicalizerPhase()).apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
new DeadCodeEliminationPhase().apply(graph);
return graph;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePropertiesTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePropertiesTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -36,7 +36,7 @@
import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.phases.BasePhase;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase.CustomCanonicalizer;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase.CustomSimplification;
import org.graalvm.compiler.phases.contract.NodeCostUtil;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.junit.Assert;
@@ -162,19 +162,21 @@
@Test
public void testCanonicalizationExample() {
HighTierContext htc = getDefaultHighTierContext();
- ImprovementSavingCanonicalizer c1 = new ImprovementSavingCanonicalizer();
+ ImprovementSavingCalculator c1 = new ImprovementSavingCalculator();
StructuredGraph g1 = parseForCompile(getResolvedJavaMethod("test1Snippet"));
- new CanonicalizerPhase(c1).apply(g1, htc);
- ImprovementSavingCanonicalizer c2 = new ImprovementSavingCanonicalizer();
+ CanonicalizerPhase canonicalizer1 = this.createCanonicalizerPhase().copyWithCustomSimplification(c1);
+ canonicalizer1.apply(g1, htc);
+ ImprovementSavingCalculator c2 = new ImprovementSavingCalculator();
StructuredGraph g2 = parseForCompile(getResolvedJavaMethod("test2Snippet"));
- new CanonicalizerPhase(c2).apply(g2, htc);
+ CanonicalizerPhase canonicalizer2 = this.createCanonicalizerPhase().copyWithCustomSimplification(c2);
+ canonicalizer2.apply(g2, htc);
Assert.assertEquals(0, c1.savedCycles);
Assert.assertEquals(0, c2.savedCycles);
}
- private static void prepareGraphForLoopFrequencies(StructuredGraph g, HighTierContext htc) {
+ private void prepareGraphForLoopFrequencies(StructuredGraph g, HighTierContext htc) {
// let canonicalizer work away branch probability nodes
- new CanonicalizerPhase().apply(g, htc);
+ createCanonicalizerPhase().apply(g, htc);
// recompute the loop frequencies
ComputeLoopFrequenciesClosure.compute(g);
}
@@ -242,8 +244,8 @@
StructuredGraph g1 = parseForCompile(getResolvedJavaMethod("test1Snippet"));
StructuredGraph g2 = parseForCompile(getResolvedJavaMethod("test2Snippet"));
HighTierContext htc = getDefaultHighTierContext();
- new CanonicalizerPhase().apply(g1, htc);
- new CanonicalizerPhase().apply(g2, htc);
+ createCanonicalizerPhase().apply(g1, htc);
+ createCanonicalizerPhase().apply(g2, htc);
GraphCostPhase gc1 = new GraphCostPhase();
GraphCostPhase gc2 = new GraphCostPhase();
gc1.apply(g1, htc);
@@ -257,7 +259,7 @@
public void testExpectUntrusted() {
StructuredGraph g1 = parseForCompile(getResolvedJavaMethod("untrused01"));
HighTierContext htc = getDefaultHighTierContext();
- new CanonicalizerPhase().apply(g1, htc);
+ createCanonicalizerPhase().apply(g1, htc);
GraphCostPhase gc1 = new GraphCostPhase();
gc1.apply(g1, htc);
}
@@ -266,7 +268,7 @@
public void testArrayLoad() {
StructuredGraph g1 = parseForCompile(getResolvedJavaMethod("arrayLoadTest"));
HighTierContext htc = getDefaultHighTierContext();
- new CanonicalizerPhase().apply(g1, htc);
+ createCanonicalizerPhase().apply(g1, htc);
GraphCostPhase gc1 = new GraphCostPhase();
gc1.apply(g1, htc);
Assert.assertEquals(15, gc1.finalCycles, 25);
@@ -276,7 +278,7 @@
public void testArrayStore() {
StructuredGraph g1 = parseForCompile(getResolvedJavaMethod("arrayStoreTest"));
HighTierContext htc = getDefaultHighTierContext();
- new CanonicalizerPhase().apply(g1, htc);
+ createCanonicalizerPhase().apply(g1, htc);
GraphCostPhase gc1 = new GraphCostPhase();
gc1.apply(g1, htc);
Assert.assertEquals(15, gc1.finalCycles, 25);
@@ -286,7 +288,7 @@
public void testFieldLoad() {
StructuredGraph g1 = parseForCompile(getResolvedJavaMethod("fieldLoad"));
HighTierContext htc = getDefaultHighTierContext();
- new CanonicalizerPhase().apply(g1, htc);
+ createCanonicalizerPhase().apply(g1, htc);
GraphCostPhase gc1 = new GraphCostPhase();
gc1.apply(g1, htc);
Assert.assertEquals(15, gc1.finalCycles, 25);
@@ -296,13 +298,13 @@
public void testFieldStore() {
StructuredGraph g1 = parseForCompile(getResolvedJavaMethod("fieldStore"));
HighTierContext htc = getDefaultHighTierContext();
- new CanonicalizerPhase().apply(g1, htc);
+ createCanonicalizerPhase().apply(g1, htc);
GraphCostPhase gc1 = new GraphCostPhase();
gc1.apply(g1, htc);
Assert.assertEquals(15, gc1.finalCycles, 25);
}
- static class ImprovementSavingCanonicalizer extends CustomCanonicalizer {
+ static class ImprovementSavingCalculator implements CustomSimplification {
private int savedCycles;
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/PushNodesThroughPiTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/PushNodesThroughPiTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -104,7 +104,7 @@
private StructuredGraph compileTestSnippet(final String snippet) {
StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
CoreProviders context = getProviders();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = this.createCanonicalizerPhase();
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
canonicalizer.apply(graph, context);
canonicalizer.apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/PushThroughIfTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/PushThroughIfTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -29,7 +29,6 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.util.GraphUtil;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
public class PushThroughIfTest extends GraalCompilerTest {
@@ -65,15 +64,15 @@
fs.replaceAtUsages(null);
GraphUtil.killWithUnusedFloatingInputs(fs);
}
- new CanonicalizerPhase().apply(graph, getProviders());
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
StructuredGraph referenceGraph = parseEager(reference, AllowAssumptions.YES);
for (FrameState fs : referenceGraph.getNodes(FrameState.TYPE).snapshot()) {
fs.replaceAtUsages(null);
GraphUtil.killWithUnusedFloatingInputs(fs);
}
- new CanonicalizerPhase().apply(referenceGraph, getProviders());
+ createCanonicalizerPhase().apply(referenceGraph, getProviders());
assertEquals(referenceGraph, graph);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReadAfterCheckCastTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReadAfterCheckCastTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -90,7 +90,7 @@
// structure changes significantly
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
CoreProviders context = getProviders();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
new FloatingReadPhase().apply(graph);
canonicalizer.apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReassociateAndCanonicalTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReassociateAndCanonicalTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -28,7 +28,6 @@
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
public class ReassociateAndCanonicalTest extends GraalCompilerTest {
@@ -245,9 +244,9 @@
private <T extends Node & IterableNodeType> void test(String test, String ref) {
StructuredGraph testGraph = parseEager(test, AllowAssumptions.NO);
- new CanonicalizerPhase().apply(testGraph, getProviders());
+ createCanonicalizerPhase().apply(testGraph, getProviders());
StructuredGraph refGraph = parseEager(ref, AllowAssumptions.NO);
- new CanonicalizerPhase().apply(refGraph, getProviders());
+ createCanonicalizerPhase().apply(refGraph, getProviders());
assertEquals(testGraph, refGraph);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ScalarTypeSystemTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ScalarTypeSystemTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -28,7 +28,6 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.spi.CoreProviders;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
/**
@@ -134,7 +133,7 @@
StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
graph.getDebug().dump(DebugContext.BASIC_LEVEL, graph, "Graph");
CoreProviders context = getProviders();
- new CanonicalizerPhase().apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.NO);
assertEquals(referenceGraph, graph);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SchedulingTest2.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SchedulingTest2.java Thu Oct 31 16:54:16 2019 -0700
@@ -44,7 +44,6 @@
import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.phases.OptimisticOptimizations;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.FrameStateAssignmentPhase;
import org.graalvm.compiler.phases.common.GuardLoweringPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
@@ -99,8 +98,8 @@
}
CoreProviders context = getProviders();
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
+ new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+ new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
MidTierContext midContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
new GuardLoweringPhase().apply(graph, midContext);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StampCanonicalizerTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StampCanonicalizerTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -27,7 +27,6 @@
import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.junit.Test;
@@ -111,7 +110,7 @@
private void testZeroReturn(String methodName) {
StructuredGraph graph = parseEager(methodName, AllowAssumptions.YES);
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
new DeadCodeEliminationPhase().apply(graph);
assertConstantReturn(graph, 0);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StraighteningTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StraighteningTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -27,7 +27,6 @@
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
public class StraighteningTest extends GraalCompilerTest {
@@ -90,7 +89,7 @@
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
DebugContext debug = graph.getDebug();
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.YES);
assertEquals(referenceGraph, graph);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SwitchCanonicalizerTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SwitchCanonicalizerTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -26,7 +26,6 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.extended.IntegerSwitchNode;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
public class SwitchCanonicalizerTest extends GraalCompilerTest {
@@ -119,7 +118,7 @@
private void shouldFoldSwitch(String methodName) {
StructuredGraph graph = parseForCompile(getResolvedJavaMethod(methodName));
- new CanonicalizerPhase().apply(graph, getDefaultHighTierContext());
+ createCanonicalizerPhase().apply(graph, getDefaultHighTierContext());
assertTrue(graph.getNodes().filter(IntegerSwitchNode.class).isEmpty());
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SwitchDyingLoopTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SwitchDyingLoopTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -70,7 +70,7 @@
@Test
public void test() {
- CanonicalizerPhase canonicalizerPhase = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizerPhase = createCanonicalizerPhase();
HighTierContext highTierContext = getDefaultHighTierContext();
StructuredGraph graph = parseEager("snippet", StructuredGraph.AllowAssumptions.YES);
// there should be 1 loop and 1 switch
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SwitchFoldingTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SwitchFoldingTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -27,7 +27,6 @@
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
public class SwitchFoldingTest extends GraalCompilerTest {
@@ -484,7 +483,7 @@
StructuredGraph graph = parseEager(snippet, StructuredGraph.AllowAssumptions.YES);
DebugContext debug = graph.getDebug();
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
StructuredGraph referenceGraph = parseEager(ref, StructuredGraph.AllowAssumptions.YES);
assertEquals(referenceGraph, graph);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/TypeSystemTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/TypeSystemTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -41,7 +41,6 @@
import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.nodes.java.InstanceOfNode;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.ConditionalEliminationPhase;
import org.graalvm.compiler.phases.schedule.SchedulePhase;
import org.junit.Assert;
@@ -188,13 +187,13 @@
* reference graph.
*/
new ConditionalEliminationPhase(false).apply(graph, getProviders());
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
// a second canonicalizer is needed to process nested MaterializeNodes
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.NO);
new ConditionalEliminationPhase(false).apply(referenceGraph, getProviders());
- new CanonicalizerPhase().apply(referenceGraph, getProviders());
- new CanonicalizerPhase().apply(referenceGraph, getProviders());
+ this.createCanonicalizerPhase().apply(referenceGraph, getProviders());
+ this.createCanonicalizerPhase().apply(referenceGraph, getProviders());
assertEquals(referenceGraph, graph);
}
@@ -244,8 +243,8 @@
private <T extends Node> void testHelper(String snippet, Class<T> clazz) {
StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
- new CanonicalizerPhase().apply(graph, getProviders());
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
DebugContext debug = graph.getDebug();
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph " + snippet);
Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes().filter(clazz).iterator().hasNext());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeReadEliminationTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeReadEliminationTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -119,7 +119,7 @@
public void testEarlyReadElimination(StructuredGraph graph, int reads, int writes) {
CoreProviders context = getDefaultHighTierContext();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
canonicalizer.apply(graph, context);
new EarlyReadEliminationPhase(canonicalizer).apply(graph, context);
Assert.assertEquals(3, graph.getNodes().filter(UnsafeAccessNode.class).count());
@@ -134,7 +134,7 @@
public void testPartialEscapeReadElimination(StructuredGraph graph, int reads, int writes) {
OptionValues options = graph.getOptions();
CoreProviders context = getDefaultHighTierContext();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
canonicalizer.apply(graph, context);
new PartialEscapePhase(true, true, canonicalizer, null, options).apply(graph, context);
Assert.assertEquals(3, graph.getNodes().filter(UnsafeAccessNode.class).count());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -147,7 +147,7 @@
StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
OptionValues options = graph.getOptions();
CoreProviders context = getDefaultHighTierContext();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
if (canonicalizeBefore) {
canonicalizer.apply(graph, context);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnusedArray.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnusedArray.java Thu Oct 31 16:54:16 2019 -0700
@@ -30,7 +30,6 @@
import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.java.NewArrayNode;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Test;
public class UnusedArray extends GraalCompilerTest {
@@ -66,7 +65,7 @@
public void test(String method) {
StructuredGraph graph = parseEager(method, StructuredGraph.AllowAssumptions.YES);
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
NodeIterable<NewArrayNode> newArrayNodes = graph.getNodes().filter(NewArrayNode.class);
assertThat(newArrayNodes, isEmpty());
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/deopt/CompiledMethodTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/deopt/CompiledMethodTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -29,7 +29,6 @@
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.junit.Assert;
import org.junit.Test;
@@ -62,7 +61,7 @@
public void test1() {
final ResolvedJavaMethod javaMethod = getResolvedJavaMethod("testMethod");
final StructuredGraph graph = parseEager(javaMethod, AllowAssumptions.NO);
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
new DeadCodeEliminationPhase().apply(graph);
for (ConstantNode node : ConstantNode.getConstantNodes(graph)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java Thu Oct 31 16:54:16 2019 -0700
@@ -37,7 +37,6 @@
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;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
@@ -173,7 +172,7 @@
createInliningPhase().apply(graph, context);
new DeadCodeEliminationPhase().apply(graph);
canonicalizeGraph();
- new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
+ new PartialEscapePhase(iterativeEscapeAnalysis, false, createCanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
postEACanonicalizeGraph();
returnNodes = graph.getNodes(ReturnNode.TYPE).snapshot();
} catch (Throwable e) {
@@ -185,6 +184,6 @@
}
protected void canonicalizeGraph() {
- new CanonicalizerPhase().apply(graph, context);
+ this.createCanonicalizerPhase().apply(graph, context);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EarlyReadEliminationTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EarlyReadEliminationTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -27,6 +27,9 @@
import java.util.List;
import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.IfNode;
+import org.graalvm.compiler.nodes.LogicConstantNode;
import org.graalvm.compiler.nodes.ProxyNode;
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.StructuredGraph;
@@ -37,7 +40,6 @@
import org.graalvm.compiler.nodes.java.StoreFieldNode;
import org.graalvm.compiler.nodes.memory.ReadNode;
import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.virtual.phases.ea.EarlyReadEliminationPhase;
@@ -47,6 +49,50 @@
public static Object staticField;
+ static void cfgSnippet() {
+ if (staticField != null) {
+ staticField = 12;
+ if (staticField != null) {
+ staticField = 12;
+ }
+ if (staticField != null) {
+ staticField = 12;
+ }
+ if (staticField != null) {
+ staticField = 12;
+ }
+ if (staticField != null) {
+ staticField = 12;
+ }
+ } else {
+ if (staticField != null) {
+ staticField = 12;
+ } else {
+ if (staticField != null) {
+ staticField = 12;
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testDeadBranches() {
+ StructuredGraph graph = parseEager(getResolvedJavaMethod("cfgSnippet"), AllowAssumptions.NO);
+ HighTierContext context = getDefaultHighTierContext();
+ int index = 0;
+ boolean[] conditions = new boolean[]{true, false, false, true, true, true, false};
+ /*
+ * Create a graph with "dead" branches in the beginning.
+ */
+ for (Node n : graph.getNodes()) {
+ if (n instanceof IfNode) {
+ IfNode ifNode = (IfNode) n;
+ ifNode.setCondition(LogicConstantNode.forBoolean(conditions[index++], graph));
+ }
+ }
+ new EarlyReadEliminationPhase(createCanonicalizerPhase()).apply(graph, context);
+ }
+
public static class TestObject {
public int x;
@@ -264,9 +310,9 @@
HighTierContext context = getDefaultHighTierContext();
createInliningPhase().apply(graph, context);
if (doLowering) {
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+ new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
}
- new EarlyReadEliminationPhase(new CanonicalizerPhase()).apply(graph, context);
+ new EarlyReadEliminationPhase(createCanonicalizerPhase()).apply(graph, context);
return graph;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EscapeAnalysisTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EscapeAnalysisTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -38,7 +38,6 @@
import org.graalvm.compiler.nodes.java.LoadFieldNode;
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.schedule.SchedulePhase;
import org.graalvm.compiler.test.SubprocessUtil;
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
@@ -327,7 +326,7 @@
Assert.assertEquals(1, graph.getNodes().filter(BoxNode.class).count());
List<Node> nodes = graph.getNodes().snapshot();
// verify that an additional run doesn't add or remove nodes
- new PartialEscapePhase(false, false, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
+ new PartialEscapePhase(false, false, createCanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
Assert.assertEquals(nodes.size(), graph.getNodeCount());
for (Node node : nodes) {
Assert.assertTrue(node.isAlive());
@@ -362,9 +361,9 @@
Assert.assertEquals(2, graph.getNodes().filter(CommitAllocationNode.class).count());
// create the situation by removing the if
graph.replaceFixedWithFloating(graph.getNodes().filter(LoadFieldNode.class).first(), graph.unique(ConstantNode.forInt(0)));
- new CanonicalizerPhase().apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
// verify that an additional run removes all allocations
- new PartialEscapePhase(false, false, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
+ new PartialEscapePhase(false, false, createCanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
Assert.assertEquals(0, graph.getNodes().filter(CommitAllocationNode.class).count());
}
@@ -440,8 +439,8 @@
@Test
public void testFullyUnrolledLoop() {
prepareGraph("testFullyUnrolledLoopSnippet", false);
- new LoopFullUnrollPhase(new CanonicalizerPhase(), new DefaultLoopPolicies()).apply(graph, context);
- new PartialEscapePhase(false, new CanonicalizerPhase(), graph.getOptions()).apply(graph, context);
+ new LoopFullUnrollPhase(createCanonicalizerPhase(), new DefaultLoopPolicies()).apply(graph, context);
+ new PartialEscapePhase(false, createCanonicalizerPhase(), graph.getOptions()).apply(graph, context);
Assert.assertEquals(1, returnNodes.size());
Assert.assertTrue(returnNodes.get(0).result() instanceof AllocatedObjectNode);
CommitAllocationNode commit = ((AllocatedObjectNode) returnNodes.get(0).result()).getCommit();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PEAReadEliminationTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PEAReadEliminationTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -30,7 +30,6 @@
import org.graalvm.compiler.nodes.extended.RawLoadNode;
import org.graalvm.compiler.nodes.java.LoadIndexedNode;
import org.graalvm.compiler.nodes.java.StoreIndexedNode;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
import org.junit.Test;
@@ -181,7 +180,7 @@
StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
HighTierContext context = getDefaultHighTierContext();
createInliningPhase().apply(graph, context);
- new PartialEscapePhase(false, true, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
+ new PartialEscapePhase(false, true, createCanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
return graph;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisIterationTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisIterationTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -31,7 +31,6 @@
import org.graalvm.compiler.nodes.extended.UnboxNode;
import org.graalvm.compiler.nodes.java.StoreFieldNode;
import org.graalvm.compiler.nodes.virtual.CommitAllocationNode;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
import org.junit.Assert;
import org.junit.Test;
@@ -147,7 +146,7 @@
for (String name : new String[]{"noLoopIterationEmpty", "noLoopIteration"}) {
prepareGraph(name, false);
List<CommitAllocationNode> allocations = graph.getNodes().filter(CommitAllocationNode.class).snapshot();
- new PartialEscapePhase(true, false, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
+ new PartialEscapePhase(true, false, createCanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
Assert.assertEquals(1, allocations.size());
Assert.assertTrue(allocations.get(0).isAlive());
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -44,7 +44,6 @@
import org.graalvm.compiler.nodes.java.NewInstanceNode;
import org.graalvm.compiler.nodes.java.StoreFieldNode;
import org.graalvm.compiler.nodes.virtual.CommitAllocationNode;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
/**
@@ -287,7 +286,7 @@
merge.setStateAfter(null);
}
new DeadCodeEliminationPhase().apply(graph);
- new CanonicalizerPhase().apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
try {
Assert.assertTrue("partial escape analysis should have removed all NewInstanceNode allocations", graph.getNodes().filter(NewInstanceNode.class).isEmpty());
Assert.assertTrue("partial escape analysis should have removed all NewArrayNode allocations", graph.getNodes().filter(NewArrayNode.class).isEmpty());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisTreesTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisTreesTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -30,7 +30,6 @@
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.nodes.debug.BlackholeNode;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.junit.Assert;
import org.junit.Test;
@@ -118,7 +117,7 @@
graph.removeFixed(node);
}
new DeadCodeEliminationPhase().apply(graph);
- new CanonicalizerPhase().apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
InstalledCode code = getCode(method, graph, true);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PoorMansEATest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PoorMansEATest.java Thu Oct 31 16:54:16 2019 -0700
@@ -35,7 +35,6 @@
import org.graalvm.compiler.nodes.java.NewInstanceNode;
import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.junit.Test;
@@ -68,7 +67,7 @@
HighTierContext highTierContext = getDefaultHighTierContext();
createInliningPhase().apply(graph, highTierContext);
CoreProviders context = getProviders();
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+ new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
// remove framestates in order to trigger the simplification.
cleanup: for (FrameState fs : graph.getNodes(FrameState.TYPE).snapshot()) {
@@ -80,7 +79,7 @@
}
}
}
- new CanonicalizerPhase().apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
} catch (Throwable e) {
throw debug.handle(e);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/TrufflePEATest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/TrufflePEATest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -32,7 +32,6 @@
import org.graalvm.compiler.nodes.extended.RawLoadNode;
import org.graalvm.compiler.nodes.extended.RawStoreNode;
import org.graalvm.compiler.nodes.virtual.CommitAllocationNode;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
import org.junit.Test;
@@ -123,7 +122,7 @@
StructuredGraph graph = parseEager(snippet, StructuredGraph.AllowAssumptions.NO);
HighTierContext context = getDefaultHighTierContext();
createInliningPhase().apply(graph, context);
- new PartialEscapePhase(true, true, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
+ new PartialEscapePhase(true, true, createCanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
return graph;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/UnsafeEATest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/UnsafeEATest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -37,7 +37,6 @@
import org.graalvm.compiler.nodes.extended.RawStoreNode;
import org.graalvm.compiler.nodes.extended.UnsafeAccessNode;
import org.graalvm.compiler.nodes.java.LoadFieldNode;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Assert;
import org.junit.Test;
@@ -123,7 +122,7 @@
for (UnpackEndianHalfNode node : graph.getNodes().filter(UnpackEndianHalfNode.class)) {
node.lower(getTarget().arch.getByteOrder());
}
- new CanonicalizerPhase().applyIncremental(graph, context, mark);
+ createCanonicalizerPhase().applyIncremental(graph, context, mark);
}
private boolean testingUnsafe;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/InliningTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/InliningTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -41,7 +41,6 @@
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.OptimisticOptimizations;
import org.graalvm.compiler.phases.PhaseSuite;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.junit.Assert;
@@ -291,10 +290,10 @@
: getDefaultGraphBuilderSuite();
HighTierContext context = new HighTierContext(getProviders(), graphBuilderSuite, OptimisticOptimizations.ALL);
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
- new CanonicalizerPhase().apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
createInliningPhase().apply(graph, context);
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
- new CanonicalizerPhase().apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
new DeadCodeEliminationPhase().apply(graph);
return graph;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -112,8 +112,8 @@
StructuredGraph g1 = prepareGraph(snippet, i);
StructuredGraph g2 = (StructuredGraph) g1.copy(g1.getDebug());
ResolvedJavaMethod method = g1.method();
- long elapsedRE = runAndTimePhase(g1, new EarlyReadEliminationPhase(new CanonicalizerPhase()));
- long elapsedPEA = runAndTimePhase(g2, new PartialEscapePhase(true, new CanonicalizerPhase(), g1.getOptions()));
+ long elapsedRE = runAndTimePhase(g1, new EarlyReadEliminationPhase(createCanonicalizerPhase()));
+ long elapsedPEA = runAndTimePhase(g2, new PartialEscapePhase(true, createCanonicalizerPhase(), g1.getOptions()));
if (LOG_PHASE_TIMINGS) {
TTY.printf("Needed %dms to run early partial escape analysis on a graph with %d nested loops compiling method %s\n", elapsedPEA, i, method);
}
@@ -138,7 +138,7 @@
StructuredGraph callerGraph = parseEager(callerMethod, AllowAssumptions.YES);
PhaseSuite<HighTierContext> graphBuilderSuite = getDefaultGraphBuilderSuite();
HighTierContext context = new HighTierContext(getProviders(), graphBuilderSuite, OptimisticOptimizations.ALL);
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
Invoke next = callerGraph.getNodes(MethodCallTargetNode.TYPE).first().invoke();
StructuredGraph calleeGraph = parseBytecodes(next.callTarget().targetMethod(), context, canonicalizer);
ResolvedJavaMethod calleeMethod = next.callTarget().targetMethod();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeMatchRules.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeMatchRules.java Thu Oct 31 16:54:16 2019 -0700
@@ -63,6 +63,7 @@
import org.graalvm.compiler.nodes.java.ValueCompareAndSwapNode;
import org.graalvm.compiler.nodes.memory.FloatingReadNode;
import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.memory.VolatileReadNode;
import org.graalvm.compiler.nodes.memory.WriteNode;
import jdk.vm.ci.meta.Value;
@@ -75,6 +76,7 @@
@MatchableNode(nodeClass = LeftShiftNode.class, inputs = {"x", "y"}, ignoresSideEffects = true)
@MatchableNode(nodeClass = NarrowNode.class, inputs = {"value"}, ignoresSideEffects = true)
@MatchableNode(nodeClass = ReadNode.class, inputs = {"address"})
+@MatchableNode(nodeClass = VolatileReadNode.class, inputs = {"address"})
@MatchableNode(nodeClass = ReinterpretNode.class, inputs = {"value"}, ignoresSideEffects = true)
@MatchableNode(nodeClass = SignExtendNode.class, inputs = {"value"}, ignoresSideEffects = true)
@MatchableNode(nodeClass = UnsignedRightShiftNode.class, inputs = {"x", "y"}, ignoresSideEffects = true)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/BaseTier.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019, 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.phases;
+
+import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
+
+import org.graalvm.compiler.loop.DefaultLoopPolicies;
+import org.graalvm.compiler.loop.LoopPolicies;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.PhaseSuite;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+
+public class BaseTier<C> extends PhaseSuite<C> {
+
+ public LoopPolicies createLoopPolicies() {
+ return new DefaultLoopPolicies();
+ }
+
+ public CanonicalizerPhase createCanonicalizerPhase(OptionValues options) {
+ CanonicalizerPhase canonicalizer = null;
+ if (ImmutableCode.getValue(options)) {
+ canonicalizer = CanonicalizerPhase.createWithoutReadCanonicalization();
+ } else {
+ canonicalizer = CanonicalizerPhase.create();
+ }
+ return canonicalizer;
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyHighTier.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyHighTier.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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,23 +24,16 @@
package org.graalvm.compiler.core.phases;
-import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
-
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
-public class EconomyHighTier extends PhaseSuite<HighTierContext> {
+public class EconomyHighTier extends BaseTier<HighTierContext> {
public EconomyHighTier(OptionValues options) {
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
- if (ImmutableCode.getValue(options)) {
- canonicalizer.disableReadCanonicalization();
- }
-
+ CanonicalizerPhase canonicalizer = this.createCanonicalizerPhase(options);
appendPhase(canonicalizer);
appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER));
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyLowTier.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyLowTier.java Thu Oct 31 16:54:16 2019 -0700
@@ -24,29 +24,20 @@
package org.graalvm.compiler.core.phases;
-import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
-
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.ExpandLogicPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.schedule.SchedulePhase;
import org.graalvm.compiler.phases.tiers.LowTierContext;
-public class EconomyLowTier extends PhaseSuite<LowTierContext> {
+public class EconomyLowTier extends BaseTier<LowTierContext> {
public EconomyLowTier(OptionValues options) {
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
- if (ImmutableCode.getValue(options)) {
- canonicalizer.disableReadCanonicalization();
- }
-
+ CanonicalizerPhase canonicalizer = this.createCanonicalizerPhase(options);
appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.LOW_TIER));
-
appendPhase(new ExpandLogicPhase());
-
appendPhase(new SchedulePhase(SchedulePhase.SchedulingStrategy.LATEST_OUT_OF_LOOPS));
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyMidTier.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyMidTier.java Thu Oct 31 16:54:16 2019 -0700
@@ -24,11 +24,8 @@
package org.graalvm.compiler.core.phases;
-import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
-
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.FrameStateAssignmentPhase;
import org.graalvm.compiler.phases.common.GuardLoweringPhase;
@@ -38,23 +35,15 @@
import org.graalvm.compiler.phases.common.WriteBarrierAdditionPhase;
import org.graalvm.compiler.phases.tiers.MidTierContext;
-public class EconomyMidTier extends PhaseSuite<MidTierContext> {
+public class EconomyMidTier extends BaseTier<MidTierContext> {
public EconomyMidTier(OptionValues options) {
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
- if (ImmutableCode.getValue(options)) {
- canonicalizer.disableReadCanonicalization();
- }
+ CanonicalizerPhase canonicalizer = this.createCanonicalizerPhase(options);
appendPhase(new RemoveValueProxyPhase());
-
appendPhase(new LoopSafepointInsertionPhase());
-
appendPhase(new GuardLoweringPhase());
-
appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER));
-
appendPhase(new FrameStateAssignmentPhase());
-
appendPhase(new WriteBarrierAdditionPhase());
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/HighTier.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/HighTier.java Thu Oct 31 16:54:16 2019 -0700
@@ -25,17 +25,16 @@
package org.graalvm.compiler.core.phases;
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.LoopPeeling;
import static org.graalvm.compiler.core.common.GraalOptions.LoopUnswitch;
import static org.graalvm.compiler.core.common.GraalOptions.OptConvertDeoptsToGuards;
-import static org.graalvm.compiler.core.common.GraalOptions.OptLoopTransform;
import static org.graalvm.compiler.core.common.GraalOptions.OptReadElimination;
import static org.graalvm.compiler.core.common.GraalOptions.PartialEscapeAnalysis;
import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Optional;
import org.graalvm.compiler.loop.DefaultLoopPolicies;
import org.graalvm.compiler.loop.LoopPolicies;
+import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase;
import org.graalvm.compiler.loop.phases.LoopFullUnrollPhase;
import org.graalvm.compiler.loop.phases.LoopPeelingPhase;
import org.graalvm.compiler.loop.phases.LoopUnswitchingPhase;
@@ -44,22 +43,19 @@
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.common.IncrementalCanonicalizerPhase;
import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.common.NodeCounterPhase;
-import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
import org.graalvm.compiler.phases.common.inlining.InliningPhase;
import org.graalvm.compiler.phases.common.inlining.policy.GreedyInliningPolicy;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.virtual.phases.ea.EarlyReadEliminationPhase;
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
-public class HighTier extends PhaseSuite<HighTierContext> {
+public class HighTier extends BaseTier<HighTierContext> {
public static class Options {
@@ -70,11 +66,7 @@
}
public HighTier(OptionValues options) {
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
- if (ImmutableCode.getValue(options)) {
- canonicalizer.disableReadCanonicalization();
- }
-
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase(options);
appendPhase(canonicalizer);
if (NodeCounterPhase.Options.NodeCounters.getValue(options)) {
@@ -101,13 +93,12 @@
LoopPolicies loopPolicies = createLoopPolicies();
appendPhase(new LoopFullUnrollPhase(canonicalizer, loopPolicies));
- if (OptLoopTransform.getValue(options)) {
- if (LoopPeeling.getValue(options)) {
- appendPhase(new IncrementalCanonicalizerPhase<>(canonicalizer, new LoopPeelingPhase(loopPolicies)));
- }
- if (LoopUnswitch.getValue(options)) {
- appendPhase(new IncrementalCanonicalizerPhase<>(canonicalizer, new LoopUnswitchingPhase(loopPolicies)));
- }
+ if (LoopPeeling.getValue(options)) {
+ appendPhase(new IncrementalCanonicalizerPhase<>(canonicalizer, new LoopPeelingPhase(loopPolicies)));
+ }
+
+ if (LoopUnswitch.getValue(options)) {
+ appendPhase(new IncrementalCanonicalizerPhase<>(canonicalizer, new LoopUnswitchingPhase(loopPolicies)));
}
if (PartialEscapeAnalysis.getValue(options)) {
@@ -118,8 +109,6 @@
appendPhase(new EarlyReadEliminationPhase(canonicalizer));
}
- appendPhase(new RemoveValueProxyPhase());
-
if (NodeCounterPhase.Options.NodeCounters.getValue(options)) {
appendPhase(new NodeCounterPhase(NodeCounterPhase.Stage.LATE));
}
@@ -127,6 +116,7 @@
appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER));
}
+ @Override
public LoopPolicies createLoopPolicies() {
return new DefaultLoopPolicies();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/LowTier.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/LowTier.java Thu Oct 31 16:54:16 2019 -0700
@@ -24,7 +24,7 @@
package org.graalvm.compiler.core.phases;
-import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
+import static org.graalvm.compiler.core.common.GraalOptions.LateMembars;
import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Required;
import org.graalvm.compiler.core.common.GraalOptions;
@@ -33,11 +33,11 @@
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.common.ExpandLogicPhase;
import org.graalvm.compiler.phases.common.FixReadsPhase;
+import org.graalvm.compiler.phases.common.InsertMembarsPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.common.ProfileCompiledMethodsPhase;
import org.graalvm.compiler.phases.common.PropagateDeoptimizeProbabilityPhase;
@@ -46,7 +46,7 @@
import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
import org.graalvm.compiler.phases.tiers.LowTierContext;
-public class LowTier extends PhaseSuite<LowTierContext> {
+public class LowTier extends BaseTier<LowTierContext> {
static class Options {
@@ -58,13 +58,8 @@
}
public LowTier(OptionValues options) {
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
- CanonicalizerPhase canonicalizerWithoutGVN = new CanonicalizerPhase();
- canonicalizerWithoutGVN.disableGVN();
- if (ImmutableCode.getValue(options)) {
- canonicalizer.disableReadCanonicalization();
- canonicalizerWithoutGVN.disableReadCanonicalization();
- }
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase(options);
+ CanonicalizerPhase canonicalizerWithoutGVN = canonicalizer.copyWithoutGVN();
if (Options.ProfileCompiledMethods.getValue(options)) {
appendPhase(new ProfileCompiledMethodsPhase());
@@ -85,6 +80,9 @@
appendPhase(new PropagateDeoptimizeProbabilityPhase());
+ if (LateMembars.getValue(options)) {
+ appendPhase(new InsertMembarsPhase());
+ }
appendPhase(new SchedulePhase(SchedulePhase.SchedulingStrategy.LATEST_OUT_OF_LOOPS));
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/MidTier.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/MidTier.java Thu Oct 31 16:54:16 2019 -0700
@@ -25,10 +25,8 @@
package org.graalvm.compiler.core.phases;
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;
import static org.graalvm.compiler.core.common.GraalOptions.OptFloatingReads;
-import static org.graalvm.compiler.core.common.GraalOptions.OptLoopTransform;
import static org.graalvm.compiler.core.common.GraalOptions.PartialUnroll;
import static org.graalvm.compiler.core.common.GraalOptions.ReassociateInvariants;
import static org.graalvm.compiler.core.common.GraalOptions.VerifyHeapAtReturn;
@@ -43,7 +41,6 @@
import org.graalvm.compiler.loop.phases.ReassociateInvariantPhase;
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeoptimizationGroupingPhase;
import org.graalvm.compiler.phases.common.FloatingReadPhase;
@@ -56,17 +53,15 @@
import org.graalvm.compiler.phases.common.LoopSafepointInsertionPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.common.OptimizeDivPhase;
+import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
import org.graalvm.compiler.phases.common.VerifyHeapAtReturnPhase;
import org.graalvm.compiler.phases.common.WriteBarrierAdditionPhase;
import org.graalvm.compiler.phases.tiers.MidTierContext;
-public class MidTier extends PhaseSuite<MidTierContext> {
+public class MidTier extends BaseTier<MidTierContext> {
public MidTier(OptionValues options) {
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
- if (ImmutableCode.getValue(options)) {
- canonicalizer.disableReadCanonicalization();
- }
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase(options);
appendPhase(new LockEliminationPhase());
@@ -80,8 +75,6 @@
appendPhase(new LoopSafepointEliminationPhase());
- appendPhase(new LoopSafepointInsertionPhase());
-
appendPhase(new GuardLoweringPhase());
if (MitigateSpeculativeExecutionAttacks.getValue(options) == GuardTargets || MitigateSpeculativeExecutionAttacks.getValue(options) == NonDeoptGuardTargets) {
@@ -92,18 +85,21 @@
appendPhase(new VerifyHeapAtReturnPhase());
}
+ appendPhase(new IncrementalCanonicalizerPhase<>(canonicalizer, new RemoveValueProxyPhase()));
+
+ appendPhase(new LoopSafepointInsertionPhase());
+
appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER));
appendPhase(new OptimizeDivPhase());
appendPhase(new FrameStateAssignmentPhase());
- LoopPolicies loopPolicies = createLoopPolicies();
- if (OptLoopTransform.getValue(options)) {
- if (PartialUnroll.getValue(options)) {
- appendPhase(new LoopPartialUnrollPhase(loopPolicies, canonicalizer));
- }
+ if (PartialUnroll.getValue(options)) {
+ LoopPolicies loopPolicies = createLoopPolicies();
+ appendPhase(new LoopPartialUnrollPhase(loopPolicies, canonicalizer));
}
+
if (ReassociateInvariants.getValue(options)) {
appendPhase(new ReassociateInvariantPhase());
}
@@ -117,6 +113,7 @@
appendPhase(new WriteBarrierAdditionPhase());
}
+ @Override
public LoopPolicies createLoopPolicies() {
return new DefaultLoopPolicies();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Thu Oct 31 16:54:16 2019 -0700
@@ -100,6 +100,7 @@
public HotSpotBackend createBackend(HotSpotGraalRuntimeProvider graalRuntime, CompilerConfiguration compilerConfiguration, HotSpotJVMCIRuntime jvmciRuntime, HotSpotBackend host) {
assert host == null;
+ OptionValues options = graalRuntime.getOptions();
JVMCIBackend jvmci = jvmciRuntime.getHostJVMCIBackend();
GraalHotSpotVMConfig config = graalRuntime.getVMConfig();
HotSpotProviders providers;
@@ -156,7 +157,7 @@
}
try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
plugins = createGraphBuilderPlugins(graalRuntime, compilerConfiguration, config, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes,
- graalRuntime.getOptions());
+ graalRuntime.getOptions(), target);
replacements.setGraphBuilderPlugins(plugins);
}
try (InitTimer rt = timer("create Suites provider")) {
@@ -165,6 +166,7 @@
providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers,
snippetReflection, wordTypes, plugins, gc);
replacements.setProviders(providers);
+ replacements.maybeInitializeEncoder(options);
}
try (InitTimer rt = timer("instantiate backend")) {
return createBackend(config, graalRuntime, providers);
@@ -180,7 +182,8 @@
HotSpotSnippetReflectionProvider snippetReflection,
HotSpotReplacementsImpl replacements,
HotSpotWordTypes wordTypes,
- OptionValues options) {
+ OptionValues options,
+ TargetDescription target) {
Plugins plugins = HotSpotGraphBuilderPlugins.create(graalRuntime,
compilerConfiguration,
config,
@@ -190,8 +193,9 @@
snippetReflection,
foreignCalls,
replacements,
- options);
- AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false,
+ options,
+ target);
+ AArch64GraphBuilderPlugins.register(plugins, replacements, false, //
/* registerMathPlugins */true, /* emitJDK9StringSubstitutions */true, config.useFMAIntrinsics);
return plugins;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java Thu Oct 31 16:54:16 2019 -0700
@@ -158,6 +158,7 @@
providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers,
snippetReflection, wordTypes, plugins, gc);
replacements.setProviders(providers);
+ replacements.maybeInitializeEncoder(options);
}
try (InitTimer rt = timer("instantiate backend")) {
return createBackend(config, graalRuntime, providers);
@@ -185,8 +186,9 @@
snippetReflection,
foreignCalls,
replacements,
- options);
- AMD64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), (AMD64) target.arch, false, JavaVersionUtil.JAVA_SPEC >= 9, config.useFMAIntrinsics);
+ options,
+ target);
+ AMD64GraphBuilderPlugins.register(plugins, replacements, (AMD64) target.arch, false, JavaVersionUtil.JAVA_SPEC >= 9, config.useFMAIntrinsics);
return plugins;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java Thu Oct 31 16:54:16 2019 -0700
@@ -87,6 +87,7 @@
public HotSpotBackend createBackend(HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, HotSpotJVMCIRuntime jvmciRuntime, HotSpotBackend host) {
assert host == null;
+ OptionValues options = runtime.getOptions();
GraalHotSpotVMConfig config = runtime.getVMConfig();
JVMCIBackend jvmci = jvmciRuntime.getHostJVMCIBackend();
HotSpotRegistersProvider registers = createRegisters();
@@ -106,12 +107,13 @@
BytecodeProvider bytecodeProvider = createBytecodeProvider(metaAccess, snippetReflection);
HotSpotReplacementsImpl replacements = createReplacements(target, p, snippetReflection, bytecodeProvider);
Plugins plugins = createGraphBuilderPlugins(runtime, compilerConfiguration, config, metaAccess, constantReflection, foreignCalls, snippetReflection, replacements, wordTypes,
- runtime.getOptions());
+ runtime.getOptions(), target);
replacements.setGraphBuilderPlugins(plugins);
HotSpotSuitesProvider suites = createSuites(config, runtime, compilerConfiguration, plugins, replacements);
HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers,
snippetReflection, wordTypes, plugins, gc);
replacements.setProviders(providers);
+ replacements.maybeInitializeEncoder(options);
return createBackend(config, runtime, providers);
}
@@ -125,7 +127,8 @@
HotSpotSnippetReflectionProvider snippetReflection,
HotSpotReplacementsImpl replacements,
HotSpotWordTypes wordTypes,
- OptionValues options) {
+ OptionValues options,
+ TargetDescription target) {
Plugins plugins = HotSpotGraphBuilderPlugins.create(
graalRuntime,
compilerConfiguration,
@@ -136,8 +139,9 @@
snippetReflection,
foreignCalls,
replacements,
- options);
- SPARCGraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false);
+ options,
+ target);
+ SPARCGraphBuilderPlugins.register(plugins, replacements, false);
return plugins;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Thu Oct 31 16:54:16 2019 -0700
@@ -24,9 +24,6 @@
package org.graalvm.compiler.hotspot.test;
-import static org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins.aesDecryptName;
-import static org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins.aesEncryptName;
-
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
@@ -368,10 +365,6 @@
add(ignore,
"com/sun/crypto/provider/GHASH.processBlocks([BII[J[J)V");
}
- if (!(config.useSHA1Intrinsics() || config.useSHA256Intrinsics() || config.useSHA512Intrinsics())) {
- add(ignore,
- "sun/security/provider/DigestBase.implCompressMultiBlock0([BII)I");
- }
if (!config.useFMAIntrinsics) {
add(ignore,
"java/lang/Math.fma(DDD)D",
@@ -516,15 +509,16 @@
"java/util/zip/CRC32C.updateDirectByteBuffer(IJII)I");
}
- boolean implNames = HotSpotGraphBuilderPlugins.cbcUsesImplNames(config);
- String cbcEncryptName = implNames ? "implEncrypt" : "encrypt";
- String cbcDecryptName = implNames ? "implDecrypt" : "decrypt";
+ String cbcEncryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implEncrypt", "encrypt");
+ String cbcDecryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implDecrypt", "decrypt");
+ String aesEncryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implEncryptBlock", "encryptBlock");
+ String aesDecryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implDecryptBlock", "decryptBlock");
// AES intrinsics
if (!config.useAESIntrinsics) {
add(ignore,
+ "com/sun/crypto/provider/AESCrypt." + aesEncryptName + "([BI[BI)V",
"com/sun/crypto/provider/AESCrypt." + aesDecryptName + "([BI[BI)V",
- "com/sun/crypto/provider/AESCrypt." + aesEncryptName + "([BI[BI)V",
"com/sun/crypto/provider/CipherBlockChaining." + cbcDecryptName + "([BII[BI)I",
"com/sun/crypto/provider/CipherBlockChaining." + cbcEncryptName + "([BII[BI)I");
}
@@ -549,28 +543,21 @@
if (!config.useSquareToLenIntrinsic()) {
add(ignore, "java/math/BigInteger.implSquareToLen([II[II)[I");
}
-
+ // DigestBase intrinsics
+ if (HotSpotGraphBuilderPlugins.isIntrinsicName(config, "sun/security/provider/DigestBase", "implCompressMultiBlock0") &&
+ !(config.useSHA1Intrinsics() || config.useSHA256Intrinsics() || config.useSHA512Intrinsics())) {
+ add(ignore, "sun/security/provider/DigestBase.implCompressMultiBlock0([BII)I");
+ }
// SHA intrinsics
+ String shaCompressName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(config, "sun/security/provider/SHA", "implCompress0", "implCompress");
if (!config.useSHA1Intrinsics()) {
- if (isJDK9OrHigher()) {
- add(ignore, "sun/security/provider/SHA.implCompress0([BI)V");
- } else {
- add(ignore, "sun/security/provider/SHA.implCompress([BI)V");
- }
+ add(ignore, "sun/security/provider/SHA." + shaCompressName + "([BI)V");
}
if (!config.useSHA256Intrinsics()) {
- if (isJDK9OrHigher()) {
- add(ignore, "sun/security/provider/SHA2.implCompress0([BI)V");
- } else {
- add(ignore, "sun/security/provider/SHA2.implCompress([BI)V");
- }
+ add(ignore, "sun/security/provider/SHA2." + shaCompressName + "([BI)V");
}
if (!config.useSHA512Intrinsics()) {
- if (isJDK9OrHigher()) {
- add(ignore, "sun/security/provider/SHA5.implCompress0([BI)V");
- } else {
- add(ignore, "sun/security/provider/SHA5.implCompress([BI)V");
- }
+ add(ignore, "sun/security/provider/SHA5." + shaCompressName + "([BI)V");
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java Thu Oct 31 16:54:16 2019 -0700
@@ -101,10 +101,10 @@
import org.graalvm.compiler.options.OptionsParser;
import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
-import org.graalvm.compiler.test.ModuleSupport;
+import org.graalvm.compiler.api.test.ModuleSupport;
import jdk.internal.vm.compiler.libgraal.LibGraal;
import jdk.internal.vm.compiler.libgraal.LibGraalScope;
-import jdk.internal.vm.compiler.libgraal.OptionsEncoder;
+import org.graalvm.util.OptionsEncoder;
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ConstantPoolSubstitutionsTests.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ConstantPoolSubstitutionsTests.java Thu Oct 31 16:54:16 2019 -0700
@@ -34,7 +34,7 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
-import org.graalvm.compiler.test.ModuleSupport;
+import org.graalvm.compiler.api.test.ModuleSupport;
import org.junit.BeforeClass;
import org.junit.Test;
import org.objectweb.asm.ClassWriter;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/DeferredBarrierAdditionTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/DeferredBarrierAdditionTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -38,7 +38,6 @@
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.OptimisticOptimizations;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.GuardLoweringPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.common.WriteBarrierAdditionPhase;
@@ -83,12 +82,12 @@
StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO, debug);
HighTierContext highContext = getDefaultHighTierContext();
MidTierContext midContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
- new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase()).apply(graph, highContext);
- new CanonicalizerPhase().apply(graph, highContext);
- new PartialEscapePhase(false, new CanonicalizerPhase(), debug.getOptions()).apply(graph, highContext);
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext);
+ new InliningPhase(new InlineEverythingPolicy(), createCanonicalizerPhase()).apply(graph, highContext);
+ this.createCanonicalizerPhase().apply(graph, highContext);
+ new PartialEscapePhase(false, createCanonicalizerPhase(), debug.getOptions()).apply(graph, highContext);
+ new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext);
new GuardLoweringPhase().apply(graph, midContext);
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
+ new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
new WriteBarrierAdditionPhase().apply(graph, midContext);
debug.dump(DebugContext.BASIC_LEVEL, graph, "After Write Barrier Addition");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotCryptoSubstitutionTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotCryptoSubstitutionTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -80,7 +80,9 @@
@Test
public void testAESCryptIntrinsics() throws Exception {
- if (compileAndInstall("com.sun.crypto.provider.AESCrypt", HotSpotGraphBuilderPlugins.aesEncryptName, HotSpotGraphBuilderPlugins.aesDecryptName)) {
+ String aesEncryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(runtime().getVMConfig(), "com/sun/crypto/provider/AESCrypt", "implEncryptBlock", "encryptBlock");
+ String aesDecryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(runtime().getVMConfig(), "com/sun/crypto/provider/AESCrypt", "implDecryptBlock", "decryptBlock");
+ if (compileAndInstall("com.sun.crypto.provider.AESCrypt", aesEncryptName, aesDecryptName)) {
ByteArrayOutputStream actual = new ByteArrayOutputStream();
actual.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding"));
actual.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding"));
@@ -90,9 +92,8 @@
@Test
public void testCipherBlockChainingIntrinsics() throws Exception {
- boolean implNames = HotSpotGraphBuilderPlugins.cbcUsesImplNames(runtime().getVMConfig());
- String cbcEncryptName = implNames ? "implEncrypt" : "encrypt";
- String cbcDecryptName = implNames ? "implDecrypt" : "decrypt";
+ String cbcEncryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(runtime().getVMConfig(), "com/sun/crypto/provider/CipherBlockChaining", "implEncrypt", "encrypt");
+ String cbcDecryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(runtime().getVMConfig(), "com/sun/crypto/provider/CipherBlockChaining", "implDecrypt", "decrypt");
if (compileAndInstall("com.sun.crypto.provider.CipherBlockChaining", cbcEncryptName, cbcDecryptName)) {
ByteArrayOutputStream actual = new ByteArrayOutputStream();
actual.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding"));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotInvokeDynamicPluginTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotInvokeDynamicPluginTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -93,7 +93,7 @@
StructuredGraph graph = parseEager(name, AllowAssumptions.NO, new OptionValues(getInitialOptions(), GraalOptions.GeneratePIC, true));
MidTierContext midTierContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
Assert.assertEquals(expectedResolves, graph.getNodes().filter(ResolveDynamicConstantNode.class).count());
Assert.assertEquals(0, graph.getNodes().filter(ResolveDynamicStubCall.class).count());
CoreProviders context = getProviders();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ReplaceConstantNodesPhaseTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ReplaceConstantNodesPhaseTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -117,7 +117,7 @@
private void test(String name, int expectedInits, int expectedResolves, int expectedLoads) {
StructuredGraph graph = parseEager(name, AllowAssumptions.NO, new OptionValues(getInitialOptions(), GraalOptions.GeneratePIC, true));
HighTierContext highTierContext = getDefaultHighTierContext();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
new EliminateRedundantInitializationPhase().apply(graph, highTierContext);
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext);
new LoadJavaMirrorWithKlassPhase(config).apply(graph, highTierContext);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestSHASubstitutions.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestSHASubstitutions.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -34,9 +34,7 @@
import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
-import org.graalvm.compiler.hotspot.replacements.SHA2Substitutions;
-import org.graalvm.compiler.hotspot.replacements.SHA5Substitutions;
-import org.graalvm.compiler.hotspot.replacements.SHASubstitutions;
+import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins;
import org.graalvm.compiler.runtime.RuntimeProvider;
import jdk.vm.ci.code.InstalledCode;
@@ -74,7 +72,8 @@
@Test
public void testSha1() {
if (getConfig().useSHA1Intrinsics()) {
- testWithInstalledIntrinsic("sun.security.provider.SHA", SHASubstitutions.implCompressName, "testDigest", "SHA-1", getData());
+ String implCompressName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(getConfig(), "sun/security/provider/SHA", "implCompress0", "implCompress");
+ testWithInstalledIntrinsic("sun.security.provider.SHA", implCompressName, "testDigest", "SHA-1", getData());
}
}
@@ -107,14 +106,16 @@
@Test
public void testSha256() {
if (getConfig().useSHA256Intrinsics()) {
- testWithInstalledIntrinsic("sun.security.provider.SHA2", SHA2Substitutions.implCompressName, "testDigest", "SHA-256", getData());
+ String implCompressName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(getConfig(), "sun/security/provider/SHA", "implCompress0", "implCompress");
+ testWithInstalledIntrinsic("sun.security.provider.SHA2", implCompressName, "testDigest", "SHA-256", getData());
}
}
@Test
public void testSha512() {
if (getConfig().useSHA512Intrinsics()) {
- testWithInstalledIntrinsic("sun.security.provider.SHA5", SHA5Substitutions.implCompressName, "testDigest", "SHA-512", getData());
+ String implCompressName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(getConfig(), "sun/security/provider/SHA", "implCompress0", "implCompress");
+ testWithInstalledIntrinsic("sun.security.provider.SHA5", implCompressName, "testDigest", "SHA-512", getData());
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierAdditionTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierAdditionTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -44,7 +44,6 @@
import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.phases.OptimisticOptimizations;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.GuardLoweringPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.common.WriteBarrierAdditionPhase;
@@ -263,11 +262,11 @@
StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO, debug);
HighTierContext highContext = getDefaultHighTierContext();
MidTierContext midContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
- new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase()).apply(graph, highContext);
- new CanonicalizerPhase().apply(graph, highContext);
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext);
+ new InliningPhase(new InlineEverythingPolicy(), createCanonicalizerPhase()).apply(graph, highContext);
+ this.createCanonicalizerPhase().apply(graph, highContext);
+ new LoweringPhase(this.createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext);
new GuardLoweringPhase().apply(graph, midContext);
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
+ new LoweringPhase(this.createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
new WriteBarrierAdditionPhase().apply(graph, midContext);
debug.dump(DebugContext.BASIC_LEVEL, graph, "After Write Barrier Addition");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java Thu Oct 31 16:54:16 2019 -0700
@@ -72,26 +72,40 @@
replacements.getDefaultReplacementBytecodeProvider(), replacements.target);
}
+ public void maybeInitializeEncoder(OptionValues options) {
+ if (IS_BUILDING_NATIVE_IMAGE || UseEncodedGraphs.getValue(options)) {
+ synchronized (HotSpotReplacementsImpl.class) {
+ if (snippetEncoder == null) {
+ snippetEncoder = new SymbolicSnippetEncoder(this);
+ }
+ }
+ }
+ }
+
@Override
public Class<? extends GraphBuilderPlugin> getIntrinsifyingPlugin(ResolvedJavaMethod method) {
return method.getAnnotation(HotSpotOperation.class) != null ? HotSpotWordOperationPlugin.class : super.getIntrinsifyingPlugin(method);
}
@Override
- public void registerMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context, OptionValues options) {
- if (!IS_IN_NATIVE_IMAGE) {
- if (IS_BUILDING_NATIVE_IMAGE || UseEncodedGraphs.getValue(options)) {
- synchronized (HotSpotReplacementsImpl.class) {
- if (snippetEncoder == null) {
- snippetEncoder = new SymbolicSnippetEncoder(this);
- }
- snippetEncoder.registerMethodSubstitution(plugin, original, context, options);
- }
- }
+ public void registerMethodSubstitution(MethodSubstitutionPlugin plugin) {
+ if (snippetEncoder != null) {
+ snippetEncoder.registerMethodSubstitution(plugin);
}
}
@Override
+ public void registerConditionalPlugin(InvocationPlugin plugin) {
+ if (snippetEncoder != null) {
+ snippetEncoder.registerConditionalPlugin(plugin);
+ }
+ }
+
+ public void checkRegistered(MethodSubstitutionPlugin plugin) {
+ snippetEncoder.checkRegistered(plugin);
+ }
+
+ @Override
public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug, Cancellable cancellable) {
boolean useEncodedGraphs = UseEncodedGraphs.getValue(debug.getOptions());
if (IS_IN_NATIVE_IMAGE || useEncodedGraphs) {
@@ -99,8 +113,9 @@
InvocationPlugin plugin = replacements.getGraphBuilderPlugins().getInvocationPlugins().lookupInvocation(method);
if (plugin instanceof MethodSubstitutionPlugin) {
MethodSubstitutionPlugin msp = (MethodSubstitutionPlugin) plugin;
- if (useEncodedGraphs) {
- replacements.registerMethodSubstitution(msp, method, ROOT_COMPILATION, debug.getOptions());
+ if (!IS_IN_NATIVE_IMAGE && useEncodedGraphs) {
+ replacements.maybeInitializeEncoder(debug.getOptions());
+ replacements.registerMethodSubstitution(msp);
}
StructuredGraph methodSubstitution = replacements.getMethodSubstitution(msp, method, ROOT_COMPILATION, StructuredGraph.AllowAssumptions.YES, cancellable, debug.getOptions());
methodSubstitution.resetDebug(debug);
@@ -119,7 +134,8 @@
if (plugin instanceof MethodSubstitutionPlugin && (!plugin.inlineOnly() || invokeBci >= 0)) {
MethodSubstitutionPlugin msPlugin = (MethodSubstitutionPlugin) plugin;
if (!IS_IN_NATIVE_IMAGE && useEncodedGraphs) {
- registerMethodSubstitution(msPlugin, targetMethod, INLINE_AFTER_PARSING, options);
+ maybeInitializeEncoder(options);
+ registerMethodSubstitution(msPlugin);
}
// This assumes the normal path creates the graph using
// GraphBuilderConfiguration.getSnippetDefault with omits exception edges
@@ -155,9 +171,6 @@
assert registeredSnippets.add(method) : "Cannot register snippet twice: " + method.format("%H.%n(%p)");
if (IS_BUILDING_NATIVE_IMAGE || UseEncodedGraphs.getValue(options)) {
synchronized (HotSpotReplacementsImpl.class) {
- if (snippetEncoder == null) {
- snippetEncoder = new SymbolicSnippetEncoder(this);
- }
snippetEncoder.registerSnippet(method, original, receiver, trackNodeSourcePosition, options);
}
}
@@ -169,7 +182,10 @@
snippetRegistrationClosed = true;
}
- private static SymbolicSnippetEncoder.EncodedSnippets getEncodedSnippets() {
+ private static SymbolicSnippetEncoder.EncodedSnippets getEncodedSnippets(OptionValues options) {
+ if (!IS_IN_NATIVE_IMAGE && snippetEncoder != null) {
+ snippetEncoder.encode(options);
+ }
return encodedSnippets;
}
@@ -210,20 +226,15 @@
@SuppressWarnings("try")
private StructuredGraph getEncodedSnippet(ResolvedJavaMethod method, Object[] args, StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) {
- boolean useEncodedGraphs = UseEncodedGraphs.getValue(options);
- if (IS_IN_NATIVE_IMAGE || useEncodedGraphs) {
+ if (IS_IN_NATIVE_IMAGE || UseEncodedGraphs.getValue(options)) {
synchronized (HotSpotReplacementsImpl.class) {
- if (!IS_IN_NATIVE_IMAGE) {
- snippetEncoder.encode(options);
- }
-
- if (getEncodedSnippets() == null) {
+ if (getEncodedSnippets(options) == null) {
throw GraalError.shouldNotReachHere("encoded snippets not found");
}
// Snippets graphs can contain foreign object reference and
// outlive a single compilation.
try (CompilationContext scope = HotSpotGraalServices.enterGlobalCompilationContext()) {
- StructuredGraph graph = getEncodedSnippets().getEncodedSnippet(method, this, args, allowAssumptions, options);
+ StructuredGraph graph = getEncodedSnippets(options).getEncodedSnippet(method, this, args, allowAssumptions, options);
if (graph == null) {
throw GraalError.shouldNotReachHere("snippet not found: " + method.format("%H.%n(%p)"));
}
@@ -239,16 +250,11 @@
@Override
public StructuredGraph getMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context,
StructuredGraph.AllowAssumptions allowAssumptions, Cancellable cancellable, OptionValues options) {
- boolean useEncodedGraphs = UseEncodedGraphs.getValue(options);
- if (IS_IN_NATIVE_IMAGE || useEncodedGraphs) {
- if (!IS_IN_NATIVE_IMAGE) {
- snippetEncoder.encode(options);
- }
-
- if (getEncodedSnippets() == null) {
+ if (IS_IN_NATIVE_IMAGE || UseEncodedGraphs.getValue(options)) {
+ if (getEncodedSnippets(options) == null) {
throw GraalError.shouldNotReachHere("encoded snippets not found");
}
- return getEncodedSnippets().getMethodSubstitutionGraph(plugin, original, this, context, allowAssumptions, cancellable, options);
+ return getEncodedSnippets(options).getMethodSubstitutionGraph(plugin, original, this, context, allowAssumptions, cancellable, options);
}
return null;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java Thu Oct 31 16:54:16 2019 -0700
@@ -30,6 +30,7 @@
import static org.graalvm.compiler.core.common.GraalOptions.UseEncodedGraphs;
import static org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.createIntrinsicInlineInfo;
import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.INLINE_AFTER_PARSING;
+import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.ROOT_COMPILATION;
import java.util.ArrayList;
import java.util.Arrays;
@@ -156,6 +157,12 @@
*/
private Map<String, StructuredGraph> preparedSnippetGraphs = new HashMap<>();
+ private Set<MethodSubstitutionPlugin> knownPlugins = new HashSet<>();
+
+ private Set<InvocationPlugin> conditionalPlugins = new HashSet<>();
+
+ private int preparedPlugins = 0;
+
/**
* The invocation plugins which were delayed during graph preparation.
*/
@@ -239,7 +246,7 @@
* for lookup.
*/
private static String methodKey(ResolvedJavaMethod method) {
- return method.format("%f %H.%n(%P)");
+ return method.format("%H.%n(%P)");
}
SymbolicSnippetEncoder(HotSpotReplacementsImpl replacements) {
@@ -255,15 +262,30 @@
this.snippetReplacements.setGraphBuilderPlugins(copy);
}
+ synchronized void registerMethodSubstitution(MethodSubstitutionPlugin plugin) {
+ knownPlugins.add(plugin);
+ }
+
+ void registerConditionalPlugin(InvocationPlugin plugin) {
+ conditionalPlugins.add(plugin);
+ }
+
+ synchronized void checkRegistered(MethodSubstitutionPlugin plugin) {
+ if (!knownPlugins.contains(plugin)) {
+ throw new GraalError("missing plugin should have been registered during construction");
+ }
+ }
+
/**
* Compiles the snippet and stores the graph.
*/
- synchronized void registerMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context, OptionValues options) {
+ private synchronized void registerMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context, OptionValues options) {
ResolvedJavaMethod method = plugin.getSubstitute(snippetReplacements.getProviders().getMetaAccess());
assert method.getAnnotation(MethodSubstitution.class) != null : "MethodSubstitution must be annotated with @" + MethodSubstitution.class.getSimpleName();
- StructuredGraph subst = buildGraph(method, original, null, true, false, context, options);
+ String originalMethodString = plugin.originalMethodAsString();
+ StructuredGraph subst = buildGraph(method, original, originalMethodString, null, true, false, context, options);
snippetMethods.add(method);
- originalMethods.put(methodKey(method), methodKey(original));
+ originalMethods.put(methodKey(method), originalMethodString);
preparedSnippetGraphs.put(plugin.toString() + context, subst);
}
@@ -370,7 +392,7 @@
}
}
- private StructuredGraph buildGraph(ResolvedJavaMethod method, ResolvedJavaMethod original, Object receiver, boolean requireInlining, boolean trackNodeSourcePosition,
+ private StructuredGraph buildGraph(ResolvedJavaMethod method, ResolvedJavaMethod original, String originalMethodString, Object receiver, boolean requireInlining, boolean trackNodeSourcePosition,
IntrinsicContext.CompilationContext context, OptionValues options) {
assert method.hasBytecodes() : "Snippet must not be abstract or native";
Object[] args = null;
@@ -378,7 +400,13 @@
args = new Object[method.getSignature().getParameterCount(true)];
args[0] = receiver;
}
- try (DebugContext debug = openDebugContext("Snippet_", method, options)) {
+ // To get dumping out from this context during image building, it's necessary to pass the
+ // dumping options directly to the VM, otherwise they aren't available during initialization
+ // of the backend. Use this:
+ //
+ // -J-Dgraal.Dump=SymbolicSnippetEncoder_:2 -J-Dgraal.PrintGraph=File
+ // -J-Dgraal.DebugStubsAndSnippets=true
+ try (DebugContext debug = openDebugContext("SymbolicSnippetEncoder_", method, options)) {
StructuredGraph graph = snippetReplacements.makeGraph(debug, snippetReplacements.getDefaultReplacementBytecodeProvider(), method, args, original, trackNodeSourcePosition, null, context);
// Check if all methods which should be inlined are really inlined.
@@ -388,7 +416,7 @@
throw GraalError.shouldNotReachHere("method " + callee.format("%H.%n") + " not inlined in snippet " + method.getName() + " (maybe not final?)");
}
}
- assert verifySnippetEncodeDecode(method, original, trackNodeSourcePosition, graph);
+ assert verifySnippetEncodeDecode(debug, method, original, originalMethodString, trackNodeSourcePosition, graph);
debug.dump(DebugContext.VERBOSE_LEVEL, graph, "After buildGraph");
return graph;
}
@@ -426,46 +454,45 @@
}
@SuppressWarnings("try")
- private boolean verifySnippetEncodeDecode(ResolvedJavaMethod method, ResolvedJavaMethod original, boolean trackNodeSourcePosition, StructuredGraph graph) {
+ private boolean verifySnippetEncodeDecode(DebugContext debug, ResolvedJavaMethod method, ResolvedJavaMethod original, String originalMethodString, boolean trackNodeSourcePosition,
+ StructuredGraph graph) {
// Verify the encoding and decoding process
EncodedGraph encodedGraph = GraphEncoder.encodeSingleGraph(graph, HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getTarget().arch);
- try (DebugContext debug = snippetReplacements.openDebugContext("VerifySnippetEncodeDecode_", method, graph.getOptions())) {
- HotSpotProviders originalProvider = (HotSpotProviders) snippetReplacements.getProviders();
+ HotSpotProviders originalProvider = (HotSpotProviders) snippetReplacements.getProviders();
- SnippetReflectionProvider snippetReflection = originalProvider.getSnippetReflection();
- SymbolicSnippetEncoder.HotSpotSubstrateConstantReflectionProvider constantReflection = new SymbolicSnippetEncoder.HotSpotSubstrateConstantReflectionProvider(
- originalProvider.getConstantReflection());
- HotSpotProviders newProviders = new HotSpotProviders(originalProvider.getMetaAccess(), originalProvider.getCodeCache(), constantReflection,
- originalProvider.getConstantFieldProvider(), originalProvider.getForeignCalls(), originalProvider.getLowerer(), null, originalProvider.getSuites(),
- originalProvider.getRegisters(), snippetReflection, originalProvider.getWordTypes(), originalProvider.getGraphBuilderPlugins(), originalProvider.getGC());
- HotSpotSnippetReplacementsImpl filteringReplacements = new HotSpotSnippetReplacementsImpl(newProviders, snippetReflection,
- originalProvider.getReplacements().getDefaultReplacementBytecodeProvider(), originalProvider.getCodeCache().getTarget());
- filteringReplacements.setGraphBuilderPlugins(originalProvider.getReplacements().getGraphBuilderPlugins());
- try (DebugContext.Scope scaope = debug.scope("VerifySnippetEncodeDecode", graph)) {
- for (int i = 0; i < encodedGraph.getNumObjects(); i++) {
- filterSnippetObject(encodedGraph.getObject(i));
- }
- StructuredGraph snippet = filteringReplacements.makeGraph(debug, filteringReplacements.getDefaultReplacementBytecodeProvider(), method, null, original,
- trackNodeSourcePosition, null);
- SymbolicEncodedGraph symbolicGraph = new SymbolicEncodedGraph(encodedGraph, method.getDeclaringClass(), original != null ? methodKey(original) : null);
- StructuredGraph decodedSnippet = decodeSnippetGraph(symbolicGraph, original != null ? original : method, originalReplacements, null,
- StructuredGraph.AllowAssumptions.ifNonNull(graph.getAssumptions()), graph.getOptions());
- String snippetString = getCanonicalGraphString(snippet, true, false);
- String decodedSnippetString = getCanonicalGraphString(decodedSnippet, true, false);
- if (snippetString.equals(decodedSnippetString)) {
- debug.log("Snippet decode for %s produces exactly same graph", method);
- debug.dump(DebugContext.VERBOSE_LEVEL, decodedSnippet, "Decoded snippet graph for %s", method);
- } else {
- debug.log("Snippet decode for %s produces different graph", method);
- debug.log("%s", compareGraphStrings(snippet, snippetString, decodedSnippet, decodedSnippetString));
- debug.dump(DebugContext.VERBOSE_LEVEL, snippet, "Snippet graph for %s", method);
- debug.dump(DebugContext.VERBOSE_LEVEL, graph, "Encoded snippet graph for %s", method);
- debug.dump(DebugContext.VERBOSE_LEVEL, decodedSnippet, "Decoded snippet graph for %s", method);
- }
- } catch (Throwable t) {
- throw debug.handle(t);
+ SnippetReflectionProvider snippetReflection = originalProvider.getSnippetReflection();
+ SymbolicSnippetEncoder.HotSpotSubstrateConstantReflectionProvider constantReflection = new SymbolicSnippetEncoder.HotSpotSubstrateConstantReflectionProvider(
+ originalProvider.getConstantReflection());
+ HotSpotProviders newProviders = new HotSpotProviders(originalProvider.getMetaAccess(), originalProvider.getCodeCache(), constantReflection,
+ originalProvider.getConstantFieldProvider(), originalProvider.getForeignCalls(), originalProvider.getLowerer(), null, originalProvider.getSuites(),
+ originalProvider.getRegisters(), snippetReflection, originalProvider.getWordTypes(), originalProvider.getGraphBuilderPlugins(), originalProvider.getGC());
+ HotSpotSnippetReplacementsImpl filteringReplacements = new HotSpotSnippetReplacementsImpl(newProviders, snippetReflection,
+ originalProvider.getReplacements().getDefaultReplacementBytecodeProvider(), originalProvider.getCodeCache().getTarget());
+ filteringReplacements.setGraphBuilderPlugins(originalProvider.getReplacements().getGraphBuilderPlugins());
+ try (DebugContext.Scope scaope = debug.scope("VerifySnippetEncodeDecode", graph)) {
+ for (int i = 0; i < encodedGraph.getNumObjects(); i++) {
+ filterSnippetObject(encodedGraph.getObject(i));
}
+ StructuredGraph snippet = filteringReplacements.makeGraph(debug, filteringReplacements.getDefaultReplacementBytecodeProvider(), method, null, original,
+ trackNodeSourcePosition, null);
+ SymbolicEncodedGraph symbolicGraph = new SymbolicEncodedGraph(encodedGraph, method.getDeclaringClass(), originalMethodString);
+ StructuredGraph decodedSnippet = decodeSnippetGraph(symbolicGraph, original != null ? original : method, originalReplacements, null,
+ StructuredGraph.AllowAssumptions.ifNonNull(graph.getAssumptions()), graph.getOptions());
+ String snippetString = getCanonicalGraphString(snippet, true, false);
+ String decodedSnippetString = getCanonicalGraphString(decodedSnippet, true, false);
+ if (snippetString.equals(decodedSnippetString)) {
+ debug.log("Snippet decode for %s produces exactly same graph", method);
+ debug.dump(DebugContext.VERBOSE_LEVEL, decodedSnippet, "Decoded snippet graph for %s", method);
+ } else {
+ debug.log("Snippet decode for %s produces different graph", method);
+ debug.log("%s", compareGraphStrings(snippet, snippetString, decodedSnippet, decodedSnippetString));
+ debug.dump(DebugContext.VERBOSE_LEVEL, snippet, "Snippet graph for %s", method);
+ debug.dump(DebugContext.VERBOSE_LEVEL, graph, "Encoded snippet graph for %s", method);
+ debug.dump(DebugContext.VERBOSE_LEVEL, decodedSnippet, "Decoded snippet graph for %s", method);
+ }
+ } catch (Throwable t) {
+ throw debug.handle(t);
}
return true;
}
@@ -475,6 +502,17 @@
*/
@SuppressWarnings("try")
private synchronized EncodedSnippets maybeEncodeSnippets(OptionValues options) {
+ Set<MethodSubstitutionPlugin> plugins = this.knownPlugins;
+ if (preparedPlugins != plugins.size()) {
+ for (MethodSubstitutionPlugin plugin : plugins) {
+ ResolvedJavaMethod original = plugin.getOriginalMethod(originalReplacements.getProviders().getMetaAccess());
+ registerMethodSubstitution(plugin, original, INLINE_AFTER_PARSING, options);
+ if (!original.isNative()) {
+ registerMethodSubstitution(plugin, original, ROOT_COMPILATION, options);
+ }
+ }
+ preparedPlugins = plugins.size();
+ }
Map<String, StructuredGraph> graphs = this.preparedSnippetGraphs;
if (encodedGraphs != graphs.size()) {
DebugContext debug = openDebugContext("SnippetEncoder", null, options);
@@ -499,7 +537,7 @@
if (original != null) {
originalMethods.put(key, methodKey(original));
}
- StructuredGraph snippet = buildGraph(method, original, receiver, true, trackNodeSourcePosition, INLINE_AFTER_PARSING, options);
+ StructuredGraph snippet = buildGraph(method, original, null, receiver, true, trackNodeSourcePosition, INLINE_AFTER_PARSING, options);
snippetMethods.add(method);
preparedSnippetGraphs.put(key, snippet);
}
@@ -1001,7 +1039,7 @@
* This horror show of classes exists solely get {@link HotSpotSnippetBytecodeParser} to be used
* as the parser for these snippets.
*/
- static class HotSpotSnippetReplacementsImpl extends HotSpotReplacementsImpl {
+ class HotSpotSnippetReplacementsImpl extends HotSpotReplacementsImpl {
HotSpotSnippetReplacementsImpl(HotSpotReplacementsImpl replacements, Providers providers) {
super(replacements, providers);
}
@@ -1016,7 +1054,7 @@
}
}
- static class SnippetGraphMaker extends ReplacementsImpl.GraphMaker {
+ class SnippetGraphMaker extends ReplacementsImpl.GraphMaker {
SnippetGraphMaker(ReplacementsImpl replacements, ResolvedJavaMethod substitute, ResolvedJavaMethod substitutedMethod) {
super(replacements, substitute, substitutedMethod);
}
@@ -1028,7 +1066,7 @@
}
}
- static class HotSpotSnippetGraphBuilderPhase extends GraphBuilderPhase.Instance {
+ class HotSpotSnippetGraphBuilderPhase extends GraphBuilderPhase.Instance {
HotSpotSnippetGraphBuilderPhase(Providers theProviders, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, IntrinsicContext initialIntrinsicContext) {
super(theProviders, graphBuilderConfig, optimisticOpts, initialIntrinsicContext);
}
@@ -1039,7 +1077,7 @@
}
}
- static class HotSpotSnippetBytecodeParser extends BytecodeParser {
+ class HotSpotSnippetBytecodeParser extends BytecodeParser {
HotSpotSnippetBytecodeParser(GraphBuilderPhase.Instance graphBuilderInstance, StructuredGraph graph, BytecodeParser parent, ResolvedJavaMethod method, int entryBCI,
IntrinsicContext intrinsicContext) {
super(graphBuilderInstance, graph, parent, method, entryBCI, intrinsicContext);
@@ -1066,6 +1104,13 @@
// Always defer Fold until decode time but NodeIntrinsics may fold if they are able.
return false;
}
+ InvocationPlugin plugin = graphBuilderConfig.getPlugins().getInvocationPlugins().lookupInvocation(targetMethod);
+ if (conditionalPlugins.contains(plugin)) {
+ // Because supporting arbitrary plugins in the context of encoded graphs is complex
+ // we disallow it. This limitation can be worked around through the use of method
+ // substitutions.
+ throw new GraalError("conditional plugins are unsupported in snippets and method substitutions: " + targetMethod + " " + plugin);
+ }
return super.tryInvocationPlugin(invokeKind, args, targetMethod, resultType);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java Thu Oct 31 16:54:16 2019 -0700
@@ -646,7 +646,7 @@
// write the displaced mark to the correct stack slot
AddressNode addressDisplacedMark = createOffsetAddress(graph, beginLockScope, runtime.getVMConfig().basicLockDisplacedHeaderOffset);
- WriteNode writeStackSlot = graph.add(new WriteNode(addressDisplacedMark, DISPLACED_MARK_WORD_LOCATION, loadDisplacedHeader, BarrierType.NONE));
+ WriteNode writeStackSlot = graph.add(new WriteNode(addressDisplacedMark, DISPLACED_MARK_WORD_LOCATION, loadDisplacedHeader, BarrierType.NONE, false));
graph.addBeforeFixed(migrationEnd, writeStackSlot);
// load the lock object from the osr buffer
@@ -776,7 +776,7 @@
}
AddressNode address = createOffsetAddress(graph, object, runtime.getVMConfig().hubOffset);
- return graph.add(new WriteNode(address, HUB_WRITE_LOCATION, writeValue, BarrierType.NONE));
+ return graph.add(new WriteNode(address, HUB_WRITE_LOCATION, writeValue, BarrierType.NONE, false));
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Thu Oct 31 16:54:16 2019 -0700
@@ -39,7 +39,6 @@
import java.util.zip.CRC32;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
-import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.core.common.type.StampFactory;
@@ -92,6 +91,7 @@
import org.graalvm.compiler.nodes.memory.ReadNode;
import org.graalvm.compiler.nodes.memory.address.AddressNode;
import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
+import org.graalvm.compiler.nodes.spi.Replacements;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
@@ -108,6 +108,7 @@
import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.vm.ci.code.CodeUtil;
+import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.hotspot.VMIntrinsicMethod;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.DeoptimizationAction;
@@ -128,6 +129,7 @@
* @param snippetReflection
* @param foreignCalls
* @param options
+ * @param target
*/
public static Plugins create(HotSpotGraalRuntimeProvider graalRuntime,
CompilerConfiguration compilerConfiguration,
@@ -138,11 +140,11 @@
SnippetReflectionProvider snippetReflection,
ForeignCallsProvider foreignCalls,
ReplacementsImpl replacements,
- OptionValues options) {
+ OptionValues options, TargetDescription target) {
InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(graalRuntime, config, compilerConfiguration);
Plugins plugins = new Plugins(invocationPlugins);
- NodeIntrinsificationProvider nodeIntrinsificationProvider = new NodeIntrinsificationProvider(metaAccess, snippetReflection, foreignCalls, wordTypes);
+ NodeIntrinsificationProvider nodeIntrinsificationProvider = new NodeIntrinsificationProvider(metaAccess, snippetReflection, foreignCalls, wordTypes, target);
HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(snippetReflection, wordTypes);
HotSpotNodePlugin nodePlugin = new HotSpotNodePlugin(wordOperationPlugin, config, wordTypes);
@@ -171,29 +173,28 @@
@Override
public void run() {
- BytecodeProvider replacementBytecodeProvider = replacements.getDefaultReplacementBytecodeProvider();
- registerObjectPlugins(invocationPlugins, options, config, replacementBytecodeProvider);
- registerClassPlugins(plugins, config, replacementBytecodeProvider);
+ registerObjectPlugins(invocationPlugins, options, config, replacements);
+ registerClassPlugins(plugins, config, replacements);
registerSystemPlugins(invocationPlugins, foreignCalls);
- registerThreadPlugins(invocationPlugins, metaAccess, wordTypes, config, replacementBytecodeProvider);
+ registerThreadPlugins(invocationPlugins, metaAccess, wordTypes, config, replacements);
if (!GeneratePIC.getValue(options)) {
registerCallSitePlugins(invocationPlugins);
}
- registerReflectionPlugins(invocationPlugins, replacementBytecodeProvider);
- registerConstantPoolPlugins(invocationPlugins, wordTypes, config, replacementBytecodeProvider);
- registerAESPlugins(invocationPlugins, config, replacementBytecodeProvider);
- registerCRC32Plugins(invocationPlugins, config, replacementBytecodeProvider);
- registerCRC32CPlugins(invocationPlugins, config, replacementBytecodeProvider);
- registerBigIntegerPlugins(invocationPlugins, config, replacementBytecodeProvider);
- registerSHAPlugins(invocationPlugins, config, replacementBytecodeProvider);
+ registerReflectionPlugins(invocationPlugins, replacements);
+ registerConstantPoolPlugins(invocationPlugins, wordTypes, config, replacements);
+ registerAESPlugins(invocationPlugins, config, replacements);
+ registerCRC32Plugins(invocationPlugins, config, replacements);
+ registerCRC32CPlugins(invocationPlugins, config, replacements);
+ registerBigIntegerPlugins(invocationPlugins, config, replacements);
+ registerSHAPlugins(invocationPlugins, config, replacements);
registerGHASHPlugins(invocationPlugins, config, metaAccess, foreignCalls);
- registerCounterModePlugins(invocationPlugins, config, replacementBytecodeProvider);
+ registerCounterModePlugins(invocationPlugins, config, replacements);
registerBase64Plugins(invocationPlugins, config, metaAccess, foreignCalls);
- registerUnsafePlugins(invocationPlugins, config, replacementBytecodeProvider);
- StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, snippetReflection, invocationPlugins, replacementBytecodeProvider, true, false);
- registerArrayPlugins(invocationPlugins, replacementBytecodeProvider);
- registerStringPlugins(invocationPlugins, replacementBytecodeProvider);
- registerArraysSupportPlugins(invocationPlugins, config, replacementBytecodeProvider);
+ registerUnsafePlugins(invocationPlugins, config, replacements);
+ StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, snippetReflection, invocationPlugins, replacements, true, false);
+ registerArrayPlugins(invocationPlugins, replacements);
+ registerStringPlugins(invocationPlugins, replacements);
+ registerArraysSupportPlugins(invocationPlugins, config, replacements);
for (NodeIntrinsicPluginFactory factory : GraalServices.load(NodeIntrinsicPluginFactory.class)) {
factory.registerPlugins(invocationPlugins, nodeIntrinsificationProvider);
@@ -203,8 +204,8 @@
return plugins;
}
- private static void registerObjectPlugins(InvocationPlugins plugins, OptionValues options, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins, Object.class, bytecodeProvider);
+ private static void registerObjectPlugins(InvocationPlugins plugins, OptionValues options, GraalHotSpotVMConfig config, Replacements replacements) {
+ Registration r = new Registration(plugins, Object.class, replacements);
if (!GeneratePIC.getValue(options)) {
// FIXME: clone() requires speculation and requires a fix in here (to check that
// b.getAssumptions() != null), and in ReplacementImpl.getSubstitution() where there is
@@ -235,8 +236,8 @@
}
}
- private static void registerClassPlugins(Plugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins.getInvocationPlugins(), Class.class, bytecodeProvider);
+ private static void registerClassPlugins(Plugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
+ Registration r = new Registration(plugins.getInvocationPlugins(), Class.class, replacements);
r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "getModifiers", Receiver.class);
r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "isInterface", Receiver.class);
@@ -273,8 +274,8 @@
plugins.register(plugin, VolatileCallSite.class, "getTarget", Receiver.class);
}
- private static void registerReflectionPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins, reflectionClass, bytecodeProvider);
+ private static void registerReflectionPlugins(InvocationPlugins plugins, Replacements replacements) {
+ Registration r = new Registration(plugins, reflectionClass, replacements);
r.register0("getCallerClass", new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
@@ -290,12 +291,12 @@
r.registerMethodSubstitution(ReflectionSubstitutions.class, "getClassAccessFlags", Class.class);
}
- private static void registerUnsafePlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider replacementBytecodeProvider) {
+ private static void registerUnsafePlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
Registration r;
if (JavaVersionUtil.JAVA_SPEC <= 8) {
- r = new Registration(plugins, Unsafe.class, replacementBytecodeProvider);
+ r = new Registration(plugins, Unsafe.class, replacements);
} else {
- r = new Registration(plugins, "jdk.internal.misc.Unsafe", replacementBytecodeProvider);
+ r = new Registration(plugins, "jdk.internal.misc.Unsafe", replacements);
}
String substituteMethodName = config.doingUnsafeAccessOffset != Integer.MAX_VALUE ? "copyMemoryGuarded" : "copyMemory";
r.registerMethodSubstitution(HotSpotUnsafeSubstitutions.class, HotSpotUnsafeSubstitutions.copyMemoryName, substituteMethodName, Receiver.class, Object.class, long.class, Object.class,
@@ -340,8 +341,8 @@
return true;
}
- private static void registerConstantPoolPlugins(InvocationPlugins plugins, WordTypes wordTypes, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins, constantPoolClass, bytecodeProvider);
+ private static void registerConstantPoolPlugins(InvocationPlugins plugins, WordTypes wordTypes, GraalHotSpotVMConfig config, Replacements replacements) {
+ Registration r = new Registration(plugins, constantPoolClass, replacements);
r.register2("getSize0", Receiver.class, Object.class, new InvocationPlugin() {
@Override
@@ -411,22 +412,22 @@
});
}
- private static void registerArrayPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins, Array.class, bytecodeProvider);
+ private static void registerArrayPlugins(InvocationPlugins plugins, Replacements replacements) {
+ Registration r = new Registration(plugins, Array.class, replacements);
r.setAllowOverwrite(true);
r.registerMethodSubstitution(HotSpotArraySubstitutions.class, "newInstance", Class.class, int.class);
}
- private static void registerStringPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
+ private static void registerStringPlugins(InvocationPlugins plugins, Replacements replacements) {
if (JavaVersionUtil.JAVA_SPEC > 8) {
- final Registration utf16r = new Registration(plugins, "java.lang.StringUTF16", bytecodeProvider);
+ final Registration utf16r = new Registration(plugins, "java.lang.StringUTF16", replacements);
utf16r.registerMethodSubstitution(StringUTF16Substitutions.class, "toBytes", char[].class, int.class, int.class);
utf16r.registerMethodSubstitution(StringUTF16Substitutions.class, "getChars", byte[].class, int.class, int.class, char[].class, int.class);
}
}
- private static void registerThreadPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, WordTypes wordTypes, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins, Thread.class, bytecodeProvider);
+ private static void registerThreadPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, WordTypes wordTypes, GraalHotSpotVMConfig config, Replacements replacements) {
+ Registration r = new Registration(plugins, Thread.class, replacements);
r.register0("currentThread", new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
@@ -443,40 +444,51 @@
r.registerMethodSubstitution(ThreadSubstitutions.class, "isInterrupted", Receiver.class, boolean.class);
}
- public static final String aesEncryptName;
- public static final String aesDecryptName;
-
public static final String reflectionClass;
public static final String constantPoolClass;
static {
if (JavaVersionUtil.JAVA_SPEC <= 8) {
- aesEncryptName = "encryptBlock";
- aesDecryptName = "decryptBlock";
reflectionClass = "sun.reflect.Reflection";
constantPoolClass = "sun.reflect.ConstantPool";
} else {
- aesEncryptName = "implEncryptBlock";
- aesDecryptName = "implDecryptBlock";
reflectionClass = "jdk.internal.reflect.Reflection";
constantPoolClass = "jdk.internal.reflect.ConstantPool";
}
}
- public static boolean cbcUsesImplNames(GraalHotSpotVMConfig config) {
+ public static String lookupIntrinsicName(GraalHotSpotVMConfig config, String className, String name1, String name2) {
+ boolean foundName1 = false;
+ boolean foundName2 = false;
+ String name = name1;
for (VMIntrinsicMethod intrinsic : config.getStore().getIntrinsics()) {
- if ("com/sun/crypto/provider/CipherBlockChaining".equals(intrinsic.declaringClass)) {
- if ("encrypt".equals(intrinsic.name)) {
- return false;
- } else if ("implEncrypt".equals(intrinsic.name)) {
+ if (className.equals(intrinsic.declaringClass)) {
+ if (name1.equals(intrinsic.name)) {
+ foundName1 = true;
+ } else if (name2.equals(intrinsic.name)) {
+ foundName2 = true;
+ name = name2;
+ }
+ }
+ }
+ if (foundName1 != foundName2) {
+ return name;
+ }
+ throw GraalError.shouldNotReachHere();
+ }
+
+ public static boolean isIntrinsicName(GraalHotSpotVMConfig config, String className, String name) {
+ for (VMIntrinsicMethod intrinsic : config.getStore().getIntrinsics()) {
+ if (className.equals(intrinsic.declaringClass)) {
+ if (name.equals(intrinsic.name)) {
return true;
}
}
}
- throw GraalError.shouldNotReachHere();
+ return false;
}
- private static void registerAESPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
+ private static void registerAESPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
if (config.useAESIntrinsics) {
assert config.aescryptEncryptBlockStub != 0L;
assert config.aescryptDecryptBlockStub != 0L;
@@ -484,72 +496,66 @@
assert config.cipherBlockChainingDecryptAESCryptStub != 0L;
String arch = config.osArch;
String decryptSuffix = arch.equals("sparc") ? "WithOriginalKey" : "";
- Registration r = new Registration(plugins, "com.sun.crypto.provider.CipherBlockChaining", bytecodeProvider);
- boolean implNames = cbcUsesImplNames(config);
- String cbcEncryptName = implNames ? "implEncrypt" : "encrypt";
- String cbcDecryptName = implNames ? "implDecrypt" : "decrypt";
-
+ String cbcEncryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implEncrypt", "encrypt");
+ String cbcDecryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implDecrypt", "decrypt");
+ Registration r = new Registration(plugins, "com.sun.crypto.provider.CipherBlockChaining", replacements);
r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcEncryptName, Receiver.class, byte[].class, int.class, int.class, byte[].class, int.class);
r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcDecryptName, cbcDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, int.class, byte[].class,
int.class);
- r = new Registration(plugins, "com.sun.crypto.provider.AESCrypt", bytecodeProvider);
+ String aesEncryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implEncryptBlock", "encryptBlock");
+ String aesDecryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implDecryptBlock", "decryptBlock");
+
+ r = new Registration(plugins, "com.sun.crypto.provider.AESCrypt", replacements);
r.registerMethodSubstitution(AESCryptSubstitutions.class, aesEncryptName, Receiver.class, byte[].class, int.class, byte[].class, int.class);
r.registerMethodSubstitution(AESCryptSubstitutions.class, aesDecryptName, aesDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, byte[].class, int.class);
}
}
- private static void registerBigIntegerPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins, BigInteger.class, bytecodeProvider);
- if (config.useMultiplyToLenIntrinsic()) {
- assert config.multiplyToLen != 0L;
- if (JavaVersionUtil.JAVA_SPEC <= 8) {
- r.registerMethodSubstitution(BigIntegerSubstitutions.class, "multiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class, int.class,
- int[].class);
- } else {
- r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMultiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class, int.class,
- int[].class);
- }
+ private static void registerBigIntegerPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
+ Registration r = new Registration(plugins, BigInteger.class, replacements);
+ assert !config.useMultiplyToLenIntrinsic() || config.multiplyToLen != 0L;
+ if (JavaVersionUtil.JAVA_SPEC <= 8) {
+ r.registerConditionalMethodSubstitution(config.useMultiplyToLenIntrinsic(), BigIntegerSubstitutions.class, "multiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class,
+ int.class, int[].class);
+ } else {
+ r.registerConditionalMethodSubstitution(config.useMultiplyToLenIntrinsic(), BigIntegerSubstitutions.class, "implMultiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class,
+ int.class, int[].class);
}
- if (config.useMulAddIntrinsic()) {
- r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMulAdd", int[].class, int[].class, int.class, int.class, int.class);
- }
- if (config.useMontgomeryMultiplyIntrinsic()) {
- r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMontgomeryMultiply", int[].class, int[].class, int[].class, int.class, long.class, int[].class);
- }
- if (config.useMontgomerySquareIntrinsic()) {
- r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMontgomerySquare", int[].class, int[].class, int.class, long.class, int[].class);
- }
- if (config.useSquareToLenIntrinsic()) {
- r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implSquareToLen", int[].class, int.class, int[].class, int.class);
- }
+ r.registerConditionalMethodSubstitution(config.useMulAddIntrinsic(), BigIntegerSubstitutions.class, "implMulAdd", int[].class, int[].class, int.class, int.class, int.class);
+ r.registerConditionalMethodSubstitution(config.useMontgomeryMultiplyIntrinsic(), BigIntegerSubstitutions.class, "implMontgomeryMultiply", int[].class, int[].class, int[].class, int.class,
+ long.class, int[].class);
+ r.registerConditionalMethodSubstitution(config.useMontgomerySquareIntrinsic(), BigIntegerSubstitutions.class, "implMontgomerySquare", int[].class, int[].class, int.class, long.class,
+ int[].class);
+ r.registerConditionalMethodSubstitution(config.useSquareToLenIntrinsic(), BigIntegerSubstitutions.class, "implSquareToLen", int[].class, int.class, int[].class, int.class);
}
- private static void registerSHAPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
+ private static void registerSHAPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
boolean useSha1 = config.useSHA1Intrinsics();
boolean useSha256 = config.useSHA256Intrinsics();
boolean useSha512 = config.useSHA512Intrinsics();
- if (JavaVersionUtil.JAVA_SPEC > 8 && (useSha1 || useSha256 || useSha512)) {
- Registration r = new Registration(plugins, "sun.security.provider.DigestBase", bytecodeProvider);
+ if (isIntrinsicName(config, "sun/security/provider/DigestBase", "implCompressMultiBlock0") && (useSha1 || useSha256 || useSha512)) {
+ Registration r = new Registration(plugins, "sun.security.provider.DigestBase", replacements);
r.registerMethodSubstitution(DigestBaseSubstitutions.class, "implCompressMultiBlock0", Receiver.class, byte[].class, int.class, int.class);
}
+ String implCompressName = lookupIntrinsicName(config, "sun/security/provider/SHA", "implCompress", "implCompress0");
if (useSha1) {
assert config.sha1ImplCompress != 0L;
- Registration r = new Registration(plugins, "sun.security.provider.SHA", bytecodeProvider);
- r.registerMethodSubstitution(SHASubstitutions.class, SHASubstitutions.implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
+ Registration r = new Registration(plugins, "sun.security.provider.SHA", replacements);
+ r.registerMethodSubstitution(SHASubstitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
}
if (useSha256) {
assert config.sha256ImplCompress != 0L;
- Registration r = new Registration(plugins, "sun.security.provider.SHA2", bytecodeProvider);
- r.registerMethodSubstitution(SHA2Substitutions.class, SHA2Substitutions.implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
+ Registration r = new Registration(plugins, "sun.security.provider.SHA2", replacements);
+ r.registerMethodSubstitution(SHA2Substitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
}
if (useSha512) {
assert config.sha512ImplCompress != 0L;
- Registration r = new Registration(plugins, "sun.security.provider.SHA5", bytecodeProvider);
- r.registerMethodSubstitution(SHA5Substitutions.class, SHA5Substitutions.implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
+ Registration r = new Registration(plugins, "sun.security.provider.SHA5", replacements);
+ r.registerMethodSubstitution(SHA5Substitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
}
}
@@ -586,11 +592,12 @@
}
}
- private static void registerCounterModePlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
- if (config.useAESCTRIntrinsics) {
- assert config.counterModeAESCrypt != 0L;
- Registration r = new Registration(plugins, "com.sun.crypto.provider.CounterMode", bytecodeProvider);
- r.registerMethodSubstitution(CounterModeSubstitutions.class, "implCrypt", Receiver.class, byte[].class, int.class, int.class, byte[].class, int.class);
+ private static void registerCounterModePlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
+ if (JavaVersionUtil.JAVA_SPEC > 8) {
+ assert !config.useAESCTRIntrinsics || config.counterModeAESCrypt != 0L;
+ Registration r = new Registration(plugins, "com.sun.crypto.provider.CounterMode", replacements);
+ r.registerConditionalMethodSubstitution(config.useAESCTRIntrinsics, CounterModeSubstitutions.class, "implCrypt", Receiver.class, byte[].class, int.class, int.class, byte[].class,
+ int.class);
}
}
@@ -626,32 +633,31 @@
}
}
- private static void registerCRC32Plugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
- if (config.useCRC32Intrinsics) {
- Registration r = new Registration(plugins, CRC32.class, bytecodeProvider);
- r.registerMethodSubstitution(CRC32Substitutions.class, "update", int.class, int.class);
- if (JavaVersionUtil.JAVA_SPEC <= 8) {
- r.registerMethodSubstitution(CRC32Substitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
- r.registerMethodSubstitution(CRC32Substitutions.class, "updateByteBuffer", int.class, long.class, int.class, int.class);
- } else {
- r.registerMethodSubstitution(CRC32Substitutions.class, "updateBytes0", int.class, byte[].class, int.class, int.class);
- r.registerMethodSubstitution(CRC32Substitutions.class, "updateByteBuffer0", int.class, long.class, int.class, int.class);
- }
+ private static void registerCRC32Plugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
+ Registration r = new Registration(plugins, CRC32.class, replacements);
+ r.registerConditionalMethodSubstitution(config.useCRC32Intrinsics, CRC32Substitutions.class, "update", int.class, int.class);
+ if (JavaVersionUtil.JAVA_SPEC <= 8) {
+ r.registerConditionalMethodSubstitution(config.useCRC32Intrinsics, CRC32Substitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
+ r.registerConditionalMethodSubstitution(config.useCRC32Intrinsics, CRC32Substitutions.class, "updateByteBuffer", int.class, long.class, int.class, int.class);
+ } else {
+ r.registerConditionalMethodSubstitution(config.useCRC32Intrinsics, CRC32Substitutions.class, "updateBytes0", int.class, byte[].class, int.class, int.class);
+ r.registerConditionalMethodSubstitution(config.useCRC32Intrinsics, CRC32Substitutions.class, "updateByteBuffer0", int.class, long.class, int.class, int.class);
}
}
- private static void registerCRC32CPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
- if (config.useCRC32CIntrinsics) {
- Registration r = new Registration(plugins, "java.util.zip.CRC32C", bytecodeProvider);
- r.registerMethodSubstitution(CRC32CSubstitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
- r.registerMethodSubstitution(CRC32CSubstitutions.class, "updateDirectByteBuffer", int.class, long.class, int.class, int.class);
+ private static void registerCRC32CPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
+ if (JavaVersionUtil.JAVA_SPEC > 8) {
+ Registration r = new Registration(plugins, "java.util.zip.CRC32C", replacements);
+ r.registerConditionalMethodSubstitution(config.useCRC32CIntrinsics, CRC32CSubstitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
+ r.registerConditionalMethodSubstitution(config.useCRC32CIntrinsics, CRC32CSubstitutions.class, "updateDirectByteBuffer", int.class, long.class, int.class, int.class);
}
}
- private static void registerArraysSupportPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
- if (config.useVectorizedMismatchIntrinsic) {
- Registration r = new Registration(plugins, "jdk.internal.util.ArraysSupport", bytecodeProvider);
- r.registerMethodSubstitution(ArraysSupportSubstitutions.class, "vectorizedMismatch", Object.class, long.class, Object.class, long.class, int.class, int.class);
+ private static void registerArraysSupportPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
+ if (JavaVersionUtil.JAVA_SPEC > 8) {
+ Registration r = new Registration(plugins, "jdk.internal.util.ArraysSupport", replacements);
+ r.registerConditionalMethodSubstitution(config.useVectorizedMismatchIntrinsic, ArraysSupportSubstitutions.class, "vectorizedMismatch", Object.class, long.class, Object.class, long.class,
+ int.class, int.class);
}
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java Thu Oct 31 16:54:16 2019 -0700
@@ -339,8 +339,8 @@
linkForeignCall(options, providers, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
linkForeignCall(options, providers, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
linkForeignCall(options, providers, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, STACK_INSPECTABLE_LEAF, NOT_REEXECUTABLE, any());
- linkForeignCall(options, providers, NOTIFY, c.notifyAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
- linkForeignCall(options, providers, NOTIFY_ALL, c.notifyAllAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any());
+ linkForeignCall(options, providers, NOTIFY, c.notifyAddress, PREPEND_THREAD, LEAF_NO_VZERO, NOT_REEXECUTABLE, any());
+ linkForeignCall(options, providers, NOTIFY_ALL, c.notifyAllAddress, PREPEND_THREAD, LEAF_NO_VZERO, NOT_REEXECUTABLE, any());
linkForeignCall(options, providers, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
linkForeignCall(options, providers, LOG_OBJECT, c.logObjectAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
linkForeignCall(options, providers, LOG_PRIMITIVE, c.logPrimitiveAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSuitesProvider.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSuitesProvider.java Thu Oct 31 16:54:16 2019 -0700
@@ -168,7 +168,7 @@
if (profileInstructions != null) {
suites.getPostAllocationOptimizationStage().appendPhase(new HotSpotInstructionProfiling(profileInstructions));
}
- if (Assertions.detailedAssertionsEnabled(options)) {
+ if (Assertions.assertionsEnabled()) {
suites.getPostAllocationOptimizationStage().appendPhase(new VerifyMaxRegisterSizePhase(config.maxVectorSize));
}
return suites;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/BeginLockScopeNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/BeginLockScopeNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -73,7 +73,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/EndLockScopeNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/EndLockScopeNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -56,7 +56,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/StubForeignCallNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/StubForeignCallNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -72,7 +72,7 @@
}
@Override
- public LocationIdentity[] getLocationIdentities() {
+ public LocationIdentity[] getKilledLocationIdentities() {
LocationIdentity[] killedLocations = foreignCalls.getKilledLocations(descriptor);
killedLocations = Arrays.copyOf(killedLocations, killedLocations.length + 1);
killedLocations[killedLocations.length - 1] = HotSpotReplacementsUtil.PENDING_EXCEPTION_LOCATION;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -64,7 +64,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -98,7 +98,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicConstantNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicConstantNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -64,7 +64,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicStubCall.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicStubCall.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -93,7 +93,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/AheadOfTimeVerificationPhase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/AheadOfTimeVerificationPhase.java Thu Oct 31 16:54:16 2019 -0700
@@ -70,10 +70,22 @@
}
private static boolean isDirectMethodHandle(ConstantNode node) {
+ String typeName = StampTool.typeOrNull(node).getName();
if (!isObject(node)) {
return false;
}
- return "Ljava/lang/invoke/DirectMethodHandle;".equals(StampTool.typeOrNull(node).getName());
+
+ switch (typeName) {
+ case "Ljava/lang/invoke/DirectMethodHandle;":
+ case "Ljava/lang/invoke/DirectMethodHandle$StaticAccessor;":
+ case "Ljava/lang/invoke/DirectMethodHandle$Accessor;":
+ case "Ljava/lang/invoke/DirectMethodHandle$Constructor;":
+ case "Ljava/lang/invoke/DirectMethodHandle$Special;":
+ case "Ljava/lang/invoke/DirectMethodHandle$Interface;":
+ return true;
+ default:
+ return false;
+ }
}
private static boolean isBoundMethodHandle(ConstantNode node) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -61,7 +61,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return HotSpotReplacementsUtil.MARK_WORD_LOCATION;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA2Substitutions.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA2Substitutions.java Thu Oct 31 16:54:16 2019 -0700
@@ -36,7 +36,6 @@
import org.graalvm.compiler.nodes.extended.RawLoadNode;
import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
import org.graalvm.compiler.replacements.ReplacementsUtil;
-import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.graalvm.compiler.word.Word;
import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.internal.vm.compiler.word.WordFactory;
@@ -46,8 +45,6 @@
@ClassSubstitution(className = "sun.security.provider.SHA2", optional = true)
public class SHA2Substitutions {
- public static final String implCompressName = JavaVersionUtil.JAVA_SPEC <= 8 ? "implCompress" : "implCompress0";
-
@MethodSubstitution(isStatic = false)
static void implCompress0(Object receiver, byte[] buf, int ofs) {
Object realReceiver = PiNode.piCastNonNull(receiver, HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA5Substitutions.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA5Substitutions.java Thu Oct 31 16:54:16 2019 -0700
@@ -37,7 +37,6 @@
import org.graalvm.compiler.nodes.extended.RawLoadNode;
import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
import org.graalvm.compiler.replacements.ReplacementsUtil;
-import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.graalvm.compiler.word.Word;
import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.internal.vm.compiler.word.WordFactory;
@@ -47,8 +46,6 @@
@ClassSubstitution(className = "sun.security.provider.SHA5", optional = true)
public class SHA5Substitutions {
- public static final String implCompressName = JavaVersionUtil.JAVA_SPEC <= 8 ? "implCompress" : "implCompress0";
-
@MethodSubstitution(isStatic = false)
static void implCompress0(Object receiver, byte[] buf, int ofs) {
Object realReceiver = PiNode.piCastNonNull(receiver, HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHASubstitutions.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHASubstitutions.java Thu Oct 31 16:54:16 2019 -0700
@@ -37,7 +37,6 @@
import org.graalvm.compiler.nodes.extended.RawLoadNode;
import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
import org.graalvm.compiler.replacements.ReplacementsUtil;
-import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.graalvm.compiler.word.Word;
import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.internal.vm.compiler.word.WordFactory;
@@ -47,8 +46,6 @@
@ClassSubstitution(className = "sun.security.provider.SHA", optional = true)
public class SHASubstitutions {
- public static final String implCompressName = JavaVersionUtil.JAVA_SPEC <= 8 ? "implCompress" : "implCompress0";
-
@MethodSubstitution(isStatic = false)
static void implCompress0(Object receiver, byte[] buf, int ofs) {
Object realReceiver = PiNode.piCastNonNull(receiver, HotSpotReplacementsUtil.methodHolderClass(INJECTED_INTRINSIC_CONTEXT));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ForeignCallStub.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ForeignCallStub.java Thu Oct 31 16:54:16 2019 -0700
@@ -56,7 +56,6 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
import org.graalvm.compiler.replacements.GraphKit;
import org.graalvm.compiler.replacements.nodes.ReadRegisterNode;
import org.graalvm.compiler.word.Word;
@@ -258,7 +257,6 @@
debug.dump(DebugContext.VERBOSE_LEVEL, graph, "Initial stub graph");
kit.inlineInvokes("Foreign call stub.", "Backend");
- new RemoveValueProxyPhase().apply(graph);
debug.dump(DebugContext.VERBOSE_LEVEL, graph, "Stub graph before compilation");
return graph;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/SnippetStub.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/SnippetStub.java Thu Oct 31 16:54:16 2019 -0700
@@ -41,7 +41,6 @@
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
-import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
import org.graalvm.compiler.replacements.SnippetTemplate;
import org.graalvm.compiler.replacements.Snippets;
@@ -100,9 +99,8 @@
}
}
- new RemoveValueProxyPhase().apply(graph);
graph.setGuardsStage(GuardsStage.FLOATING_GUARDS);
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = CanonicalizerPhase.create();
canonicalizer.apply(graph, providers);
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, providers);
} catch (Throwable e) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Thu Oct 31 16:54:16 2019 -0700
@@ -3221,7 +3221,7 @@
lastInstr = loopBegin;
// Create phi functions for all local variables and operand stack slots.
- frameState.insertLoopPhis(liveness, block.loopId, loopBegin, forceLoopPhis(), stampFromValueForForcedPhis());
+ frameState.insertLoopPhis(liveness, block.loopId, loopBegin, forceLoopPhis() || this.graphBuilderConfig.replaceLocalsWithConstants(), stampFromValueForForcedPhis());
loopBegin.setStateAfter(createFrameState(block.startBci, loopBegin));
/*
@@ -3545,8 +3545,9 @@
* will never see that the branch is taken. This can lead to deopt loops or OSR
* failure.
*/
+ double calculatedProbability = negated ? BranchProbabilityNode.DEOPT_PROBABILITY : 1.0 - BranchProbabilityNode.DEOPT_PROBABILITY;
FixedNode deoptSuccessor = BeginNode.begin(deopt);
- ValueNode ifNode = genIfNode(condition, negated ? deoptSuccessor : noDeoptSuccessor, negated ? noDeoptSuccessor : deoptSuccessor, negated ? 1 - probability : probability);
+ ValueNode ifNode = genIfNode(condition, negated ? deoptSuccessor : noDeoptSuccessor, negated ? noDeoptSuccessor : deoptSuccessor, calculatedProbability);
postProcessIfNode(ifNode);
append(ifNode);
}
@@ -3569,8 +3570,28 @@
}
this.controlFlowSplit = true;
- FixedNode trueSuccessor = createTarget(trueBlock, frameState, false, false);
- FixedNode falseSuccessor = createTarget(falseBlock, frameState, false, true);
+ FixedNode falseSuccessor = createTarget(falseBlock, frameState, false, false);
+ FixedNode trueSuccessor = createTarget(trueBlock, frameState, false, true);
+
+ if (this.graphBuilderConfig.replaceLocalsWithConstants() && condition instanceof CompareNode) {
+ CompareNode compareNode = (CompareNode) condition;
+ if (compareNode.condition() == CanonicalCondition.EQ) {
+ ValueNode constantNode = null;
+ ValueNode nonConstantNode = null;
+ if (compareNode.getX() instanceof ConstantNode) {
+ constantNode = compareNode.getX();
+ nonConstantNode = compareNode.getY();
+ } else if (compareNode.getY() instanceof ConstantNode) {
+ constantNode = compareNode.getY();
+ nonConstantNode = compareNode.getX();
+ }
+
+ if (constantNode != null && nonConstantNode != null) {
+ this.getEntryState(trueBlock).replaceValue(nonConstantNode, constantNode);
+ }
+ }
+ }
+
ValueNode ifNode = genIfNode(condition, trueSuccessor, falseSuccessor, probability);
postProcessIfNode(ifNode);
append(ifNode);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java Thu Oct 31 16:54:16 2019 -0700
@@ -328,8 +328,7 @@
outerFrameState = parent.getFrameStateBuilder().create(parent.bci(), parent.getNonIntrinsicAncestor(), true, null, null);
}
if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI && parent != null) {
- FrameState newFrameState = outerFrameState.duplicateModified(outerFrameState.bci, true, false, JavaKind.Void, new JavaKind[]{JavaKind.Object}, new ValueNode[]{stack[0]});
- return newFrameState;
+ return outerFrameState.duplicateModified(graph, outerFrameState.bci, true, false, JavaKind.Void, new JavaKind[]{JavaKind.Object}, new ValueNode[]{stack[0]});
}
if (bci == BytecodeFrame.INVALID_FRAMESTATE_BCI) {
throw shouldNotReachHere();
@@ -527,21 +526,21 @@
ValueNode value = locals[i];
if (value != null && value != TWO_SLOT_MARKER && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) {
debug.log(" inserting proxy for %s", value);
- locals[i] = ProxyNode.forValue(value, loopExit, graph);
+ locals[i] = ProxyNode.forValue(value, loopExit);
}
}
for (int i = 0; i < stackSize(); i++) {
ValueNode value = stack[i];
if (value != null && value != TWO_SLOT_MARKER && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) {
debug.log(" inserting proxy for %s", value);
- stack[i] = ProxyNode.forValue(value, loopExit, graph);
+ stack[i] = ProxyNode.forValue(value, loopExit);
}
}
for (int i = 0; i < lockedObjects.length; i++) {
ValueNode value = lockedObjects[i];
if (value != null && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) {
debug.log(" inserting proxy for %s", value);
- lockedObjects[i] = ProxyNode.forValue(value, loopExit, graph);
+ lockedObjects[i] = ProxyNode.forValue(value, loopExit);
}
}
}
@@ -1028,4 +1027,17 @@
}
sideEffects.add(sideEffect);
}
+
+ public void replaceValue(ValueNode oldValue, ValueNode newValue) {
+ for (int i = 0; i < locals.length; ++i) {
+ if (locals[i] == oldValue) {
+ locals[i] = newValue;
+ }
+ }
+ for (int i = 0; i < stack.length; ++i) {
+ if (stack[i] == oldValue) {
+ stack[i] = newValue;
+ }
+ }
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/backend/LargeConstantSectionTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/backend/LargeConstantSectionTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -38,7 +38,7 @@
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.jtt.JTTTest;
-import org.graalvm.compiler.test.ExportingClassLoader;
+import org.graalvm.compiler.api.test.ExportingClassLoader;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/except/UntrustedInterfaces.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/except/UntrustedInterfaces.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -25,7 +25,7 @@
package org.graalvm.compiler.jtt.except;
import org.graalvm.compiler.jtt.JTTTest;
-import org.graalvm.compiler.test.ExportingClassLoader;
+import org.graalvm.compiler.api.test.ExportingClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import org.objectweb.asm.ClassWriter;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/NestedLoop_EA.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/NestedLoop_EA.java Thu Oct 31 16:54:16 2019 -0700
@@ -44,7 +44,7 @@
protected Suites createSuites(OptionValues options) {
Suites suites = super.createSuites(options);
ListIterator<BasePhase<? super HighTierContext>> position = suites.getHighTier().findPhase(PartialEscapePhase.class);
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = this.createCanonicalizerPhase();
// incremental canonicalizer of PEA is missing some important canonicalization (TODO?)
position.add(canonicalizer);
position.add(new PartialEscapePhase(true, canonicalizer, options));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/TrichotomyTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/TrichotomyTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -2527,7 +2527,7 @@
// test folding
StructuredGraph graph = self.parseForCompile(self.getResolvedJavaMethod(name));
HighTierContext context = self.getDefaultHighTierContext();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = self.createCanonicalizerPhase();
canonicalizer.apply(graph, context);
Assert.assertTrue("Too many ConditionalNodes after canonicalization", graph.getNodes().filter(ConditionalNode.class).count() <= 1);
Assert.assertTrue("Unexpected IfNodes after canonicalization", graph.getNodes().filter(IfNode.class).isEmpty());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArithmeticOp.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArithmeticOp.java Thu Oct 31 16:54:16 2019 -0700
@@ -58,6 +58,13 @@
DIV,
SMULH,
UMULH,
+ SMULL,
+ SMNEGL,
+ MADD,
+ MSUB,
+ FMADD,
+ SMADDL,
+ SMSUBL,
REM,
UDIV,
UREM,
@@ -279,6 +286,12 @@
case MNEG:
masm.mneg(size, dst, src1, src2);
break;
+ case SMULL:
+ masm.smull(size, dst, src1, src2);
+ break;
+ case SMNEGL:
+ masm.smnegl(size, dst, src1, src2);
+ break;
case DIV:
masm.sdiv(size, dst, src1, src2);
break;
@@ -477,11 +490,10 @@
@Use(REG) protected AllocatableValue src3;
/**
- * Computes <code>result = src3 <op> src1 * src2</code>.
+ * Computes <code>result = src3 +/- src1 * src2</code>.
*/
public MultiplyAddSubOp(AArch64ArithmeticOp op, AllocatableValue result, AllocatableValue src1, AllocatableValue src2, AllocatableValue src3) {
super(TYPE);
- assert op == ADD || op == SUB || op == FADD;
this.op = op;
this.result = result;
this.src1 = src1;
@@ -493,15 +505,23 @@
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
int size = result.getPlatformKind().getSizeInBytes() * Byte.SIZE;
switch (op) {
- case ADD:
+ case MADD:
masm.madd(size, asRegister(result), asRegister(src1), asRegister(src2), asRegister(src3));
break;
- case SUB:
+ case MSUB:
masm.msub(size, asRegister(result), asRegister(src1), asRegister(src2), asRegister(src3));
break;
- case FADD:
+ case FMADD:
masm.fmadd(size, asRegister(result), asRegister(src1), asRegister(src2), asRegister(src3));
break;
+ case SMADDL:
+ assert size == 64;
+ masm.smaddl(size, asRegister(result), asRegister(src1), asRegister(src2), asRegister(src3));
+ break;
+ case SMSUBL:
+ assert size == 64;
+ masm.smsubl(size, asRegister(result), asRegister(src1), asRegister(src2), asRegister(src3));
+ break;
default:
throw GraalError.shouldNotReachHere();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java Thu Oct 31 16:54:16 2019 -0700
@@ -96,7 +96,7 @@
public static final class MoveToRegOp extends AbstractMoveOp {
public static final LIRInstructionClass<MoveToRegOp> TYPE = LIRInstructionClass.create(MoveToRegOp.class);
- @Def({REG, HINT}) protected AllocatableValue result;
+ @Def({REG, STACK, HINT}) protected AllocatableValue result;
@Use({REG, STACK}) protected AllocatableValue input;
public MoveToRegOp(AMD64Kind moveKind, AllocatableValue result, AllocatableValue input) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringLatin1InflateOp.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringLatin1InflateOp.java Thu Oct 31 16:54:16 2019 -0700
@@ -32,6 +32,8 @@
import static jdk.vm.ci.code.ValueUtil.asRegister;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
+import java.util.EnumSet;
+
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.amd64.AMD64Address;
import org.graalvm.compiler.asm.amd64.AMD64Assembler;
@@ -43,8 +45,10 @@
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.amd64.AMD64.CPUFeature;
import jdk.vm.ci.amd64.AMD64Kind;
import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.meta.Value;
@Opcode("AMD64_STRING_INFLATE")
@@ -73,7 +77,7 @@
rdstTemp = rdst = dst;
rlenTemp = rlen = len;
- vtmp1 = tool.newVariable(LIRKind.value(AMD64Kind.V512_BYTE));
+ vtmp1 = useAVX512ForStringInflateCompress(tool.target()) ? tool.newVariable(LIRKind.value(AMD64Kind.V512_BYTE)) : tool.newVariable(LIRKind.value(AMD64Kind.V128_BYTE));
rtmp2 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD));
}
@@ -89,6 +93,13 @@
byteArrayInflate(masm, src, dst, len, tmp1, tmp2);
}
+ public static boolean useAVX512ForStringInflateCompress(TargetDescription target) {
+ EnumSet<CPUFeature> features = ((AMD64) target.arch).getFeatures();
+ return features.contains(AMD64.CPUFeature.AVX512BW) &&
+ features.contains(AMD64.CPUFeature.AVX512VL) &&
+ features.contains(AMD64.CPUFeature.BMI2);
+ }
+
/**
* Inflate a Latin1 string using a byte[] array representation into a UTF16 string using a
* char[] array representation.
@@ -110,10 +121,7 @@
assert dst.number != len.number && dst.number != tmp.number;
assert len.number != tmp.number;
- if (masm.supports(AMD64.CPUFeature.AVX512BW) &&
- masm.supports(AMD64.CPUFeature.AVX512VL) &&
- masm.supports(AMD64.CPUFeature.BMI2)) {
-
+ if (useAVX512ForStringInflateCompress(masm.target)) {
// If the length of the string is less than 16, we chose not to use the
// AVX512 instructions.
masm.testl(len, -16);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringUTF16CompressOp.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringUTF16CompressOp.java Thu Oct 31 16:54:16 2019 -0700
@@ -34,6 +34,7 @@
import static jdk.vm.ci.amd64.AMD64.rsp;
import static jdk.vm.ci.code.ValueUtil.asRegister;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
+import static org.graalvm.compiler.lir.amd64.AMD64StringLatin1InflateOp.useAVX512ForStringInflateCompress;
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.amd64.AMD64Address;
@@ -82,7 +83,7 @@
rdstTemp = rdst = dst;
rlenTemp = rlen = len;
- LIRKind vkind = LIRKind.value(AMD64Kind.V512_BYTE);
+ LIRKind vkind = useAVX512ForStringInflateCompress(tool.target()) ? LIRKind.value(AMD64Kind.V512_BYTE) : LIRKind.value(AMD64Kind.V128_BYTE);
vtmp1 = tool.newVariable(vkind);
vtmp2 = tool.newVariable(vkind);
@@ -139,10 +140,7 @@
masm.push(len); // Save length for return.
- if (masm.supports(AMD64.CPUFeature.AVX512BW) &&
- masm.supports(AMD64.CPUFeature.AVX512VL) &&
- masm.supports(AMD64.CPUFeature.BMI2)) {
-
+ if (useAVX512ForStringInflateCompress(masm.target)) {
Label labelRestoreK1ReturnZero = new Label();
Label labelAvxPostAlignment = new Label();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorMove.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorMove.java Thu Oct 31 16:54:16 2019 -0700
@@ -74,7 +74,7 @@
public static final class MoveToRegOp extends AMD64LIRInstruction implements ValueMoveOp {
public static final LIRInstructionClass<MoveToRegOp> TYPE = LIRInstructionClass.create(MoveToRegOp.class);
- @Def({REG, HINT}) protected AllocatableValue result;
+ @Def({REG, STACK, HINT}) protected AllocatableValue result;
@Use({REG, STACK}) protected AllocatableValue input;
public MoveToRegOp(AllocatableValue result, AllocatableValue input) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRIntrospection.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRIntrospection.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -214,6 +214,23 @@
}
}
+ private static boolean verifyAssignment(LIRInstruction inst, Value newValue, EnumSet<OperandFlag> flags) {
+ Class<?> type = newValue.getClass();
+ if (!flags.contains(REG)) {
+ assert !type.isAssignableFrom(REGISTER_VALUE_CLASS) && !type.isAssignableFrom(VARIABLE_CLASS) : "Cannot assign RegisterValue / Variable to field without REG flag: " + inst + " newValue=" +
+ newValue;
+ }
+ if (!flags.contains(STACK)) {
+ assert !type.isAssignableFrom(STACK_SLOT_CLASS) : "Cannot assign StackSlot to field without STACK flag: " + inst + " newValue=" +
+ newValue;
+ }
+ if (!flags.contains(CONST)) {
+ assert !type.isAssignableFrom(CONSTANT_VALUE_CLASS) : "Cannot assign Constant to field without CONST flag: " + inst + " newValue=" +
+ newValue;
+ }
+ return true;
+ }
+
protected static void forEach(LIRInstruction inst, Values values, OperandMode mode, InstructionValueProcedure proc) {
for (int i = 0; i < values.getCount(); i++) {
assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(values.getFlags(i));
@@ -228,6 +245,9 @@
newValue = proc.doValue(inst, value, mode, values.getFlags(i));
}
if (!value.identityEquals(newValue)) {
+ if (!(value instanceof CompositeValue)) {
+ assert verifyAssignment(inst, newValue, values.getFlags(i));
+ }
values.setValue(inst, i, newValue);
}
} else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java Thu Oct 31 16:54:16 2019 -0700
@@ -881,7 +881,12 @@
}
}
}
- return move.getConstant();
+ Constant constant = move.getConstant();
+ if (!(constant instanceof JavaConstant)) {
+ // Other kinds of constants might not be supported by the generic move operation.
+ return null;
+ }
+ return constant;
}
return null;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/ConvertDeoptimizeToGuardPhase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/ConvertDeoptimizeToGuardPhase.java Thu Oct 31 16:54:16 2019 -0700
@@ -217,7 +217,7 @@
Node newGuard = guard;
if (survivingSuccessor instanceof LoopExitNode) {
- newGuard = ProxyNode.forGuard(guard, (LoopExitNode) survivingSuccessor, graph);
+ newGuard = ProxyNode.forGuard(guard, (LoopExitNode) survivingSuccessor);
}
survivingSuccessor.replaceAtUsages(InputType.Guard, newGuard);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopPeelingPhase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopPeelingPhase.java Thu Oct 31 16:54:16 2019 -0700
@@ -24,6 +24,7 @@
package org.graalvm.compiler.loop.phases;
+import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.loop.LoopEx;
import org.graalvm.compiler.loop.LoopPolicies;
@@ -33,6 +34,8 @@
public class LoopPeelingPhase extends LoopPhase<LoopPolicies> {
+ public static final CounterKey PEELED = DebugContext.counter("Peeled");
+
public LoopPeelingPhase(LoopPolicies policies) {
super(policies);
}
@@ -45,10 +48,13 @@
LoopsData data = new LoopsData(graph);
try (DebugContext.Scope s = debug.scope("peeling", data.getCFG())) {
for (LoopEx loop : data.outerFirst()) {
- if (getPolicies().shouldPeel(loop, data.getCFG(), context.getMetaAccess())) {
- debug.log("Peeling %s", loop);
- LoopTransformations.peel(loop);
- debug.dump(DebugContext.DETAILED_LEVEL, graph, "Peeling %s", loop);
+ if (loop.canDuplicateLoop() && loop.loopBegin().getLoopEndCount() > 0) {
+ if (LoopPolicies.Options.PeelALot.getValue(graph.getOptions()) || getPolicies().shouldPeel(loop, data.getCFG(), context.getMetaAccess())) {
+ debug.log("Peeling %s", loop);
+ PEELED.add(debug, 1);
+ LoopTransformations.peel(loop);
+ debug.dump(DebugContext.DETAILED_LEVEL, graph, "Peeling %s", loop);
+ }
}
}
data.deleteUnusedNodes();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopTransformations.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopTransformations.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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,9 +35,13 @@
import org.graalvm.compiler.core.common.calc.CanonicalCondition;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.graph.Graph.Mark;
+import org.graalvm.compiler.graph.Graph.NodeEventScope;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.Position;
+import org.graalvm.compiler.graph.spi.Simplifiable;
+import org.graalvm.compiler.graph.spi.SimplifierTool;
import org.graalvm.compiler.loop.CountedLoopInfo;
+import org.graalvm.compiler.loop.DefaultLoopPolicies;
import org.graalvm.compiler.loop.InductionVariable.Direction;
import org.graalvm.compiler.loop.LoopEx;
import org.graalvm.compiler.loop.LoopFragmentInside;
@@ -49,6 +53,7 @@
import org.graalvm.compiler.nodes.BeginNode;
import org.graalvm.compiler.nodes.ControlSplitNode;
import org.graalvm.compiler.nodes.EndNode;
+import org.graalvm.compiler.nodes.FixedGuardNode;
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.IfNode;
@@ -65,8 +70,10 @@
import org.graalvm.compiler.nodes.extended.OpaqueNode;
import org.graalvm.compiler.nodes.extended.SwitchNode;
import org.graalvm.compiler.nodes.spi.CoreProviders;
+import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.nodes.util.IntegerHelper;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.common.util.EconomicSetNodeEventListener;
public abstract class LoopTransformations {
@@ -75,24 +82,63 @@
}
public static void peel(LoopEx loop) {
+ loop.detectCounted();
loop.inside().duplicate().insertBefore(loop);
- loop.loopBegin().setLoopFrequency(Math.max(0.0, loop.loopBegin().loopFrequency() - 1));
+ if (loop.isCounted()) {
+ // For counted loops we assume that we have an effect on the loop frequency.
+ loop.loopBegin().setLoopFrequency(Math.max(1.0, loop.loopBegin().loopFrequency() - 1));
+ }
}
+ @SuppressWarnings("try")
public static void fullUnroll(LoopEx loop, CoreProviders context, CanonicalizerPhase canonicalizer) {
// assert loop.isCounted(); //TODO (gd) strengthen : counted with known trip count
LoopBeginNode loopBegin = loop.loopBegin();
StructuredGraph graph = loopBegin.graph();
int initialNodeCount = graph.getNodeCount();
- while (!loopBegin.isDeleted()) {
- Mark mark = graph.getMark();
- peel(loop);
- canonicalizer.applyIncremental(graph, context, mark);
- loop.invalidateFragments();
- if (graph.getNodeCount() > initialNodeCount + MaximumDesiredSize.getValue(graph.getOptions()) * 2) {
- throw new RetryableBailoutException("FullUnroll : Graph seems to grow out of proportion");
+ SimplifierTool defaultSimplifier = GraphUtil.getDefaultSimplifier(context.getMetaAccess(), context.getConstantReflection(), context.getConstantFieldProvider(),
+ canonicalizer.getCanonicalizeReads(), graph.getAssumptions(), graph.getOptions());
+ /*
+ * IMPORTANT: Canonicalizations inside the body of the remaining loop can introduce new
+ * control flow that is not automatically picked up by the control flow graph computation of
+ * the original LoopEx data structure, thus we disable simplification and manually simplify
+ * conditions in the peeled iteration to simplify the exit path.
+ */
+ CanonicalizerPhase c = canonicalizer.copyWithoutSimplification();
+ EconomicSetNodeEventListener l = new EconomicSetNodeEventListener();
+ int peelings = 0;
+ try (NodeEventScope ev = graph.trackNodeEvents(l)) {
+ while (!loopBegin.isDeleted()) {
+ Mark newNodes = graph.getMark();
+ /*
+ * Mark is not enough for the canonicalization of the floating nodes in the unrolled
+ * code since pre-existing constants are not new nodes. Therefore, we canonicalize
+ * (without simplification) all floating nodes changed during peeling but only
+ * simplify new (in the peeled iteration) ones.
+ */
+ EconomicSetNodeEventListener peeledListener = new EconomicSetNodeEventListener();
+ try (NodeEventScope peeledScope = graph.trackNodeEvents(peeledListener)) {
+ LoopTransformations.peel(loop);
+ }
+ graph.getDebug().dump(DebugContext.VERY_DETAILED_LEVEL, graph, "After peeling loop %s", loop);
+ c.applyIncremental(graph, context, peeledListener.getNodes());
+ loop.invalidateFragments();
+ for (Node n : graph.getNewNodes(newNodes)) {
+ if (n.isAlive() && (n instanceof IfNode || n instanceof SwitchNode || n instanceof FixedGuardNode || n instanceof BeginNode)) {
+ Simplifiable s = (Simplifiable) n;
+ s.simplify(defaultSimplifier);
+ graph.getDebug().dump(DebugContext.VERY_DETAILED_LEVEL, graph, "After simplifying if %s", s);
+ }
+ }
+ if (graph.getNodeCount() > initialNodeCount + MaximumDesiredSize.getValue(graph.getOptions()) * 2 ||
+ peelings > DefaultLoopPolicies.Options.FullUnrollMaxIterations.getValue(graph.getOptions())) {
+ throw new RetryableBailoutException("FullUnroll : Graph seems to grow out of proportion");
+ }
+ peelings++;
}
}
+ // Canonicalize with the original canonicalizer to capture all simplifications
+ canonicalizer.applyIncremental(graph, context, l.getNodes());
}
public static void unswitch(LoopEx loop, List<ControlSplitNode> controlSplitNodeSet) {
@@ -280,9 +326,9 @@
// Change the preLoop to execute one iteration for now
updatePreLoopLimit(preCounted);
- preLoopBegin.setLoopFrequency(1);
- mainLoopBegin.setLoopFrequency(Math.max(0.0, mainLoopBegin.loopFrequency() - 2));
- postLoopBegin.setLoopFrequency(Math.max(0.0, postLoopBegin.loopFrequency() - 1));
+ preLoopBegin.setLoopFrequency(1.0);
+ mainLoopBegin.setLoopFrequency(Math.max(1.0, mainLoopBegin.loopFrequency() - 2));
+ postLoopBegin.setLoopFrequency(Math.max(1.0, postLoopBegin.loopFrequency() - 1));
// The pre and post loops don't require safepoints at all
for (SafepointNode safepoint : preLoop.nodes().filter(SafepointNode.class)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -302,7 +302,7 @@
try (DebugContext.Scope buildScope = graph.getDebug().scope(name, method, graph)) {
MidTierContext context = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, null);
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = this.createCanonicalizerPhase();
canonicalizer.apply(graph, context);
new RemoveValueProxyPhase().apply(graph);
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
@@ -338,7 +338,7 @@
StructuredGraph referenceGraph = buildGraph(reference, false);
StructuredGraph testGraph = buildGraph(test, true);
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
canonicalizer.apply(testGraph, getDefaultMidTierContext());
canonicalizer.apply(referenceGraph, getDefaultMidTierContext());
assertEquals(referenceGraph, testGraph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -122,18 +122,18 @@
}
ValueNode range = sub(max, min);
- ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1);
+ ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph);
if (oneOff) {
range = add(range, one);
}
// round-away-from-zero divison: (range + stride -/+ 1) / stride
- ValueNode denominator = add(range, sub(absStride, one));
+ ValueNode denominator = add(graph, range, sub(absStride, one), NodeView.DEFAULT);
ValueNode div = unsignedDivBefore(graph, loop.entryPoint(), denominator, absStride, null);
if (assumeLoopEntered) {
return graph.addOrUniqueWithInputs(div);
}
- ConstantNode zero = ConstantNode.forIntegerStamp(stamp, 0);
+ ConstantNode zero = ConstantNode.forIntegerStamp(stamp, 0, graph);
// This check is "wide": it looks like min <= max
// That's OK even if the loop is strict (`!isLimitIncluded()`)
// because in this case, `div` will be zero when min == max
@@ -142,6 +142,40 @@
}
/**
+ * Determine if the loop might be entered. Returns {@code false} if we can tell statically that
+ * the loop cannot be entered; returns {@code true} if the loop might possibly be entered,
+ * including in the case where we cannot be sure statically.
+ *
+ * @return false if the loop can definitely not be entered, true otherwise
+ */
+ public boolean loopMightBeEntered() {
+ Stamp stamp = iv.valueNode().stamp(NodeView.DEFAULT);
+
+ ValueNode max;
+ ValueNode min;
+ if (iv.direction() == Direction.Up) {
+ max = end;
+ min = iv.initNode();
+ } else {
+ assert iv.direction() == Direction.Down;
+ max = iv.initNode();
+ min = end;
+ }
+ if (oneOff) {
+ max = add(max, ConstantNode.forIntegerStamp(stamp, 1));
+ }
+
+ LogicNode entryCheck = getCounterIntegerHelper().createCompareNode(min, max, NodeView.DEFAULT);
+ if (entryCheck.isContradiction()) {
+ // We can definitely not enter this loop.
+ return false;
+ } else {
+ // We don't know for sure that the loop can't be entered, so assume it can.
+ return true;
+ }
+ }
+
+ /**
* @return true if the loop has constant bounds.
*/
public boolean isConstantMaxTripCount() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DefaultLoopPolicies.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DefaultLoopPolicies.java Thu Oct 31 16:54:16 2019 -0700
@@ -26,7 +26,7 @@
import static org.graalvm.compiler.core.common.GraalOptions.LoopMaxUnswitch;
import static org.graalvm.compiler.core.common.GraalOptions.MaximumDesiredSize;
-import static org.graalvm.compiler.core.common.GraalOptions.MinimumPeelProbability;
+import static org.graalvm.compiler.core.common.GraalOptions.MinimumPeelFrequency;
import java.util.List;
@@ -38,9 +38,6 @@
import org.graalvm.compiler.graph.NodeBitMap;
import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.ControlSplitNode;
-import org.graalvm.compiler.nodes.DeoptimizeNode;
-import org.graalvm.compiler.nodes.FixedNode;
-import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.InvokeNode;
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.MergeNode;
@@ -51,7 +48,6 @@
import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
import org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode;
-import org.graalvm.compiler.nodes.java.TypeSwitchNode;
import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionType;
@@ -79,13 +75,32 @@
public boolean shouldPeel(LoopEx loop, ControlFlowGraph cfg, MetaAccessProvider metaAccess) {
LoopBeginNode loopBegin = loop.loopBegin();
double entryProbability = cfg.blockFor(loopBegin.forwardEnd()).getRelativeFrequency();
- OptionValues options = cfg.graph.getOptions();
- if (entryProbability > MinimumPeelProbability.getValue(options) && loop.size() + loopBegin.graph().getNodeCount() < MaximumDesiredSize.getValue(options)) {
- // check whether we're allowed to peel this loop
- return loop.canDuplicateLoop();
- } else {
+ StructuredGraph graph = cfg.graph;
+ OptionValues options = graph.getOptions();
+
+ if (entryProbability < MinimumPeelFrequency.getValue(options)) {
return false;
}
+
+ if (loop.parent() != null) {
+ if (loop.size() > loop.parent().size() >> 1) {
+ // This loops make up more than half of the parent loop in terms of number of nodes.
+ // There is a risk that this loop unproportionally increases parent loop body size.
+ return false;
+ }
+ }
+
+ if (loop.loop().getChildren().size() > 0) {
+ // This loop has child loops. Loop peeling could explode graph size.
+ return false;
+ }
+
+ if (loop.size() + graph.getNodeCount() > MaximumDesiredSize.getValue(options)) {
+ // We are out of budget for peeling.
+ return false;
+ }
+
+ return true;
}
@Override
@@ -189,7 +204,7 @@
return false;
}
OptionValues options = loop.entryPoint().getOptions();
- return loopBegin.unswitches() <= LoopMaxUnswitch.getValue(options);
+ return loopBegin.unswitches() < LoopMaxUnswitch.getValue(options);
}
private static final class CountingClosure implements VirtualClosure {
@@ -238,19 +253,9 @@
int loopTotal = loop.size() - loop.loopBegin().phis().count() - stateNodesCount.count - 1;
int actualDiff = (loopTotal - inBranchTotal);
ControlSplitNode firstSplit = controlSplits.get(0);
- if (firstSplit instanceof TypeSwitchNode) {
- int copies = firstSplit.successors().count() - 1;
- for (Node succ : firstSplit.successors()) {
- FixedNode current = (FixedNode) succ;
- while (current instanceof FixedWithNextNode) {
- current = ((FixedWithNextNode) current).next();
- }
- if (current instanceof DeoptimizeNode) {
- copies--;
- }
- }
- actualDiff = actualDiff * copies;
- }
+
+ int copies = firstSplit.successors().count() - 1;
+ actualDiff = actualDiff * copies;
debug.log("shouldUnswitch(%s, %s) : delta=%d (%.2f%% inside of branches), max=%d, f=%.2f, phis=%d -> %b", loop, controlSplits, actualDiff, (double) (inBranchTotal) / loopTotal * 100, maxDiff,
loopFrequency, phis, actualDiff <= maxDiff);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java Thu Oct 31 16:54:16 2019 -0700
@@ -81,6 +81,7 @@
private LoopsData data;
private EconomicMap<Node, InductionVariable> ivs;
private boolean countedLoopChecked;
+ private int size = -1;
LoopEx(Loop<Block> loop, LoopsData data) {
this.loop = loop;
@@ -156,7 +157,10 @@
}
public int size() {
- return whole().nodes().count();
+ if (size == -1) {
+ size = whole().nodes().count();
+ }
+ return size;
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragment.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragment.java Thu Oct 31 16:54:16 2019 -0700
@@ -349,12 +349,11 @@
TriState isAnchorInLoop = isLoopNode(anchor, loopNodes, nonLoopNodes);
if (isAnchorInLoop != TriState.FALSE) {
if (!(anchor instanceof LoopExitNode && ((LoopExitNode) anchor).loopBegin() == loopBeginNode)) {
- /*
- * (gd) this is wrong in general, it's completely avoidable while we
- * are doing loop transforms using ValueProxies. If it happens after
- * it could still cause problem.
- */
- assert !((GuardNode) current).graph().hasValueProxies();
+ // It is undecidable whether the node is in the loop or not. This is
+ // not an issue for getting counted loop information,
+ // but causes issues when using the information for actual loop
+ // transformations. This is why a loop transformation must
+ // not happen while guards are floating.
isLoopNode = true;
}
} else if (AbstractControlFlowGraph.strictlyDominates(cfg.blockFor(anchor), cfg.blockFor(loopBeginNode))) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java Thu Oct 31 16:54:16 2019 -0700
@@ -233,7 +233,7 @@
}
}
mainLoopBegin.setUnrollFactor(mainLoopBegin.getUnrollFactor() * 2);
- mainLoopBegin.setLoopFrequency(mainLoopBegin.loopFrequency() / 2);
+ mainLoopBegin.setLoopFrequency(Math.max(1.0, mainLoopBegin.loopFrequency() / 2));
graph.getDebug().dump(DebugContext.DETAILED_LEVEL, graph, "LoopPartialUnroll %s", loop);
mainLoopBegin.getDebug().dump(DebugContext.VERBOSE_LEVEL, mainLoopBegin.graph(), "After insertWithinAfter %s", mainLoopBegin);
@@ -438,7 +438,7 @@
for (int i = 0; i < phi.valueCount(); i++) {
ValueNode v = phi.valueAt(i);
if (loopBegin.isPhiAtMerge(v)) {
- PhiNode newV = peel.getDuplicatedNode((ValuePhiNode) v);
+ PhiNode newV = peel.getDuplicatedNode((PhiNode) v);
if (newV != null) {
phi.setValueAt(i, newV);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopPolicies.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopPolicies.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -28,10 +28,18 @@
import org.graalvm.compiler.nodes.ControlSplitNode;
import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
+import org.graalvm.compiler.options.Option;
+import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionType;
import jdk.vm.ci.meta.MetaAccessProvider;
public interface LoopPolicies {
+
+ class Options {
+ @Option(help = "", type = OptionType.Expert) public static final OptionKey<Boolean> PeelALot = new OptionKey<>(false);
+ }
+
boolean shouldPeel(LoopEx loop, ControlFlowGraph cfg, MetaAccessProvider metaAccess);
boolean shouldFullUnroll(LoopEx loop);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/MathUtil.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/MathUtil.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -94,7 +94,9 @@
if (before.predecessor() instanceof FixedBinaryNode) {
FixedBinaryNode binaryPredecessor = (FixedBinaryNode) before.predecessor();
if (fixedDiv.dataFlowEquals(binaryPredecessor)) {
- fixedDiv.safeDelete();
+ if (fixedDiv.isAlive()) {
+ fixedDiv.safeDelete();
+ }
return binaryPredecessor;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.microbenchmarks/src/org/graalvm/compiler/microbenchmarks/graal/GraalBenchmark.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.microbenchmarks/src/org/graalvm/compiler/microbenchmarks/graal/GraalBenchmark.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -28,6 +28,8 @@
import static org.graalvm.compiler.microbenchmarks.graal.GraalBenchmark.Defaults.MEASUREMENT_ITERATIONS;
import static org.graalvm.compiler.microbenchmarks.graal.GraalBenchmark.Defaults.WARMUP_ITERATIONS;
+import org.graalvm.compiler.api.test.ModuleSupport;
+
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Warmup;
@@ -41,6 +43,9 @@
@Measurement(iterations = MEASUREMENT_ITERATIONS)
@Fork(FORKS)
public class GraalBenchmark {
+ static {
+ ModuleSupport.exportAndOpenAllPackagesToUnnamed("jdk.internal.vm.compiler");
+ }
public static class Defaults {
public static final int MEASUREMENT_ITERATIONS = 5;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.microbenchmarks/src/org/graalvm/compiler/microbenchmarks/graal/TestJMHWhitebox.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.microbenchmarks/src/org/graalvm/compiler/microbenchmarks/graal/TestJMHWhitebox.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -36,7 +36,7 @@
/**
* This dummy class is used to verify that the JMH microbenchmarking environment is set up properly.
*/
-public class TestJMHWhitebox {
+public class TestJMHWhitebox extends GraalBenchmark {
@Benchmark
public void testJMH(@SuppressWarnings("unused") GraalState s) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IfNodeCanonicalizationTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IfNodeCanonicalizationTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -67,19 +67,19 @@
for (byte d : testValues) {
values[3] = d;
value = 2;
- super.test("testSnippet1", values, true);
- super.test("testSnippet1", values, false);
+ super.test("testSnippet1", values);
}
}
}
}
}
- public int testSnippet1(byte[] values, boolean test) {
+ public int testSnippet1(byte[] values) {
int v = values[0] - values[1];
- if (test) {
- v = values[2] - values[3];
+ if (v < 0) {
+ value = 2;
}
+ v = values[3] - values[2];
if (v < 0) {
value = 1;
}
@@ -156,13 +156,12 @@
StructuredGraph graph = parseEager(name, AllowAssumptions.YES);
CoreProviders context = getProviders();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
new ConvertDeoptimizeToGuardPhase().apply(graph, context);
graph.clearAllStateAfter();
graph.setGuardsStage(StructuredGraph.GuardsStage.AFTER_FSA);
canonicalizer.apply(graph, context);
- // new DominatorConditionalEliminationPhase(true).apply(graph, context);
new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context);
canonicalizer.apply(graph, context);
canonicalizer.apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/LoopPhiCanonicalizerTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/LoopPhiCanonicalizerTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -31,7 +31,6 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.spi.CoreProviders;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -67,7 +66,7 @@
CoreProviders context = getProviders();
Assert.assertEquals(5, graph.getNodes().filter(loopPhis).count());
- new CanonicalizerPhase().apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
Assert.assertEquals(2, graph.getNodes().filter(loopPhis).count());
test("loopSnippet");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ShortCircuitOrNodeTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ShortCircuitOrNodeTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -378,7 +378,7 @@
String snippet = "testCascadeSnippet" + i;
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
CoreProviders context = getProviders();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
canonicalizer.apply(graph, context);
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
new IncrementalCanonicalizerPhase<>(canonicalizer, new FloatingReadPhase()).apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FrameState.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FrameState.java Thu Oct 31 16:54:16 2019 -0700
@@ -306,15 +306,8 @@
/**
* Gets a copy of this frame state.
*/
- public FrameState duplicate(int newBci) {
- return graph().add(new FrameState(outerFrameState(), code, newBci, values, localsSize, stackSize, rethrowException, duringCall, monitorIds, virtualObjectMappings));
- }
-
- /**
- * Gets a copy of this frame state.
- */
public FrameState duplicate() {
- return duplicate(bci);
+ return graph().add(new FrameState(outerFrameState(), code, bci, values, localsSize, stackSize, rethrowException, duringCall, monitorIds, virtualObjectMappings));
}
/**
@@ -350,20 +343,6 @@
}
/**
- * Creates a copy of this frame state with one stack element of type {@code popKind} popped from
- * the stack and the values in {@code pushedValues} pushed on the stack. The
- * {@code pushedValues} will be formatted correctly in slot encoding: a long or double will be
- * followed by a null slot.
- */
- public FrameState duplicateModified(int newBci, boolean newRethrowException, JavaKind popKind, JavaKind[] pushedSlotKinds, ValueNode[] pushedValues) {
- return duplicateModified(graph(), newBci, newRethrowException, duringCall, popKind, pushedSlotKinds, pushedValues);
- }
-
- public FrameState duplicateModified(int newBci, boolean newRethrowException, boolean newDuringCall, JavaKind popKind, JavaKind[] pushedSlotKinds, ValueNode[] pushedValues) {
- return duplicateModified(graph(), newBci, newRethrowException, newDuringCall, popKind, pushedSlotKinds, pushedValues);
- }
-
- /**
* Creates a copy of this frame state with the top of stack replaced with with
* {@code pushedValue} which must be of type {@code popKind}.
*/
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -1748,7 +1748,7 @@
"Value flowing out of loop, but we are not prepared to insert a ProxyNode");
ProxyPlaceholder proxyPlaceholder = (ProxyPlaceholder) value;
- ValueProxyNode proxy = ProxyNode.forValue(proxyPlaceholder.value, loopExit, graph);
+ ValueProxyNode proxy = ProxyNode.forValue(proxyPlaceholder.value, loopExit);
proxyPlaceholder.setValue(proxy);
newValues.add(proxy);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GuardProxyNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GuardProxyNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -25,19 +25,13 @@
package org.graalvm.compiler.nodes;
import org.graalvm.compiler.core.common.type.StampFactory;
-import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.graph.spi.Canonicalizable;
-import org.graalvm.compiler.graph.spi.CanonicalizerTool;
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.extended.GuardingNode;
-import org.graalvm.compiler.nodes.spi.LIRLowerable;
-import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.compiler.nodes.spi.Proxy;
-@NodeInfo(allowedUsageTypes = {InputType.Guard}, nameTemplate = "Proxy({i#value})")
-public final class GuardProxyNode extends ProxyNode implements GuardingNode, Proxy, LIRLowerable, Canonicalizable {
+@NodeInfo(allowedUsageTypes = {InputType.Guard}, nameTemplate = "GuardProxy({i#value})")
+public final class GuardProxyNode extends ProxyNode implements GuardingNode {
public static final NodeClass<GuardProxyNode> TYPE = NodeClass.create(GuardProxyNode.class);
@OptionalInput(InputType.Guard) GuardingNode value;
@@ -47,10 +41,6 @@
this.value = value;
}
- @Override
- public void generate(NodeLIRBuilderTool generator) {
- }
-
public void setValue(GuardingNode newValue) {
this.updateUsages(value.asNode(), newValue.asNode());
this.value = newValue;
@@ -65,17 +55,4 @@
public PhiNode createPhi(AbstractMergeNode merge) {
return graph().addWithoutUnique(new GuardPhiNode(merge));
}
-
- @Override
- public Node getOriginalNode() {
- return (value == null ? null : value.asNode());
- }
-
- @Override
- public Node canonical(CanonicalizerTool tool) {
- if (value == null) {
- return null;
- }
- return this;
- }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -54,7 +54,6 @@
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.NodeSourcePosition;
import org.graalvm.compiler.graph.iterators.NodeIterable;
-import org.graalvm.compiler.graph.spi.Canonicalizable;
import org.graalvm.compiler.graph.spi.Simplifiable;
import org.graalvm.compiler.graph.spi.SimplifierTool;
import org.graalvm.compiler.nodeinfo.InputType;
@@ -95,9 +94,6 @@
public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable, IterableNodeType, SwitchFoldable {
public static final NodeClass<IfNode> TYPE = NodeClass.create(IfNode.class);
- private static final int MAX_USAGE_COLOR_SET_SIZE = 64;
- private static final int MAX_FRAMESTATE_SEARCH_DEPTH = 4;
-
private static final CounterKey CORRECTED_PROBABILITIES = DebugContext.counter("CorrectedProbabilities");
@Successor AbstractBeginNode trueSuccessor;
@@ -297,10 +293,6 @@
return;
}
- if (splitIfAtPhi(tool)) {
- return;
- }
-
if (conditionalNodeOptimization(tool)) {
return;
}
@@ -1185,400 +1177,6 @@
}
/**
- * Take an if that is immediately dominated by a merge with a single phi and split off any paths
- * where the test would be statically decidable creating a new merge below the appropriate side
- * of the IfNode. Any undecidable tests will continue to use the original IfNode.
- *
- * @param tool
- */
- @SuppressWarnings("try")
- private boolean splitIfAtPhi(SimplifierTool tool) {
- if (!(predecessor() instanceof MergeNode)) {
- return false;
- }
- MergeNode merge = (MergeNode) predecessor();
- if (merge.forwardEndCount() == 1) {
- // Don't bother.
- return false;
- }
- if (merge.getUsageCount() != 1 || merge.phis().count() != 1) {
- // Don't trigger with multiple phis. Would require more rewiring.
- // Most of the time the additional phis are memory phis that are removed after
- // fixed read phase.
- return false;
- }
- if (graph().getGuardsStage().areFrameStatesAtSideEffects() && merge.stateAfter() == null) {
- return false;
- }
-
- PhiNode generalPhi = merge.phis().first();
- if (!(generalPhi instanceof ValuePhiNode)) {
- return false;
- }
-
- if (trueSuccessor().isUsedAsGuardInput() || falseSuccessor().isUsedAsGuardInput()) {
- return false;
- }
-
- ValuePhiNode phi = (ValuePhiNode) generalPhi;
-
- EconomicMap<Node, NodeColor> coloredNodes = EconomicMap.create(Equivalence.IDENTITY, 8);
-
- /*
- * Check that the condition uses the phi and that there is only one user of the condition
- * expression.
- */
- if (!conditionUses(condition(), phi, coloredNodes)) {
- return false;
- }
-
- if (!mayRemoveSplit(merge)) {
- return false;
- }
-
- LogicNode[] results = new LogicNode[merge.forwardEndCount()];
- boolean success = false;
- for (int i = 0; i < results.length; ++i) {
- ValueNode value = phi.valueAt(i);
- LogicNode curResult = computeCondition(tool, condition, phi, value);
- if (curResult != condition) {
- for (Node n : curResult.inputs()) {
- if (n instanceof ConstantNode || n instanceof ParameterNode || n instanceof FixedNode) {
- // Constant inputs or parameters or fixed nodes are OK.
- } else if (n == value) {
- // References to the value itself are also OK.
- } else {
- // Input may cause scheduling issues.
- curResult = condition;
- break;
- }
- }
- success = true;
- }
- results[i] = curResult;
- }
-
- if (!success) {
- return false;
- }
-
- for (Node usage : phi.usages()) {
- if (usage == merge.stateAfter()) {
- // This usage can be ignored, because it is directly in the state after.
- } else {
- NodeColor color = colorUsage(coloredNodes, usage, merge, this.trueSuccessor(), this.falseSuccessor());
- if (color == NodeColor.MIXED) {
- return false;
- }
- }
- }
-
- /*
- * We could additionally filter for the case that at least some of the Phi inputs or one of
- * the condition inputs are constants but there are cases where a non-constant is
- * simplifiable, usually where the stamp allows the question to be answered.
- */
-
- /* Each successor of the if gets a new merge if needed. */
- MergeNode trueMerge = null;
- MergeNode falseMerge = null;
- int i = 0;
- for (EndNode end : merge.forwardEnds().snapshot()) {
- ValueNode value = phi.valueAt(end);
- LogicNode result = results[i++];
- if (result instanceof LogicConstantNode) {
- if (((LogicConstantNode) result).getValue()) {
- if (trueMerge == null) {
- trueMerge = insertMerge(trueSuccessor(), phi, merge.stateAfter(), tool);
- replaceNodesInBranch(coloredNodes, NodeColor.TRUE_BRANCH, phi, trueMerge.phis().first());
- }
- trueMerge.phis().first().addInput(value);
- trueMerge.addForwardEnd(end);
- } else {
- if (falseMerge == null) {
- falseMerge = insertMerge(falseSuccessor(), phi, merge.stateAfter(), tool);
- replaceNodesInBranch(coloredNodes, NodeColor.FALSE_BRANCH, phi, falseMerge.phis().first());
- }
- falseMerge.phis().first().addInput(value);
- falseMerge.addForwardEnd(end);
- }
- merge.removeEnd(end);
- } else if (result != condition) {
- // Build a new IfNode using the new condition
- BeginNode trueBegin = graph().add(new BeginNode());
- trueBegin.setNodeSourcePosition(trueSuccessor().getNodeSourcePosition());
- BeginNode falseBegin = graph().add(new BeginNode());
- falseBegin.setNodeSourcePosition(falseSuccessor().getNodeSourcePosition());
-
- if (result.graph() == null) {
- result = graph().addOrUniqueWithInputs(result);
- result.setNodeSourcePosition(condition.getNodeSourcePosition());
- }
- IfNode newIfNode = graph().add(new IfNode(result, trueBegin, falseBegin, trueSuccessorProbability));
- newIfNode.setNodeSourcePosition(getNodeSourcePosition());
-
- if (trueMerge == null) {
- trueMerge = insertMerge(trueSuccessor(), phi, merge.stateAfter(), tool);
- replaceNodesInBranch(coloredNodes, NodeColor.TRUE_BRANCH, phi, trueMerge.phis().first());
- }
- trueMerge.phis().first().addInput(value);
- trueBegin.setNext(graph().add(new EndNode()));
- trueMerge.addForwardEnd((EndNode) trueBegin.next());
-
- if (falseMerge == null) {
- falseMerge = insertMerge(falseSuccessor(), phi, merge.stateAfter(), tool);
- replaceNodesInBranch(coloredNodes, NodeColor.FALSE_BRANCH, phi, falseMerge.phis().first());
- }
- falseMerge.phis().first().addInput(value);
- falseBegin.setNext(graph().add(new EndNode()));
- falseMerge.addForwardEnd((EndNode) falseBegin.next());
-
- merge.removeEnd(end);
- ((FixedWithNextNode) end.predecessor()).setNext(newIfNode);
- end.safeDelete();
- }
- }
-
- cleanupMerge(merge);
- cleanupMerge(trueMerge);
- cleanupMerge(falseMerge);
-
- return true;
- }
-
- private static void replaceNodesInBranch(EconomicMap<Node, NodeColor> coloredNodes, NodeColor branch, ValuePhiNode phi, ValueNode newValue) {
- for (Node n : phi.usages().snapshot()) {
- if (coloredNodes.get(n) == branch) {
- n.replaceAllInputs(phi, newValue);
- } else if (coloredNodes.get(n) == NodeColor.PHI_MIXED) {
- assert n instanceof PhiNode;
- PhiNode phiNode = (PhiNode) n;
- AbstractMergeNode merge = phiNode.merge();
- for (int i = 0; i < merge.forwardEndCount(); ++i) {
- if (phiNode.valueAt(i) == phi && coloredNodes.get(merge.forwardEndAt(i)) == branch) {
- phiNode.setValueAt(i, newValue);
- }
- }
- }
- }
- }
-
- private NodeColor colorUsage(EconomicMap<Node, NodeColor> coloredNodes, Node node, MergeNode merge, AbstractBeginNode trueSucc, AbstractBeginNode falseSucc) {
- NodeColor color = coloredNodes.get(node);
- if (color == null) {
-
- if (coloredNodes.size() >= MAX_USAGE_COLOR_SET_SIZE) {
- return NodeColor.MIXED;
- }
-
- coloredNodes.put(node, NodeColor.MIXED);
-
- if (node == merge) {
- color = NodeColor.MIXED;
- } else if (node == trueSucc) {
- color = NodeColor.TRUE_BRANCH;
- } else if (node == falseSucc) {
- color = NodeColor.FALSE_BRANCH;
- } else {
- if (node instanceof AbstractMergeNode) {
- AbstractMergeNode mergeNode = (AbstractMergeNode) node;
- NodeColor combinedColor = null;
- for (int i = 0; i < mergeNode.forwardEndCount(); ++i) {
- NodeColor curColor = colorUsage(coloredNodes, mergeNode.forwardEndAt(i), merge, trueSucc, falseSucc);
- if (combinedColor == null) {
- combinedColor = curColor;
- } else if (combinedColor != curColor) {
- combinedColor = NodeColor.MIXED;
- break;
- }
- }
- color = combinedColor;
- } else if (node instanceof StartNode) {
- color = NodeColor.MIXED;
- } else if (node instanceof FixedNode) {
- FixedNode fixedNode = (FixedNode) node;
- Node predecessor = fixedNode.predecessor();
- assert predecessor != null : fixedNode;
- color = colorUsage(coloredNodes, predecessor, merge, trueSucc, falseSucc);
- } else if (node instanceof PhiNode) {
- PhiNode phiNode = (PhiNode) node;
- AbstractMergeNode phiMerge = phiNode.merge();
-
- if (phiMerge instanceof LoopBeginNode) {
- color = colorUsage(coloredNodes, phiMerge, merge, trueSucc, falseSucc);
- } else {
-
- for (int i = 0; i < phiMerge.forwardEndCount(); ++i) {
- NodeColor curColor = colorUsage(coloredNodes, phiMerge.forwardEndAt(i), merge, trueSucc, falseSucc);
- if (curColor != NodeColor.TRUE_BRANCH && curColor != NodeColor.FALSE_BRANCH) {
- color = NodeColor.MIXED;
- break;
- }
- }
-
- if (color == null) {
- // Each of the inputs to the phi are either coming unambigously from
- // true or false branch.
- color = NodeColor.PHI_MIXED;
- assert node instanceof PhiNode;
- }
- }
- } else {
- NodeColor combinedColor = null;
- for (Node n : node.usages()) {
- if (n != node) {
- NodeColor curColor = colorUsage(coloredNodes, n, merge, trueSucc, falseSucc);
- if (combinedColor == null) {
- combinedColor = curColor;
- } else if (combinedColor != curColor) {
- combinedColor = NodeColor.MIXED;
- break;
- }
- }
- }
- if (combinedColor == NodeColor.PHI_MIXED) {
- combinedColor = NodeColor.MIXED;
- }
- if (combinedColor == null) {
- // Floating node without usages => association unclear.
- combinedColor = NodeColor.MIXED;
- }
- color = combinedColor;
- }
- }
-
- assert color != null : node;
- coloredNodes.put(node, color);
- }
- return color;
- }
-
- /**
- * @param condition
- * @param phi
- * @param coloredNodes
- * @return true if the passed in {@code condition} uses {@code phi} and the condition is only
- * used once. Since the phi will go dead the condition using it will also have to be
- * dead after the optimization.
- */
- private static boolean conditionUses(LogicNode condition, PhiNode phi, EconomicMap<Node, NodeColor> coloredNodes) {
- if (!condition.hasExactlyOneUsage()) {
- return false;
- }
- if (condition instanceof ShortCircuitOrNode) {
- if (condition.graph().getGuardsStage().areDeoptsFixed()) {
- /*
- * It can be unsafe to simplify a ShortCircuitOr before deopts are fixed because
- * conversion to guards assumes that all the required conditions are being tested.
- * Simplfying the condition based on context before this happens may lose a
- * condition.
- */
- ShortCircuitOrNode orNode = (ShortCircuitOrNode) condition;
- return (conditionUses(orNode.x, phi, coloredNodes) || conditionUses(orNode.y, phi, coloredNodes));
- }
- } else if (condition instanceof Canonicalizable.Unary<?>) {
- Canonicalizable.Unary<?> unary = (Canonicalizable.Unary<?>) condition;
- if (unary.getValue() == phi) {
- coloredNodes.put(condition, NodeColor.CONDITION_USAGE);
- return true;
- }
- } else if (condition instanceof Canonicalizable.Binary<?>) {
- Canonicalizable.Binary<?> binary = (Canonicalizable.Binary<?>) condition;
- if (binary.getX() == phi || binary.getY() == phi) {
- coloredNodes.put(condition, NodeColor.CONDITION_USAGE);
- return true;
- }
- }
- return false;
- }
-
- /**
- * Canonicalize {@code} condition using {@code value} in place of {@code phi}.
- *
- * @param tool
- * @param condition
- * @param phi
- * @param value
- * @return an improved LogicNode or the original condition
- */
- @SuppressWarnings("unchecked")
- private static LogicNode computeCondition(SimplifierTool tool, LogicNode condition, PhiNode phi, Node value) {
- if (condition instanceof ShortCircuitOrNode) {
- if (condition.graph().getGuardsStage().areDeoptsFixed() && !condition.graph().isAfterExpandLogic()) {
- ShortCircuitOrNode orNode = (ShortCircuitOrNode) condition;
- LogicNode resultX = computeCondition(tool, orNode.x, phi, value);
- LogicNode resultY = computeCondition(tool, orNode.y, phi, value);
- if (resultX != orNode.x || resultY != orNode.y) {
- LogicNode result = orNode.canonical(tool, resultX, resultY);
- if (result != orNode) {
- return result;
- }
- /*
- * Create a new node to carry the optimized inputs.
- */
- ShortCircuitOrNode newOr = new ShortCircuitOrNode(resultX, orNode.xNegated, resultY,
- orNode.yNegated, orNode.getShortCircuitProbability());
- return newOr.canonical(tool);
- }
- return orNode;
- }
- } else if (condition instanceof Canonicalizable.Binary<?>) {
- Canonicalizable.Binary<Node> compare = (Canonicalizable.Binary<Node>) condition;
- if (compare.getX() == phi || compare.getY() == phi) {
- return (LogicNode) compare.canonical(tool, compare.getX() == phi ? value : compare.getX(), compare.getY() == phi ? value : compare.getY());
- }
- } else if (condition instanceof Canonicalizable.Unary<?>) {
- Canonicalizable.Unary<Node> compare = (Canonicalizable.Unary<Node>) condition;
- if (compare.getValue() == phi) {
- return (LogicNode) compare.canonical(tool, value);
- }
- }
- if (condition instanceof Canonicalizable) {
- return (LogicNode) ((Canonicalizable) condition).canonical(tool);
- }
- return condition;
- }
-
- private void cleanupMerge(MergeNode merge) {
- if (merge != null && merge.isAlive()) {
- if (merge.forwardEndCount() == 0) {
- GraphUtil.killCFG(merge);
- } else if (merge.forwardEndCount() == 1) {
- graph().reduceTrivialMerge(merge);
- }
- }
- }
-
- @SuppressWarnings("try")
- private MergeNode insertMerge(AbstractBeginNode begin, ValuePhiNode oldPhi, FrameState stateAfter, SimplifierTool tool) {
- MergeNode merge = graph().add(new MergeNode());
-
- AbstractBeginNode newBegin;
- try (DebugCloseable position = begin.withNodeSourcePosition()) {
- newBegin = graph().add(new BeginNode());
- begin.replaceAtPredecessor(newBegin);
- newBegin.setNext(begin);
- }
-
- FixedNode next = newBegin.next();
- next.replaceAtPredecessor(merge);
- newBegin.setNext(graph().add(new EndNode()));
- merge.addForwardEnd((EndNode) newBegin.next());
-
- ValuePhiNode phi = begin.graph().addOrUnique(new ValuePhiNode(oldPhi.stamp(NodeView.DEFAULT), merge));
- phi.addInput(oldPhi);
-
- if (stateAfter != null) {
- FrameState newState = stateAfter.duplicate();
- newState.replaceAllInputs(oldPhi, phi);
- merge.setStateAfter(newState);
- }
- merge.setNext(next);
- tool.addToWorkList(begin);
- return merge;
- }
-
- /**
* Tries to connect code that initializes a variable directly with the successors of an if
* construct that switches on the variable. For example, the pseudo code below:
*
@@ -1709,7 +1307,7 @@
return false;
}
- if (!mayRemoveSplit(merge)) {
+ if (merge.stateAfter() != null && !GraphUtil.mayRemoveSplit(this)) {
return false;
}
@@ -1771,15 +1369,6 @@
return true;
}
- private boolean mayRemoveSplit(AbstractMergeNode merge) {
-
- if (merge.stateAfter() != null && (!checkFrameState(trueSuccessor, MAX_FRAMESTATE_SEARCH_DEPTH) || !checkFrameState(trueSuccessor, MAX_FRAMESTATE_SEARCH_DEPTH))) {
- return false;
- }
-
- return true;
- }
-
private static void propagateZeroProbability(FixedNode startNode) {
Node prev = null;
for (FixedNode node : GraphUtil.predecessorIterable(startNode)) {
@@ -1817,53 +1406,6 @@
}
/**
- * Snippet lowerings may produce patterns without a frame state on the merge. We need to take
- * extra care when optimizing these patterns.
- */
- private static boolean checkFrameState(FixedNode start, int maxDepth) {
- if (maxDepth == 0) {
- return false;
- }
- FixedNode node = start;
- while (true) {
- if (node instanceof AbstractMergeNode) {
- AbstractMergeNode mergeNode = (AbstractMergeNode) node;
- if (mergeNode.stateAfter() == null) {
- return false;
- } else {
- return true;
- }
- } else if (node instanceof StateSplit) {
- StateSplit stateSplitNode = (StateSplit) node;
- if (stateSplitNode.stateAfter() != null) {
- return true;
- }
- }
-
- if (node instanceof ControlSplitNode) {
- ControlSplitNode controlSplitNode = (ControlSplitNode) node;
- for (Node succ : controlSplitNode.cfgSuccessors()) {
- if (checkFrameState((FixedNode) succ, maxDepth - 1)) {
- return true;
- }
- }
- return false;
- } else if (node instanceof FixedWithNextNode) {
- FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) node;
- node = fixedWithNextNode.next();
- } else if (node instanceof AbstractEndNode) {
- AbstractEndNode endNode = (AbstractEndNode) node;
- node = endNode.merge();
- } else if (node instanceof ControlSinkNode) {
- return true;
- } else {
- assert false : "unexpected node";
- return false;
- }
- }
- }
-
- /**
* Connects a set of ends to a given successor, inserting a merge node if there is more than one
* end. If {@code ends} is not empty, then {@code successor} is added to {@code tool}'s
* {@linkplain SimplifierTool#addToWorkList(org.graalvm.compiler.graph.Node) work list}.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -109,7 +109,7 @@
this.bci = invoke.bci;
this.polymorphic = invoke.polymorphic;
this.useForInlining = invoke.useForInlining;
- this.identity = invoke.getLocationIdentity();
+ this.identity = invoke.getKilledLocationIdentity();
}
@Override
@@ -181,7 +181,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return identity;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeWithExceptionNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeWithExceptionNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -159,7 +159,7 @@
@Override
public void setNext(FixedNode x) {
if (x != null) {
- this.setNext(KillingBeginNode.begin(x, getLocationIdentity()));
+ this.setNext(KillingBeginNode.begin(x, this.getKilledLocationIdentity()));
} else {
this.setNext(null);
}
@@ -192,7 +192,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
@@ -290,7 +290,7 @@
* code.
*/
public InvokeNode replaceWithInvoke() {
- InvokeNode newInvoke = graph().add(new InvokeNode(callTarget, bci, stamp, getLocationIdentity()));
+ InvokeNode newInvoke = graph().add(new InvokeNode(callTarget, bci, stamp, this.getKilledLocationIdentity()));
newInvoke.setStateAfter(stateAfter);
newInvoke.setStateDuring(stateDuring);
AbstractBeginNode oldException = this.exceptionEdge;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/KillingBeginNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/KillingBeginNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -58,7 +58,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return locationIdentity;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopBeginNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopBeginNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -141,7 +141,7 @@
}
public void setLoopFrequency(double loopFrequency) {
- assert loopFrequency >= 0;
+ assert loopFrequency >= 1.0;
this.loopFrequency = loopFrequency;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/MemoryProxyNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2019, 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.nodes;
+
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.memory.MemoryNode;
+import org.graalvm.compiler.nodes.memory.MemoryPhiNode;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+
+@NodeInfo(allowedUsageTypes = {InputType.Memory}, nameTemplate = "MemoryProxy({i#value})")
+public final class MemoryProxyNode extends ProxyNode implements MemoryNode {
+
+ public static final NodeClass<MemoryProxyNode> TYPE = NodeClass.create(MemoryProxyNode.class);
+ @OptionalInput(InputType.Memory) MemoryNode value;
+ protected final LocationIdentity locationIdentity;
+
+ public MemoryProxyNode(MemoryNode value, LoopExitNode proxyPoint, LocationIdentity locationIdentity) {
+ super(TYPE, StampFactory.forVoid(), proxyPoint);
+ this.value = value;
+ this.locationIdentity = locationIdentity;
+ }
+
+ public void setValue(MemoryNode newValue) {
+ this.updateUsages(value.asNode(), newValue.asNode());
+ this.value = newValue;
+ }
+
+ @Override
+ public ValueNode value() {
+ return (value == null ? null : value.asNode());
+ }
+
+ @Override
+ public PhiNode createPhi(AbstractMergeNode merge) {
+ return graph().addWithoutUnique(new MemoryPhiNode(merge, locationIdentity));
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ProxyNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ProxyNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -29,18 +29,24 @@
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0;
import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.Node.ValueNumberable;
+import org.graalvm.compiler.graph.spi.Canonicalizable;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.extended.GuardingNode;
+import org.graalvm.compiler.nodes.memory.MemoryNode;
+import org.graalvm.compiler.nodes.spi.Proxy;
+import jdk.internal.vm.compiler.word.LocationIdentity;
/**
* A proxy is inserted at loop exits for any value that is created inside the loop (i.e. was not
* live on entry to the loop) and is (potentially) used after the loop.
*/
@NodeInfo(cycles = CYCLES_0, size = SIZE_0)
-public abstract class ProxyNode extends FloatingNode implements ValueNumberable {
+public abstract class ProxyNode extends FloatingNode implements Proxy, ValueNumberable, Canonicalizable {
public static final NodeClass<ProxyNode> TYPE = NodeClass.create(ProxyNode.class);
@Input(Association) LoopExitNode loopExit;
@@ -63,17 +69,34 @@
}
@Override
+ public ValueNode getOriginalNode() {
+ return value();
+ }
+
+ @Override
public boolean verify() {
assert !(value() instanceof ProxyNode) || ((ProxyNode) value()).loopExit != loopExit;
return super.verify();
}
- public static ValueProxyNode forValue(ValueNode value, LoopExitNode exit, StructuredGraph graph) {
- return graph.unique(new ValueProxyNode(value, exit));
+ public static ValueProxyNode forValue(ValueNode value, LoopExitNode exit) {
+ return exit.graph().unique(new ValueProxyNode(value, exit));
+ }
+
+ public static GuardProxyNode forGuard(GuardingNode value, LoopExitNode exit) {
+ return exit.graph().unique(new GuardProxyNode(value, exit));
}
- public static GuardProxyNode forGuard(GuardingNode value, LoopExitNode exit, StructuredGraph graph) {
- return graph.unique(new GuardProxyNode(value, exit));
+ public static MemoryProxyNode forMemory(MemoryNode value, LoopExitNode exit, LocationIdentity locationIdentity) {
+ return exit.graph().unique(new MemoryProxyNode(value, exit, locationIdentity));
+ }
+
+ @Override
+ public Node canonical(CanonicalizerTool tool) {
+ if (value() == null) {
+ return null;
+ }
+ return this;
}
public abstract PhiNode createPhi(AbstractMergeNode merge);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StartNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StartNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -49,7 +49,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java Thu Oct 31 16:54:16 2019 -0700
@@ -125,6 +125,10 @@
public boolean areDeoptsFixed() {
return this.ordinal() >= FIXED_DEOPTS.ordinal();
}
+
+ public boolean requiresValueProxies() {
+ return this != AFTER_FSA;
+ }
}
/**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueProxyNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueProxyNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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,7 +35,7 @@
import org.graalvm.compiler.nodes.spi.VirtualizerTool;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
-@NodeInfo(nameTemplate = "Proxy({i#value})")
+@NodeInfo(nameTemplate = "ValueProxy({i#value})")
public final class ValueProxyNode extends ProxyNode implements Canonicalizable, Virtualizable, ValueProxy {
public static final NodeClass<ValueProxyNode> TYPE = NodeClass.create(ValueProxyNode.class);
@@ -65,8 +65,13 @@
@Override
public Node canonical(CanonicalizerTool tool) {
+ Node result = super.canonical(tool);
+ if (result != this) {
+ return result;
+ }
+
ValueNode curValue = value;
- if (curValue.isConstant()) {
+ if (curValue.getNodeClass().isLeafNode()) {
return curValue;
}
if (loopPhiProxy && !loopExit.loopBegin().isPhiAtMerge(curValue)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AndNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AndNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -28,7 +28,6 @@
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.And;
import org.graalvm.compiler.core.common.type.IntegerStamp;
-import org.graalvm.compiler.core.common.type.PrimitiveStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative;
@@ -41,7 +40,6 @@
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import org.graalvm.compiler.nodes.util.GraphUtil;
-import jdk.vm.ci.code.CodeUtil;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.PrimitiveConstant;
@@ -61,7 +59,7 @@
if (tryConstantFold != null) {
return tryConstantFold;
}
- return canonical(null, op, stamp, x, y, view);
+ return canonical(null, op, x, y, view);
}
@Override
@@ -77,16 +75,29 @@
}
NodeView view = NodeView.from(tool);
- return canonical(this, getOp(forX, forY), stamp(view), forX, forY, view);
+ return canonical(this, getOp(forX, forY), forX, forY, view);
}
- private static ValueNode canonical(AndNode self, BinaryOp<And> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
+ private static ValueNode canonical(AndNode self, BinaryOp<And> op, ValueNode forX, ValueNode forY, NodeView view) {
if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
return forX;
}
if (forX.isConstant() && !forY.isConstant()) {
return new AndNode(forY, forX);
}
+
+ Stamp rawXStamp = forX.stamp(view);
+ Stamp rawYStamp = forY.stamp(view);
+ if (rawXStamp instanceof IntegerStamp && rawYStamp instanceof IntegerStamp) {
+ IntegerStamp xStamp = (IntegerStamp) rawXStamp;
+ IntegerStamp yStamp = (IntegerStamp) rawYStamp;
+ if (((~xStamp.downMask()) & yStamp.upMask()) == 0) {
+ return forY;
+ } else if (((~yStamp.downMask()) & xStamp.upMask()) == 0) {
+ return forX;
+ }
+ }
+
if (forY.isConstant()) {
Constant c = forY.asConstant();
if (op.isNeutral(c)) {
@@ -95,21 +106,12 @@
if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
long rawY = ((PrimitiveConstant) c).asLong();
- long mask = CodeUtil.mask(PrimitiveStamp.getBits(stamp));
- if ((rawY & mask) == 0) {
- return ConstantNode.forIntegerStamp(stamp, 0);
- }
if (forX instanceof SignExtendNode) {
SignExtendNode ext = (SignExtendNode) forX;
if (rawY == ((1L << ext.getInputBits()) - 1)) {
return new ZeroExtendNode(ext.getValue(), ext.getResultBits());
}
}
- IntegerStamp xStamp = (IntegerStamp) forX.stamp(view);
- if (((xStamp.upMask() | xStamp.downMask()) & ~rawY) == 0) {
- // No bits are set which are outside the mask, so the mask will have no effect.
- return forX;
- }
}
return reassociate(self != null ? self : (AndNode) new AndNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -59,6 +59,10 @@
super(c, opForStampComputation.foldStamp(x.stamp(NodeView.DEFAULT), y.stamp(NodeView.DEFAULT)), x, y);
}
+ protected BinaryArithmeticNode(NodeClass<? extends BinaryArithmeticNode<OP>> c, Stamp stamp, ValueNode x, ValueNode y) {
+ super(c, stamp, x, y);
+ }
+
public static ArithmeticOpTable getArithmeticOpTable(ValueNode forValue) {
return ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT));
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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,8 +33,11 @@
import org.graalvm.compiler.core.common.type.AbstractObjectStamp;
import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.Position;
import org.graalvm.compiler.graph.spi.Canonicalizable;
+import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.BinaryOpLogicNode;
import org.graalvm.compiler.nodes.ConstantNode;
@@ -44,6 +47,7 @@
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.VolatileReadNode;
import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.meta.Constant;
@@ -189,6 +193,19 @@
} else if (nonConstant instanceof ConvertNode) {
ConvertNode convert = (ConvertNode) nonConstant;
boolean multiUsage = (convert.asNode().hasMoreThanOneUsage() && convert.getValue().hasExactlyOneUsage());
+ if (!multiUsage && convert.asNode().hasMoreThanOneUsage() && convert.getValue() instanceof VolatileReadNode) {
+ // Only account for data usages
+ VolatileReadNode read = (VolatileReadNode) convert.getValue();
+ int nonMemoryEdges = 0;
+ for (Node u : read.usages()) {
+ for (Position pos : u.inputPositions()) {
+ if (pos.get(u) == read && pos.getInputType() != InputType.Memory) {
+ nonMemoryEdges++;
+ }
+ }
+ }
+ multiUsage = nonMemoryEdges == 1;
+ }
if (convert instanceof IntegerConvertNode && multiUsage) {
// Do not perform for integer convers if it could introduce
// new live values.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -27,7 +27,7 @@
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Or;
-import org.graalvm.compiler.core.common.type.PrimitiveStamp;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative;
@@ -40,9 +40,7 @@
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import org.graalvm.compiler.nodes.util.GraphUtil;
-import jdk.vm.ci.code.CodeUtil;
import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.PrimitiveConstant;
@NodeInfo(shortName = "|")
public final class OrNode extends BinaryArithmeticNode<Or> implements BinaryCommutative<ValueNode>, NarrowableArithmeticNode {
@@ -53,6 +51,18 @@
super(TYPE, getArithmeticOpTable(x).getOr(), x, y);
}
+ private OrNode(ValueNode x, ValueNode y, Stamp forcedStamp) {
+ super(TYPE, forcedStamp, x, y);
+ }
+
+ /**
+ * Create a new XorNode with a forced stamp, without eager folding. This should only be used in
+ * snippet code, where native-image may assign wrong stamps during graph generation.
+ */
+ public static ValueNode createForSnippet(ValueNode x, ValueNode y, Stamp forcedStamp) {
+ return new OrNode(x, y, forcedStamp);
+ }
+
public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp(view)).getOr();
Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
@@ -60,7 +70,7 @@
if (tryConstantFold != null) {
return tryConstantFold;
}
- return canonical(null, op, stamp, x, y, view);
+ return canonical(null, op, x, y, view);
}
@Override
@@ -76,34 +86,42 @@
return ret;
}
- return canonical(this, getOp(forX, forY), stamp(view), forX, forY, view);
+ return canonical(this, getOp(forX, forY), forX, forY, view);
}
- private static ValueNode canonical(OrNode self, BinaryOp<Or> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
+ private static ValueNode canonical(OrNode self, BinaryOp<Or> op, ValueNode forX, ValueNode forY, NodeView view) {
if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
return forX;
}
if (forX.isConstant() && !forY.isConstant()) {
return new OrNode(forY, forX);
}
+
+ Stamp rawXStamp = forX.stamp(view);
+ Stamp rawYStamp = forY.stamp(view);
+ if (rawXStamp instanceof IntegerStamp && rawYStamp instanceof IntegerStamp) {
+ IntegerStamp xStamp = (IntegerStamp) rawXStamp;
+ IntegerStamp yStamp = (IntegerStamp) rawYStamp;
+ if (((~xStamp.downMask()) & yStamp.upMask()) == 0) {
+ return forX;
+ } else if (((~yStamp.downMask()) & xStamp.upMask()) == 0) {
+ return forY;
+ }
+ }
+
if (forY.isConstant()) {
Constant c = forY.asConstant();
if (op.isNeutral(c)) {
return forX;
}
- if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
- long rawY = ((PrimitiveConstant) c).asLong();
- long mask = CodeUtil.mask(PrimitiveStamp.getBits(stamp));
- if ((rawY & mask) == mask) {
- return ConstantNode.forIntegerStamp(stamp, mask);
- }
- }
return reassociate(self != null ? self : (OrNode) new OrNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
}
+
if (forX instanceof NotNode && forY instanceof NotNode) {
return new NotNode(AndNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue(), view));
}
+
return self != null ? self : new OrNode(forX, forY).maybeCommuteInputs();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/XorNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/XorNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -54,6 +54,18 @@
assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT));
}
+ private XorNode(ValueNode x, ValueNode y, Stamp forcedStamp) {
+ super(TYPE, forcedStamp, x, y);
+ }
+
+ /**
+ * Create a new XorNode with a forced stamp, without eager folding. This should only be used in
+ * snippet code, where native-image may assign wrong stamps during graph generation.
+ */
+ public static ValueNode createForSnippet(ValueNode x, ValueNode y, Stamp forcedStamp) {
+ return new XorNode(x, y, forcedStamp);
+ }
+
public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
BinaryOp<Xor> op = ArithmeticOpTable.forStamp(x.stamp(view)).getXor();
Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/Block.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/Block.java Thu Oct 31 16:54:16 2019 -0700
@@ -260,10 +260,10 @@
LocationSet result = new LocationSet();
for (FixedNode node : this.getNodes()) {
if (node instanceof MemoryCheckpoint.Single) {
- LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
+ LocationIdentity identity = ((MemoryCheckpoint.Single) node).getKilledLocationIdentity();
result.add(identity);
} else if (node instanceof MemoryCheckpoint.Multi) {
- for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) {
+ for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getKilledLocationIdentities()) {
result.add(identity);
}
}
@@ -365,4 +365,26 @@
protected void setPostDominator(Block postdominator) {
this.postdominator = postdominator;
}
+
+ /**
+ * Checks whether {@code this} block is in the same loop or an outer loop of the block given as
+ * parameter.
+ */
+ public boolean isInSameOrOuterLoopOf(Block block) {
+
+ if (this.loop == null) {
+ // We are in no loop, so this holds true for every other block.
+ return true;
+ }
+
+ Loop<Block> l = block.loop;
+ while (l != null) {
+ if (l == this.loop) {
+ return true;
+ }
+ l = l.getParent();
+ }
+
+ return false;
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java Thu Oct 31 16:54:16 2019 -0700
@@ -38,6 +38,7 @@
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeMap;
+import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.AbstractEndNode;
import org.graalvm.compiler.nodes.ControlSinkNode;
@@ -416,6 +417,15 @@
return nodeToBlock.get(node);
}
+ public Block commonDominatorFor(NodeIterable<? extends Node> nodes) {
+ Block commonDom = null;
+ for (Node n : nodes) {
+ Block b = blockFor(n);
+ commonDom = (Block) AbstractControlFlowGraph.commonDominator(commonDom, b);
+ }
+ return commonDom;
+ }
+
@Override
public List<Loop<Block>> getLoops() {
return loops;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/StringToBytesNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/StringToBytesNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -66,7 +66,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return NamedLocationIdentity.getArrayLocation(JavaKind.Byte);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BytecodeExceptionNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BytecodeExceptionNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -100,7 +100,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ForeignCallNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ForeignCallNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -159,7 +159,7 @@
}
@Override
- public LocationIdentity[] getLocationIdentities() {
+ public LocationIdentity[] getKilledLocationIdentities() {
return foreignCalls.getKilledLocations(descriptor);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/JavaWriteNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/JavaWriteNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -79,4 +79,9 @@
public Stamp getAccessStamp() {
return StampFactory.forKind(writeKind);
}
+
+ @Override
+ public LocationIdentity getKilledLocationIdentity() {
+ return getLocationIdentity();
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/MembarNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/MembarNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -58,7 +58,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return location;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -161,7 +161,7 @@
@Override
protected ValueNode cloneAsFieldAccess(Assumptions assumptions, ResolvedJavaField field, boolean volatileAccess) {
- return LoadFieldNode.create(assumptions, object(), field, volatileAccess);
+ return LoadFieldNode.create(assumptions, field.isStatic() ? null : object(), field, volatileAccess);
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -134,7 +134,7 @@
@Override
protected ValueNode cloneAsFieldAccess(Assumptions assumptions, ResolvedJavaField field, boolean volatileAccess) {
- return new StoreFieldNode(object(), field, value(), stateAfter(), volatileAccess);
+ return new StoreFieldNode(field.isStatic() ? null : object(), field, value(), stateAfter(), volatileAccess);
}
@Override
@@ -145,4 +145,9 @@
public FrameState getState() {
return stateAfter;
}
+
+ @Override
+ public LocationIdentity getKilledLocationIdentity() {
+ return getLocationIdentity();
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -290,4 +290,7 @@
}
}
+ public int[] getKeySuccessors() {
+ return keySuccessors.clone();
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeAccessNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeAccessNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -27,6 +27,8 @@
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+import java.nio.ByteOrder;
+
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
@@ -40,6 +42,8 @@
import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.vm.ci.meta.Assumptions;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaType;
@@ -95,10 +99,14 @@
// Try to canonicalize to a field access.
ResolvedJavaType receiverType = StampTool.typeOrNull(object());
if (receiverType != null) {
- ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(constantOffset, accessKind());
- // No need for checking that the receiver is non-null. The field access includes
- // the null check and if a field is found, the offset is so small that this is
- // never a valid access of an arbitrary address.
+ ResolvedJavaField field = getStaticFieldUnsafeAccess(tool.getConstantReflection());
+ if (field == null) {
+ field = receiverType.findInstanceFieldWithOffset(constantOffset, accessKind());
+ }
+
+ // No need for checking that the receiver is non-null. The field access
+ // includes the null check and if a field is found, the offset is so small that
+ // this is never a valid access of an arbitrary address.
if (field != null && field.getJavaKind() == this.accessKind()) {
assert !graph().isAfterFloatingReadPhase() : "cannot add more precise memory location after floating read phase";
// Unsafe accesses never have volatile semantics.
@@ -128,4 +136,58 @@
protected abstract ValueNode cloneAsFieldAccess(Assumptions assumptions, ResolvedJavaField field, boolean volatileAccess);
protected abstract ValueNode cloneAsArrayAccess(ValueNode location, LocationIdentity identity);
+
+ /**
+ * In this method we check if the unsafe access is to a static field. This is the case when
+ * {@code object} is a constant of type {@link Class} (static field's declaring class) and
+ * {@code offset} is a constant (HotSpot-specific field offset from the declaring class).
+ *
+ * @return the static field, if any, that this node is reading
+ */
+ private ResolvedJavaField getStaticFieldUnsafeAccess(ConstantReflectionProvider constantReflection) {
+ if (!object().isJavaConstant() || !offset().isJavaConstant() ||
+ object().isNullConstant() || offset().isNullConstant()) {
+ return null;
+ }
+ JavaConstant objectConstant = object().asJavaConstant();
+ JavaConstant offsetConstant = offset().asJavaConstant();
+ assert objectConstant != null && offsetConstant != null : "Verified by the check at the beginning.";
+ ResolvedJavaType staticReceiverType = constantReflection.asJavaType(objectConstant);
+ if (staticReceiverType == null) {
+ // object is not of type Class so it is not a static field
+ return null;
+ }
+ return findStaticFieldWithOffset(staticReceiverType, offsetConstant.asLong(), accessKind);
+ }
+
+ private static ResolvedJavaField findStaticFieldWithOffset(ResolvedJavaType type, long offset, JavaKind expectedEntryKind) {
+ try {
+ ResolvedJavaField[] declaredFields = type.getStaticFields();
+ return findFieldWithOffset(offset, expectedEntryKind, declaredFields);
+ } catch (UnsupportedOperationException e) {
+ return null;
+ }
+ }
+
+ /**
+ * NOTE GR-18873: this is a copy-paste implementation derived from
+ * {@code jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl#findStaticFieldWithOffset}.
+ */
+ private static ResolvedJavaField findFieldWithOffset(long offset, JavaKind expectedEntryKind, ResolvedJavaField[] declaredFields) {
+ for (ResolvedJavaField field : declaredFields) {
+ long resolvedFieldOffset = field.getOffset();
+ if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN &&
+ expectedEntryKind.isPrimitive() &&
+ !expectedEntryKind.equals(JavaKind.Void) &&
+ field.getJavaKind().isPrimitive()) {
+ resolvedFieldOffset += field.getJavaKind().getByteCount() -
+ Math.min(field.getJavaKind().getByteCount(), 4 + expectedEntryKind.getByteCount());
+ }
+ if (resolvedFieldOffset == offset) {
+ return field;
+ }
+ }
+ return null;
+ }
+
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeMemoryStoreNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnsafeMemoryStoreNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -77,7 +77,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return locationIdentity;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderConfiguration.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderConfiguration.java Thu Oct 31 16:54:16 2019 -0700
@@ -203,6 +203,7 @@
private final boolean trackNodeSourcePosition;
private final boolean retainLocalVariables;
private final Plugins plugins;
+ private final boolean replaceLocalsWithConstants;
public enum BytecodeExceptionMode {
/**
@@ -231,6 +232,7 @@
boolean insertFullInfopoints,
boolean trackNodeSourcePosition,
boolean retainLocalVariables,
+ boolean replaceLocalsWithConstants,
List<ResolvedJavaType> skippedExceptionTypes,
Plugins plugins) {
this.eagerResolving = eagerResolving;
@@ -240,6 +242,7 @@
this.insertFullInfopoints = insertFullInfopoints;
this.trackNodeSourcePosition = trackNodeSourcePosition;
this.retainLocalVariables = retainLocalVariables;
+ this.replaceLocalsWithConstants = replaceLocalsWithConstants;
this.skippedExceptionTypes = skippedExceptionTypes;
this.plugins = plugins;
}
@@ -259,6 +262,7 @@
insertFullInfopoints,
trackNodeSourcePosition,
retainLocalVariables,
+ replaceLocalsWithConstants,
skippedExceptionTypes,
newPlugins);
return result;
@@ -279,6 +283,7 @@
insertFullInfopoints,
trackNodeSourcePosition,
retainLocalVariables,
+ replaceLocalsWithConstants,
skippedExceptionTypes,
plugins);
}
@@ -292,6 +297,7 @@
insertFullInfopoints,
trackNodeSourcePosition,
retainLocalVariables,
+ replaceLocalsWithConstants,
skippedExceptionTypes,
plugins);
}
@@ -305,6 +311,7 @@
insertFullInfopoints,
trackNodeSourcePosition,
retainLocalVariables,
+ replaceLocalsWithConstants,
Collections.unmodifiableList(Arrays.asList(newSkippedExceptionTypes)),
plugins);
}
@@ -317,6 +324,7 @@
insertFullInfopoints,
trackNodeSourcePosition,
retainLocalVariables,
+ replaceLocalsWithConstants,
skippedExceptionTypes,
plugins);
}
@@ -330,6 +338,7 @@
insertFullInfopoints,
trackNodeSourcePosition,
retainLocalVariables,
+ replaceLocalsWithConstants,
skippedExceptionTypes,
plugins);
}
@@ -343,6 +352,7 @@
newInsertFullInfopoints,
trackNodeSourcePosition,
retainLocalVariables,
+ replaceLocalsWithConstants,
skippedExceptionTypes,
plugins);
}
@@ -356,6 +366,7 @@
insertFullInfopoints,
newTrackNodeSourcePosition,
retainLocalVariables,
+ replaceLocalsWithConstants,
skippedExceptionTypes,
plugins);
}
@@ -369,6 +380,21 @@
insertFullInfopoints,
trackNodeSourcePosition,
newRetainLocalVariables,
+ replaceLocalsWithConstants,
+ skippedExceptionTypes,
+ plugins);
+ }
+
+ public GraphBuilderConfiguration withReplaceLocalsWithConstants(boolean newReplaceLocalsWithConstants) {
+ return new GraphBuilderConfiguration(
+ eagerResolving,
+ unresolvedIsError,
+ bytecodeExceptionMode,
+ omitAssertions,
+ insertFullInfopoints,
+ trackNodeSourcePosition,
+ retainLocalVariables,
+ newReplaceLocalsWithConstants,
skippedExceptionTypes,
plugins);
}
@@ -401,6 +427,10 @@
return insertFullInfopoints;
}
+ public boolean replaceLocalsWithConstants() {
+ return this.replaceLocalsWithConstants;
+ }
+
public static GraphBuilderConfiguration getDefault(Plugins plugins) {
return new GraphBuilderConfiguration(
/* eagerResolving: */ false,
@@ -410,6 +440,7 @@
/* insertFullInfopoints: */ false,
/* trackNodeSourcePosition: */ false,
/* retainLocalVariables */ false,
+ /* replaceLocalsWithConstants */ false,
Collections.emptyList(),
plugins);
}
@@ -423,6 +454,7 @@
/* insertFullInfopoints: */ false,
/* trackNodeSourcePosition: */ false,
/* retainLocalVariables */ false,
+ /* replaceLocalsWithConstants */ false,
Collections.emptyList(),
plugins);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java Thu Oct 31 16:54:16 2019 -0700
@@ -46,7 +46,6 @@
import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
import org.graalvm.compiler.api.replacements.MethodSubstitution;
-import org.graalvm.compiler.api.replacements.MethodSubstitutionRegistry;
import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.core.common.SuppressFBWarnings;
import org.graalvm.compiler.debug.Assertions;
@@ -55,6 +54,7 @@
import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver;
+import org.graalvm.compiler.nodes.spi.Replacements;
import jdk.vm.ci.meta.MetaUtil;
import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -175,21 +175,25 @@
}
/**
- * Utility for {@linkplain InvocationPlugins#register(InvocationPlugin, Class, String, Class...)
- * registration} of invocation plugins.
+ * Utility for {@linkplain InvocationPlugins#register registration} of invocation plugins.
*/
- public static class Registration implements MethodSubstitutionRegistry {
+ public static class Registration {
private final InvocationPlugins plugins;
+
private final Type declaringType;
- private final BytecodeProvider methodSubstitutionBytecodeProvider;
+ private final Replacements replacements;
+ private final BytecodeProvider bytecodeProvider;
private boolean allowOverwrite;
- @Override
public Class<?> getReceiverType() {
return Receiver.class;
}
+ public Type getDeclaringType() {
+ return declaringType;
+ }
+
/**
* Creates an object for registering {@link InvocationPlugin}s for methods declared by a
* given class.
@@ -201,7 +205,8 @@
public Registration(InvocationPlugins plugins, Type declaringType) {
this.plugins = plugins;
this.declaringType = declaringType;
- this.methodSubstitutionBytecodeProvider = null;
+ this.replacements = null;
+ this.bytecodeProvider = null;
}
/**
@@ -211,13 +216,29 @@
* @param plugins where to register the plugins
* @param declaringType the class declaring the methods for which plugins will be registered
* via this object
- * @param methodSubstitutionBytecodeProvider provider used to get the bytecodes to parse for
- * method substitutions
+ * @param replacements the current Replacements provider
*/
- public Registration(InvocationPlugins plugins, Type declaringType, BytecodeProvider methodSubstitutionBytecodeProvider) {
+ public Registration(InvocationPlugins plugins, Type declaringType, Replacements replacements) {
this.plugins = plugins;
this.declaringType = declaringType;
- this.methodSubstitutionBytecodeProvider = methodSubstitutionBytecodeProvider;
+ this.replacements = replacements;
+ this.bytecodeProvider = replacements != null ? replacements.getDefaultReplacementBytecodeProvider() : null;
+ }
+
+ /**
+ * Creates an object for registering {@link InvocationPlugin}s for methods declared by a
+ * given class.
+ *
+ * @param plugins where to register the plugins
+ * @param declaringType the class declaring the methods for which plugins will be registered
+ * via this object
+ * @param replacements the current Replacements provider
+ */
+ public Registration(InvocationPlugins plugins, Type declaringType, Replacements replacements, BytecodeProvider bytecodeProvider) {
+ this.plugins = plugins;
+ this.declaringType = declaringType;
+ this.replacements = replacements;
+ this.bytecodeProvider = bytecodeProvider;
}
/**
@@ -231,7 +252,8 @@
public Registration(InvocationPlugins plugins, String declaringClassName) {
this.plugins = plugins;
this.declaringType = new OptionalLazySymbol(declaringClassName);
- this.methodSubstitutionBytecodeProvider = null;
+ this.replacements = null;
+ this.bytecodeProvider = null;
}
/**
@@ -241,13 +263,13 @@
* @param plugins where to register the plugins
* @param declaringClassName the name of the class class declaring the methods for which
* plugins will be registered via this object
- * @param methodSubstitutionBytecodeProvider provider used to get the bytecodes to parse for
- * method substitutions
+ * @param replacements the current Replacements provider
*/
- public Registration(InvocationPlugins plugins, String declaringClassName, BytecodeProvider methodSubstitutionBytecodeProvider) {
+ public Registration(InvocationPlugins plugins, String declaringClassName, Replacements replacements) {
this.plugins = plugins;
this.declaringType = new OptionalLazySymbol(declaringClassName);
- this.methodSubstitutionBytecodeProvider = methodSubstitutionBytecodeProvider;
+ this.replacements = replacements;
+ this.bytecodeProvider = replacements != null ? replacements.getDefaultReplacementBytecodeProvider() : null;
}
/**
@@ -339,6 +361,118 @@
}
/**
+ * Registers a plugin for a method with no arguments that is conditionally enabled. This
+ * ensures that {@code Replacements} is aware of this plugin.
+ *
+ * @param name the name of the method
+ * @param plugin the plugin to be registered
+ */
+ public void registerConditional0(boolean isEnabled, String name, InvocationPlugin plugin) {
+ replacements.registerConditionalPlugin(plugin);
+ if (isEnabled) {
+ plugins.register(plugin, false, allowOverwrite, declaringType, name);
+ }
+ }
+
+ /**
+ * Registers a plugin for a method with 1 argument that is conditionally enabled. This
+ * ensures that {@code Replacements} is aware of this plugin.
+ *
+ * @param name the name of the method
+ * @param plugin the plugin to be registered
+ */
+ public void registerConditional1(boolean isEnabled, String name, Type arg, InvocationPlugin plugin) {
+ replacements.registerConditionalPlugin(plugin);
+ if (isEnabled) {
+ plugins.register(plugin, false, allowOverwrite, declaringType, name, arg);
+ }
+ }
+
+ /**
+ * Registers a plugin for a method with 2 arguments that is conditionally enabled. This
+ * ensures that {@code Replacements} is aware of this plugin.
+ *
+ * @param name the name of the method
+ * @param plugin the plugin to be registered
+ */
+ public void registerConditional2(boolean isEnabled, String name, Type arg1, Type arg2, InvocationPlugin plugin) {
+ replacements.registerConditionalPlugin(plugin);
+ if (isEnabled) {
+ plugins.register(plugin, false, allowOverwrite, declaringType, name, arg1, arg2);
+ }
+ }
+
+ /**
+ * Registers a plugin for a method with 3 arguments that is conditionally enabled. This
+ * ensures that {@code Replacements} is aware of this plugin.
+ *
+ * @param name the name of the method
+ * @param plugin the plugin to be registered
+ */
+ public void registerConditional3(boolean isEnabled, String name, Type arg1, Type arg2, Type arg3, InvocationPlugin plugin) {
+ replacements.registerConditionalPlugin(plugin);
+ if (isEnabled) {
+ plugins.register(plugin, false, allowOverwrite, declaringType, name, arg1, arg2, arg3);
+ }
+ }
+
+ /**
+ * Registers a plugin for a method with 4 arguments that is conditionally enabled. This
+ * ensures that {@code Replacements} is aware of this plugin.
+ *
+ * @param name the name of the method
+ * @param plugin the plugin to be registered
+ */
+ public void registerConditional4(boolean isEnabled, String name, Type arg1, Type arg2, Type arg3, Type arg4, InvocationPlugin plugin) {
+ replacements.registerConditionalPlugin(plugin);
+ if (isEnabled) {
+ plugins.register(plugin, false, allowOverwrite, declaringType, name, arg1, arg2, arg3, arg4);
+ }
+ }
+
+ /**
+ * Registers a plugin for a method with 5 arguments that is conditionally enabled. This
+ * ensures that {@code Replacements} is aware of this plugin.
+ *
+ * @param name the name of the method
+ * @param plugin the plugin to be registered
+ */
+ public void registerConditional5(boolean isEnabled, String name, Type arg1, Type arg2, Type arg3, Type arg4, Type arg5, InvocationPlugin plugin) {
+ replacements.registerConditionalPlugin(plugin);
+ if (isEnabled) {
+ plugins.register(plugin, false, allowOverwrite, declaringType, name, arg1, arg2, arg3, arg4, arg5);
+ }
+ }
+
+ /**
+ * Registers a plugin for a method with 6 arguments that is conditionally enabled. This
+ * ensures that {@code Replacements} is aware of this plugin.
+ *
+ * @param name the name of the method
+ * @param plugin the plugin to be registered
+ */
+ public void registerConditional6(boolean isEnabled, String name, Type arg1, Type arg2, Type arg3, Type arg4, Type arg5, Type arg6, InvocationPlugin plugin) {
+ replacements.registerConditionalPlugin(plugin);
+ if (isEnabled) {
+ plugins.register(plugin, false, allowOverwrite, declaringType, name, arg1, arg2, arg3, arg4, arg5, arg6);
+ }
+ }
+
+ /**
+ * Registers a plugin for a method with 7 arguments that is conditionally enabled. This
+ * ensures that {@code Replacements} is aware of this plugin.
+ *
+ * @param name the name of the method
+ * @param plugin the plugin to be registered
+ */
+ public void registerConditional7(boolean isEnabled, String name, Type arg1, Type arg2, Type arg3, Type arg4, Type arg5, Type arg6, Type arg7, InvocationPlugin plugin) {
+ replacements.registerConditionalPlugin(plugin);
+ if (isEnabled) {
+ plugins.register(plugin, false, allowOverwrite, declaringType, name, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+ }
+ }
+
+ /**
* Registers a plugin for an optional method with no arguments.
*
* @param name the name of the method
@@ -398,7 +532,6 @@
* is non-static. Upon returning, element 0 will have been rewritten to
* {@code declaringClass}
*/
- @Override
public void registerMethodSubstitution(Class<?> substituteDeclaringClass, String name, Type... argumentTypes) {
registerMethodSubstitution(substituteDeclaringClass, name, name, argumentTypes);
}
@@ -407,25 +540,63 @@
* Registers a plugin that implements a method based on the bytecode of a substitute method.
*
* @param substituteDeclaringClass the class declaring the substitute method
- * @param name the name of both the original method
+ * @param name the name of the original method
* @param substituteName the name of the substitute method
* @param argumentTypes the argument types of the method. Element 0 of this array must be
* the {@link Class} value for {@link InvocationPlugin.Receiver} iff the method
* is non-static. Upon returning, element 0 will have been rewritten to
* {@code declaringClass}
*/
- @Override
public void registerMethodSubstitution(Class<?> substituteDeclaringClass, String name, String substituteName, Type... argumentTypes) {
- MethodSubstitutionPlugin plugin = createMethodSubstitution(substituteDeclaringClass, substituteName, argumentTypes);
- plugins.register(plugin, false, allowOverwrite, declaringType, name, argumentTypes);
+ doMethodSubstitutionRegistration(false, true, substituteDeclaringClass, name, substituteName, argumentTypes);
+ }
+
+ /**
+ * Registers a plugin that implements a method based on the bytecode of a substitute method
+ * that is conditinally enabled. This ensures that {@code Replacements} is aware of this
+ * plugin.
+ *
+ * @param isEnabled whether the plugin is enabled in the current compiler
+ * @param substituteDeclaringClass the class declaring the substitute method
+ * @param name the name of both the original and substitute method
+ * @param argumentTypes the argument types of the method. Element 0 of this array must be
+ * the {@link Class} value for {@link InvocationPlugin.Receiver} iff the method
+ * is non-static. Upon returning, element 0 will have been rewritten to
+ * {@code declaringClass}
+ */
+ public void registerConditionalMethodSubstitution(boolean isEnabled, Class<?> substituteDeclaringClass, String name, Type... argumentTypes) {
+ registerConditionalMethodSubstitution(isEnabled, substituteDeclaringClass, name, name, argumentTypes);
}
- public MethodSubstitutionPlugin createMethodSubstitution(Class<?> substituteDeclaringClass, String substituteName, Type... argumentTypes) {
- assert methodSubstitutionBytecodeProvider != null : "Registration used for method substitutions requires a non-null methodSubstitutionBytecodeProvider";
- MethodSubstitutionPlugin plugin = new MethodSubstitutionPlugin(methodSubstitutionBytecodeProvider, substituteDeclaringClass, substituteName, argumentTypes);
- return plugin;
+ /**
+ * Registers a plugin that implements a method based on the bytecode of a substitute method
+ * that is conditinally enabled. This ensures that {@code Replacements} is aware of this
+ * plugin.
+ *
+ * @param isEnabled whether the plugin is enabled in the current compiler
+ * @param substituteDeclaringClass the class declaring the substitute method
+ * @param name the name of the original method
+ * @param substituteName the name of the substitute method
+ * @param argumentTypes the argument types of the method. Element 0 of this array must be
+ * the {@link Class} value for {@link InvocationPlugin.Receiver} iff the method
+ * is non-static. Upon returning, element 0 will have been rewritten to
+ * {@code declaringClass}
+ */
+ public void registerConditionalMethodSubstitution(boolean isEnabled, Class<?> substituteDeclaringClass, String name, String substituteName, Type... argumentTypes) {
+ doMethodSubstitutionRegistration(true, isEnabled, substituteDeclaringClass, name, substituteName, argumentTypes);
}
+ private void doMethodSubstitutionRegistration(boolean isConditional, boolean isEnabled, Class<?> substituteDeclaringClass, String name, String substituteName, Type[] argumentTypes) {
+ MethodSubstitutionPlugin plugin = new MethodSubstitutionPlugin(this, bytecodeProvider, name, substituteDeclaringClass, substituteName, argumentTypes);
+ replacements.registerMethodSubstitution(plugin);
+ if (isConditional) {
+ // Notify Replacements about the plugin even if it's not current enabled
+ replacements.registerConditionalPlugin(plugin);
+ }
+ if (isEnabled) {
+ plugins.register(plugin, false, allowOverwrite, declaringType, name, argumentTypes);
+ }
+ }
}
/**
@@ -519,13 +690,7 @@
this.plugin = data;
this.isStatic = isStatic;
this.name = name;
- StringBuilder buf = new StringBuilder();
- buf.append('(');
- for (int i = isStatic ? 0 : 1; i < argumentTypes.length; i++) {
- buf.append(MetaUtil.toInternalName(argumentTypes[i].getTypeName()));
- }
- buf.append(')');
- this.argumentsDescriptor = buf.toString();
+ this.argumentsDescriptor = toArgumentDescriptor(isStatic, argumentTypes);
assert !name.equals("<init>") || !isStatic : this;
}
@@ -546,6 +711,16 @@
}
}
+ static String toArgumentDescriptor(boolean isStatic, Type[] argumentTypes) {
+ StringBuilder buf = new StringBuilder();
+ buf.append('(');
+ for (int i = isStatic ? 0 : 1; i < argumentTypes.length; i++) {
+ buf.append(MetaUtil.toInternalName(argumentTypes[i].getTypeName()));
+ }
+ buf.append(')');
+ return buf.toString();
+ }
+
/**
* Plugin registrations for already resolved methods. If non-null, then {@link #registrations}
* is null and no further registrations can be made.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java Thu Oct 31 16:54:16 2019 -0700
@@ -42,6 +42,7 @@
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
/**
* An {@link InvocationPlugin} for a method where the implementation of the method is provided by a
@@ -56,6 +57,8 @@
*/
public final class MethodSubstitutionPlugin implements InvocationPlugin {
+ private InvocationPlugins.Registration registration;
+
private ResolvedJavaMethod cachedSubstitute;
/**
@@ -64,9 +67,14 @@
private final Class<?> declaringClass;
/**
- * The name of the original and substitute method.
+ * The name of the substitute method.
*/
- private final String name;
+ private final String substituteName;
+
+ /**
+ * The name of the original method.
+ */
+ private final String originalName;
/**
* The parameter types of the substitute method.
@@ -81,16 +89,21 @@
* Creates a method substitution plugin.
*
* @param bytecodeProvider used to get the bytecodes to parse for the substitute method
+ * @param originalName the name of the original method
* @param declaringClass the class in which the substitute method is declared
- * @param name the name of the substitute method
+ * @param substituteName the name of the substitute method
* @param parameters the parameter types of the substitute method. If the original method is not
* static, then {@code parameters[0]} must be the {@link Class} value denoting
* {@link InvocationPlugin.Receiver}
*/
- public MethodSubstitutionPlugin(BytecodeProvider bytecodeProvider, Class<?> declaringClass, String name, Type... parameters) {
+ public MethodSubstitutionPlugin(InvocationPlugins.Registration registration, BytecodeProvider bytecodeProvider, String originalName, Class<?> declaringClass, String substituteName,
+ Type... parameters) {
+ assert bytecodeProvider != null : "Requires a non-null methodSubstitutionBytecodeProvider";
+ this.registration = registration;
this.bytecodeProvider = bytecodeProvider;
+ this.originalName = originalName;
this.declaringClass = declaringClass;
- this.name = name;
+ this.substituteName = substituteName;
this.parameters = parameters;
this.originalIsStatic = parameters.length == 0 || parameters[0] != InvocationPlugin.Receiver.class;
}
@@ -144,7 +157,7 @@
* Determines if a given method is the substitute method of this plugin.
*/
private boolean isSubstitute(Method m) {
- if (Modifier.isStatic(m.getModifiers()) && m.getName().equals(name)) {
+ if (Modifier.isStatic(m.getModifiers()) && m.getName().equals(substituteName)) {
if (parameters.length == m.getParameterCount()) {
Class<?>[] mparams = m.getParameterTypes();
int start = 0;
@@ -189,9 +202,6 @@
@Override
public boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode[] argsIncludingReceiver) {
if (IS_IN_NATIVE_IMAGE || (UseEncodedGraphs.getValue(b.getOptions()) && !b.parsingIntrinsic())) {
- if (!IS_IN_NATIVE_IMAGE && UseEncodedGraphs.getValue(b.getOptions())) {
- b.getReplacements().registerMethodSubstitution(this, targetMethod, INLINE_AFTER_PARSING, b.getOptions());
- }
StructuredGraph subst = b.getReplacements().getMethodSubstitution(this,
targetMethod,
INLINE_AFTER_PARSING,
@@ -220,7 +230,27 @@
@Override
public String toString() {
- return String.format("%s[%s.%s(%s)]", getClass().getSimpleName(), declaringClass.getName(), name,
+ return String.format("%s[%s.%s(%s)]", getClass().getSimpleName(), declaringClass.getName(), substituteName,
Arrays.asList(parameters).stream().map(c -> c.getTypeName()).collect(Collectors.joining(", ")));
}
+
+ public String originalMethodAsString() {
+ return String.format("%s.%s(%s)", declaringClass.getName(), substituteName, Arrays.asList(parameters).stream().map(c -> c.getTypeName()).collect(Collectors.joining(", ")));
+ }
+
+ public ResolvedJavaMethod getOriginalMethod(MetaAccessProvider metaAccess) {
+ Class<?> clazz = resolveType(registration.getDeclaringType(), false);
+ if (clazz == null) {
+ throw new GraalError("Can't find original class for " + this + " with class " + registration.getDeclaringType());
+ }
+ ResolvedJavaType type = metaAccess.lookupJavaType(clazz);
+ String argumentsDescriptor = InvocationPlugins.toArgumentDescriptor(originalIsStatic, this.parameters);
+ for (ResolvedJavaMethod declared : type.getDeclaredMethods()) {
+ if (declared.getName().equals(originalName) && declared.isStatic() == originalIsStatic &&
+ declared.getSignature().toMethodDescriptor().startsWith(argumentsDescriptor)) {
+ return declared;
+ }
+ }
+ throw new GraalError("Can't find original method for " + this + " with class " + registration.getDeclaringType());
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractCompareAndSwapNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractCompareAndSwapNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -93,4 +93,9 @@
public Stamp getAccessStamp() {
return expectedValue.stamp(NodeView.DEFAULT).meet(newValue.stamp(NodeView.DEFAULT)).unrestricted();
}
+
+ @Override
+ public LocationIdentity getKilledLocationIdentity() {
+ return getLocationIdentity();
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractUnsafeCompareAndSwapNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractUnsafeCompareAndSwapNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -97,7 +97,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return locationIdentity;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndAddNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndAddNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -74,7 +74,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return locationIdentity;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndWriteNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndWriteNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -80,7 +80,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return locationIdentity;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ExceptionObjectNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ExceptionObjectNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, 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
@@ -60,7 +60,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
@@ -80,7 +80,7 @@
* Now the lowering to BeginNode+LoadExceptionNode can be performed, since no more
* deopts can float in between the begin node and the load exception node.
*/
- LocationIdentity locationsKilledByInvoke = ((InvokeWithExceptionNode) predecessor()).getLocationIdentity();
+ LocationIdentity locationsKilledByInvoke = ((InvokeWithExceptionNode) predecessor()).getKilledLocationIdentity();
AbstractBeginNode entry = graph().add(KillingBeginNode.create(locationsKilledByInvoke));
LoadExceptionObjectNode loadException = graph().add(new LoadExceptionObjectNode(stamp(NodeView.DEFAULT)));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoweredAtomicReadAndWriteNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoweredAtomicReadAndWriteNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -103,4 +103,9 @@
public Stamp getAccessStamp() {
return stamp(NodeView.DEFAULT);
}
+
+ @Override
+ public LocationIdentity getKilledLocationIdentity() {
+ return getLocationIdentity();
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorEnterNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorEnterNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, 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
@@ -57,7 +57,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorExitNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorExitNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -70,7 +70,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RawMonitorEnterNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RawMonitorEnterNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, 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
@@ -64,7 +64,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FixedAccessNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FixedAccessNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -25,6 +25,7 @@
package org.graalvm.compiler.nodes.memory;
import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.graph.IterableNodeType;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.NodeInfo;
@@ -39,7 +40,7 @@
* does not include a null check on the object.
*/
@NodeInfo
-public abstract class FixedAccessNode extends DeoptimizingFixedWithNextNode implements Access {
+public abstract class FixedAccessNode extends DeoptimizingFixedWithNextNode implements Access, IterableNodeType {
public static final NodeClass<FixedAccessNode> TYPE = NodeClass.create(FixedAccessNode.class);
@OptionalInput(InputType.Guard) protected GuardingNode guard;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryCheckpoint.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryCheckpoint.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -44,8 +44,7 @@
*
* @return the identity of the location killed by this node.
*/
- LocationIdentity getLocationIdentity();
-
+ LocationIdentity getKilledLocationIdentity();
}
interface Multi extends MemoryCheckpoint {
@@ -57,7 +56,7 @@
*
* @return the identities of all locations killed by this node.
*/
- LocationIdentity[] getLocationIdentities();
+ LocationIdentity[] getKilledLocationIdentities();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/VolatileReadNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Red Hat Inc. 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.nodes.memory;
+
+import org.graalvm.compiler.core.common.GraalOptions;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+
+import static org.graalvm.compiler.nodeinfo.InputType.Memory;
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+
+@NodeInfo(nameTemplate = "Read#{p#location/s}", allowedUsageTypes = Memory, cycles = CYCLES_2, size = SIZE_1)
+public class VolatileReadNode extends ReadNode implements MemoryCheckpoint.Single {
+ public static final NodeClass<VolatileReadNode> TYPE = NodeClass.create(VolatileReadNode.class);
+
+ public VolatileReadNode(AddressNode address, LocationIdentity location, Stamp stamp, BarrierType barrierType) {
+ super(TYPE, address, location, stamp, null, barrierType, false, null);
+ assert GraalOptions.LateMembars.getValue(address.getOptions());
+ }
+
+ @SuppressWarnings("try")
+ @Override
+ public FloatingAccessNode asFloatingNode() {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public boolean canFloat() {
+ return false;
+ }
+
+ @Override
+ public LocationIdentity getKilledLocationIdentity() {
+ return LocationIdentity.any();
+ }
+
+ @Override
+ public boolean canNullCheck() {
+ return false;
+ }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/WriteNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/WriteNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -44,13 +44,16 @@
public class WriteNode extends AbstractWriteNode implements LIRLowerableAccess, Canonicalizable {
public static final NodeClass<WriteNode> TYPE = NodeClass.create(WriteNode.class);
+ private final boolean volatileAccess;
- public WriteNode(AddressNode address, LocationIdentity location, ValueNode value, BarrierType barrierType) {
+ public WriteNode(AddressNode address, LocationIdentity location, ValueNode value, BarrierType barrierType, boolean volatileAccess) {
super(TYPE, address, location, value, barrierType);
+ this.volatileAccess = volatileAccess;
}
protected WriteNode(NodeClass<? extends WriteNode> c, AddressNode address, LocationIdentity location, ValueNode value, BarrierType barrierType) {
super(c, address, location, value, barrierType);
+ this.volatileAccess = false;
}
@Override
@@ -61,7 +64,7 @@
@Override
public boolean canNullCheck() {
- return true;
+ return !isVolatile();
}
@Override
@@ -73,11 +76,23 @@
public Node canonical(CanonicalizerTool tool) {
if (tool.canonicalizeReads() && hasExactlyOneUsage() && next() instanceof WriteNode) {
WriteNode write = (WriteNode) next();
- if (write.lastLocationAccess == this && write.getAddress() == getAddress() && getAccessStamp().isCompatible(write.getAccessStamp())) {
+ if (write.lastLocationAccess == this && write.getAddress() == getAddress() && getAccessStamp().isCompatible(write.getAccessStamp()) && !isVolatile()) {
write.setLastLocationAccess(getLastLocationAccess());
return write;
}
}
return this;
}
+
+ @Override
+ public LocationIdentity getKilledLocationIdentity() {
+ if (isVolatile()) {
+ return LocationIdentity.any();
+ }
+ return getLocationIdentity();
+ }
+
+ public boolean isVolatile() {
+ return volatileAccess;
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DelegatingReplacements.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DelegatingReplacements.java Thu Oct 31 16:54:16 2019 -0700
@@ -34,6 +34,7 @@
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
+import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin;
import org.graalvm.compiler.options.OptionValues;
@@ -82,8 +83,13 @@
}
@Override
- public void registerMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context, OptionValues options) {
- delegate.registerMethodSubstitution(plugin, original, context, options);
+ public void registerMethodSubstitution(MethodSubstitutionPlugin plugin) {
+ delegate.registerMethodSubstitution(plugin);
+ }
+
+ @Override
+ public void registerConditionalPlugin(InvocationPlugin plugin) {
+ delegate.registerConditionalPlugin(plugin);
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/Replacements.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/Replacements.java Thu Oct 31 16:54:16 2019 -0700
@@ -97,7 +97,14 @@
/**
* Registers a plugin as a substitution.
*/
- void registerMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context, OptionValues options);
+ void registerMethodSubstitution(MethodSubstitutionPlugin plugin);
+
+ /**
+ * Marks a plugin as conditionally applied. In the contenxt of libgraal conditional plugins
+ * can't be used in during graph encoding for snippets and method substitutions and this is used
+ * to detect violations of this restriction.
+ */
+ void registerConditionalPlugin(InvocationPlugin plugin);
/**
* Gets a graph that is a substitution for a given method.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Thu Oct 31 16:54:16 2019 -0700
@@ -54,11 +54,13 @@
import org.graalvm.compiler.nodes.AbstractEndNode;
import org.graalvm.compiler.nodes.AbstractMergeNode;
import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.ControlSinkNode;
import org.graalvm.compiler.nodes.ControlSplitNode;
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.GuardNode;
+import org.graalvm.compiler.nodes.IfNode;
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.LoopEndNode;
import org.graalvm.compiler.nodes.LoopExitNode;
@@ -105,6 +107,8 @@
public static final OptionKey<Boolean> VerifyKillCFGUnusedNodes = new OptionKey<>(false);
}
+ public static final int MAX_FRAMESTATE_SEARCH_DEPTH = 4;
+
private static void killCFGInner(FixedNode node) {
EconomicSet<Node> markedNodes = EconomicSet.create();
EconomicMap<AbstractMergeNode, List<AbstractEndNode>> unmarkedMerges = EconomicMap.create();
@@ -1110,4 +1114,55 @@
tool.createVirtualObject(newVirtualArray, newEntryState, Collections.<MonitorIdNode> emptyList(), false);
tool.replaceWithVirtual(newVirtualArray);
}
+
+ /**
+ * Snippet lowerings may produce patterns without a frame state on the merge. We need to take
+ * extra care when optimizing these patterns.
+ */
+ public static boolean checkFrameState(FixedNode start, int maxDepth) {
+ if (maxDepth == 0) {
+ return false;
+ }
+ FixedNode node = start;
+ while (true) {
+ if (node instanceof AbstractMergeNode) {
+ AbstractMergeNode mergeNode = (AbstractMergeNode) node;
+ if (mergeNode.stateAfter() == null) {
+ return false;
+ } else {
+ return true;
+ }
+ } else if (node instanceof StateSplit) {
+ StateSplit stateSplitNode = (StateSplit) node;
+ if (stateSplitNode.stateAfter() != null) {
+ return true;
+ }
+ }
+
+ if (node instanceof ControlSplitNode) {
+ ControlSplitNode controlSplitNode = (ControlSplitNode) node;
+ for (Node succ : controlSplitNode.cfgSuccessors()) {
+ if (checkFrameState((FixedNode) succ, maxDepth - 1)) {
+ return true;
+ }
+ }
+ return false;
+ } else if (node instanceof FixedWithNextNode) {
+ FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) node;
+ node = fixedWithNextNode.next();
+ } else if (node instanceof AbstractEndNode) {
+ AbstractEndNode endNode = (AbstractEndNode) node;
+ node = endNode.merge();
+ } else if (node instanceof ControlSinkNode) {
+ return true;
+ } else {
+ assert false : "unexpected node";
+ return false;
+ }
+ }
+ }
+
+ public static boolean mayRemoveSplit(IfNode ifNode) {
+ return GraphUtil.checkFrameState(ifNode.trueSuccessor(), MAX_FRAMESTATE_SEARCH_DEPTH) && GraphUtil.checkFrameState(ifNode.falseSuccessor(), MAX_FRAMESTATE_SEARCH_DEPTH);
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/AllocatedObjectNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/AllocatedObjectNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, 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
@@ -36,7 +36,7 @@
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.spi.ArrayLengthProvider;
-import org.graalvm.compiler.nodes.spi.Virtualizable;
+import org.graalvm.compiler.nodes.spi.VirtualizableAllocation;
import org.graalvm.compiler.nodes.spi.VirtualizerTool;
import org.graalvm.compiler.nodes.util.GraphUtil;
@@ -45,7 +45,7 @@
* {@link VirtualObjectNode}.
*/
@NodeInfo(cycles = CYCLES_0, size = SIZE_0)
-public final class AllocatedObjectNode extends FloatingNode implements Virtualizable, ArrayLengthProvider {
+public final class AllocatedObjectNode extends FloatingNode implements VirtualizableAllocation, ArrayLengthProvider {
public static final NodeClass<AllocatedObjectNode> TYPE = NodeClass.create(AllocatedObjectNode.class);
@Input VirtualObjectNode virtualObject;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/CommitAllocationNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/CommitAllocationNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, 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
@@ -121,7 +121,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return locks.isEmpty() ? LocationIdentity.init() : LocationIdentity.any();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java Thu Oct 31 16:54:16 2019 -0700
@@ -24,6 +24,12 @@
package org.graalvm.compiler.phases.common;
+import static org.graalvm.compiler.phases.common.CanonicalizerPhase.CanonicalizerFeature.CFG_SIMPLIFICATION;
+import static org.graalvm.compiler.phases.common.CanonicalizerPhase.CanonicalizerFeature.GVN;
+import static org.graalvm.compiler.phases.common.CanonicalizerPhase.CanonicalizerFeature.READ_CANONICALIZATION;
+
+import java.util.EnumSet;
+
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.debug.CounterKey;
@@ -66,6 +72,12 @@
public class CanonicalizerPhase extends BasePhase<CoreProviders> {
+ public enum CanonicalizerFeature {
+ READ_CANONICALIZATION,
+ CFG_SIMPLIFICATION,
+ GVN
+ }
+
private static final int MAX_ITERATION_PER_NODE = 10;
private static final CounterKey COUNTER_CANONICALIZED_NODES = DebugContext.counter("CanonicalizedNodes");
private static final CounterKey COUNTER_PROCESSED_NODES = DebugContext.counter("ProcessedNodes");
@@ -75,40 +87,79 @@
private static final CounterKey COUNTER_SIMPLIFICATION_CONSIDERED_NODES = DebugContext.counter("SimplificationConsideredNodes");
private static final CounterKey COUNTER_GLOBAL_VALUE_NUMBERING_HITS = DebugContext.counter("GlobalValueNumberingHits");
- private boolean globalValueNumber = true;
- private boolean canonicalizeReads = true;
- private boolean simplify = true;
- private final CustomCanonicalizer customCanonicalizer;
+ private final EnumSet<CanonicalizerFeature> features;
+ private final CustomCanonicalization customCanonicalization;
+ private final CustomSimplification customSimplification;
- public abstract static class CustomCanonicalizer {
+ public interface CustomCanonicalization {
+ /**
+ * @param node the node to be canonicalized
+ * @return the same node if no action should be taken, {@code null} if the node should be
+ * deleted, or a new node that should replace the given node
+ */
+ Node canonicalize(Node node);
+ }
- public Node canonicalize(Node node) {
- return node;
- }
+ public interface CustomSimplification {
+ /**
+ * @param node the node to be simplified
+ * @param tool utility available during the simplification process
+ */
+ void simplify(Node node, SimplifierTool tool);
+ }
- @SuppressWarnings("unused")
- public void simplify(Node node, SimplifierTool tool) {
- }
+ protected CanonicalizerPhase(EnumSet<CanonicalizerFeature> features) {
+ this(null, null, features);
+ }
+
+ protected CanonicalizerPhase() {
+ this(null, null, EnumSet.allOf(CanonicalizerFeature.class));
+ }
+
+ protected CanonicalizerPhase(CustomCanonicalization customCanonicalization, CustomSimplification customSimplification) {
+ this(customCanonicalization, customSimplification, EnumSet.allOf(CanonicalizerFeature.class));
}
- public CanonicalizerPhase() {
- this(null);
+ protected CanonicalizerPhase(CustomCanonicalization customCanonicalization, CustomSimplification customSimplification, EnumSet<CanonicalizerFeature> features) {
+ this.customCanonicalization = customCanonicalization;
+ this.customSimplification = customSimplification;
+ this.features = features;
}
- public CanonicalizerPhase(CustomCanonicalizer customCanonicalizer) {
- this.customCanonicalizer = customCanonicalizer;
+ public CanonicalizerPhase copyWithCustomCanonicalization(CustomCanonicalization newCanonicalization) {
+ return new CanonicalizerPhase(newCanonicalization, customSimplification, features);
+ }
+
+ public CanonicalizerPhase copyWithCustomSimplification(CustomSimplification newSimplification) {
+ return new CanonicalizerPhase(customCanonicalization, newSimplification, features);
+ }
+
+ public CanonicalizerPhase copyWithoutGVN() {
+ EnumSet<CanonicalizerFeature> newFeatures = EnumSet.copyOf(features);
+ newFeatures.remove(GVN);
+ return new CanonicalizerPhase(customCanonicalization, customSimplification, newFeatures);
}
- public void disableGVN() {
- globalValueNumber = false;
+ public CanonicalizerPhase copyWithoutSimplification() {
+ EnumSet<CanonicalizerFeature> newFeatures = EnumSet.copyOf(features);
+ newFeatures.remove(CFG_SIMPLIFICATION);
+ return new CanonicalizerPhase(customCanonicalization, customSimplification, newFeatures);
+ }
+
+ public static CanonicalizerPhase create() {
+ return new CanonicalizerPhase(null, null, EnumSet.allOf(CanonicalizerFeature.class));
}
- public void disableReadCanonicalization() {
- canonicalizeReads = false;
+ public static CanonicalizerPhase createWithoutReadCanonicalization() {
+ return new CanonicalizerPhase(EnumSet.complementOf(EnumSet.of(READ_CANONICALIZATION)));
}
- public void disableSimplification() {
- simplify = false;
+ public static CanonicalizerPhase createWithoutGVN() {
+ return new CanonicalizerPhase(EnumSet.complementOf(EnumSet.of(GVN)));
+ }
+
+ public static CanonicalizerPhase createWithoutCFGSimplification() {
+ return new CanonicalizerPhase(EnumSet.complementOf(EnumSet.of(CFG_SIMPLIFICATION)));
}
@Override
@@ -274,7 +325,7 @@
if (tryCanonicalize(node, nodeClass)) {
return true;
}
- if (globalValueNumber && tryGlobalValueNumbering(node, nodeClass)) {
+ if (features.contains(GVN) && tryGlobalValueNumbering(node, nodeClass)) {
return true;
}
if (node instanceof ValueNode) {
@@ -329,24 +380,18 @@
@SuppressWarnings("try")
public boolean tryCanonicalize(final Node node, NodeClass<?> nodeClass) {
try (DebugCloseable position = node.withNodeSourcePosition(); DebugContext.Scope scope = debug.withContext(node)) {
- if (customCanonicalizer != null) {
- Node canonical = customCanonicalizer.canonicalize(node);
- if (performReplacement(node, canonical)) {
- return true;
- } else {
- customCanonicalizer.simplify(node, tool);
- if (node.isDeleted()) {
- return true;
- }
- }
- }
if (nodeClass.isCanonicalizable()) {
COUNTER_CANONICALIZATION_CONSIDERED_NODES.increment(debug);
- Node canonical;
+ Node canonical = node;
try (AutoCloseable verify = getCanonicalizeableContractAssertion(node)) {
- canonical = ((Canonicalizable) node).canonical(tool);
- if (canonical == node && nodeClass.isCommutative()) {
- canonical = ((BinaryCommutative<?>) node).maybeCommuteInputs();
+ if (customCanonicalization != null) {
+ canonical = customCanonicalization.canonicalize(node);
+ }
+ if (canonical == node) {
+ canonical = ((Canonicalizable) node).canonical(tool);
+ if (canonical == node && nodeClass.isCommutative()) {
+ canonical = ((BinaryCommutative<?>) node).maybeCommuteInputs();
+ }
}
} catch (Throwable e) {
throw new GraalGraphError(e).addContext(node);
@@ -356,12 +401,17 @@
}
}
- if (nodeClass.isSimplifiable() && simplify) {
+ if (features.contains(CFG_SIMPLIFICATION) && nodeClass.isSimplifiable()) {
debug.log(DebugContext.VERBOSE_LEVEL, "Canonicalizer: simplifying %s", node);
COUNTER_SIMPLIFICATION_CONSIDERED_NODES.increment(debug);
- node.simplify(tool);
- if (node.isDeleted()) {
- debug.log("Canonicalizer: simplified %s", node);
+ if (customSimplification != null) {
+ customSimplification.simplify(node, tool);
+ }
+ if (node.isAlive()) {
+ node.simplify(tool);
+ if (node.isDeleted()) {
+ debug.log("Canonicalizer: simplified %s", node);
+ }
}
return node.isDeleted();
}
@@ -518,7 +568,7 @@
@Override
public boolean canonicalizeReads() {
- return canonicalizeReads;
+ return features.contains(READ_CANONICALIZATION);
}
@Override
@@ -549,7 +599,7 @@
}
public boolean getCanonicalizeReads() {
- return canonicalizeReads;
+ return features.contains(READ_CANONICALIZATION);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java Thu Oct 31 16:54:16 2019 -0700
@@ -186,6 +186,8 @@
// Check if we can move guards upwards.
AbstractBeginNode trueSuccessor = node.trueSuccessor();
+ AbstractBeginNode falseSuccessor = node.falseSuccessor();
+
EconomicMap<LogicNode, GuardNode> trueGuards = EconomicMap.create(Equivalence.IDENTITY);
for (GuardNode guard : trueSuccessor.guards()) {
LogicNode condition = guard.getCondition();
@@ -195,7 +197,7 @@
}
if (!trueGuards.isEmpty()) {
- for (GuardNode guard : node.falseSuccessor().guards().snapshot()) {
+ for (GuardNode guard : falseSuccessor.guards().snapshot()) {
GuardNode otherGuard = trueGuards.get(guard.getCondition());
if (otherGuard != null && guard.isNegated() == otherGuard.isNegated()) {
Speculation speculation = otherGuard.getSpeculation();
@@ -210,9 +212,17 @@
guard.getNoDeoptSuccessorPosition());
GuardNode newGuard = node.graph().unique(newlyCreatedGuard);
if (otherGuard.isAlive()) {
- otherGuard.replaceAndDelete(newGuard);
+ if (trueSuccessor instanceof LoopExitNode && beginNode.graph().hasValueProxies()) {
+ otherGuard.replaceAndDelete(ProxyNode.forGuard(newGuard, (LoopExitNode) trueSuccessor));
+ } else {
+ otherGuard.replaceAndDelete(newGuard);
+ }
}
- guard.replaceAndDelete(newGuard);
+ if (falseSuccessor instanceof LoopExitNode && beginNode.graph().hasValueProxies()) {
+ guard.replaceAndDelete(ProxyNode.forGuard(newGuard, (LoopExitNode) falseSuccessor));
+ } else {
+ guard.replaceAndDelete(newGuard);
+ }
}
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java Thu Oct 31 16:54:16 2019 -0700
@@ -48,6 +48,7 @@
import org.graalvm.compiler.nodes.LoopEndNode;
import org.graalvm.compiler.nodes.LoopExitNode;
import org.graalvm.compiler.nodes.PhiNode;
+import org.graalvm.compiler.nodes.ProxyNode;
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.StartNode;
import org.graalvm.compiler.nodes.StructuredGraph;
@@ -166,9 +167,9 @@
protected void processNode(FixedNode node, EconomicSet<LocationIdentity> currentState) {
if (node instanceof MemoryCheckpoint.Single) {
- processIdentity(currentState, ((MemoryCheckpoint.Single) node).getLocationIdentity());
+ processIdentity(currentState, ((MemoryCheckpoint.Single) node).getKilledLocationIdentity());
} else if (node instanceof MemoryCheckpoint.Multi) {
- for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) {
+ for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getKilledLocationIdentities()) {
processIdentity(currentState, identity);
}
}
@@ -274,7 +275,7 @@
}
mergedStatesCount++;
}
- newState.lastMemorySnapshot.put(key, merged);
+ newState.getMap().put(key, merged);
}
return newState;
@@ -301,6 +302,16 @@
@Override
protected MemoryMapImpl processNode(FixedNode node, MemoryMapImpl state) {
+
+ if (node instanceof LoopExitNode) {
+ final LoopExitNode loopExitNode = (LoopExitNode) node;
+ final EconomicSet<LocationIdentity> modifiedInLoop = modifiedInLoops.get(loopExitNode.loopBegin());
+ final boolean anyModified = modifiedInLoop.contains(LocationIdentity.any());
+ state.getMap().replaceAll((locationIdentity, memoryNode) -> (anyModified || modifiedInLoop.contains(locationIdentity))
+ ? ProxyNode.forMemory(memoryNode, loopExitNode, locationIdentity)
+ : memoryNode);
+ }
+
if (node instanceof MemoryAnchorNode) {
processAnchor((MemoryAnchorNode) node, state);
return state;
@@ -312,7 +323,8 @@
if (createFloatingReads && node instanceof FloatableAccessNode) {
processFloatable((FloatableAccessNode) node, state);
- } else if (node instanceof MemoryCheckpoint.Single) {
+ }
+ if (node instanceof MemoryCheckpoint.Single) {
processCheckpoint((MemoryCheckpoint.Single) node, state);
} else if (node instanceof MemoryCheckpoint.Multi) {
processCheckpoint((MemoryCheckpoint.Multi) node, state);
@@ -320,7 +332,7 @@
assert MemoryCheckpoint.TypeAssertion.correctType(node) : node;
if (createMemoryMapNodes && node instanceof ReturnNode) {
- ((ReturnNode) node).setMemoryMap(node.graph().unique(new MemoryMapNode(state.lastMemorySnapshot)));
+ ((ReturnNode) node).setMemoryMap(node.graph().unique(new MemoryMapNode(state.getMap())));
}
return state;
}
@@ -355,21 +367,21 @@
}
private static void processCheckpoint(MemoryCheckpoint.Single checkpoint, MemoryMapImpl state) {
- processIdentity(checkpoint.getLocationIdentity(), checkpoint, state);
+ processIdentity(checkpoint.getKilledLocationIdentity(), checkpoint, state);
}
private static void processCheckpoint(MemoryCheckpoint.Multi checkpoint, MemoryMapImpl state) {
- for (LocationIdentity identity : checkpoint.getLocationIdentities()) {
+ for (LocationIdentity identity : checkpoint.getKilledLocationIdentities()) {
processIdentity(identity, checkpoint, state);
}
}
private static void processIdentity(LocationIdentity identity, MemoryCheckpoint checkpoint, MemoryMapImpl state) {
if (identity.isAny()) {
- state.lastMemorySnapshot.clear();
+ state.getMap().clear();
}
if (identity.isMutable()) {
- state.lastMemorySnapshot.put(identity, checkpoint);
+ state.getMap().put(identity, checkpoint);
}
}
@@ -405,7 +417,7 @@
* side it needs to choose by putting in the location identity on both successors.
*/
InvokeWithExceptionNode invoke = (InvokeWithExceptionNode) node.predecessor();
- result.lastMemorySnapshot.put(invoke.getLocationIdentity(), (MemoryCheckpoint) node);
+ result.getMap().put(invoke.getKilledLocationIdentity(), (MemoryCheckpoint) node);
}
return result;
}
@@ -417,13 +429,13 @@
if (modifiedLocations.contains(LocationIdentity.any())) {
// create phis for all locations if ANY is modified in the loop
modifiedLocations = EconomicSet.create(Equivalence.DEFAULT, modifiedLocations);
- modifiedLocations.addAll(initialState.lastMemorySnapshot.getKeys());
+ modifiedLocations.addAll(initialState.getMap().getKeys());
}
for (LocationIdentity location : modifiedLocations) {
createMemoryPhi(loop, initialState, phis, location);
}
- initialState.lastMemorySnapshot.putAll(phis);
+ initialState.getMap().putAll(phis);
LoopInfo<MemoryMapImpl> loopInfo = ReentrantNodeIterator.processLoop(this, loop, initialState);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/GuardLoweringPhase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/GuardLoweringPhase.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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,7 +24,6 @@
package org.graalvm.compiler.phases.common;
-import org.graalvm.compiler.core.common.cfg.Loop;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.graph.Node;
@@ -34,8 +33,6 @@
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.GuardNode;
import org.graalvm.compiler.nodes.IfNode;
-import org.graalvm.compiler.nodes.LoopBeginNode;
-import org.graalvm.compiler.nodes.LoopExitNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
@@ -62,11 +59,9 @@
private static class LowerGuards extends ScheduledNodeIterator {
- private final Block block;
private boolean useGuardIdAsDebugId;
- LowerGuards(Block block, boolean useGuardIdAsDebugId) {
- this.block = block;
+ LowerGuards(boolean useGuardIdAsDebugId) {
this.useGuardIdAsDebugId = useGuardIdAsDebugId;
}
@@ -95,7 +90,6 @@
AbstractBeginNode deoptBranch = BeginNode.begin(deopt);
AbstractBeginNode trueSuccessor;
AbstractBeginNode falseSuccessor;
- insertLoopExits(deopt);
if (guard.isNegated()) {
trueSuccessor = deoptBranch;
falseSuccessor = fastPath;
@@ -108,16 +102,6 @@
insert(ifNode, fastPath);
}
}
-
- private void insertLoopExits(DeoptimizeNode deopt) {
- Loop<Block> loop = block.getLoop();
- StructuredGraph graph = deopt.graph();
- while (loop != null) {
- LoopExitNode exit = graph.add(new LoopExitNode((LoopBeginNode) loop.getHeader().getBeginNode()));
- graph.addBeforeFixed(deopt, exit);
- loop = loop.getParent();
- }
- }
}
@Override
@@ -143,6 +127,6 @@
private static void processBlock(Block block, ScheduleResult schedule) {
DebugContext debug = block.getBeginNode().getDebug();
- new LowerGuards(block, debug.isDumpEnabledForMethod() || debug.isLogEnabledForMethod()).processNodes(block, schedule);
+ new LowerGuards(debug.isDumpEnabledForMethod() || debug.isLogEnabledForMethod()).processNodes(block, schedule);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/InsertMembarsPhase.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Red Hat Inc. 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.phases.common;
+
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.extended.MembarNode;
+import org.graalvm.compiler.nodes.memory.FixedAccessNode;
+import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.memory.VolatileReadNode;
+import org.graalvm.compiler.nodes.memory.WriteNode;
+import org.graalvm.compiler.phases.Phase;
+
+import static jdk.vm.ci.code.MemoryBarriers.JMM_POST_VOLATILE_READ;
+import static jdk.vm.ci.code.MemoryBarriers.JMM_POST_VOLATILE_WRITE;
+import static jdk.vm.ci.code.MemoryBarriers.JMM_PRE_VOLATILE_READ;
+import static jdk.vm.ci.code.MemoryBarriers.JMM_PRE_VOLATILE_WRITE;
+
+public class InsertMembarsPhase extends Phase {
+ @Override
+ protected void run(StructuredGraph graph) {
+ for (FixedAccessNode access : graph.getNodes(FixedAccessNode.TYPE)) {
+ if (access instanceof VolatileReadNode) {
+ ReadNode read = (ReadNode) access;
+ MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ));
+ graph.addBeforeFixed(read, preMembar);
+ MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_READ));
+ graph.addAfterFixed(read, postMembar);
+ } else if (access instanceof WriteNode && ((WriteNode) access).isVolatile()) {
+ WriteNode write = (WriteNode) access;
+ MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
+ graph.addBeforeFixed(write, preMembar);
+ MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_WRITE));
+ graph.addAfterFixed(write, postMembar);
+ }
+ }
+ }
+
+ @Override
+ public float codeSizeIncrease() {
+ return 3f;
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java Thu Oct 31 16:54:16 2019 -0700
@@ -46,6 +46,7 @@
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeBitMap;
import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.NodeMap;
import org.graalvm.compiler.graph.NodeSourcePosition;
import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.nodeinfo.InputType;
@@ -131,12 +132,14 @@
private final NodeBitMap activeGuards;
private AnchoringNode guardAnchor;
private FixedWithNextNode lastFixedNode;
+ private NodeMap<Block> nodeMap;
- LoweringToolImpl(CoreProviders context, AnchoringNode guardAnchor, NodeBitMap activeGuards, FixedWithNextNode lastFixedNode) {
+ LoweringToolImpl(CoreProviders context, AnchoringNode guardAnchor, NodeBitMap activeGuards, FixedWithNextNode lastFixedNode, NodeMap<Block> nodeMap) {
this.context = context;
this.guardAnchor = guardAnchor;
this.activeGuards = activeGuards;
this.lastFixedNode = lastFixedNode;
+ this.nodeMap = nodeMap;
}
@Override
@@ -199,7 +202,8 @@
StructuredGraph graph = before.graph();
if (OptEliminateGuards.getValue(graph.getOptions())) {
for (Node usage : condition.usages()) {
- if (!activeGuards.isNew(usage) && activeGuards.isMarked(usage) && ((GuardNode) usage).isNegated() == negated) {
+ if (!activeGuards.isNew(usage) && activeGuards.isMarked(usage) && ((GuardNode) usage).isNegated() == negated &&
+ (!before.graph().hasValueProxies() || nodeMap.get(((GuardNode) usage).getAnchor().asNode()).isInSameOrOuterLoopOf(nodeMap.get(before)))) {
return (GuardNode) usage;
}
}
@@ -310,9 +314,9 @@
*/
boolean isAny = false;
if (n instanceof MemoryCheckpoint.Single) {
- isAny = ((MemoryCheckpoint.Single) n).getLocationIdentity().isAny();
+ isAny = ((MemoryCheckpoint.Single) n).getKilledLocationIdentity().isAny();
} else {
- for (LocationIdentity ident : ((MemoryCheckpoint.Multi) n).getLocationIdentities()) {
+ for (LocationIdentity ident : ((MemoryCheckpoint.Multi) n).getKilledLocationIdentities()) {
if (ident.isAny()) {
isAny = true;
}
@@ -447,7 +451,7 @@
@SuppressWarnings("try")
private AnchoringNode process(final Block b, final NodeBitMap activeGuards, final AnchoringNode startAnchor) {
- final LoweringToolImpl loweringTool = new LoweringToolImpl(context, startAnchor, activeGuards, b.getBeginNode());
+ final LoweringToolImpl loweringTool = new LoweringToolImpl(context, startAnchor, activeGuards, b.getBeginNode(), this.schedule.getNodeToBlockMap());
// Lower the instructions of this block.
List<Node> nodes = schedule.nodesFor(b);
@@ -613,69 +617,6 @@
}
}
- public static void processBlockBounded(final Frame<?> rootFrame) {
- ProcessBlockState state = ST_PROCESS;
- Frame<?> f = rootFrame;
- while (f != null) {
- ProcessBlockState nextState;
- if (state == ST_PROCESS || state == ST_PROCESS_ALWAYS_REACHED) {
- f.preprocess();
- nextState = state == ST_PROCESS_ALWAYS_REACHED ? ST_ENTER : ST_ENTER_ALWAYS_REACHED;
- } else if (state == ST_ENTER_ALWAYS_REACHED) {
- if (f.alwaysReachedBlock != null && f.alwaysReachedBlock.getDominator() == f.block) {
- Frame<?> continueRecur = f.enterAlwaysReached(f.alwaysReachedBlock);
- if (continueRecur == null) {
- // stop recursion here
- f.postprocess();
- f = f.parent;
- state = ST_ENTER;
- continue;
- }
- f = continueRecur;
- nextState = ST_PROCESS;
- } else {
- nextState = ST_ENTER;
- }
- } else if (state == ST_ENTER) {
- if (f.dominated != null) {
- Block n = f.dominated;
- f.dominated = n.getDominatedSibling();
- if (n == f.alwaysReachedBlock) {
- if (f.dominated != null) {
- n = f.dominated;
- f.dominated = n.getDominatedSibling();
- } else {
- n = null;
- }
- }
- if (n == null) {
- nextState = ST_LEAVE;
- } else {
- Frame<?> continueRecur = f.enter(n);
- if (continueRecur == null) {
- // stop recursion here
- f.postprocess();
- f = f.parent;
- state = ST_ENTER;
- continue;
- }
- f = continueRecur;
- nextState = ST_PROCESS;
- }
- } else {
- nextState = ST_LEAVE;
- }
- } else if (state == ST_LEAVE) {
- f.postprocess();
- f = f.parent;
- nextState = ST_ENTER;
- } else {
- throw GraalError.shouldNotReachHere();
- }
- state = nextState;
- }
- }
-
public abstract static class Frame<T extends Frame<?>> {
protected final Block block;
final T parent;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java Thu Oct 31 16:54:16 2019 -0700
@@ -56,6 +56,7 @@
import org.graalvm.compiler.graph.NodeMap;
import org.graalvm.compiler.graph.NodeSourcePosition;
import org.graalvm.compiler.graph.NodeWorkList;
+import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.Verbosity;
import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.AbstractEndNode;
@@ -87,6 +88,7 @@
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.IsNullNode;
import org.graalvm.compiler.nodes.extended.ForeignCallNode;
+import org.graalvm.compiler.nodes.extended.GuardedNode;
import org.graalvm.compiler.nodes.extended.GuardingNode;
import org.graalvm.compiler.nodes.java.ExceptionObjectNode;
import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
@@ -526,7 +528,17 @@
assert unwindNode.predecessor() != null;
assert invokeWithException.exceptionEdge().successors().count() == 1;
ExceptionObjectNode obj = (ExceptionObjectNode) invokeWithException.exceptionEdge();
- obj.replaceAtUsages(unwindNode.exception());
+ /*
+ * The exception object node is a begin node, i.e., it can be used as an anchor for
+ * other nodes, thus we need to re-route them to a valid anchor, i.e. the begin node
+ * of the unwind block.
+ */
+ assert obj.usages().filter(x -> x instanceof GuardedNode && ((GuardedNode) x).getGuard() == obj).count() == 0 : "Must not have guards attached to an exception object node";
+ AbstractBeginNode replacementAnchor = AbstractBeginNode.prevBegin(unwindNode);
+ assert replacementAnchor != null;
+ obj.replaceAtUsages(InputType.Anchor, replacementAnchor);
+ obj.replaceAtUsages(InputType.Value, unwindNode.exception());
+
Node n = obj.next();
obj.setNext(null);
unwindNode.replaceAndDelete(n);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -208,8 +208,10 @@
FixedNode exceptionSux = exceptionEdge.next();
graph.addBeforeFixed(exceptionSux, exceptionMerge);
exceptionObjectPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(JavaKind.Object), exceptionMerge));
- exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, JavaKind.Object, new JavaKind[]{JavaKind.Object},
- new ValueNode[]{exceptionObjectPhi}));
+
+ assert exceptionEdge.stateAfter().bci == invoke.bci();
+ assert exceptionEdge.stateAfter().rethrowException();
+ exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(JavaKind.Object, JavaKind.Object, exceptionObjectPhi));
}
// create one separate block for each invoked method
@@ -396,7 +398,7 @@
JavaKind kind = invoke.asNode().getStackKind();
if (kind != JavaKind.Void) {
FrameState stateAfter = invoke.stateAfter();
- stateAfter = stateAfter.duplicate(stateAfter.bci);
+ stateAfter = stateAfter.duplicate();
stateAfter.replaceFirstInput(invoke.asNode(), result.asNode());
result.setStateAfter(stateAfter);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/MemoryScheduleVerification.java Thu Oct 31 14:23:06 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2015, 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.phases.schedule;
-
-import java.util.List;
-
-import jdk.internal.vm.compiler.collections.EconomicSet;
-import jdk.internal.vm.compiler.collections.Equivalence;
-import org.graalvm.compiler.core.common.cfg.BlockMap;
-import org.graalvm.compiler.core.common.cfg.Loop;
-import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.nodes.AbstractBeginNode;
-import org.graalvm.compiler.nodes.AbstractMergeNode;
-import org.graalvm.compiler.nodes.LoopBeginNode;
-import org.graalvm.compiler.nodes.PhiNode;
-import org.graalvm.compiler.nodes.cfg.Block;
-import org.graalvm.compiler.nodes.cfg.HIRLoop;
-import org.graalvm.compiler.nodes.memory.FloatingReadNode;
-import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
-import org.graalvm.compiler.nodes.memory.MemoryNode;
-import org.graalvm.compiler.nodes.memory.MemoryPhiNode;
-import org.graalvm.compiler.phases.graph.ReentrantBlockIterator;
-import org.graalvm.compiler.phases.graph.ReentrantBlockIterator.BlockIteratorClosure;
-import jdk.internal.vm.compiler.word.LocationIdentity;
-
-public final class MemoryScheduleVerification extends BlockIteratorClosure<EconomicSet<FloatingReadNode>> {
-
- private final BlockMap<List<Node>> blockToNodesMap;
-
- public static boolean check(Block startBlock, BlockMap<List<Node>> blockToNodesMap) {
- ReentrantBlockIterator.apply(new MemoryScheduleVerification(blockToNodesMap), startBlock);
- return true;
- }
-
- private MemoryScheduleVerification(BlockMap<List<Node>> blockToNodesMap) {
- this.blockToNodesMap = blockToNodesMap;
- }
-
- @Override
- protected EconomicSet<FloatingReadNode> getInitialState() {
- return EconomicSet.create(Equivalence.IDENTITY);
- }
-
- @Override
- protected EconomicSet<FloatingReadNode> processBlock(Block block, EconomicSet<FloatingReadNode> currentState) {
- AbstractBeginNode beginNode = block.getBeginNode();
- if (beginNode instanceof AbstractMergeNode) {
- AbstractMergeNode abstractMergeNode = (AbstractMergeNode) beginNode;
- for (PhiNode phi : abstractMergeNode.phis()) {
- if (phi instanceof MemoryPhiNode) {
- MemoryPhiNode memoryPhiNode = (MemoryPhiNode) phi;
- addFloatingReadUsages(currentState, memoryPhiNode);
- }
- }
- }
- for (Node n : blockToNodesMap.get(block)) {
- if (n instanceof MemoryCheckpoint) {
- if (n instanceof MemoryCheckpoint.Single) {
- MemoryCheckpoint.Single single = (MemoryCheckpoint.Single) n;
- processLocation(n, single.getLocationIdentity(), currentState);
- } else if (n instanceof MemoryCheckpoint.Multi) {
- MemoryCheckpoint.Multi multi = (MemoryCheckpoint.Multi) n;
- for (LocationIdentity location : multi.getLocationIdentities()) {
- processLocation(n, location, currentState);
- }
- }
-
- addFloatingReadUsages(currentState, n);
- } else if (n instanceof MemoryNode) {
- addFloatingReadUsages(currentState, n);
- } else if (n instanceof FloatingReadNode) {
- FloatingReadNode floatingReadNode = (FloatingReadNode) n;
- if (floatingReadNode.getLastLocationAccess() != null && floatingReadNode.getLocationIdentity().isMutable()) {
- if (currentState.contains(floatingReadNode)) {
- // Floating read was found in the state.
- currentState.remove(floatingReadNode);
- } else {
- throw new RuntimeException("Floating read node " + n + " was not found in the state, i.e., it was killed by a memory check point before its place in the schedule. Block=" +
- block + ", block begin: " + block.getBeginNode() + " block loop: " + block.getLoop() + ", " + blockToNodesMap.get(block).get(0));
- }
- }
-
- }
- }
- return currentState;
- }
-
- private static void addFloatingReadUsages(EconomicSet<FloatingReadNode> currentState, Node n) {
- for (FloatingReadNode read : n.usages().filter(FloatingReadNode.class)) {
- if (read.getLastLocationAccess() == n && read.getLocationIdentity().isMutable()) {
- currentState.add(read);
- }
- }
- }
-
- private void processLocation(Node n, LocationIdentity location, EconomicSet<FloatingReadNode> currentState) {
- assert n != null;
- if (location.isImmutable()) {
- return;
- }
-
- for (FloatingReadNode r : cloneState(currentState)) {
- if (r.getLocationIdentity().overlaps(location)) {
- // This read is killed by this location.
- r.getDebug().log(DebugContext.VERBOSE_LEVEL, "%s removing %s from state", n, r);
- currentState.remove(r);
- }
- }
- }
-
- @Override
- protected EconomicSet<FloatingReadNode> merge(Block merge, List<EconomicSet<FloatingReadNode>> states) {
- EconomicSet<FloatingReadNode> result = states.get(0);
- for (int i = 1; i < states.size(); ++i) {
- result.retainAll(states.get(i));
- }
- return result;
- }
-
- @Override
- protected EconomicSet<FloatingReadNode> cloneState(EconomicSet<FloatingReadNode> oldState) {
- EconomicSet<FloatingReadNode> result = EconomicSet.create(Equivalence.IDENTITY);
- if (oldState != null) {
- result.addAll(oldState);
- }
- return result;
- }
-
- @Override
- protected List<EconomicSet<FloatingReadNode>> processLoop(Loop<Block> loop, EconomicSet<FloatingReadNode> initialState) {
- HIRLoop l = (HIRLoop) loop;
- for (MemoryPhiNode memoryPhi : ((LoopBeginNode) l.getHeader().getBeginNode()).memoryPhis()) {
- for (FloatingReadNode r : cloneState(initialState)) {
- if (r.getLocationIdentity().overlaps(memoryPhi.getLocationIdentity())) {
- initialState.remove(r);
- }
- }
- }
- return ReentrantBlockIterator.processLoop(this, loop, initialState).exitStates;
- }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/SchedulePhase.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/SchedulePhase.java Thu Oct 31 16:54:16 2019 -0700
@@ -206,7 +206,8 @@
sortNodesLatestWithinBlock(cfg, earliestBlockToNodesMap, latestBlockToNodesMap, currentNodeMap, watchListMap, visited);
assert verifySchedule(cfg, latestBlockToNodesMap, currentNodeMap);
- assert (!Assertions.detailedAssertionsEnabled(graph.getOptions())) || MemoryScheduleVerification.check(cfg.getStartBlock(), latestBlockToNodesMap);
+ assert (!Assertions.detailedAssertionsEnabled(graph.getOptions())) ||
+ ScheduleVerification.check(cfg.getStartBlock(), latestBlockToNodesMap, currentNodeMap);
this.blockToNodesMap = latestBlockToNodesMap;
@@ -358,7 +359,7 @@
}
if (lastBlock.getBeginNode() instanceof KillingBeginNode) {
- LocationIdentity locationIdentity = ((KillingBeginNode) lastBlock.getBeginNode()).getLocationIdentity();
+ LocationIdentity locationIdentity = ((KillingBeginNode) lastBlock.getBeginNode()).getKilledLocationIdentity();
if ((locationIdentity.isAny() || locationIdentity.equals(location)) && lastBlock != earliestBlock) {
// The begin of this block kills the location, so we *have* to schedule the node
// in the dominating block.
@@ -374,13 +375,13 @@
for (Node n : subList) {
// Check if this node kills a node in the watch list.
if (n instanceof MemoryCheckpoint.Single) {
- LocationIdentity identity = ((MemoryCheckpoint.Single) n).getLocationIdentity();
+ LocationIdentity identity = ((MemoryCheckpoint.Single) n).getKilledLocationIdentity();
killed.add(identity);
if (killed.isAny()) {
return;
}
} else if (n instanceof MemoryCheckpoint.Multi) {
- for (LocationIdentity identity : ((MemoryCheckpoint.Multi) n).getLocationIdentities()) {
+ for (LocationIdentity identity : ((MemoryCheckpoint.Multi) n).getKilledLocationIdentities()) {
killed.add(identity);
if (killed.isAny()) {
return;
@@ -471,10 +472,10 @@
if (watchList != null && !watchList.isEmpty()) {
// Check if this node kills a node in the watch list.
if (n instanceof MemoryCheckpoint.Single) {
- LocationIdentity identity = ((MemoryCheckpoint.Single) n).getLocationIdentity();
+ LocationIdentity identity = ((MemoryCheckpoint.Single) n).getKilledLocationIdentity();
checkWatchList(watchList, identity, b, result, nodeMap, unprocessed);
} else if (n instanceof MemoryCheckpoint.Multi) {
- for (LocationIdentity identity : ((MemoryCheckpoint.Multi) n).getLocationIdentities()) {
+ for (LocationIdentity identity : ((MemoryCheckpoint.Multi) n).getKilledLocationIdentities()) {
checkWatchList(watchList, identity, b, result, nodeMap, unprocessed);
}
}
@@ -896,7 +897,7 @@
}
}
- assert (!Assertions.detailedAssertionsEnabled(cfg.graph.getOptions())) || MemoryScheduleVerification.check(cfg.getStartBlock(), blockToNodes);
+ assert (!Assertions.detailedAssertionsEnabled(cfg.graph.getOptions())) || ScheduleVerification.check(cfg.getStartBlock(), blockToNodes, nodeToBlock);
}
private static void processNodes(NodeBitMap visited, NodeMap<MicroBlock> entries, NodeStack stack, MicroBlock startBlock, Iterable<? extends Node> nodes) {
@@ -1183,10 +1184,10 @@
Formatter buf = new Formatter();
buf.format("%s", n);
if (n instanceof MemoryCheckpoint.Single) {
- buf.format(" // kills %s", ((MemoryCheckpoint.Single) n).getLocationIdentity());
+ buf.format(" // kills %s", ((MemoryCheckpoint.Single) n).getKilledLocationIdentity());
} else if (n instanceof MemoryCheckpoint.Multi) {
buf.format(" // kills ");
- for (LocationIdentity locid : ((MemoryCheckpoint.Multi) n).getLocationIdentities()) {
+ for (LocationIdentity locid : ((MemoryCheckpoint.Multi) n).getKilledLocationIdentities()) {
buf.format("%s, ", locid);
}
} else if (n instanceof FloatingReadNode) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/ScheduleVerification.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2015, 2019, 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.phases.schedule;
+
+import java.util.List;
+
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
+import org.graalvm.compiler.core.common.cfg.BlockMap;
+import org.graalvm.compiler.core.common.cfg.Loop;
+import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.NodeMap;
+import org.graalvm.compiler.nodes.AbstractBeginNode;
+import org.graalvm.compiler.nodes.AbstractMergeNode;
+import org.graalvm.compiler.nodes.LoopBeginNode;
+import org.graalvm.compiler.nodes.LoopExitNode;
+import org.graalvm.compiler.nodes.MemoryProxyNode;
+import org.graalvm.compiler.nodes.PhiNode;
+import org.graalvm.compiler.nodes.ProxyNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.VirtualState;
+import org.graalvm.compiler.nodes.cfg.Block;
+import org.graalvm.compiler.nodes.cfg.HIRLoop;
+import org.graalvm.compiler.nodes.memory.FloatingReadNode;
+import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
+import org.graalvm.compiler.nodes.memory.MemoryNode;
+import org.graalvm.compiler.nodes.memory.MemoryPhiNode;
+import org.graalvm.compiler.phases.graph.ReentrantBlockIterator;
+import org.graalvm.compiler.phases.graph.ReentrantBlockIterator.BlockIteratorClosure;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+
+/**
+ * Verifies that the schedule of the graph is correct. Checks that floating reads are not killed
+ * between definition and usage. Also checks that there are no usages spanning loop exits without a
+ * proper proxy node.
+ */
+public final class ScheduleVerification extends BlockIteratorClosure<EconomicSet<FloatingReadNode>> {
+
+ private final BlockMap<List<Node>> blockToNodesMap;
+ private final NodeMap<Block> nodeMap;
+ private final StructuredGraph graph;
+
+ public static boolean check(Block startBlock, BlockMap<List<Node>> blockToNodesMap, NodeMap<Block> nodeMap) {
+ ReentrantBlockIterator.apply(new ScheduleVerification(blockToNodesMap, nodeMap, startBlock.getBeginNode().graph()), startBlock);
+ return true;
+ }
+
+ private ScheduleVerification(BlockMap<List<Node>> blockToNodesMap, NodeMap<Block> nodeMap, StructuredGraph graph) {
+ this.blockToNodesMap = blockToNodesMap;
+ this.nodeMap = nodeMap;
+ this.graph = graph;
+ }
+
+ @Override
+ protected EconomicSet<FloatingReadNode> getInitialState() {
+ return EconomicSet.create(Equivalence.IDENTITY);
+ }
+
+ @Override
+ protected EconomicSet<FloatingReadNode> processBlock(Block block, EconomicSet<FloatingReadNode> currentState) {
+ AbstractBeginNode beginNode = block.getBeginNode();
+ if (beginNode instanceof AbstractMergeNode) {
+ AbstractMergeNode abstractMergeNode = (AbstractMergeNode) beginNode;
+ for (PhiNode phi : abstractMergeNode.phis()) {
+ if (phi instanceof MemoryPhiNode) {
+ MemoryPhiNode memoryPhiNode = (MemoryPhiNode) phi;
+ addFloatingReadUsages(currentState, memoryPhiNode);
+ }
+ }
+ }
+ if (beginNode instanceof LoopExitNode) {
+ LoopExitNode loopExitNode = (LoopExitNode) beginNode;
+ for (ProxyNode proxy : loopExitNode.proxies()) {
+ if (proxy instanceof MemoryProxyNode) {
+ MemoryProxyNode memoryProxyNode = (MemoryProxyNode) proxy;
+ addFloatingReadUsages(currentState, memoryProxyNode);
+ }
+ }
+ }
+ for (Node n : blockToNodesMap.get(block)) {
+ if (n instanceof MemoryCheckpoint) {
+ if (n instanceof MemoryCheckpoint.Single) {
+ MemoryCheckpoint.Single single = (MemoryCheckpoint.Single) n;
+ processLocation(n, single.getKilledLocationIdentity(), currentState);
+ } else if (n instanceof MemoryCheckpoint.Multi) {
+ MemoryCheckpoint.Multi multi = (MemoryCheckpoint.Multi) n;
+ for (LocationIdentity location : multi.getKilledLocationIdentities()) {
+ processLocation(n, location, currentState);
+ }
+ }
+
+ addFloatingReadUsages(currentState, n);
+ } else if (n instanceof MemoryNode) {
+ addFloatingReadUsages(currentState, n);
+ } else if (n instanceof FloatingReadNode) {
+ FloatingReadNode floatingReadNode = (FloatingReadNode) n;
+ if (floatingReadNode.getLastLocationAccess() != null && floatingReadNode.getLocationIdentity().isMutable()) {
+ if (currentState.contains(floatingReadNode)) {
+ // Floating read was found in the state.
+ currentState.remove(floatingReadNode);
+ } else {
+ throw new RuntimeException("Floating read node " + n + " was not found in the state, i.e., it was killed by a memory check point before its place in the schedule. Block=" +
+ block + ", block begin: " + block.getBeginNode() + " block loop: " + block.getLoop() + ", " + blockToNodesMap.get(block).get(0));
+ }
+ }
+ }
+ assert nodeMap.get(n) == block;
+ if (graph.hasValueProxies() && block.getLoop() != null && !(n instanceof VirtualState)) {
+ for (Node usage : n.usages()) {
+ Node usageNode = usage;
+
+ if (usageNode instanceof PhiNode) {
+ PhiNode phiNode = (PhiNode) usage;
+ usageNode = phiNode.merge();
+ }
+
+ if (usageNode instanceof LoopExitNode) {
+ LoopExitNode loopExitNode = (LoopExitNode) usageNode;
+ if (loopExitNode.loopBegin() == n || loopExitNode.stateAfter() == n) {
+ continue;
+ }
+ }
+ Block usageBlock = nodeMap.get(usageNode);
+
+ Loop<Block> usageLoop = null;
+ if (usageNode instanceof ProxyNode) {
+ ProxyNode proxyNode = (ProxyNode) usageNode;
+ usageLoop = nodeMap.get(proxyNode.proxyPoint().loopBegin()).getLoop();
+ } else {
+ if (usageBlock.getBeginNode() instanceof LoopExitNode) {
+ // For nodes in the loop exit node block, we don't know for sure
+ // whether they are "in the loop" or not. It depends on whether
+ // one of their transient usages is a loop proxy node.
+ // For now, let's just assume those nodes are OK, i.e., "in the loop".
+ LoopExitNode loopExitNode = (LoopExitNode) usageBlock.getBeginNode();
+ usageLoop = nodeMap.get(loopExitNode.loopBegin()).getLoop();
+ } else {
+ usageLoop = usageBlock.getLoop();
+ }
+ }
+
+ assert usageLoop != null : n + ", " + nodeMap.get(n) + " / " + usageNode + ", " + nodeMap.get(usageNode);
+ while (usageLoop != block.getLoop() && usageLoop != null) {
+ usageLoop = usageLoop.getParent();
+ }
+ assert usageLoop != null : n + ", " + usageNode + ", " + usageBlock + ", " + usageBlock.getLoop() + ", " + block + ", " + block.getLoop();
+ }
+ }
+ }
+ return currentState;
+ }
+
+ private static void addFloatingReadUsages(EconomicSet<FloatingReadNode> currentState, Node n) {
+ for (FloatingReadNode read : n.usages().filter(FloatingReadNode.class)) {
+ if (read.getLastLocationAccess() == n && read.getLocationIdentity().isMutable()) {
+ currentState.add(read);
+ }
+ }
+ }
+
+ private void processLocation(Node n, LocationIdentity location, EconomicSet<FloatingReadNode> currentState) {
+ assert n != null;
+ if (location.isImmutable()) {
+ return;
+ }
+
+ for (FloatingReadNode r : cloneState(currentState)) {
+ if (r.getLocationIdentity().overlaps(location)) {
+ // This read is killed by this location.
+ r.getDebug().log(DebugContext.VERBOSE_LEVEL, "%s removing %s from state", n, r);
+ currentState.remove(r);
+ }
+ }
+ }
+
+ @Override
+ protected EconomicSet<FloatingReadNode> merge(Block merge, List<EconomicSet<FloatingReadNode>> states) {
+ EconomicSet<FloatingReadNode> result = states.get(0);
+ for (int i = 1; i < states.size(); ++i) {
+ result.retainAll(states.get(i));
+ }
+ return result;
+ }
+
+ @Override
+ protected EconomicSet<FloatingReadNode> cloneState(EconomicSet<FloatingReadNode> oldState) {
+ EconomicSet<FloatingReadNode> result = EconomicSet.create(Equivalence.IDENTITY);
+ if (oldState != null) {
+ result.addAll(oldState);
+ }
+ return result;
+ }
+
+ @Override
+ protected List<EconomicSet<FloatingReadNode>> processLoop(Loop<Block> loop, EconomicSet<FloatingReadNode> initialState) {
+ HIRLoop l = (HIRLoop) loop;
+ for (MemoryPhiNode memoryPhi : ((LoopBeginNode) l.getHeader().getBeginNode()).memoryPhis()) {
+ for (FloatingReadNode r : cloneState(initialState)) {
+ if (r.getLocationIdentity().overlaps(memoryPhi.getLocationIdentity())) {
+ initialState.remove(r);
+ }
+ }
+ }
+ return ReentrantBlockIterator.processLoop(this, loop, initialState).exitStates;
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java Thu Oct 31 16:54:16 2019 -0700
@@ -32,7 +32,6 @@
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
-import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticLIRGeneratorTool.RoundingMode;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
@@ -45,6 +44,7 @@
import org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode;
import org.graalvm.compiler.nodes.memory.address.AddressNode;
import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
+import org.graalvm.compiler.nodes.spi.Replacements;
import org.graalvm.compiler.replacements.TargetGraphBuilderPlugins;
import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
import org.graalvm.compiler.replacements.nodes.FusedMultiplyAddNode;
@@ -60,39 +60,39 @@
public class AArch64GraphBuilderPlugins implements TargetGraphBuilderPlugins {
@Override
- public void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, Architecture arch, boolean explicitUnsafeNullChecks, boolean registerMathPlugins,
+ public void register(Plugins plugins, Replacements replacements, Architecture arch, boolean explicitUnsafeNullChecks, boolean registerMathPlugins,
boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) {
- register(plugins, replacementsBytecodeProvider, explicitUnsafeNullChecks, registerMathPlugins, emitJDK9StringSubstitutions, useFMAIntrinsics);
+ register(plugins, replacements, explicitUnsafeNullChecks, registerMathPlugins, emitJDK9StringSubstitutions, useFMAIntrinsics);
}
- public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks,
+ public static void register(Plugins plugins, Replacements replacements, boolean explicitUnsafeNullChecks,
boolean registerMathPlugins, boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) {
InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
invocationPlugins.defer(new Runnable() {
@Override
public void run() {
- registerIntegerLongPlugins(invocationPlugins, JavaKind.Int, bytecodeProvider);
- registerIntegerLongPlugins(invocationPlugins, JavaKind.Long, bytecodeProvider);
+ registerIntegerLongPlugins(invocationPlugins, JavaKind.Int, replacements);
+ registerIntegerLongPlugins(invocationPlugins, JavaKind.Long, replacements);
if (registerMathPlugins) {
registerMathPlugins(invocationPlugins, useFMAIntrinsics);
}
if (emitJDK9StringSubstitutions) {
- registerStringLatin1Plugins(invocationPlugins, bytecodeProvider);
- registerStringUTF16Plugins(invocationPlugins, bytecodeProvider);
+ registerStringLatin1Plugins(invocationPlugins, replacements);
+ registerStringUTF16Plugins(invocationPlugins, replacements);
}
- registerUnsafePlugins(invocationPlugins, bytecodeProvider);
+ registerUnsafePlugins(invocationPlugins, replacements);
// This is temporarily disabled until we implement correct emitting of the CAS
// instructions of the proper width.
- registerPlatformSpecificUnsafePlugins(invocationPlugins, bytecodeProvider, explicitUnsafeNullChecks,
+ registerPlatformSpecificUnsafePlugins(invocationPlugins, replacements, explicitUnsafeNullChecks,
new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object});
}
});
}
- private static void registerIntegerLongPlugins(InvocationPlugins plugins, JavaKind kind, BytecodeProvider bytecodeProvider) {
+ private static void registerIntegerLongPlugins(InvocationPlugins plugins, JavaKind kind, Replacements replacements) {
Class<?> declaringClass = kind.toBoxedJavaClass();
Class<?> type = kind.toJavaClass();
- Registration r = new Registration(plugins, declaringClass, bytecodeProvider);
+ Registration r = new Registration(plugins, declaringClass, replacements);
r.register1("numberOfLeadingZeros", type, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
@@ -196,29 +196,29 @@
});
}
- private static void registerStringLatin1Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
+ private static void registerStringLatin1Plugins(InvocationPlugins plugins, Replacements replacements) {
if (JavaVersionUtil.JAVA_SPEC >= 9) {
- Registration r = new Registration(plugins, "java.lang.StringLatin1", replacementsBytecodeProvider);
+ Registration r = new Registration(plugins, "java.lang.StringLatin1", replacements);
r.setAllowOverwrite(true);
r.registerMethodSubstitution(AArch64StringLatin1Substitutions.class, "compareTo", byte[].class, byte[].class);
r.registerMethodSubstitution(AArch64StringLatin1Substitutions.class, "compareToUTF16", byte[].class, byte[].class);
}
}
- private static void registerStringUTF16Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
+ private static void registerStringUTF16Plugins(InvocationPlugins plugins, Replacements replacements) {
if (JavaVersionUtil.JAVA_SPEC >= 9) {
- Registration r = new Registration(plugins, "java.lang.StringUTF16", replacementsBytecodeProvider);
+ Registration r = new Registration(plugins, "java.lang.StringUTF16", replacements);
r.setAllowOverwrite(true);
r.registerMethodSubstitution(AArch64StringUTF16Substitutions.class, "compareTo", byte[].class, byte[].class);
r.registerMethodSubstitution(AArch64StringUTF16Substitutions.class, "compareToLatin1", byte[].class, byte[].class);
}
}
- private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
+ private static void registerUnsafePlugins(InvocationPlugins plugins, Replacements replacements) {
registerUnsafePlugins(new Registration(plugins, Unsafe.class),
new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object}, "Object");
if (JavaVersionUtil.JAVA_SPEC > 8) {
- registerUnsafePlugins(new Registration(plugins, "jdk.internal.misc.Unsafe", replacementsBytecodeProvider),
+ registerUnsafePlugins(new Registration(plugins, "jdk.internal.misc.Unsafe", replacements),
new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object},
JavaVersionUtil.JAVA_SPEC <= 11 ? "Object" : "Reference");
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountLeadingZerosNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountLeadingZerosNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -90,4 +90,10 @@
public void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen) {
builder.setResult(this, ((AMD64ArithmeticLIRGeneratorTool) gen).emitCountLeadingZeros(builder.operand(getValue())));
}
+
+ @NodeIntrinsic
+ public static native int countLeadingZeros(int i);
+
+ @NodeIntrinsic
+ public static native int countLeadingZeros(long i);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountTrailingZerosNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountTrailingZerosNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -90,4 +90,10 @@
public void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen) {
builder.setResult(this, ((AMD64ArithmeticLIRGeneratorTool) gen).emitCountTrailingZeros(builder.operand(getValue())));
}
+
+ @NodeIntrinsic
+ public static native int countTrailingZeros(int i);
+
+ @NodeIntrinsic
+ public static native int countTrailingZeros(long i);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java Thu Oct 31 16:54:16 2019 -0700
@@ -35,7 +35,6 @@
import java.util.Arrays;
-import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool.RoundingMode;
import org.graalvm.compiler.nodes.PauseNode;
import org.graalvm.compiler.nodes.ValueNode;
@@ -48,9 +47,8 @@
import org.graalvm.compiler.nodes.java.AtomicReadAndAddNode;
import org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode;
import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
+import org.graalvm.compiler.nodes.spi.Replacements;
import org.graalvm.compiler.replacements.ArraysSubstitutions;
-import org.graalvm.compiler.replacements.IntegerSubstitutions;
-import org.graalvm.compiler.replacements.LongSubstitutions;
import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafeAccessPlugin;
import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafeGetPlugin;
import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafePutPlugin;
@@ -72,30 +70,31 @@
public class AMD64GraphBuilderPlugins implements TargetGraphBuilderPlugins {
@Override
- public void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, Architecture architecture, boolean explicitUnsafeNullChecks,
+ public void register(Plugins plugins, Replacements replacements, Architecture architecture, boolean explicitUnsafeNullChecks,
boolean registerMathPlugins, boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) {
- register(plugins, replacementsBytecodeProvider, (AMD64) architecture, explicitUnsafeNullChecks, emitJDK9StringSubstitutions, useFMAIntrinsics);
+ register(plugins, replacements, (AMD64) architecture, explicitUnsafeNullChecks, emitJDK9StringSubstitutions, useFMAIntrinsics);
}
- public static void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, AMD64 arch, boolean explicitUnsafeNullChecks, boolean emitJDK9StringSubstitutions,
+ public static void register(Plugins plugins, Replacements replacements, AMD64 arch, boolean explicitUnsafeNullChecks,
+ boolean emitJDK9StringSubstitutions,
boolean useFMAIntrinsics) {
InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
invocationPlugins.defer(new Runnable() {
@Override
public void run() {
registerThreadPlugins(invocationPlugins, arch);
- registerIntegerLongPlugins(invocationPlugins, IntegerSubstitutions.class, JavaKind.Int, arch, replacementsBytecodeProvider);
- registerIntegerLongPlugins(invocationPlugins, LongSubstitutions.class, JavaKind.Long, arch, replacementsBytecodeProvider);
- registerPlatformSpecificUnsafePlugins(invocationPlugins, replacementsBytecodeProvider, explicitUnsafeNullChecks,
+ registerIntegerLongPlugins(invocationPlugins, AMD64IntegerSubstitutions.class, JavaKind.Int, arch, replacements);
+ registerIntegerLongPlugins(invocationPlugins, AMD64LongSubstitutions.class, JavaKind.Long, arch, replacements);
+ registerPlatformSpecificUnsafePlugins(invocationPlugins, replacements, explicitUnsafeNullChecks,
new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object, JavaKind.Boolean, JavaKind.Byte, JavaKind.Short, JavaKind.Char, JavaKind.Float, JavaKind.Double});
- registerUnsafePlugins(invocationPlugins, replacementsBytecodeProvider, explicitUnsafeNullChecks);
- registerStringPlugins(invocationPlugins, replacementsBytecodeProvider);
+ registerUnsafePlugins(invocationPlugins, replacements, explicitUnsafeNullChecks);
+ registerStringPlugins(invocationPlugins, replacements);
if (emitJDK9StringSubstitutions) {
- registerStringLatin1Plugins(invocationPlugins, replacementsBytecodeProvider);
- registerStringUTF16Plugins(invocationPlugins, replacementsBytecodeProvider);
+ registerStringLatin1Plugins(invocationPlugins, replacements);
+ registerStringUTF16Plugins(invocationPlugins, replacements);
}
- registerMathPlugins(invocationPlugins, useFMAIntrinsics, arch, replacementsBytecodeProvider);
- registerArraysEqualsPlugins(invocationPlugins, replacementsBytecodeProvider);
+ registerMathPlugins(invocationPlugins, useFMAIntrinsics, arch, replacements);
+ registerArraysEqualsPlugins(invocationPlugins, replacements);
}
});
}
@@ -103,72 +102,37 @@
private static void registerThreadPlugins(InvocationPlugins plugins, AMD64 arch) {
if (JavaVersionUtil.JAVA_SPEC > 8) {
// Pause instruction introduced with SSE2
- if (arch.getFeatures().contains(AMD64.CPUFeature.SSE2)) {
- Registration r = new Registration(plugins, Thread.class);
- r.register0("onSpinWait", new InvocationPlugin() {
- @Override
- public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
- b.append(new PauseNode());
- return true;
- }
- });
- }
- }
- }
-
- private static void registerIntegerLongPlugins(InvocationPlugins plugins, Class<?> substituteDeclaringClass, JavaKind kind, AMD64 arch, BytecodeProvider bytecodeProvider) {
- Class<?> declaringClass = kind.toBoxedJavaClass();
- Class<?> type = kind.toJavaClass();
- Registration r = new Registration(plugins, declaringClass, bytecodeProvider);
- r.registerMethodSubstitution(substituteDeclaringClass, "numberOfLeadingZeros", type);
- if (arch.getFeatures().contains(AMD64.CPUFeature.LZCNT) && arch.getFlags().contains(AMD64.Flag.UseCountLeadingZerosInstruction)) {
- r.setAllowOverwrite(true);
- r.register1("numberOfLeadingZeros", type, new InvocationPlugin() {
+ assert (arch.getFeatures().contains(AMD64.CPUFeature.SSE2));
+ Registration r = new Registration(plugins, Thread.class);
+ r.register0("onSpinWait", new InvocationPlugin() {
@Override
- public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
- ValueNode folded = AMD64CountLeadingZerosNode.tryFold(value);
- if (folded != null) {
- b.addPush(JavaKind.Int, folded);
- } else {
- b.addPush(JavaKind.Int, new AMD64CountLeadingZerosNode(value));
- }
+ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
+ b.append(new PauseNode());
return true;
}
});
}
-
- r.registerMethodSubstitution(substituteDeclaringClass, "numberOfTrailingZeros", type);
- if (arch.getFeatures().contains(AMD64.CPUFeature.BMI1) && arch.getFlags().contains(AMD64.Flag.UseCountTrailingZerosInstruction)) {
- r.setAllowOverwrite(true);
- r.register1("numberOfTrailingZeros", type, new InvocationPlugin() {
-
- @Override
- public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
- ValueNode folded = AMD64CountTrailingZerosNode.tryFold(value);
- if (folded != null) {
- b.addPush(JavaKind.Int, folded);
- } else {
- b.addPush(JavaKind.Int, new AMD64CountTrailingZerosNode(value));
- }
- return true;
- }
- });
- }
-
- if (arch.getFeatures().contains(AMD64.CPUFeature.POPCNT)) {
- r.register1("bitCount", type, new InvocationPlugin() {
- @Override
- public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
- b.push(JavaKind.Int, b.append(new BitCountNode(value).canonical(null)));
- return true;
- }
- });
- }
-
}
- private static void registerMathPlugins(InvocationPlugins plugins, boolean useFMAIntrinsics, AMD64 arch, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins, Math.class, bytecodeProvider);
+ private static void registerIntegerLongPlugins(InvocationPlugins plugins, Class<?> substituteDeclaringClass, JavaKind kind, AMD64 arch, Replacements replacements) {
+ Class<?> declaringClass = kind.toBoxedJavaClass();
+ Class<?> type = kind.toJavaClass();
+ Registration r = new Registration(plugins, declaringClass, replacements);
+ r.registerMethodSubstitution(substituteDeclaringClass, "numberOfLeadingZeros", type);
+ r.registerMethodSubstitution(substituteDeclaringClass, "numberOfTrailingZeros", type);
+
+ r.registerConditional1(arch.getFeatures().contains(AMD64.CPUFeature.POPCNT),
+ "bitCount", type, new InvocationPlugin() {
+ @Override
+ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
+ b.push(JavaKind.Int, b.append(new BitCountNode(value).canonical(null)));
+ return true;
+ }
+ });
+ }
+
+ private static void registerMathPlugins(InvocationPlugins plugins, boolean useFMAIntrinsics, AMD64 arch, Replacements replacements) {
+ Registration r = new Registration(plugins, Math.class, replacements);
registerUnaryMath(r, "log", LOG);
registerUnaryMath(r, "log10", LOG10);
registerUnaryMath(r, "exp", EXP);
@@ -177,19 +141,18 @@
registerUnaryMath(r, "cos", COS);
registerUnaryMath(r, "tan", TAN);
- if (arch.getFeatures().contains(CPUFeature.SSE4_1)) {
- registerRound(r, "rint", RoundingMode.NEAREST);
- registerRound(r, "ceil", RoundingMode.UP);
- registerRound(r, "floor", RoundingMode.DOWN);
- }
+ boolean roundEnabled = arch.getFeatures().contains(CPUFeature.SSE4_1);
+ registerRound(roundEnabled, r, "rint", RoundingMode.NEAREST);
+ registerRound(roundEnabled, r, "ceil", RoundingMode.UP);
+ registerRound(roundEnabled, r, "floor", RoundingMode.DOWN);
- if (useFMAIntrinsics && JavaVersionUtil.JAVA_SPEC > 8 && arch.getFeatures().contains(CPUFeature.FMA)) {
- registerFMA(r);
+ if (JavaVersionUtil.JAVA_SPEC > 8) {
+ registerFMA(r, useFMAIntrinsics && arch.getFeatures().contains(CPUFeature.FMA));
}
}
- private static void registerFMA(Registration r) {
- r.register3("fma",
+ private static void registerFMA(Registration r, boolean isEnabled) {
+ r.registerConditional3(isEnabled, "fma",
Double.TYPE,
Double.TYPE,
Double.TYPE,
@@ -205,7 +168,7 @@
return true;
}
});
- r.register3("fma",
+ r.registerConditional3(isEnabled, "fma",
Float.TYPE,
Float.TYPE,
Float.TYPE,
@@ -243,8 +206,8 @@
});
}
- private static void registerRound(Registration r, String name, RoundingMode mode) {
- r.register1(name, Double.TYPE, new InvocationPlugin() {
+ private static void registerRound(boolean isEnabled, Registration r, String name, RoundingMode mode) {
+ r.registerConditional1(isEnabled, name, Double.TYPE, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
b.push(JavaKind.Double, b.append(new AMD64RoundNode(arg, mode)));
@@ -253,10 +216,10 @@
});
}
- private static void registerStringPlugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
+ private static void registerStringPlugins(InvocationPlugins plugins, Replacements replacements) {
if (JavaVersionUtil.JAVA_SPEC <= 8) {
Registration r;
- r = new Registration(plugins, String.class, replacementsBytecodeProvider);
+ r = new Registration(plugins, String.class, replacements);
r.setAllowOverwrite(true);
r.registerMethodSubstitution(AMD64StringSubstitutions.class, "indexOf", char[].class, int.class,
int.class, char[].class, int.class, int.class, int.class);
@@ -265,8 +228,8 @@
}
}
- private static void registerStringLatin1Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
- Registration r = new Registration(plugins, "java.lang.StringLatin1", replacementsBytecodeProvider);
+ private static void registerStringLatin1Plugins(InvocationPlugins plugins, Replacements replacements) {
+ Registration r = new Registration(plugins, "java.lang.StringLatin1", replacements);
r.setAllowOverwrite(true);
r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareTo", byte[].class, byte[].class);
r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareToUTF16", byte[].class, byte[].class);
@@ -276,8 +239,8 @@
r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "indexOf", byte[].class, int.class, byte[].class, int.class, int.class);
}
- private static void registerStringUTF16Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
- Registration r = new Registration(plugins, "java.lang.StringUTF16", replacementsBytecodeProvider);
+ private static void registerStringUTF16Plugins(InvocationPlugins plugins, Replacements replacements) {
+ Registration r = new Registration(plugins, "java.lang.StringUTF16", replacements);
r.setAllowOverwrite(true);
r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareTo", byte[].class, byte[].class);
r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareToLatin1", byte[].class, byte[].class);
@@ -288,10 +251,10 @@
r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfLatin1Unsafe", byte[].class, int.class, byte[].class, int.class, int.class);
}
- private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider, boolean explicitUnsafeNullChecks) {
+ private static void registerUnsafePlugins(InvocationPlugins plugins, Replacements replacements, boolean explicitUnsafeNullChecks) {
registerUnsafePlugins(new Registration(plugins, Unsafe.class), explicitUnsafeNullChecks, new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object}, true);
if (JavaVersionUtil.JAVA_SPEC > 8) {
- registerUnsafePlugins(new Registration(plugins, "jdk.internal.misc.Unsafe", replacementsBytecodeProvider), explicitUnsafeNullChecks,
+ registerUnsafePlugins(new Registration(plugins, "jdk.internal.misc.Unsafe", replacements), explicitUnsafeNullChecks,
new JavaKind[]{JavaKind.Boolean, JavaKind.Byte, JavaKind.Char, JavaKind.Short, JavaKind.Int, JavaKind.Long, JavaKind.Object},
JavaVersionUtil.JAVA_SPEC <= 11);
}
@@ -330,8 +293,8 @@
}
}
- private static void registerArraysEqualsPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins, Arrays.class, bytecodeProvider);
+ private static void registerArraysEqualsPlugins(InvocationPlugins plugins, Replacements replacements) {
+ Registration r = new Registration(plugins, Arrays.class, replacements);
r.registerMethodSubstitution(ArraysSubstitutions.class, "equals", float[].class, float[].class);
r.registerMethodSubstitution(ArraysSubstitutions.class, "equals", double[].class, double[].class);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64IntegerSubstitutions.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2019, 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.replacements.amd64;
+
+import static org.graalvm.compiler.replacements.NodeIntrinsificationProvider.INJECTED_TARGET;
+
+import org.graalvm.compiler.api.replacements.ClassSubstitution;
+import org.graalvm.compiler.api.replacements.Fold;
+import org.graalvm.compiler.api.replacements.MethodSubstitution;
+import org.graalvm.compiler.core.common.SuppressFBWarnings;
+import org.graalvm.compiler.replacements.nodes.BitScanForwardNode;
+import org.graalvm.compiler.replacements.nodes.BitScanReverseNode;
+
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.code.TargetDescription;
+
+@ClassSubstitution(Integer.class)
+public class AMD64IntegerSubstitutions {
+
+ @Fold
+ static boolean lzcnt(@Fold.InjectedParameter TargetDescription target) {
+ AMD64 arch = (AMD64) target.arch;
+ return arch.getFeatures().contains(AMD64.CPUFeature.LZCNT) && arch.getFlags().contains(AMD64.Flag.UseCountLeadingZerosInstruction);
+ }
+
+ @Fold
+ static boolean tzcnt(@Fold.InjectedParameter TargetDescription target) {
+ AMD64 arch = (AMD64) target.arch;
+ return arch.getFeatures().contains(AMD64.CPUFeature.BMI1) && arch.getFlags().contains(AMD64.Flag.UseCountTrailingZerosInstruction);
+ }
+
+ @MethodSubstitution
+ @SuppressFBWarnings(value = "NP_NULL_PARAM_DEREF_NONVIRTUAL", justification = "foldable method parameters are injected")
+ public static int numberOfLeadingZeros(int i) {
+ if (lzcnt(INJECTED_TARGET)) {
+ return AMD64CountLeadingZerosNode.countLeadingZeros(i);
+ }
+ if (i == 0) {
+ return 32;
+ }
+ return 31 - BitScanReverseNode.unsafeScan(i);
+ }
+
+ @MethodSubstitution
+ @SuppressFBWarnings(value = "NP_NULL_PARAM_DEREF_NONVIRTUAL", justification = "foldable method parameters are injected")
+ public static int numberOfTrailingZeros(int i) {
+ if (tzcnt(INJECTED_TARGET)) {
+ return AMD64CountTrailingZerosNode.countTrailingZeros(i);
+ }
+ if (i == 0) {
+ return 32;
+ }
+ return BitScanForwardNode.unsafeScan(i);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64LongSubstitutions.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2019, 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.replacements.amd64;
+
+// JaCoCo Exclude
+
+import static org.graalvm.compiler.replacements.NodeIntrinsificationProvider.INJECTED_TARGET;
+
+import org.graalvm.compiler.api.replacements.ClassSubstitution;
+import org.graalvm.compiler.api.replacements.Fold;
+import org.graalvm.compiler.api.replacements.MethodSubstitution;
+import org.graalvm.compiler.core.common.SuppressFBWarnings;
+import org.graalvm.compiler.replacements.nodes.BitScanForwardNode;
+import org.graalvm.compiler.replacements.nodes.BitScanReverseNode;
+
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.code.TargetDescription;
+
+@ClassSubstitution(Long.class)
+public class AMD64LongSubstitutions {
+
+ @Fold
+ static boolean lzcnt(@Fold.InjectedParameter TargetDescription target) {
+ AMD64 arch = (AMD64) target.arch;
+ return arch.getFeatures().contains(AMD64.CPUFeature.LZCNT) && arch.getFlags().contains(AMD64.Flag.UseCountLeadingZerosInstruction);
+ }
+
+ @Fold
+ static boolean tzcnt(@Fold.InjectedParameter TargetDescription target) {
+ AMD64 arch = (AMD64) target.arch;
+ return arch.getFeatures().contains(AMD64.CPUFeature.BMI1) && arch.getFlags().contains(AMD64.Flag.UseCountTrailingZerosInstruction);
+ }
+
+ @MethodSubstitution
+ @SuppressFBWarnings(value = "NP_NULL_PARAM_DEREF_NONVIRTUAL", justification = "foldable method parameters are injected")
+ public static int numberOfLeadingZeros(long i) {
+ if (lzcnt(INJECTED_TARGET)) {
+ return AMD64CountLeadingZerosNode.countLeadingZeros(i);
+ }
+ if (i == 0) {
+ return 64;
+ }
+ return 63 - BitScanReverseNode.unsafeScan(i);
+ }
+
+ @MethodSubstitution
+ @SuppressFBWarnings(value = "NP_NULL_PARAM_DEREF_NONVIRTUAL", justification = "foldable method parameters are injected")
+ public static int numberOfTrailingZeros(long i) {
+ if (tzcnt(INJECTED_TARGET)) {
+ return AMD64CountTrailingZerosNode.countTrailingZeros(i);
+ }
+
+ if (i == 0) {
+ return 64;
+ }
+ return BitScanForwardNode.unsafeScan(i);
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1InflateNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1InflateNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -82,7 +82,7 @@
}
@Override
- public LocationIdentity[] getLocationIdentities() {
+ public LocationIdentity[] getKilledLocationIdentities() {
// Model write access via 'dst' using:
return new LocationIdentity[]{NamedLocationIdentity.getArrayLocation(writeKind)};
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16CompressNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16CompressNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -82,7 +82,7 @@
}
@Override
- public LocationIdentity[] getLocationIdentities() {
+ public LocationIdentity[] getKilledLocationIdentities() {
// Model write access via 'dst' using:
return new LocationIdentity[]{NamedLocationIdentity.getArrayLocation(JavaKind.Byte)};
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.jdk9.test/src/org/graalvm/compiler/replacements/jdk9/test/VarHandleTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.jdk9.test/src/org/graalvm/compiler/replacements/jdk9/test/VarHandleTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -162,12 +162,12 @@
startNodes++;
} else if (n instanceof MemoryCheckpoint.Single) {
MemoryCheckpoint.Single single = (MemoryCheckpoint.Single) n;
- if (single.getLocationIdentity().isAny()) {
+ if (single.getKilledLocationIdentity().isAny()) {
anyKillCount++;
}
} else if (n instanceof MemoryCheckpoint.Multi) {
MemoryCheckpoint.Multi multi = (MemoryCheckpoint.Multi) n;
- for (LocationIdentity loc : multi.getLocationIdentities()) {
+ for (LocationIdentity loc : multi.getKilledLocationIdentities()) {
if (loc.isAny()) {
anyKillCount++;
break;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.sparc/src/org/graalvm/compiler/replacements/sparc/SPARCGraphBuilderPlugins.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.sparc/src/org/graalvm/compiler/replacements/sparc/SPARCGraphBuilderPlugins.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -32,13 +32,13 @@
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
-import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
+import org.graalvm.compiler.nodes.spi.Replacements;
import org.graalvm.compiler.replacements.IntegerSubstitutions;
import org.graalvm.compiler.replacements.LongSubstitutions;
import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
@@ -51,26 +51,26 @@
public class SPARCGraphBuilderPlugins {
- public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks) {
+ public static void register(Plugins plugins, Replacements replacements, boolean explicitUnsafeNullChecks) {
InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
invocationPlugins.defer(new Runnable() {
@Override
public void run() {
- registerIntegerLongPlugins(invocationPlugins, IntegerSubstitutions.class, JavaKind.Int, bytecodeProvider);
- registerIntegerLongPlugins(invocationPlugins, LongSubstitutions.class, JavaKind.Long, bytecodeProvider);
+ registerIntegerLongPlugins(invocationPlugins, IntegerSubstitutions.class, JavaKind.Int, replacements);
+ registerIntegerLongPlugins(invocationPlugins, LongSubstitutions.class, JavaKind.Long, replacements);
registerMathPlugins(invocationPlugins);
// This is temporarily disabled until we implement correct emitting of the CAS
// instructions of the proper width.
- registerPlatformSpecificUnsafePlugins(invocationPlugins, bytecodeProvider, explicitUnsafeNullChecks,
+ registerPlatformSpecificUnsafePlugins(invocationPlugins, replacements, explicitUnsafeNullChecks,
new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object});
}
});
}
- private static void registerIntegerLongPlugins(InvocationPlugins plugins, Class<?> substituteDeclaringClass, JavaKind kind, BytecodeProvider bytecodeProvider) {
+ private static void registerIntegerLongPlugins(InvocationPlugins plugins, Class<?> substituteDeclaringClass, JavaKind kind, Replacements replacements) {
Class<?> declaringClass = kind.toBoxedJavaClass();
Class<?> type = kind.toJavaClass();
- Registration r = new Registration(plugins, declaringClass, bytecodeProvider);
+ Registration r = new Registration(plugins, declaringClass, replacements);
r.registerMethodSubstitution(substituteDeclaringClass, "numberOfLeadingZeros", type);
r.registerMethodSubstitution(substituteDeclaringClass, "numberOfTrailingZeros", type);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ArraysSubstitutionsTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ArraysSubstitutionsTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -31,7 +31,6 @@
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.phases.OptimisticOptimizations;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.replacements.nodes.ArrayEqualsNode;
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
@@ -132,7 +131,7 @@
StructuredGraph graph = parseEager("testCanonicalLengthSnippet", AllowAssumptions.NO);
HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
createInliningPhase().apply(graph, context);
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 0);
}
@@ -148,7 +147,7 @@
StructuredGraph graph = parseEager("testCanonicalEqualSnippet", AllowAssumptions.NO);
HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
createInliningPhase().apply(graph, context);
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 1);
}
@@ -162,9 +161,9 @@
StructuredGraph graph = parseEager("testVirtualEqualSnippet", AllowAssumptions.NO);
HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
createInliningPhase().apply(graph, context);
- new CanonicalizerPhase().apply(graph, getProviders());
- new PartialEscapePhase(false, new CanonicalizerPhase(), graph.getOptions()).apply(graph, context);
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
+ new PartialEscapePhase(false, this.createCanonicalizerPhase(), graph.getOptions()).apply(graph, context);
+ createCanonicalizerPhase().apply(graph, getProviders());
Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 1);
}
@@ -180,9 +179,9 @@
StructuredGraph graph = parseEager("testVirtualNotEqualSnippet", AllowAssumptions.NO);
HighTierContext context = getDefaultHighTierContext();
createInliningPhase().apply(graph, context);
- new CanonicalizerPhase().apply(graph, getProviders());
- new PartialEscapePhase(false, new CanonicalizerPhase(), graph.getOptions()).apply(graph, context);
- new CanonicalizerPhase().apply(graph, getProviders());
+ createCanonicalizerPhase().apply(graph, getProviders());
+ new PartialEscapePhase(false, this.createCanonicalizerPhase(), graph.getOptions()).apply(graph, context);
+ createCanonicalizerPhase().apply(graph, getProviders());
Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 0);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/BitOpNodesTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/BitOpNodesTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -303,7 +303,7 @@
private ValueNode parseAndInline(String name, Class<? extends ValueNode> expectedClass) {
StructuredGraph graph = parseEager(name, AllowAssumptions.YES);
HighTierContext context = getDefaultHighTierContext();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
canonicalizer.apply(graph, context);
createInliningPhase(canonicalizer).apply(graph, context);
canonicalizer.apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnExceptionTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnExceptionTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -35,7 +35,7 @@
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.common.AbstractInliningPhase;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
-import org.graalvm.compiler.test.ExportingClassLoader;
+import org.graalvm.compiler.api.test.ExportingClassLoader;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/EdgesTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/EdgesTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -45,7 +45,6 @@
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.java.InstanceOfNode;
import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.inlining.InliningPhase;
import org.graalvm.compiler.phases.common.inlining.policy.InlineMethodSubstitutionsPolicy;
import org.graalvm.compiler.phases.tiers.HighTierContext;
@@ -133,8 +132,8 @@
ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method);
StructuredGraph g = parseProfiled(javaMethod, AllowAssumptions.NO);
HighTierContext context = getDefaultHighTierContext();
- new InliningPhase(new InlineMethodSubstitutionsPolicy(), new CanonicalizerPhase()).apply(g, context);
- new CanonicalizerPhase().apply(g, context);
+ new InliningPhase(new InlineMethodSubstitutionsPolicy(), createCanonicalizerPhase()).apply(g, context);
+ this.createCanonicalizerPhase().apply(g, context);
Assert.assertTrue(g.getNodes().filter(InstanceOfNode.class).isEmpty());
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/FoldTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/FoldTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -81,10 +81,10 @@
@Override
protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) {
- InjectionProvider injection = new NodeIntrinsificationProvider(getMetaAccess(), getSnippetReflection(), getProviders().getForeignCalls(), null);
+ InjectionProvider injection = new NodeIntrinsificationProvider(getMetaAccess(), getSnippetReflection(), getProviders().getForeignCalls(), null, getTarget());
new PluginFactory_FoldTest().registerPlugins(invocationPlugins, injection);
BytecodeProvider replacementBytecodeProvider = getSystemClassLoaderBytecodeProvider();
- Registration r = new Registration(invocationPlugins, TestMethod.class, replacementBytecodeProvider);
+ Registration r = new Registration(invocationPlugins, TestMethod.class, getReplacements(), replacementBytecodeProvider);
r.registerMethodSubstitution(TestMethodSubstitution.class, "test");
super.registerInvocationPlugins(invocationPlugins);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactFoldTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactFoldTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -94,7 +94,7 @@
Node originalNode = graph.getNodes().filter(x -> x instanceof IntegerExactArithmeticNode).first();
assertNotNull("original node must be in the graph", originalNode);
- new CanonicalizerPhase().apply(graph, getDefaultHighTierContext());
+ createCanonicalizerPhase().apply(graph, getDefaultHighTierContext());
ValueNode node = findNode(graph);
boolean overflowExpected = node instanceof IntegerExactArithmeticNode;
@@ -109,19 +109,19 @@
Node originalNode = graph.getNodes().filter(x -> x instanceof IntegerExactArithmeticNode).first();
assertNotNull("original node must be in the graph", originalNode);
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
HighTierContext highTierContext = getDefaultHighTierContext();
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext);
MidTierContext midTierContext = getDefaultMidTierContext();
new GuardLoweringPhase().apply(graph, midTierContext);
- new CanonicalizerPhase().apply(graph, midTierContext);
+ createCanonicalizerPhase().apply(graph, midTierContext);
IntegerExactArithmeticSplitNode loweredNode = graph.getNodes().filter(IntegerExactArithmeticSplitNode.class).first();
assertNotNull("the lowered node must be in the graph", loweredNode);
loweredNode.getX().setStamp(StampFactory.forInteger(bits, lowerBoundA, upperBoundA));
loweredNode.getY().setStamp(StampFactory.forInteger(bits, lowerBoundB, upperBoundB));
- new CanonicalizerPhase().apply(graph, midTierContext);
+ createCanonicalizerPhase().apply(graph, midTierContext);
ValueNode node = findNode(graph);
boolean overflowExpected = node instanceof IntegerExactArithmeticSplitNode;
@@ -144,7 +144,7 @@
String snippet = "snippetInt" + bits;
StructuredGraph graph = parseEager(getResolvedJavaMethod(operation.getClass(), snippet), AllowAssumptions.NO);
HighTierContext context = getDefaultHighTierContext();
- new CanonicalizerPhase().apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
return graph;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -25,6 +25,7 @@
package org.graalvm.compiler.replacements.test;
import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
import org.graalvm.compiler.api.replacements.MethodSubstitution;
import org.graalvm.compiler.core.test.GraalCompilerTest;
@@ -35,7 +36,6 @@
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
@@ -78,14 +78,14 @@
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
createInliningPhase().apply(graph, context);
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
- new CanonicalizerPhase().apply(graph, context);
+ createCanonicalizerPhase().apply(graph, context);
new DeadCodeEliminationPhase().apply(graph);
// Try to ensure any macro nodes are lowered to expose any resulting invokes
if (graph.getNodes().filter(MacroNode.class).isNotEmpty()) {
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+ new LoweringPhase(this.createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
}
if (graph.getNodes().filter(MacroNode.class).isNotEmpty()) {
- new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
+ new LoweringPhase(this.createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
}
assertNotInGraph(graph, MacroNode.class);
if (name != null) {
@@ -153,13 +153,20 @@
}
}
- protected static StructuredGraph assertInGraph(StructuredGraph graph, Class<?> clazz) {
+ protected static StructuredGraph assertInGraph(StructuredGraph graph, Class<?>... clazzes) {
for (Node node : graph.getNodes()) {
- if (clazz.isInstance(node)) {
- return graph;
+ for (Class<?> clazz : clazzes) {
+ if (clazz.isInstance(node)) {
+ return graph;
+ }
}
}
- fail("Graph does not contain a node of class " + clazz.getName());
+ if (clazzes.length == 1) {
+ fail("Graph does not contain a node of class " + clazzes[0].getName());
+ } else {
+ fail("Graph does not contain a node of one these classes class " + Arrays.toString(clazzes));
+
+ }
return graph;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ObjectAccessTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ObjectAccessTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -130,7 +130,7 @@
Assert.assertEquals(graph.getParameter(0), address.getBase());
Assert.assertEquals(BytecodeFrame.AFTER_BCI, write.stateAfter().bci);
- Assert.assertEquals(locationIdentity, write.getLocationIdentity());
+ Assert.assertEquals(locationIdentity, write.getKilledLocationIdentity());
if (indexConvert) {
SignExtendNode convert = (SignExtendNode) address.getOffset();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -46,7 +46,6 @@
import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.phases.OptimisticOptimizations;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.replacements.CachingPEGraphDecoder;
import jdk.internal.vm.compiler.word.LocationIdentity;
import org.junit.Test;
@@ -146,7 +145,7 @@
targetGraph.verify();
CoreProviders context = getProviders();
- new CanonicalizerPhase().apply(targetGraph, context);
+ createCanonicalizerPhase().apply(targetGraph, context);
targetGraph.verify();
} catch (Throwable ex) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PointerTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PointerTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -37,7 +37,6 @@
import org.graalvm.compiler.nodes.extended.JavaWriteNode;
import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
import org.graalvm.compiler.phases.OptimisticOptimizations;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.word.Word;
import org.graalvm.compiler.word.WordCastNode;
@@ -150,7 +149,7 @@
Assert.assertEquals(graph.getParameter(0), cast.getInput());
Assert.assertEquals(target.wordJavaKind, cast.stamp(NodeView.DEFAULT).getStackKind());
- Assert.assertEquals(locationIdentity, write.getLocationIdentity());
+ Assert.assertEquals(locationIdentity, write.getKilledLocationIdentity());
if (indexConvert) {
SignExtendNode convert = (SignExtendNode) address.getOffset();
@@ -409,7 +408,7 @@
HighTierContext context = new HighTierContext(getProviders(), null, OptimisticOptimizations.ALL);
StructuredGraph graph = parseEager(snippetName, AllowAssumptions.YES);
- new CanonicalizerPhase().apply(graph, context);
+ this.createCanonicalizerPhase().apply(graph, context);
Assert.assertEquals(expectedWordCasts, graph.getNodes().filter(WordCastNode.class).count());
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsParseTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsParseTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -318,7 +318,7 @@
@Override
protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) {
BytecodeProvider replacementBytecodeProvider = getSystemClassLoaderBytecodeProvider();
- Registration r = new Registration(invocationPlugins, TestObject.class, replacementBytecodeProvider);
+ Registration r = new Registration(invocationPlugins, TestObject.class, getReplacements(), replacementBytecodeProvider);
NodeIntrinsicPluginFactory.InjectionProvider injections = new DummyInjectionProvider();
new PluginFactory_ReplacementsParseTest().registerPlugins(invocationPlugins, injections);
r.registerMethodSubstitution(TestObjectSubstitutions.class, "nextAfter", double.class, double.class);
@@ -634,7 +634,7 @@
node.remove();
}
HighTierContext context = getDefaultHighTierContext();
- CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
new FloatingReadPhase().apply(graph);
canonicalizer.apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StandardMethodSubstitutionsTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StandardMethodSubstitutionsTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -31,6 +31,8 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.calc.AbsNode;
import org.graalvm.compiler.nodes.calc.ReinterpretNode;
+import org.graalvm.compiler.replacements.amd64.AMD64CountLeadingZerosNode;
+import org.graalvm.compiler.replacements.amd64.AMD64CountTrailingZerosNode;
import org.graalvm.compiler.replacements.nodes.BitCountNode;
import org.graalvm.compiler.replacements.nodes.BitScanForwardNode;
import org.graalvm.compiler.replacements.nodes.BitScanReverseNode;
@@ -132,7 +134,7 @@
return Math.sqrt(value) + Math.log(value) + Math.log10(value) + Math.sin(value) + Math.cos(value) + Math.tan(value);
}
- public void testSubstitution(String testMethodName, Class<?> intrinsicClass, Class<?> holder, String methodName, boolean optional, Object... args) {
+ public void testSubstitution(String testMethodName, Class<?> holder, String methodName, boolean optional, Object[] args, Class<?>... intrinsicClasses) {
ResolvedJavaMethod realJavaMethod = getResolvedJavaMethod(holder, methodName);
ResolvedJavaMethod testJavaMethod = getResolvedJavaMethod(testMethodName);
StructuredGraph graph = testGraph(testMethodName);
@@ -140,7 +142,7 @@
// Check to see if the resulting graph contains the expected node
StructuredGraph replacement = getReplacements().getSubstitution(realJavaMethod, -1, false, null, graph.getOptions());
if (replacement == null && !optional) {
- assertInGraph(graph, intrinsicClass);
+ assertInGraph(graph, intrinsicClasses);
}
for (Object l : args) {
@@ -159,7 +161,7 @@
public void testCharSubstitutions() {
Object[] args = new Character[]{Character.MIN_VALUE, (char) -1, (char) 0, (char) 1, Character.MAX_VALUE};
- testSubstitution("charReverseBytes", ReverseBytesNode.class, Character.class, "reverseBytes", false, args);
+ testSubstitution("charReverseBytes", Character.class, "reverseBytes", false, args, ReverseBytesNode.class);
}
public static char charReverseBytes(char value) {
@@ -183,7 +185,7 @@
public void testShortSubstitutions() {
Object[] args = new Short[]{Short.MIN_VALUE, -1, 0, 1, Short.MAX_VALUE};
- testSubstitution("shortReverseBytes", ReverseBytesNode.class, Short.class, "reverseBytes", false, args);
+ testSubstitution("shortReverseBytes", Short.class, "reverseBytes", false, args, ReverseBytesNode.class);
}
public static short shortReverseBytes(short value) {
@@ -207,10 +209,10 @@
public void testIntegerSubstitutions() {
Object[] args = new Object[]{Integer.MIN_VALUE, -1, 0, 1, Integer.MAX_VALUE};
- testSubstitution("integerReverseBytes", ReverseBytesNode.class, Integer.class, "reverseBytes", false, args);
- testSubstitution("integerNumberOfLeadingZeros", BitScanReverseNode.class, Integer.class, "numberOfLeadingZeros", true, args);
- testSubstitution("integerNumberOfTrailingZeros", BitScanForwardNode.class, Integer.class, "numberOfTrailingZeros", false, args);
- testSubstitution("integerBitCount", BitCountNode.class, Integer.class, "bitCount", true, args);
+ testSubstitution("integerReverseBytes", Integer.class, "reverseBytes", false, args, ReverseBytesNode.class);
+ testSubstitution("integerNumberOfLeadingZeros", Integer.class, "numberOfLeadingZeros", true, args, BitScanReverseNode.class, AMD64CountLeadingZerosNode.class);
+ testSubstitution("integerNumberOfTrailingZeros", Integer.class, "numberOfTrailingZeros", false, args, BitScanForwardNode.class, AMD64CountTrailingZerosNode.class);
+ testSubstitution("integerBitCount", Integer.class, "bitCount", true, args, BitCountNode.class);
}
public static int integerReverseBytes(int value) {
@@ -233,10 +235,10 @@
public void testLongSubstitutions() {
Object[] args = new Object[]{Long.MIN_VALUE, -1L, 0L, 1L, Long.MAX_VALUE};
- testSubstitution("longReverseBytes", ReverseBytesNode.class, Long.class, "reverseBytes", false, args);
- testSubstitution("longNumberOfLeadingZeros", BitScanReverseNode.class, Long.class, "numberOfLeadingZeros", true, args);
- testSubstitution("longNumberOfTrailingZeros", BitScanForwardNode.class, Long.class, "numberOfTrailingZeros", false, args);
- testSubstitution("longBitCount", BitCountNode.class, Long.class, "bitCount", true, args);
+ testSubstitution("longReverseBytes", Long.class, "reverseBytes", false, args, ReverseBytesNode.class);
+ testSubstitution("longNumberOfLeadingZeros", Long.class, "numberOfLeadingZeros", true, args, BitScanReverseNode.class, AMD64CountLeadingZerosNode.class);
+ testSubstitution("longNumberOfTrailingZeros", Long.class, "numberOfTrailingZeros", false, args, BitScanForwardNode.class, AMD64CountTrailingZerosNode.class);
+ testSubstitution("longBitCount", Long.class, "bitCount", true, args, BitCountNode.class);
}
public static long longReverseBytes(long value) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SubstitutionNodeSourcePositionTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SubstitutionNodeSourcePositionTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -84,7 +84,7 @@
protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) {
new PluginFactory_SubstitutionNodeSourcePositionTest().registerPlugins(invocationPlugins, null);
ClassfileBytecodeProvider bytecodeProvider = getSystemClassLoaderBytecodeProvider();
- InvocationPlugins.Registration r = new InvocationPlugins.Registration(invocationPlugins, TestMethod.class, bytecodeProvider);
+ InvocationPlugins.Registration r = new InvocationPlugins.Registration(invocationPlugins, TestMethod.class, getReplacements(), bytecodeProvider);
r.registerMethodSubstitution(TestMethodSubstitution.class, "test", int.class);
super.registerInvocationPlugins(invocationPlugins);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SubstitutionsTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SubstitutionsTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -120,7 +120,7 @@
protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) {
new PluginFactory_SubstitutionsTest().registerPlugins(invocationPlugins, null);
ClassfileBytecodeProvider bytecodeProvider = getSystemClassLoaderBytecodeProvider();
- Registration r = new Registration(invocationPlugins, TestMethod.class, bytecodeProvider);
+ Registration r = new Registration(invocationPlugins, TestMethod.class, getReplacements(), bytecodeProvider);
r.registerMethodSubstitution(TestMethodSubstitution.class, "test");
super.registerInvocationPlugins(invocationPlugins);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -104,7 +104,7 @@
import org.graalvm.compiler.replacements.classfile.ClassfileBytecodeProvider;
import org.graalvm.compiler.runtime.RuntimeProvider;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
-import org.graalvm.compiler.test.ModuleSupport;
+import org.graalvm.compiler.api.test.ModuleSupport;
import org.graalvm.compiler.test.SubprocessUtil;
import org.junit.Assert;
import org.junit.Assume;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/RedefineIntrinsicTest.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/RedefineIntrinsicTest.java Thu Oct 31 16:54:16 2019 -0700
@@ -87,7 +87,7 @@
@Override
protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) {
BytecodeProvider replacementBytecodeProvider = getSystemClassLoaderBytecodeProvider();
- Registration r = new Registration(invocationPlugins, Original.class, replacementBytecodeProvider);
+ Registration r = new Registration(invocationPlugins, Original.class, getReplacements(), replacementBytecodeProvider);
r.registerMethodSubstitution(Intrinsic.class, "getValue");
super.registerInvocationPlugins(invocationPlugins);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java Thu Oct 31 16:54:16 2019 -0700
@@ -132,7 +132,7 @@
: null;
GraphBuilderPhase.Instance graphBuilderPhaseInstance = createGraphBuilderPhaseInstance(initialIntrinsicContext);
graphBuilderPhaseInstance.apply(graphToEncode);
- new CanonicalizerPhase().apply(graphToEncode, providers);
+ CanonicalizerPhase.create().apply(graphToEncode, providers);
if (postParsingPhase != null) {
postParsingPhase.apply(graphToEncode, providers);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java Thu Oct 31 16:54:16 2019 -0700
@@ -47,6 +47,7 @@
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
+import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
@@ -129,6 +130,7 @@
import org.graalvm.compiler.nodes.java.ValueCompareAndSwapNode;
import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.memory.VolatileReadNode;
import org.graalvm.compiler.nodes.memory.WriteNode;
import org.graalvm.compiler.nodes.memory.address.AddressNode;
import org.graalvm.compiler.nodes.memory.address.IndexAddressNode;
@@ -397,12 +399,17 @@
AddressNode address = createFieldAddress(graph, object, field);
assert address != null : "Field that is loaded must not be eliminated: " + field.getDeclaringClass().toJavaName(true) + "." + field.getName();
- ReadNode memoryRead = graph.add(new ReadNode(address, fieldLocationIdentity(field), loadStamp, fieldLoadBarrierType(field)));
+ ReadNode memoryRead = null;
+ if (loadField.isVolatile() && GraalOptions.LateMembars.getValue(graph.getOptions())) {
+ memoryRead = graph.add(new VolatileReadNode(address, fieldLocationIdentity(field), loadStamp, fieldLoadBarrierType(field)));
+ } else {
+ memoryRead = graph.add(new ReadNode(address, fieldLocationIdentity(field), loadStamp, fieldLoadBarrierType(field)));
+ }
ValueNode readValue = implicitLoadConvert(graph, getStorageKind(field), memoryRead);
loadField.replaceAtUsages(readValue);
graph.replaceFixed(loadField, memoryRead);
- if (loadField.isVolatile()) {
+ if (loadField.isVolatile() && !GraalOptions.LateMembars.getValue(graph.getOptions())) {
MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ));
graph.addBeforeFixed(memoryRead, preMembar);
MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_READ));
@@ -419,11 +426,11 @@
AddressNode address = createFieldAddress(graph, object, field);
assert address != null;
- WriteNode memoryWrite = graph.add(new WriteNode(address, fieldLocationIdentity(field), value, fieldStoreBarrierType(storeField.field())));
+ WriteNode memoryWrite = graph.add(new WriteNode(address, fieldLocationIdentity(field), value, fieldStoreBarrierType(storeField.field()), storeField.isVolatile()));
memoryWrite.setStateAfter(storeField.stateAfter());
graph.replaceFixedWithFixed(storeField, memoryWrite);
- if (storeField.isVolatile()) {
+ if (storeField.isVolatile() && !GraalOptions.LateMembars.getValue(graph.getOptions())) {
MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
graph.addBeforeFixed(memoryWrite, preMembar);
MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_WRITE));
@@ -528,7 +535,7 @@
AddressNode address = createArrayIndexAddress(graph, array, elementKind, storeIndexed.index(), boundsCheck);
WriteNode memoryWrite = graph.add(new WriteNode(address, NamedLocationIdentity.getArrayLocation(elementKind), implicitStoreConvert(graph, elementKind, value),
- arrayStoreBarrierType(storeIndexed.elementKind())));
+ arrayStoreBarrierType(storeIndexed.elementKind()), false));
memoryWrite.setGuard(boundsCheck);
if (condition != null) {
tool.createGuard(storeIndexed, condition, DeoptimizationReason.ArrayStoreException, DeoptimizationAction.InvalidateReprofile);
@@ -623,7 +630,7 @@
AddressNode address = graph.unique(new OffsetAddressNode(cas.object(), cas.offset()));
BarrierType barrierType = guessStoreBarrierType(cas.object(), expectedValue);
- LogicCompareAndSwapNode atomicNode = graph.add(new LogicCompareAndSwapNode(address, cas.getLocationIdentity(), expectedValue, newValue, barrierType));
+ LogicCompareAndSwapNode atomicNode = graph.add(new LogicCompareAndSwapNode(address, cas.getKilledLocationIdentity(), expectedValue, newValue, barrierType));
atomicNode.setStateAfter(cas.stateAfter());
graph.replaceFixedWithFixed(cas, atomicNode);
}
@@ -637,7 +644,7 @@
AddressNode address = graph.unique(new OffsetAddressNode(cas.object(), cas.offset()));
BarrierType barrierType = guessStoreBarrierType(cas.object(), expectedValue);
- ValueCompareAndSwapNode atomicNode = graph.add(new ValueCompareAndSwapNode(address, expectedValue, newValue, cas.getLocationIdentity(), barrierType));
+ ValueCompareAndSwapNode atomicNode = graph.add(new ValueCompareAndSwapNode(address, expectedValue, newValue, cas.getKilledLocationIdentity(), barrierType));
ValueNode coercedNode = implicitLoadConvert(graph, valueKind, atomicNode, true);
atomicNode.setStateAfter(cas.stateAfter());
cas.replaceAtUsages(coercedNode);
@@ -653,7 +660,7 @@
AddressNode address = graph.unique(new OffsetAddressNode(n.object(), n.offset()));
BarrierType barrierType = guessStoreBarrierType(n.object(), n.newValue());
LIRKind lirAccessKind = LIRKind.fromJavaKind(target.arch, valueKind);
- LoweredAtomicReadAndWriteNode memoryRead = graph.add(new LoweredAtomicReadAndWriteNode(address, n.getLocationIdentity(), newValue, lirAccessKind, barrierType));
+ LoweredAtomicReadAndWriteNode memoryRead = graph.add(new LoweredAtomicReadAndWriteNode(address, n.getKilledLocationIdentity(), newValue, lirAccessKind, barrierType));
memoryRead.setStateAfter(n.stateAfter());
ValueNode readValue = implicitLoadConvert(graph, valueKind, memoryRead);
@@ -744,7 +751,7 @@
JavaKind valueKind = store.accessKind();
ValueNode value = implicitStoreConvert(graph, valueKind, store.value(), compressible);
AddressNode address = createUnsafeAddress(graph, store.object(), store.offset());
- WriteNode write = graph.add(new WriteNode(address, store.getLocationIdentity(), value, unsafeStoreBarrierType(store)));
+ WriteNode write = graph.add(new WriteNode(address, store.getKilledLocationIdentity(), value, unsafeStoreBarrierType(store), false));
write.setStateAfter(store.stateAfter());
graph.replaceFixedWithFixed(store, write);
}
@@ -755,7 +762,7 @@
JavaKind valueKind = store.getKind();
ValueNode value = implicitStoreConvert(graph, valueKind, store.getValue(), false);
AddressNode address = graph.addOrUniqueWithInputs(OffsetAddressNode.create(store.getAddress()));
- WriteNode write = graph.add(new WriteNode(address, store.getLocationIdentity(), value, BarrierType.NONE));
+ WriteNode write = graph.add(new WriteNode(address, store.getKilledLocationIdentity(), value, BarrierType.NONE, false));
write.setStateAfter(store.stateAfter());
graph.replaceFixedWithFixed(store, write);
}
@@ -782,7 +789,7 @@
protected void lowerJavaWriteNode(JavaWriteNode write) {
StructuredGraph graph = write.graph();
ValueNode value = implicitStoreConvert(graph, write.getWriteKind(), write.value(), write.isCompressible());
- WriteNode memoryWrite = graph.add(new WriteNode(write.getAddress(), write.getLocationIdentity(), value, write.getBarrierType()));
+ WriteNode memoryWrite = graph.add(new WriteNode(write.getAddress(), write.getKilledLocationIdentity(), value, write.getBarrierType(), false));
memoryWrite.setStateAfter(write.stateAfter());
graph.replaceFixedWithFixed(write, memoryWrite);
memoryWrite.setGuard(write.getGuard());
@@ -842,7 +849,7 @@
barrierType = arrayInitializationBarrier(entryKind);
}
if (address != null) {
- WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, entryKind, value), barrierType);
+ WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, entryKind, value), barrierType, false);
graph.addAfterFixed(newObject, graph.add(write));
}
}
@@ -875,7 +882,7 @@
barrierType = arrayStoreBarrierType(virtual.entryKind(i));
}
if (address != null) {
- WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, JavaKind.Object, allocValue), barrierType);
+ WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, JavaKind.Object, allocValue), barrierType, false);
graph.addBeforeFixed(commit, graph.add(write));
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/NodeIntrinsificationProvider.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/NodeIntrinsificationProvider.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -34,22 +34,27 @@
import org.graalvm.compiler.replacements.arraycopy.ArrayCopyForeignCalls;
import org.graalvm.compiler.word.WordTypes;
+import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaType;
public class NodeIntrinsificationProvider implements InjectionProvider {
+ public static final TargetDescription INJECTED_TARGET = null;
+
private final MetaAccessProvider metaAccess;
private final SnippetReflectionProvider snippetReflection;
private final ForeignCallsProvider foreignCalls;
private final WordTypes wordTypes;
+ private final TargetDescription target;
- public NodeIntrinsificationProvider(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, WordTypes wordTypes) {
+ public NodeIntrinsificationProvider(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, WordTypes wordTypes, TargetDescription target) {
this.metaAccess = metaAccess;
this.snippetReflection = snippetReflection;
this.foreignCalls = foreignCalls;
this.wordTypes = wordTypes;
+ this.target = target;
}
@Override
@@ -78,6 +83,8 @@
return type.cast(snippetReflection);
} else if (type.equals(WordTypes.class)) {
return type.cast(wordTypes);
+ } else if (type.equals(TargetDescription.class)) {
+ return type.cast(target);
} else {
throw new GraalError("Cannot handle injected argument of type %s.", type.getName());
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java Thu Oct 31 16:54:16 2019 -0700
@@ -269,11 +269,15 @@
}
@Override
- public void registerMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context, OptionValues options) {
+ public void registerMethodSubstitution(MethodSubstitutionPlugin plugin) {
// No initialization needed as method substitutions are parsed by the BytecodeParser.
}
@Override
+ public void registerConditionalPlugin(InvocationPlugin plugin) {
+ }
+
+ @Override
public boolean hasSubstitution(ResolvedJavaMethod method, int invokeBci) {
InvocationPlugin plugin = graphBuilderPlugins.getInvocationPlugins().lookupInvocation(method);
return plugin != null && (!plugin.inlineOnly() || invokeBci >= 0);
@@ -560,7 +564,7 @@
createGraphBuilder(replacements.providers, config, OptimisticOptimizations.NONE, initialIntrinsicContext).apply(graph);
- new CanonicalizerPhase().apply(graph, replacements.providers);
+ CanonicalizerPhase.create().apply(graph, replacements.providers);
} catch (Throwable e) {
throw debug.handle(e);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java Thu Oct 31 16:54:16 2019 -0700
@@ -891,7 +891,7 @@
}
snippetCopy.setGuardsStage(guardsStage);
try (DebugContext.Scope s = debug.scope("LoweringSnippetTemplate", snippetCopy)) {
- new LoweringPhase(new CanonicalizerPhase(), args.cacheKey.loweringStage).apply(snippetCopy, providers);
+ new LoweringPhase(CanonicalizerPhase.create(), args.cacheKey.loweringStage).apply(snippetCopy, providers);
} catch (Throwable e) {
throw debug.handle(e);
}
@@ -930,7 +930,10 @@
assert checkAllVarargPlaceholdersAreDeleted(parameterCount, placeholders);
new FloatingReadPhase(true, true).apply(snippetCopy);
- new RemoveValueProxyPhase().apply(snippetCopy);
+
+ if (!guardsStage.requiresValueProxies()) {
+ new RemoveValueProxyPhase().apply(snippetCopy);
+ }
MemoryAnchorNode anchor = snippetCopy.add(new MemoryAnchorNode());
snippetCopy.start().replaceAtUsages(InputType.Memory, anchor);
@@ -1059,8 +1062,14 @@
if (loopBegin != null) {
LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin);
Mark mark = snippetCopy.getMark();
- LoopTransformations.fullUnroll(loop, providers, new CanonicalizerPhase());
- new CanonicalizerPhase().applyIncremental(snippetCopy, providers, mark, false);
+ CanonicalizerPhase canonicalizer = null;
+ if (GraalOptions.ImmutableCode.getValue(snippetCopy.getOptions())) {
+ canonicalizer = CanonicalizerPhase.createWithoutReadCanonicalization();
+ } else {
+ canonicalizer = CanonicalizerPhase.create();
+ }
+ LoopTransformations.fullUnroll(loop, providers, canonicalizer);
+ CanonicalizerPhase.create().applyIncremental(snippetCopy, providers, mark, false);
loop.deleteUnusedNodes();
}
GraphUtil.removeFixedWithUnusedInputs(explodeLoop);
@@ -1278,7 +1287,7 @@
if (replacee instanceof MemoryCheckpoint.Single) {
// check if some node in snippet graph also kills the same location
- LocationIdentity locationIdentity = ((MemoryCheckpoint.Single) replacee).getLocationIdentity();
+ LocationIdentity locationIdentity = ((MemoryCheckpoint.Single) replacee).getKilledLocationIdentity();
if (locationIdentity.isAny()) {
assert !(memoryMap.getLastLocationAccess(any()) instanceof MemoryAnchorNode) : replacee + " kills ANY_LOCATION, but snippet does not";
// if the replacee kills ANY_LOCATION, the snippet can kill arbitrary locations
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Thu Oct 31 16:54:16 2019 -0700
@@ -40,7 +40,6 @@
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
-import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.core.common.calc.Condition.CanonicalizedCondition;
import org.graalvm.compiler.core.common.calc.UnsignedMath;
@@ -115,6 +114,7 @@
import org.graalvm.compiler.nodes.java.UnsafeCompareAndSwapNode;
import org.graalvm.compiler.nodes.memory.HeapAccess;
import org.graalvm.compiler.nodes.memory.address.IndexAddressNode;
+import org.graalvm.compiler.nodes.spi.Replacements;
import org.graalvm.compiler.nodes.type.StampTool;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.nodes.virtual.EnsureVirtualizedNode;
@@ -154,30 +154,30 @@
*/
public class StandardGraphBuilderPlugins {
- public static void registerInvocationPlugins(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, InvocationPlugins plugins, BytecodeProvider bytecodeProvider,
+ public static void registerInvocationPlugins(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, InvocationPlugins plugins, Replacements replacements,
boolean allowDeoptimization, boolean explicitUnsafeNullChecks) {
registerObjectPlugins(plugins);
registerClassPlugins(plugins);
registerMathPlugins(plugins, allowDeoptimization);
registerStrictMathPlugins(plugins);
registerUnsignedMathPlugins(plugins);
- registerStringPlugins(plugins, bytecodeProvider, snippetReflection);
+ registerStringPlugins(plugins, replacements, snippetReflection);
registerCharacterPlugins(plugins);
registerShortPlugins(plugins);
registerIntegerLongPlugins(plugins, JavaKind.Int);
registerIntegerLongPlugins(plugins, JavaKind.Long);
registerFloatPlugins(plugins);
registerDoublePlugins(plugins);
- registerArraysPlugins(plugins, bytecodeProvider);
- registerArrayPlugins(plugins, bytecodeProvider);
- registerUnsafePlugins(plugins, bytecodeProvider, explicitUnsafeNullChecks);
+ registerArraysPlugins(plugins, replacements);
+ registerArrayPlugins(plugins, replacements);
+ registerUnsafePlugins(plugins, replacements, explicitUnsafeNullChecks);
registerEdgesPlugins(metaAccess, plugins);
registerGraalDirectivesPlugins(plugins);
registerBoxingPlugins(plugins);
- registerJMHBlackholePlugins(plugins, bytecodeProvider);
- registerJFRThrowablePlugins(plugins, bytecodeProvider);
- registerMethodHandleImplPlugins(plugins, snippetReflection, bytecodeProvider);
- registerJcovCollectPlugins(plugins, bytecodeProvider);
+ registerJMHBlackholePlugins(plugins, replacements);
+ registerJFRThrowablePlugins(plugins, replacements);
+ registerMethodHandleImplPlugins(plugins, snippetReflection, replacements);
+ registerJcovCollectPlugins(plugins, replacements);
}
private static final Field STRING_VALUE_FIELD;
@@ -196,8 +196,8 @@
STRING_CODER_FIELD = coder;
}
- private static void registerStringPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider, SnippetReflectionProvider snippetReflection) {
- final Registration r = new Registration(plugins, String.class, bytecodeProvider);
+ private static void registerStringPlugins(InvocationPlugins plugins, Replacements replacements, SnippetReflectionProvider snippetReflection) {
+ final Registration r = new Registration(plugins, String.class, replacements);
r.register1("hashCode", Receiver.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
@@ -243,7 +243,7 @@
});
} else {
r.registerMethodSubstitution(JDK9StringSubstitutions.class, "equals", Receiver.class, Object.class);
- Registration utf16sub = new Registration(plugins, StringUTF16Substitutions.class, bytecodeProvider);
+ Registration utf16sub = new Registration(plugins, StringUTF16Substitutions.class, replacements);
utf16sub.register2("getCharDirect", byte[].class, int.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg1, ValueNode arg2) {
@@ -261,10 +261,10 @@
}
});
- final Registration latin1r = new Registration(plugins, "java.lang.StringLatin1", bytecodeProvider);
+ final Registration latin1r = new Registration(plugins, "java.lang.StringLatin1", replacements);
latin1r.register5("indexOf", byte[].class, int.class, byte[].class, int.class, int.class, new StringLatin1IndexOfConstantPlugin());
- final Registration utf16r = new Registration(plugins, "java.lang.StringUTF16", bytecodeProvider);
+ final Registration utf16r = new Registration(plugins, "java.lang.StringUTF16", replacements);
utf16r.register5("indexOfUnsafe", byte[].class, int.class, byte[].class, int.class, int.class, new StringUTF16IndexOfConstantPlugin());
utf16r.setAllowOverwrite(true);
utf16r.registerMethodSubstitution(StringUTF16Substitutions.class, "getChar", byte[].class, int.class);
@@ -292,8 +292,8 @@
}
}
- private static void registerArraysPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins, Arrays.class, bytecodeProvider);
+ private static void registerArraysPlugins(InvocationPlugins plugins, Replacements replacements) {
+ Registration r = new Registration(plugins, Arrays.class, replacements);
r.registerMethodSubstitution(ArraysSubstitutions.class, "equals", boolean[].class, boolean[].class);
r.registerMethodSubstitution(ArraysSubstitutions.class, "equals", byte[].class, byte[].class);
r.registerMethodSubstitution(ArraysSubstitutions.class, "equals", short[].class, short[].class);
@@ -302,8 +302,8 @@
r.registerMethodSubstitution(ArraysSubstitutions.class, "equals", long[].class, long[].class);
}
- private static void registerArrayPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins, Array.class, bytecodeProvider);
+ private static void registerArrayPlugins(InvocationPlugins plugins, Replacements replacements) {
+ Registration r = new Registration(plugins, Array.class, replacements);
r.register2("newInstance", Class.class, int.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unused, ValueNode componentType, ValueNode length) {
@@ -381,10 +381,10 @@
private static UnsafeCompareAndExchangePluginsRegistrar unsafeCompareAndExchangePluginsRegistrar = new UnsafeCompareAndExchangePluginsRegistrar();
- public static void registerPlatformSpecificUnsafePlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks, JavaKind[] supportedCasKinds) {
+ public static void registerPlatformSpecificUnsafePlugins(InvocationPlugins plugins, Replacements replacements, boolean explicitUnsafeNullChecks, JavaKind[] supportedCasKinds) {
registerPlatformSpecificUnsafePlugins(supportedCasKinds, new Registration(plugins, Unsafe.class), true, explicitUnsafeNullChecks);
if (JavaVersionUtil.JAVA_SPEC > 8) {
- registerPlatformSpecificUnsafePlugins(supportedCasKinds, new Registration(plugins, "jdk.internal.misc.Unsafe", bytecodeProvider), false, explicitUnsafeNullChecks);
+ registerPlatformSpecificUnsafePlugins(supportedCasKinds, new Registration(plugins, "jdk.internal.misc.Unsafe", replacements), false, explicitUnsafeNullChecks);
}
}
@@ -398,10 +398,10 @@
}
}
- private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks) {
+ private static void registerUnsafePlugins(InvocationPlugins plugins, Replacements replacements, boolean explicitUnsafeNullChecks) {
registerUnsafePlugins(new Registration(plugins, Unsafe.class), true, explicitUnsafeNullChecks);
if (JavaVersionUtil.JAVA_SPEC > 8) {
- registerUnsafePlugins(new Registration(plugins, "jdk.internal.misc.Unsafe", bytecodeProvider), false, explicitUnsafeNullChecks);
+ registerUnsafePlugins(new Registration(plugins, "jdk.internal.misc.Unsafe", replacements), false, explicitUnsafeNullChecks);
}
}
@@ -1300,7 +1300,7 @@
});
}
- private static void registerJMHBlackholePlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
+ private static void registerJMHBlackholePlugins(InvocationPlugins plugins, Replacements replacements) {
InvocationPlugin blackholePlugin = new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver blackhole, ValueNode value) {
@@ -1316,7 +1316,7 @@
};
String[] names = {"org.openjdk.jmh.infra.Blackhole", "org.openjdk.jmh.logic.BlackHole"};
for (String name : names) {
- Registration r = new Registration(plugins, name, bytecodeProvider);
+ Registration r = new Registration(plugins, name, replacements);
for (JavaKind kind : JavaKind.values()) {
if ((kind.isPrimitive() && kind != JavaKind.Void) || kind == JavaKind.Object) {
Class<?> javaClass = kind == JavaKind.Object ? Object.class : kind.toJavaClass();
@@ -1327,8 +1327,8 @@
}
}
- private static void registerJFRThrowablePlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins, "oracle.jrockit.jfr.jdkevents.ThrowableTracer", bytecodeProvider);
+ private static void registerJFRThrowablePlugins(InvocationPlugins plugins, Replacements replacements) {
+ Registration r = new Registration(plugins, "oracle.jrockit.jfr.jdkevents.ThrowableTracer", replacements);
r.register2("traceThrowable", Throwable.class, String.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode throwable, ValueNode message) {
@@ -1343,8 +1343,8 @@
});
}
- private static void registerMethodHandleImplPlugins(InvocationPlugins plugins, SnippetReflectionProvider snippetReflection, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins, "java.lang.invoke.MethodHandleImpl", bytecodeProvider);
+ private static void registerMethodHandleImplPlugins(InvocationPlugins plugins, SnippetReflectionProvider snippetReflection, Replacements replacements) {
+ Registration r = new Registration(plugins, "java.lang.invoke.MethodHandleImpl", replacements);
// In later JDKs this no longer exists and the usage is replace by Class.cast which is
// already an intrinsic
r.registerOptional2("castReference", Class.class, Object.class, new InvocationPlugin() {
@@ -1408,8 +1408,8 @@
* Registers a plugin to ignore {@code com.sun.tdk.jcov.runtime.Collect.hit} within an
* intrinsic.
*/
- private static void registerJcovCollectPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
- Registration r = new Registration(plugins, "com.sun.tdk.jcov.runtime.Collect", bytecodeProvider);
+ private static void registerJcovCollectPlugins(InvocationPlugins plugins, Replacements replacements) {
+ Registration r = new Registration(plugins, "com.sun.tdk.jcov.runtime.Collect", replacements);
r.register1("hit", int.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/TargetGraphBuilderPlugins.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/TargetGraphBuilderPlugins.java Thu Oct 31 16:54:16 2019 -0700
@@ -24,12 +24,12 @@
package org.graalvm.compiler.replacements;
-import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
+import org.graalvm.compiler.nodes.spi.Replacements;
import jdk.vm.ci.code.Architecture;
public interface TargetGraphBuilderPlugins {
- void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, Architecture arch, boolean explicitUnsafeNullChecks, boolean registerMathPlugins, boolean emitJDK9StringSubstitutions,
+ void register(Plugins plugins, Replacements replacements, Architecture arch, boolean explicitUnsafeNullChecks, boolean registerMathPlugins, boolean emitJDK9StringSubstitutions,
boolean useFMAIntrinsics);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopyCallNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopyCallNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -188,6 +188,11 @@
return locationIdentity;
}
+ @Override
+ public LocationIdentity getKilledLocationIdentity() {
+ return getLocationIdentity();
+ }
+
@NodeIntrinsic(hasSideEffect = true)
private static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantNodeParameter JavaKind elementKind, @ConstantNodeParameter boolean aligned,
@ConstantNodeParameter boolean disjoint, @ConstantNodeParameter boolean uninitialized, @ConstantNodeParameter int heapWordSize);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopyNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopyNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -57,7 +57,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
if (!forceAnyLocation && elementKind == null) {
elementKind = ArrayCopySnippets.Templates.selectComponentKind(this);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/CheckcastArrayCopyCallNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/CheckcastArrayCopyCallNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -146,7 +146,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
/*
* Because of restrictions that the memory graph of snippets matches the original node,
* pretend that we kill any.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/GenericArrayCopyCallNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/GenericArrayCopyCallNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -102,7 +102,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -128,6 +128,11 @@
}
@Override
+ public LocationIdentity getKilledLocationIdentity() {
+ return getLocationIdentity();
+ }
+
+ @Override
public MemoryNode getLastLocationAccess() {
return lastLocationAccess;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -173,7 +173,7 @@
}
DebugContext debug = replacementGraph.getDebug();
try (DebugContext.Scope s = debug.scope("LoweringSnippetTemplate", replacementGraph)) {
- new LoweringPhase(new CanonicalizerPhase(), tool.getLoweringStage()).apply(replacementGraph, c);
+ new LoweringPhase(CanonicalizerPhase.create(), tool.getLoweringStage()).apply(replacementGraph, c);
} catch (Throwable e) {
throw debug.handle(e);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroStateSplitNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroStateSplitNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -75,7 +75,7 @@
}
@Override
- public LocationIdentity getLocationIdentity() {
+ public LocationIdentity getKilledLocationIdentity() {
return LocationIdentity.any();
}
@@ -87,7 +87,7 @@
}
assert invoke.stateAfter().bci == BytecodeFrame.AFTER_BCI;
// Here we need to fix the bci of the invoke
- InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), bci(), invoke.getLocationIdentity()));
+ InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), bci(), invoke.getKilledLocationIdentity()));
newInvoke.setStateAfter(invoke.stateAfter());
snippetGraph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/ExportingClassLoader.java Thu Oct 31 14:23:06 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2016, 2019, 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.test;
-
-/**
- * A class loader that exports all packages in the module defining the class loader to all classes
- * in the unnamed module associated with the loader.
- */
-public class ExportingClassLoader extends ClassLoader {
- public ExportingClassLoader() {
- ModuleSupport.exportAllPackagesTo(getClass(), this);
- }
-
- public ExportingClassLoader(ClassLoader parent) {
- super(parent);
- ModuleSupport.exportAllPackagesTo(getClass(), this);
- }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/ModuleSupport.java Thu Oct 31 14:23:06 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2019, 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.test;
-
-import java.io.IOException;
-import java.lang.module.ModuleDescriptor.Requires;
-import java.net.URI;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.graalvm.compiler.debug.DebugOptions;
-
-import jdk.internal.module.Modules;
-
-public class ModuleSupport {
-
- public static void exportPackageTo(Class<?> moduleMember, String packageName, Class<?> requestor) {
- Module moduleToExport = moduleMember.getModule();
- Module requestorModule = requestor.getModule();
- if (moduleToExport != requestorModule) {
- Modules.addExports(moduleToExport, packageName, requestorModule);
- }
- }
-
- public static void exportAllPackagesTo(Class<?> moduleMember, Class<?> requestor) {
- Module moduleToExport = moduleMember.getModule();
- Module requestorModule = requestor.getModule();
- if (moduleToExport != requestorModule) {
- for (String packageName : moduleToExport.getPackages()) {
- Modules.addExports(moduleToExport, packageName, requestorModule);
- }
- }
- }
-
- public static void exportAllPackagesTo(Class<?> moduleMember, ClassLoader cl) {
- Module moduleToExport = moduleMember.getModule();
- Module unnamedModule = cl.getUnnamedModule();
- for (String packageName : moduleToExport.getPackages()) {
- Modules.addExports(moduleToExport, packageName, unnamedModule);
- }
- }
-
- @SuppressWarnings("unused")
- public static void exportAndOpenAllPackagesToUnnamed(String name) {
- Module module = ModuleLayer.boot().findModule(name).orElseThrow();
- Set<String> packages = module.getPackages();
- for (String pkg : packages) {
- Modules.addExportsToAllUnnamed(module, pkg);
- Modules.addOpensToAllUnnamed(module, pkg);
- }
- }
-
- public static List<String> getJRTGraalClassNames() throws IOException {
- List<String> classNames = new ArrayList<>();
- FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), Collections.emptyMap());
- Module graalModule = DebugOptions.class.getModule();
- Set<String> graalModuleSet = new HashSet<>();
- graalModuleSet.add(graalModule.getName());
- for (Module module : graalModule.getLayer().modules()) {
- if (requires(module, graalModule)) {
- graalModuleSet.add(module.getName());
- }
- }
-
- Path top = fs.getPath("/modules/");
- Files.find(top, Integer.MAX_VALUE,
- (path, attrs) -> attrs.isRegularFile()).forEach(p -> {
- int nameCount = p.getNameCount();
- if (nameCount > 2) {
- String base = p.getName(nameCount - 1).toString();
- if (base.endsWith(".class") && !base.equals("module-info.class")) {
- String module = p.getName(1).toString();
- if (graalModuleSet.contains(module)) {
- // Strip module prefix and convert to dotted
- // form
- String className = p.subpath(2, nameCount).toString().replace('/', '.');
- // Strip ".class" suffix
- className = className.replace('/', '.').substring(0, className.length() - ".class".length());
- classNames.add(className);
- }
- }
- }
- });
- return classNames;
- }
-
- private static boolean requires(Module module, Module graalModule) {
- ModuleLayer graalLayer = graalModule.getLayer();
- for (Requires r : module.getDescriptor().requires()) {
- if (r.name().equals(graalModule.getName())) {
- return true;
- }
- Module dep = graalLayer.findModule(r.name()).get();
- if (requires(dep, graalModule)) {
- return true;
- }
- }
- return false;
- }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java Thu Oct 31 16:54:16 2019 -0700
@@ -121,11 +121,11 @@
return processUnsafeStore((RawStoreNode) node, state, effects);
} else if (node instanceof MemoryCheckpoint.Single) {
COUNTER_MEMORYCHECKPOINT.increment(node.getDebug());
- LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
+ LocationIdentity identity = ((MemoryCheckpoint.Single) node).getKilledLocationIdentity();
processIdentity(state, identity);
} else if (node instanceof MemoryCheckpoint.Multi) {
COUNTER_MEMORYCHECKPOINT.increment(node.getDebug());
- for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) {
+ for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getKilledLocationIdentities()) {
processIdentity(state, identity);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationBlockState.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationBlockState.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -152,6 +152,7 @@
}
public ReadEliminationBlockState(ReadEliminationBlockState other) {
+ super(other);
readCache = EconomicMap.create(Equivalence.DEFAULT, other.readCache);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationClosure.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationClosure.java Thu Oct 31 16:54:16 2019 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -135,9 +135,9 @@
}
} else if (node instanceof WriteNode) {
WriteNode write = (WriteNode) node;
- if (write.getLocationIdentity().isSingle()) {
+ if (write.getKilledLocationIdentity().isSingle()) {
ValueNode object = GraphUtil.unproxify(write.getAddress());
- LoadCacheEntry identifier = new LoadCacheEntry(object, write.getLocationIdentity());
+ LoadCacheEntry identifier = new LoadCacheEntry(object, write.getKilledLocationIdentity());
ValueNode cachedValue = state.getCacheEntry(identifier);
ValueNode value = getScalarAlias(write.value());
@@ -145,10 +145,10 @@
effects.deleteNode(write);
deleted = true;
}
- processIdentity(state, write.getLocationIdentity());
+ processIdentity(state, write.getKilledLocationIdentity());
state.addCacheEntry(identifier, value);
} else {
- processIdentity(state, write.getLocationIdentity());
+ processIdentity(state, write.getKilledLocationIdentity());
}
} else if (node instanceof UnsafeAccessNode) {
ResolvedJavaType type = StampTool.typeOrNull(((UnsafeAccessNode) node).object());
@@ -170,9 +170,9 @@
} else {
assert node instanceof RawStoreNode;
RawStoreNode write = (RawStoreNode) node;
- if (write.getLocationIdentity().isSingle()) {
+ if (write.getKilledLocationIdentity().isSingle()) {
ValueNode object = GraphUtil.unproxify(write.object());
- UnsafeLoadCacheEntry identifier = new UnsafeLoadCacheEntry(object, write.offset(), write.getLocationIdentity());
+ UnsafeLoadCacheEntry identifier = new UnsafeLoadCacheEntry(object, write.offset(), write.getKilledLocationIdentity());
ValueNode cachedValue = state.getCacheEntry(identifier);
ValueNode value = getScalarAlias(write.value());
@@ -180,18 +180,18 @@
effects.deleteNode(write);
deleted = true;
}
- processIdentity(state, write.getLocationIdentity());
+ processIdentity(state, write.getKilledLocationIdentity());
state.addCacheEntry(identifier, value);
} else {
- processIdentity(state, write.getLocationIdentity());
+ processIdentity(state, write.getKilledLocationIdentity());
}
}
}
} else if (node instanceof MemoryCheckpoint.Single) {
- LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
+ LocationIdentity identity = ((MemoryCheckpoint.Single) node).getKilledLocationIdentity();
processIdentity(state, identity);
} else if (node instanceof MemoryCheckpoint.Multi) {
- for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) {
+ for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getKilledLocationIdentities()) {
processIdentity(state, identity);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/OptionsEncoder.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2018, 2019, 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.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Facilities for encoding/decoding a set of options to/from a byte array.
+ */
+public final class OptionsEncoder {
+
+ private OptionsEncoder() {
+ }
+
+ /**
+ * Determines if {@code value} is supported by {@link #encode(Map)}.
+ */
+ public static boolean isValueSupported(Object value) {
+ return TypedDataOutputStream.isValueSupported(value);
+ }
+
+ /**
+ * Encodes {@code options} into a byte array.
+ *
+ * @throws IllegalArgumentException if any value in {@code options} is not
+ * {@linkplain #isValueSupported(Object) supported}
+ */
+ public static byte[] encode(final Map<String, Object> options) {
+ try (ByteArrayOutputStream baout = new ByteArrayOutputStream()) {
+ try (TypedDataOutputStream out = new TypedDataOutputStream(baout)) {
+ out.writeInt(options.size());
+ for (Map.Entry<String, Object> e : options.entrySet()) {
+ out.writeUTF(e.getKey());
+ try {
+ out.writeTypedValue(e.getValue());
+ } catch (IllegalArgumentException iae) {
+ throw new IllegalArgumentException(String.format("Key: %s, Value: %s, Value type: %s",
+ e.getKey(), e.getValue(), e.getValue().getClass()), iae);
+ }
+ }
+ }
+ return baout.toByteArray();
+ } catch (IOException ioe) {
+ throw new IllegalArgumentException(ioe);
+ }
+ }
+
+ /**
+ * Decodes {@code input} into a name/value map.
+ *
+ * @throws IllegalArgumentException if {@code input} cannot be decoded
+ */
+ public static Map<String, Object> decode(byte[] input) {
+ Map<String, Object> res = new LinkedHashMap<>();
+ try (TypedDataInputStream in = new TypedDataInputStream(new ByteArrayInputStream(input))) {
+ final int size = in.readInt();
+ for (int i = 0; i < size; i++) {
+ final String key = in.readUTF();
+ final Object value = in.readTypedValue();
+ res.put(key, value);
+ }
+ if (in.available() != 0) {
+ throw new IllegalArgumentException(in.available() + " undecoded bytes");
+ }
+ } catch (IOException ioe) {
+ throw new IllegalArgumentException(ioe);
+ }
+ return res;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/TypedDataInputStream.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2019, 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.util;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A stream that can read (trivial) values using their in-band data type information, intended for
+ * use with {@link TypedDataOutputStream}.
+ */
+public class TypedDataInputStream extends DataInputStream {
+ public TypedDataInputStream(InputStream in) {
+ super(in);
+ }
+
+ /**
+ * Reads a single value, using the data type encoded in the stream.
+ *
+ * @return The read value, such as a boxed primitive or a {@link String}.
+ * @exception IOException in case of an I/O error.
+ */
+ public Object readTypedValue() throws IOException {
+ Object value;
+ final byte type = readByte();
+ switch (type) {
+ case 'Z':
+ value = readBoolean();
+ break;
+ case 'B':
+ value = readByte();
+ break;
+ case 'S':
+ value = readShort();
+ break;
+ case 'C':
+ value = readChar();
+ break;
+ case 'I':
+ value = readInt();
+ break;
+ case 'J':
+ value = readLong();
+ break;
+ case 'F':
+ value = readFloat();
+ break;
+ case 'D':
+ value = readDouble();
+ break;
+ case 'U':
+ value = readUTF();
+ break;
+ default:
+ throw new IOException("Unsupported type: " + Integer.toHexString(type));
+ }
+ return value;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.util/src/org/graalvm/util/TypedDataOutputStream.java Thu Oct 31 16:54:16 2019 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2019, 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.util;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * A stream that can write (trivial) values together with their data type, for use with
+ * {@link TypedDataInputStream}.
+ */
+public class TypedDataOutputStream extends DataOutputStream {
+ /** Determines if {@code value} is supported by {@link #writeTypedValue(Object)}. */
+ public static boolean isValueSupported(Object value) {
+ if (value == null) {
+ return false;
+ }
+ Class<?> valueClass = value.getClass();
+ return valueClass == Boolean.class ||
+ valueClass == Byte.class ||
+ valueClass == Short.class ||
+ valueClass == Character.class ||
+ valueClass == Integer.class ||
+ valueClass == Long.class ||
+ valueClass == Float.class ||
+ valueClass == Double.class ||
+ valueClass == String.class ||
+ value.getClass().isEnum();
+ }
+
+ public TypedDataOutputStream(OutputStream out) {
+ super(out);
+ }
+
+ /**
+ * Writes the value that is represented by the given non-null object, together with information
+ * on the value's data type.
+ *
+ * @param value A value of a {@linkplain #isValueSupported supported type}.
+ * @exception IllegalArgumentException when the provided type is not supported.
+ * @exception IOException in case of an I/O error.
+ */
+ public void writeTypedValue(Object value) throws IOException {
+ Class<?> valueClz = value.getClass();
+ if (valueClz == Boolean.class) {
+ this.writeByte('Z');
+ this.writeBoolean((Boolean) value);
+ } else if (valueClz == Byte.class) {
+ this.writeByte('B');
+ this.writeByte((Byte) value);
+ } else if (valueClz == Short.class) {
+ this.writeByte('S');
+ this.writeShort((Short) value);
+ } else if (valueClz == Character.class) {
+ this.writeByte('C');
+ this.writeChar((Character) value);
+ } else if (valueClz == Integer.class) {
+ this.writeByte('I');
+ this.writeInt((Integer) value);
+ } else if (valueClz == Long.class) {
+ this.writeByte('J');
+ this.writeLong((Long) value);
+ } else if (valueClz == Float.class) {
+ this.writeByte('F');
+ this.writeFloat((Float) value);
+ } else if (valueClz == Double.class) {
+ this.writeByte('D');
+ this.writeDouble((Double) value);
+ } else if (valueClz == String.class) {
+ this.writeByte('U');
+ this.writeUTF((String) value);
+ } else if (valueClz.isEnum()) {
+ this.writeByte('U');
+ this.writeUTF(((Enum<?>) value).name());
+ } else {
+ throw new IllegalArgumentException(String.format("Unsupported type: Value: %s, Value type: %s", value, valueClz));
+ }
+ }
+}