diff --git a/.travis.yml b/.travis.yml index 950f0ac6ce71..75118824c38e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,8 +18,8 @@ jdk: env: global: - - JVMCI_VERSION="jvmci-0.59" - - JDK8_UPDATE_VERSION="202" + - JVMCI_VERSION="jvmci-20-b01" + - JDK8_UPDATE_VERSION="212" matrix: include: @@ -37,7 +37,7 @@ matrix: - clang-format-3.8 - libc++1 - libc++-dev - - env: JDK="jdk8" GATE="build,sulong" PRIMARY="vm" DYNAMIC_IMPORTS="/sulong,/substratevm" LLVM_VERSION="6.0" DISABLE_POLYGLOT=true DISABLE_LIBPOLYGLOT=true NATIVE_IMAGE_TESTING=true + - env: JDK="jdk8" GATE="build,sulong" PRIMARY="vm" DYNAMIC_IMPORTS="/sulong,/substratevm" LLVM_VERSION="6.0" DISABLE_POLYGLOT=true DISABLE_LIBPOLYGLOT=true addons: apt: sources: diff --git a/README.md b/README.md index 9041c28b6db4..1e9805f88722 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ The GraalVM main source repository includes the following components: * [GraalVM SDK](sdk/README.md) contains long term supported APIs of GraalVM. -* [Graal compiler](compiler/README.md) written in Java that supports both dynamic and static compilation and can integrate with +* [GraalVM compiler](compiler/README.md) written in Java that supports both dynamic and static compilation and can integrate with the Java HotSpot VM or run standalone. * [Truffle](truffle/README.md) language implementation framework for creating languages and instrumentations for GraalVM. @@ -39,8 +39,8 @@ Please report security vulnerabilities not via GitHub issues or the public maili ## Related Repositories -GraalVM allows running of following languages which are being developed and tested in related repositories with GraalVM core to run on top of it using Truffle and Graal compiler. These are: -* [Graal JavaScript](https://github.com/graalvm/graaljs) - JavaScript (ECMAScript 2019 compatible) and Node.js 10.15.2 +GraalVM allows running of following languages which are being developed and tested in related repositories with GraalVM core to run on top of it using Truffle and the GraalVM compiler. These are: +* [GraalJS](https://github.com/graalvm/graaljs) - JavaScript (ECMAScript 2019 compatible) and Node.js 10.15.2 * [FastR](https://github.com/oracle/fastr) - R Language 3.5.1 * [GraalPython](https://github.com/graalvm/graalpython) - Python 3.7 * [TruffleRuby](https://github.com/oracle/truffleruby/) - Ruby Programming Language 2.6.2 @@ -50,10 +50,10 @@ GraalVM allows running of following languages which are being developed and test ## License Each GraalVM component is licensed: -* [Truffle](/truffle/) and its dependency [GraalVM SDK](/sdk/) are licensed under the [Universal Permissive License](truffle/LICENSE.md). +* [Truffle Framework](/truffle/) and its dependency [GraalVM SDK](/sdk/) are licensed under the [Universal Permissive License](truffle/LICENSE.md). * [Tools](/tools/) project is licensed under the [GPL 2 with Classpath exception](tools/LICENSE.GPL.md). * [TRegex](/regex/) project is licensed under the [GPL 2 with Classpath exception](regex/LICENSE.GPL.md). -* The [Graal compiler](/compiler/) is licensed under the [GPL 2 with Classpath exception](compiler/LICENSE.md). +* [GraalVM compiler](/compiler/) is licensed under the [GPL 2 with Classpath exception](compiler/LICENSE.md). * [Substrate VM](/substratevm/) is licensed under the [GPL 2 with Classpath exception](substratevm/LICENSE.md). * [Sulong](/sulong/) is licensed under [3-clause BSD](sulong/LICENSE). * [VM](/vm/) is licensed under the [GPL 2 with Classpath exception](vm/LICENSE_GRAALVM_CE). diff --git a/ci_includes/publish-javadoc.hocon b/ci_includes/publish-javadoc.hocon index a2fe73d99879..3aa3ce22edfd 100644 --- a/ci_includes/publish-javadoc.hocon +++ b/ci_includes/publish-javadoc.hocon @@ -1,7 +1,7 @@ # Publish Javadoc of graal components post-merge builds += [ - ${linux-amd64} ${labsjdk8} { + ${linux-amd64} ${oraclejdk8} { timelimit : "30:00", run : [ [cd, "./sdk"], diff --git a/common.hocon b/common.hocon index 0140b06252f5..005e2082ba17 100644 --- a/common.hocon +++ b/common.hocon @@ -1,16 +1,16 @@ # overlay version -overlay = 92cc4cf61ccb3ffc91bea53450b8a73222107f8e +overlay = 24a9cd249544a2c8b61e225aa1f02c85db569fc4 # oraclejdk* are released OracleJDK binaries -# labsjdk* are JDKs based on OracleJDK binaries +# oraclejdk* are JDKs based on OracleJDK binaries # openjdk8 JDKs on Linux are built by Oracle Labs # openjdk8 JDKs on macOS are based on AdoptOpenJDK binaries jdks: { - labsjdk8: {name : labsjdk, version : "8u202-jvmci-0.59", platformspecific: true} - openjdk8: {name : openjdk, version : "8u202-jvmci-0.59", platformspecific: true} - labsjdk8Debug: {name : labsjdk, version : "8u202-jvmci-0.59-fastdebug", platformspecific: true} - oraclejdk11: {name : oraclejdk, version : "11+28", platformspecific: true} - openjdk11: {name : openjdk, version : "11+28", platformspecific: true} + oraclejdk8: {name : oraclejdk, version : "8u212-jvmci-20-b01", platformspecific: true} + openjdk8: {name : openjdk, version : "8u212-jvmci-20-b01", platformspecific: true} + oraclejdk8Debug: {name : oraclejdk, version : "8u212-jvmci-20-b01-fastdebug", platformspecific: true} + oraclejdk11: {name : oraclejdk, version : "11.0.3+12", platformspecific: true} + openjdk11: {name : openjdk, version : "11.0.3+12", platformspecific: true} } # This must always point to HEAD in the master branch but can be used to point @@ -27,8 +27,8 @@ download-hsdis : { ] } -labsjdk8 : { downloads : { JAVA_HOME : ${jdks.labsjdk8}, EXTRA_JAVA_HOMES : { pathlist :[ ${jdks.oraclejdk11} ]} }} -labsjdk8Debug : { downloads : { JAVA_HOME : ${jdks.labsjdk8Debug}, EXTRA_JAVA_HOMES : { pathlist :[ ${jdks.oraclejdk11} ]} }} +oraclejdk8 : { downloads : { JAVA_HOME : ${jdks.oraclejdk8}, EXTRA_JAVA_HOMES : { pathlist :[ ${jdks.oraclejdk11} ]} }} +oraclejdk8Debug : { downloads : { JAVA_HOME : ${jdks.oraclejdk8Debug}, EXTRA_JAVA_HOMES : { pathlist :[ ${jdks.oraclejdk11} ]} }} openjdk8 : { downloads : { JAVA_HOME : ${jdks.openjdk8} }} diff --git a/compiler/README.md b/compiler/README.md index b60c90b73835..20b9abb24a39 100644 --- a/compiler/README.md +++ b/compiler/README.md @@ -1,9 +1,10 @@ -Graal is a dynamic compiler written in Java that integrates with the HotSpot JVM. It has a focus on high performance and extensibility. -In addition, it provides optimized performance for [Truffle](https://github.com/graalvm/graal/tree/master/truffle)-based languages running on the JVM. +The GraalVM compiler is a dynamic compiler written in Java that integrates with the HotSpot JVM. It has a focus on high performance and extensibility. +In addition, it provides optimized performance for languages implemented with [Truffle Framework](https://github.com/graalvm/graal/tree/master/truffle)-based languages running on the JVM. +For brevity, the GraalVM compiler is often referred to as "the compiler" below. ## Setup -Working with Graal will mean cloning more than one repository and so it's +Working with the GraalVM compiler will mean cloning more than one repository and so it's recommended to create and use a separate directory: ``` @@ -11,9 +12,9 @@ mkdir graal cd graal ``` -## Building Graal +## Building the GraalVM compiler -To simplify Graal development, a separate Python tool called [mx](https://github.com/graalvm/mx) has been co-developed. +To simplify development, a separate Python tool called [mx](https://github.com/graalvm/mx) has been co-developed. This tool must be downloaded and put onto your PATH: ``` @@ -21,18 +22,19 @@ git clone https://github.com/graalvm/mx.git export PATH=$PWD/mx:$PATH ``` -Graal depends on a JDK that supports a compatible version of JVMCI ([JVM Compiler Interface](https://bugs.openjdk.java.net/browse/JDK-8062493)). +The compiler depends on a JDK that supports a compatible version of JVMCI ([JVM Compiler Interface](https://bugs.openjdk.java.net/browse/JDK-8062493)). There is a JVMCI [port](https://github.com/graalvm/graal-jvmci-8) for JDK 8 and the required JVMCI version is built into the JDK as of JDK 11. -To develop Graal you need either a JVMCI-enabled JDK 8 (download from [OTN](http://www.oracle.com/technetwork/oracle-labs/program-languages/downloads/index.html) or [build](#building-jvmci-jdk8) yourself) -or JDK 11 (build 20 or later). +A JVMCI-enabled JDK 8 can be downloaded from [OTN](https://www.oracle.com/technetwork/graalvm/downloads/index.html) +or [GitHub](https://github.com/graalvm/openjdk8-jvmci-builder/releases) +or you can [build](#building-jvmci-jdk8) it yourself. -Most Graal sources are compliant with Java 8. Some sources use API specific to JDK 8 or only introduced in JDK 9. +Most compiler sources are compliant with Java 8. Some sources use API specific to JDK 8 or only introduced in JDK 9. These sources are in [versioned projects](https://github.com/graalvm/mx#versioning-sources-for-different-jdk-releases). If you don't have a JDK that satisfies the requirement of a versioned project, the project is ignored by mx. -If you only want to develop Graal for a single JDK version, you only need to define `JAVA_HOME`. For example: +If you want to develop on a single JDK version, you only need to define `JAVA_HOME`. For example: ``` -export JAVA_HOME=/usr/lib/jvm/labsjdk1.8.0_172-jvmci-0.46 +export JAVA_HOME=/usr/lib/jvm/oraclejdk1.8.0_212-jvmci-20-b01 ``` or: ``` @@ -40,15 +42,15 @@ export JAVA_HOME=/usr/lib/jvm/jdk-11 ``` If you want to ensure your changes will pass both JDK 8 and JDK 11 gates, you can specify the secondary JDK(s) in `EXTRA_JAVA_HOMES`. -For example, to develop Graal for JDK 8 while ensuring `mx build` still works with the JDK 11 specific sources: +For example, to develop for JDK 8 while ensuring `mx build` still works with the JDK 11 specific sources: ``` -export JAVA_HOME=/usr/lib/jvm/labsjdk1.8.0_172-jvmci-0.46 +export JAVA_HOME=/usr/lib/jvm/oraclejdk1.8.0_212-jvmci-20-b01 export EXTRA_JAVA_HOMES=/usr/lib/jvm/jdk-11 ``` And on macOS: ``` -export JAVA_HOME=/Library/Java/JavaVirtualMachines/labsjdk1.8.0_172-jvmci-0.46/Contents/Home +export JAVA_HOME=/Library/Java/JavaVirtualMachines/oraclejdk1.8.0_212-jvmci-20-b01/Contents/Home export EXTRA_JAVA_HOMES=/Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home ``` If you omit `EXTRA_JAVA_HOMES` in the above examples, versioned projects depending on the specified JDK(s) will be ignored. @@ -59,19 +61,19 @@ Now change to the `graal/compiler` directory: cd graal/compiler ``` -Changing to the `graal/compiler` directory informs mx that the focus of development (called the _primary suite_) is Graal. +Changing to the `graal/compiler` directory informs mx that the focus of development (called the _primary suite_) is the GraalVM compiler. All subsequent mx commands should be executed from this directory. -Here's the recipe for building and running Graal: +Here's the recipe for building and running the GraalVM compiler: ``` mx build mx vm ``` -By default, Graal is only used for hosted compilation (i.e., the VM still uses C2 for compilation). -To make the VM use Graal as the top tier JIT compiler, add the `-XX:+UseJVMCICompiler` option to the command line. -To disable use of Graal altogether, use `-XX:-EnableJVMCI`. +By default, the GraalVM compiler is only used for hosted compilation (i.e., the VM still uses C2 for compilation). +To make the VM use the GraalVM compiler as the top tier JIT compiler, add the `-XX:+UseJVMCICompiler` option to the command line. +To disable use of the GraalVM compiler altogether, use `-XX:-EnableJVMCI`. ### Windows Specifics @@ -88,13 +90,14 @@ mx ideinit This will generate Eclipse, IntelliJ, and NetBeans project configurations. Further information on how to import these project configurations into individual IDEs can be found on the [IDEs](docs/IDEs.md) page. -The Graal code base includes the [Ideal Graph Visualizer](http://ssw.jku.at/General/Staff/TW/igv.html) which is very useful in terms of visualizing Graal's intermediate representation (IR). +The [Ideal Graph Visualizer](https://www.graalvm.org/docs/reference-manual/tools/#ideal-graph-visualizer)(IGV) is very useful in terms of visualizing the compiler's intermediate representation (IR). +IGV is available on [OTN](https://www.oracle.com/technetwork/graalvm/downloads/index.html). You can get a quick insight into this tool by running the commands below. -The first command launches the tool and the second runs one of the unit tests included in the Graal code base with extra options to make Graal dump the IR for all methods it compiles. +The first command launches the tool and the second runs one of the unit tests included in the code base with extra options to dump the compiler IR for all methods compiled. You should wait for the GUI to appear before running the second command. ``` -mx igv & +$GRAALVM_EE_HOME/bin/idealgraphvisualizer & mx unittest -Dgraal.Dump BC_athrow0 ``` @@ -105,33 +108,33 @@ Further information can be found on the [Debugging](docs/Debugging.md) page. ## libgraal -Building Graal as described above enables it to be used in HotSpot as Java code -called from the VM. In this mode, Graal is executed in the same way as any +Building the GraalVM compiler as described above means it is executed in the same way as any other Java code in the VM; it allocates in the HotSpot heap and it starts execution in the interpreter with hot parts being subsequently JIT compiled. -The advantage of this mode is that Graal can be debugged with a Java debugger. +The advantage of this mode is that it can be debugged with a Java debugger. -However, it has some disadvantages. Firstly, since Graal uses the object heap, it can +However, it has some disadvantages. Firstly, since it uses the object heap, it can reduce application object locality and increase GC pause times. Additionally, it can complicate fine tuning options such as `-Xmx` and `-Xms` which now need to take the -heap usage of Graal needs to be taken into account. Secondly, Graal will initially be executed +heap usage of the compiler into account. Secondly, the compiler will initially be executed in the interpreter and only get faster over time as its hot methods are JIT -compiled. This is mitigated to some degree by forcing Graal (and JVMCI) -to only be compiled by C1 but this comes at the cost of lower peak performance for Graal. +compiled. This is mitigated to some degree by forcing the GraalVM compiler +to only be compiled by C1 (i.e., `-Dgraal.CompileGraalWithC1Only=true`) but this comes at the cost +of slower compilation speed. -To address these issues, Graal can be deployed as a native shared library. The shared -library is produced using [SubstrateVM](../substratevm/README.md) to ahead-of-time compile Graal. In this mode, -Graal uses memory separate from the HotSpot heap and it runs compiled +To address these issues, the GraalVM compiler can be deployed as a native shared library. The shared +library is a native image produced using [SubstrateVM](../substratevm/README.md). In this mode, +the GraalVM compiler uses memory separate from the HotSpot heap and it runs compiled from the start. That is, it has execution properties similar to other native HotSpot compilers such as C1 and C2. -To build a GraalVM image with libgraal: +To build libgraal: ``` cd graal/vm mx --env libgraal build ``` -The newly built GraalVM image is available at: +The newly built GraalVM image containing libgraal is available at: ``` mx --env libgraal graalvm-home ``` @@ -161,7 +164,7 @@ Without leaving the `graal/vm` directory, you can now run libgraal as follows: ## Publications and Presentations -For video tutorials, presentations and publications on Graal visit the [Publications](../docs/Publications.md) page. +For video tutorials, presentations and publications on the GraalVM compiiler visit the [Publications](../docs/Publications.md) page. ## Building JVMCI JDK 8 @@ -175,10 +178,10 @@ mx --java-home /path/to/jdk8 unittest export JAVA_HOME=$(mx --java-home /path/to/jdk8 jdkhome) ``` -You need to use the same JDK the [OTN](http://www.oracle.com/technetwork/oracle-labs/program-languages/downloads/index.html) downloads are based on as the argument to `--java-home` in the above commands. +You need to use the same JDK the [OTN](https://www.oracle.com/technetwork/graalvm/downloads/index.html) downloads are based on as the argument to `--java-home` in the above commands. The build step above should work on all [supported JDK 8 build platforms](https://wiki.openjdk.java.net/display/Build/Supported+Build+Platforms). It should also work on other platforms (such as Oracle Linux, CentOS and Fedora as described [here](http://mail.openjdk.java.net/pipermail/graal-dev/2015-December/004050.html)). -If you run into build problems, send a message to the [Graal mailing list](http://mail.openjdk.java.net/mailman/listinfo/graal-dev). +If you run into build problems, send a message to http://mail.openjdk.java.net/mailman/listinfo/graal-dev. ### Windows Specifics @@ -200,4 +203,4 @@ You will also need an *MSVC 2010 SP1* compiler. The following tool chain is reco ## License -The Graal compiler is licensed under the [GPL 2](LICENSE.md). +The GraalVM compiler is licensed under the [GPL 2](LICENSE.md). diff --git a/compiler/ci_common/bench-weekly.hocon b/compiler/ci_common/bench-weekly.hocon index 2a30a28d48b9..e33b7cdcb33b 100644 --- a/compiler/ci_common/bench-weekly.hocon +++ b/compiler/ci_common/bench-weekly.hocon @@ -119,32 +119,32 @@ bench-specjbb2015-forks : ${bench-specjbb2015} ${weeklys-bench-notifications} { } builds += [ - ${x52.tmpfs10g} ${bench-dacapo-hwloc-forks} ${labsjdk8} { name: "bench-forks-compiler-dacapo-linux-x52" } - ${x52.tmpfs10g} ${bench-scala-dacapo-hwloc-forks} ${labsjdk8} { name: "bench-forks-compiler-scala-dacapo-linux-x52" } - ${x52.default} ${bench-specjvm2008-Single-forks-batch0} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-batch0" } - ${x52.default} ${bench-specjvm2008-Single-forks-batch1} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-batch1" } - ${x52.default} ${bench-specjvm2008-Single-forks-batch2} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-batch2" } - ${x52.default} ${bench-specjvm2008-Single-forks-batch3} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-batch3" } - ${x52.default} ${bench-specjvm2008-Single-forks-batch4} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-batch4" } - ${x52.tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-batch0} ${labsjdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-batch0" } - ${x52.tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-batch1} ${labsjdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-batch1" } - ${x52.tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-batch2} ${labsjdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-batch2" } - ${x52.tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-batch3} ${labsjdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-batch3" } - ${x52.default} ${bench-specjbb2005-forks} ${labsjdk8} { name: "bench-forks-compiler-specjbb2005-linux-x52" } - ${x52.default} ${bench-specjbb2015-forks} ${labsjdk8} { name: "bench-forks-compiler-specjbb2015-linux-x52" } + ${x52.tmpfs10g} ${bench-dacapo-hwloc-forks} ${oraclejdk8} { name: "bench-forks-compiler-dacapo-linux-x52" } + ${x52.tmpfs10g} ${bench-scala-dacapo-hwloc-forks} ${oraclejdk8} { name: "bench-forks-compiler-scala-dacapo-linux-x52" } + ${x52.default} ${bench-specjvm2008-Single-forks-batch0} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-batch0" } + ${x52.default} ${bench-specjvm2008-Single-forks-batch1} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-batch1" } + ${x52.default} ${bench-specjvm2008-Single-forks-batch2} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-batch2" } + ${x52.default} ${bench-specjvm2008-Single-forks-batch3} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-batch3" } + ${x52.default} ${bench-specjvm2008-Single-forks-batch4} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-batch4" } + ${x52.tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-batch0} ${oraclejdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-batch0" } + ${x52.tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-batch1} ${oraclejdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-batch1" } + ${x52.tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-batch2} ${oraclejdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-batch2" } + ${x52.tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-batch3} ${oraclejdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-batch3" } + ${x52.default} ${bench-specjbb2005-forks} ${oraclejdk8} { name: "bench-forks-compiler-specjbb2005-linux-x52" } + ${x52.default} ${bench-specjbb2015-forks} ${oraclejdk8} { name: "bench-forks-compiler-specjbb2015-linux-x52" } # libgraal - ${x52.tmpfs10g-libgraal} ${bench-dacapo-hwloc-forks} ${labsjdk8} { name: "bench-forks-compiler-dacapo-libgraal-linux-x52" } - ${x52.tmpfs10g-libgraal} ${bench-scala-dacapo-hwloc-forks} ${labsjdk8} { name: "bench-forks-compiler-scala-dacapo-libgraal-linux-x52" } - ${x52.default-libgraal} ${bench-specjvm2008-Single-forks-batch0} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-libgraal-linux-x52-batch0" } - ${x52.default-libgraal} ${bench-specjvm2008-Single-forks-batch1} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-libgraal-linux-x52-batch1" } - ${x52.default-libgraal} ${bench-specjvm2008-Single-forks-batch2} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-libgraal-linux-x52-batch2" } - ${x52.default-libgraal} ${bench-specjvm2008-Single-forks-batch3} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-libgraal-linux-x52-batch3" } - ${x52.default-libgraal} ${bench-specjvm2008-Single-forks-batch4} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-libgraal-linux-x52-batch4" } - ${x52.tmpfs10g-libgraal} ${bench-renaissance-legacy-hwloc-forks-batch0} ${labsjdk8} { name: "bench-forks-compiler-renaissance-legacy-libgraal-linux-x52-batch0" } - ${x52.tmpfs10g-libgraal} ${bench-renaissance-legacy-hwloc-forks-batch1} ${labsjdk8} { name: "bench-forks-compiler-renaissance-legacy-libgraal-linux-x52-batch1" } - ${x52.tmpfs10g-libgraal} ${bench-renaissance-legacy-hwloc-forks-batch2} ${labsjdk8} { name: "bench-forks-compiler-renaissance-legacy-libgraal-linux-x52-batch2" } - ${x52.tmpfs10g-libgraal} ${bench-renaissance-legacy-hwloc-forks-batch3} ${labsjdk8} { name: "bench-forks-compiler-renaissance-legacy-libgraal-linux-x52-batch3" } - ${x52.default-libgraal} ${bench-specjbb2005-forks} ${labsjdk8} { name: "bench-forks-compiler-specjbb2005-libgraal-linux-x52" } - ${x52.default-libgraal} ${bench-specjbb2015-forks} ${labsjdk8} { name: "bench-forks-compiler-specjbb2015-libgraal-linux-x52" } + ${x52.tmpfs10g-libgraal} ${bench-dacapo-hwloc-forks} ${oraclejdk8} { name: "bench-forks-compiler-dacapo-libgraal-linux-x52" } + ${x52.tmpfs10g-libgraal} ${bench-scala-dacapo-hwloc-forks} ${oraclejdk8} { name: "bench-forks-compiler-scala-dacapo-libgraal-linux-x52" } + ${x52.default-libgraal} ${bench-specjvm2008-Single-forks-batch0} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-libgraal-linux-x52-batch0" } + ${x52.default-libgraal} ${bench-specjvm2008-Single-forks-batch1} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-libgraal-linux-x52-batch1" } + ${x52.default-libgraal} ${bench-specjvm2008-Single-forks-batch2} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-libgraal-linux-x52-batch2" } + ${x52.default-libgraal} ${bench-specjvm2008-Single-forks-batch3} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-libgraal-linux-x52-batch3" } + ${x52.default-libgraal} ${bench-specjvm2008-Single-forks-batch4} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-libgraal-linux-x52-batch4" } + ${x52.tmpfs10g-libgraal} ${bench-renaissance-legacy-hwloc-forks-batch0} ${oraclejdk8} { name: "bench-forks-compiler-renaissance-legacy-libgraal-linux-x52-batch0" } + ${x52.tmpfs10g-libgraal} ${bench-renaissance-legacy-hwloc-forks-batch1} ${oraclejdk8} { name: "bench-forks-compiler-renaissance-legacy-libgraal-linux-x52-batch1" } + ${x52.tmpfs10g-libgraal} ${bench-renaissance-legacy-hwloc-forks-batch2} ${oraclejdk8} { name: "bench-forks-compiler-renaissance-legacy-libgraal-linux-x52-batch2" } + ${x52.tmpfs10g-libgraal} ${bench-renaissance-legacy-hwloc-forks-batch3} ${oraclejdk8} { name: "bench-forks-compiler-renaissance-legacy-libgraal-linux-x52-batch3" } + ${x52.default-libgraal} ${bench-specjbb2005-forks} ${oraclejdk8} { name: "bench-forks-compiler-specjbb2005-libgraal-linux-x52" } + ${x52.default-libgraal} ${bench-specjbb2015-forks} ${oraclejdk8} { name: "bench-forks-compiler-specjbb2015-libgraal-linux-x52" } ] diff --git a/compiler/ci_common/gate_tasks.hocon b/compiler/ci_common/gate_tasks.hocon index 870bdba6c4c9..b410dab7e68d 100644 --- a/compiler/ci_common/gate_tasks.hocon +++ b/compiler/ci_common/gate_tasks.hocon @@ -2,45 +2,45 @@ builds += [ # Darwin AMD64 - ${gateTest} ${labsjdk8} ${gateDarwinAMD64} {name: "gate-test-compiler-test-8-darwin-amd64"} + ${gateTest} ${oraclejdk8} ${gateDarwinAMD64} {name: "gate-test-compiler-test-8-darwin-amd64"} ${gateTest} ${openjdk8} ${gateDarwinAMD64} {name: "weekly-test-compiler-test-openjdk8-darwin-amd64"} ${graalWeekly} ${gateTest} ${oraclejdk11} ${gateDarwinAMD64} {name: "weekly-test-compiler-test-11-darwin-amd64"} ${graalWeekly} -# ${gateTestBenchmark} ${labsjdk8} ${gateDarwinAMD64} {name: "weekly-test-compiler-benchmarktest-8-darwin-amd64"} ${graalWeekly} +# ${gateTestBenchmark} ${oraclejdk8} ${gateDarwinAMD64} {name: "weekly-test-compiler-benchmarktest-8-darwin-amd64"} ${graalWeekly} # Windows AMD64 - ${gateTest} ${labsjdk8} ${gateWindowsAMD64} {name: "gate-compiler-test-8-windows-amd64", timelimit: "50:00", packages: {msvc: "==10.0" }} + ${gateTest} ${oraclejdk8} ${gateWindowsAMD64} {name: "gate-compiler-test-8-windows-amd64", timelimit: "50:00", packages: {msvc: "==10.0" }} # Linux AMD64 - ${gateTest} ${labsjdk8} ${gateLinuxAMD64} {name: "gate-compiler-test-8-linux-amd64"} - ${gateTest} ${openjdk8} ${gateLinuxAMD64} {name: "weekly-test-compiler-test-openjdk8-linux-amd64"} ${graalWeekly} - ${gateTestMaxVS} ${labsjdk8} ${gateLinuxAMD64} {name: "weekly-test-compiler-test-8-linux-amd64-maxvectorsize"} ${graalWeekly} - ${gateTestAVX0} ${labsjdk8} ${gateLinuxAMD64} {name: "weekly-test-compiler-test-8-linux-amd64-avx0"} ${graalWeekly} - ${gateTestAVX1} ${labsjdk8} ${gateLinuxAMD64} {name: "weekly-test-compiler-test-8-linux-amd64-avx1"} ${graalWeekly} - ${gateTest} ${oraclejdk11} ${gateLinuxAMD64} {name: "gate-compiler-test-11-linux-amd64"} - ${gateJavaBaseTest} ${oraclejdk11} ${gateLinuxAMD64} {name: "weekly-test-compiler-javabasetest-11-linux-amd64"} ${graalWeekly} - ${gateTestCTW} ${labsjdk8} ${gateLinuxAMD64} {name: "gate-compiler-ctw-8-linux-amd64"} - ${gateTestCTW} ${openjdk8} ${gateLinuxAMD64} {name: "weekly-test-compiler-ctw-openjdk8-linux-amd64"} ${graalWeekly} - ${gateTestCTW} ${oraclejdk11} ${gateLinuxAMD64} {name: "weekly-test-compiler-ctw-11-linux-amd64"} ${graalWeekly} - ${gateTest} ${labsjdk8Debug} ${gateLinuxAMD64} {name: "weekly-test-compiler-test-8-linux-amd64-fastdebug", timelimit: "1:50:00"} ${graalWeekly} - ${gateTestBenchmark} ${labsjdk8} ${gateLinuxAMD64} {name: "gate-compiler-benchmarktest-8-linux-amd64"} - ${gateTestBenchmark} ${labsjdk8Debug} ${gateLinuxAMD64} {name: "weekly-test-compiler-benchmarktest-8-linux-amd64-fastdebug"} ${graalWeekly} - ${gateStyle} ${labsjdk8} ${gateLinuxAMD64} {name: "gate-compiler-style-linux-amd64"} - ${gateCoverage} ${labsjdk8} ${gateLinuxAMD64} {name: "weekly-compiler-coverage-8-linux-amd64", timelimit: "1:50:00"} ${graalWeekly} + ${gateTest} ${oraclejdk8} ${gateLinuxAMD64} {name: "gate-compiler-test-8-linux-amd64"} + ${gateTest} ${openjdk8} ${gateLinuxAMD64} {name: "weekly-test-compiler-test-openjdk8-linux-amd64"} ${graalWeekly} + ${gateTestMaxVS} ${oraclejdk8} ${gateLinuxAMD64} {name: "weekly-test-compiler-test-8-linux-amd64-maxvectorsize"} ${graalWeekly} + ${gateTestAVX0} ${oraclejdk8} ${gateLinuxAMD64} {name: "weekly-test-compiler-test-8-linux-amd64-avx0"} ${graalWeekly} + ${gateTestAVX1} ${oraclejdk8} ${gateLinuxAMD64} {name: "weekly-test-compiler-test-8-linux-amd64-avx1"} ${graalWeekly} + ${gateTest} ${oraclejdk11} ${gateLinuxAMD64} {name: "gate-compiler-test-11-linux-amd64"} + ${gateJavaBaseTest} ${oraclejdk11} ${gateLinuxAMD64} {name: "weekly-test-compiler-javabasetest-11-linux-amd64"} ${graalWeekly} + ${gateTestCTW} ${oraclejdk8} ${gateLinuxAMD64} {name: "gate-compiler-ctw-8-linux-amd64"} + ${gateTestCTW} ${openjdk8} ${gateLinuxAMD64} {name: "weekly-test-compiler-ctw-openjdk8-linux-amd64"} ${graalWeekly} + ${gateTestCTW} ${oraclejdk11} ${gateLinuxAMD64} {name: "weekly-test-compiler-ctw-11-linux-amd64"} ${graalWeekly} + ${gateTest} ${oraclejdk8Debug} ${gateLinuxAMD64} {name: "weekly-test-compiler-test-8-linux-amd64-fastdebug", timelimit: "1:50:00"} ${graalWeekly} + ${gateTestBenchmark} ${oraclejdk8} ${gateLinuxAMD64} {name: "gate-compiler-benchmarktest-8-linux-amd64"} + ${gateTestBenchmark} ${oraclejdk8Debug} ${gateLinuxAMD64} {name: "weekly-test-compiler-benchmarktest-8-linux-amd64-fastdebug"} ${graalWeekly} + ${gateStyle} ${oraclejdk8} ${gateLinuxAMD64} {name: "gate-compiler-style-linux-amd64"} + ${gateCoverage} ${oraclejdk8} ${gateLinuxAMD64} {name: "weekly-compiler-coverage-8-linux-amd64", timelimit: "1:50:00"} ${graalWeekly} - ${gateTestCompileImmediately} ${labsjdk8} ${gateLinuxAMD64} {name: "gate-compiler-test-compile-immediately-8-linux-amd64"} + ${gateTestCompileImmediately} ${oraclejdk8} ${gateLinuxAMD64} {name: "gate-compiler-test-compile-immediately-8-linux-amd64"} ${gateMathStubsListener} {name: "daily-hotspot-mathstubs-listener"} # Solaris SPARC - ${gateTest} ${labsjdk8} ${gateSolarisSPARC} {name: "gate-compiler-test-8-solaris-sparcv9", timelimit: "1:00:00"} - ${gateTest} ${oraclejdk11} ${gateSolarisSPARC} {name: "gate-compiler-test-11-solaris-sparcv9", timelimit: "1:00:00"} - ${gateTestCTW} ${labsjdk8} ${gateSolarisSPARC} {name: "gate-compiler-ctw-8-solaris-sparcv9", timelimit: "1:00:00"} - ${gateTestCTW} ${oraclejdk11} ${gateSolarisSPARC} {name: "weekly-test-compiler-ctw-11-solaris-sparcv9", timelimit: "1:50:00"} ${graalWeekly} - ${gateTest} ${labsjdk8Debug} ${gateSolarisSPARC} {name: "weekly-test-compiler-test-8-solaris-sparcv9-fastdebug", timelimit: "1:50:00"} ${graalWeekly} - ${gateTestBenchmark} ${labsjdk8} ${gateSolarisSPARC} {name: "gate-compiler-benchmarktest-8-solaris-sparcv9", timelimit: "1:00:00"} -# ${gateTestBenchmark} ${labsjdk8Debug} ${gateSolarisSPARC} {name: "gate-compiler-benchmarktest-8-solaris-sparcv9-fastdebug", timelimit: "1:50:00"} + ${gateTest} ${oraclejdk8} ${gateSolarisSPARC} {name: "gate-compiler-test-8-solaris-sparcv9", timelimit: "1:00:00"} + ${gateTest} ${oraclejdk11} ${gateSolarisSPARC} {name: "gate-compiler-test-11-solaris-sparcv9", timelimit: "1:00:00"} + ${gateTestCTW} ${oraclejdk8} ${gateSolarisSPARC} {name: "gate-compiler-ctw-8-solaris-sparcv9", timelimit: "1:00:00"} + ${gateTestCTW} ${oraclejdk11} ${gateSolarisSPARC} {name: "weekly-test-compiler-ctw-11-solaris-sparcv9", timelimit: "1:50:00"} ${graalWeekly} + ${gateTest} ${oraclejdk8Debug} ${gateSolarisSPARC} {name: "weekly-test-compiler-test-8-solaris-sparcv9-fastdebug", timelimit: "1:50:00"} ${graalWeekly} + ${gateTestBenchmark} ${oraclejdk8} ${gateSolarisSPARC} {name: "gate-compiler-benchmarktest-8-solaris-sparcv9", timelimit: "1:00:00"} +# ${gateTestBenchmark} ${oraclejdk8Debug} ${gateSolarisSPARC} {name: "gate-compiler-benchmarktest-8-solaris-sparcv9-fastdebug", timelimit: "1:50:00"} # Linux SPARC - #${gateTest} ${labsjdk8} ${gateLinuxSPARC} {name: "weekly-test-compiler-test-8-linux-sparcv9", timelimit: "1:00:00"} ${graalWeekly} + #${gateTest} ${oraclejdk8} ${gateLinuxSPARC} {name: "weekly-test-compiler-test-8-linux-sparcv9", timelimit: "1:00:00"} ${graalWeekly} # Linux AArch64 ${gateTest} ${gateLinuxAArch64} {name: "weekly-compiler-test-11-linux-aarch64", timelimit: "1:50:00"} ${graalWeekly} diff --git a/compiler/ci_common/gate_tasks_bootstrap.hocon b/compiler/ci_common/gate_tasks_bootstrap.hocon index 04fd477fa7b8..ccdb1c86e266 100644 --- a/compiler/ci_common/gate_tasks_bootstrap.hocon +++ b/compiler/ci_common/gate_tasks_bootstrap.hocon @@ -1,18 +1,18 @@ builds += [ # Darwin AMD64 - ${gateBootstrapLite} ${labsjdk8} ${gateDarwinAMD64Bootstrap} {name: "gate-compiler-bootstraplite-8-darwin-amd64"} + ${gateBootstrapLite} ${oraclejdk8} ${gateDarwinAMD64Bootstrap} {name: "gate-compiler-bootstraplite-8-darwin-amd64"} ${gateBootstrapLite} ${oraclejdk11} ${gateDarwinAMD64Bootstrap} {name: "weekly-test-compiler-bootstraplite-11-darwin-amd64"} ${graalWeekly} # Linux AMD64 - ${gateBootstrap} ${labsjdk8} ${gateLinuxAMD64Bootstrap} {name: "gate-compiler-bootstrap-8-linux-amd64"} - ${gateBootstrapFullVerify} ${labsjdk8} ${gateLinuxAMD64Bootstrap} {name: "gate-compiler-bootstrapfullverify-8-linux-amd64"} + ${gateBootstrap} ${oraclejdk8} ${gateLinuxAMD64Bootstrap} {name: "gate-compiler-bootstrap-8-linux-amd64"} + ${gateBootstrapFullVerify} ${oraclejdk8} ${gateLinuxAMD64Bootstrap} {name: "gate-compiler-bootstrapfullverify-8-linux-amd64"} ${gateBootstrap} ${oraclejdk11} ${gateLinuxAMD64Bootstrap} {name: "gate-compiler-bootstrap-11-linux-amd64"} # Solaris SPARC - ${gateBootstrap} ${labsjdk8} ${gateSolarisSPARCBootstrap} {name: "gate-compiler-bootstrap-8-solaris-sparcv9", timelimit: "1:00:00"} + ${gateBootstrap} ${oraclejdk8} ${gateSolarisSPARCBootstrap} {name: "gate-compiler-bootstrap-8-solaris-sparcv9", timelimit: "1:00:00"} ${gateBootstrap} ${oraclejdk11} ${gateSolarisSPARCBootstrap} {name: "weekly-test-compiler-bootstrap-11-solaris-sparcv9", timelimit: "1:00:00"} ${graalWeekly} # Linux SPARC - ${gateBootstrap} ${labsjdk8} ${gateLinuxSPARCBootstrap} {name: "weekly-test-compiler-bootstrap-labsjdk8-linux-sparcv9", timelimit: "1:00:00"} ${graalWeekly} + ${gateBootstrap} ${oraclejdk8} ${gateLinuxSPARCBootstrap} {name: "weekly-test-compiler-bootstrap-oraclejdk8-linux-sparcv9", timelimit: "1:00:00"} ${graalWeekly} ] diff --git a/compiler/ci_common/m7_eighth.hocon b/compiler/ci_common/m7_eighth.hocon index 26d1f58e65b2..52bbeadc4a87 100644 --- a/compiler/ci_common/m7_eighth.hocon +++ b/compiler/ci_common/m7_eighth.hocon @@ -16,18 +16,18 @@ m7_eighth.default-g1gc : ${m7_eighth.default} { } builds += [ - ${m7_eighth.default} ${bench-dacapo} ${labsjdk8} { name: "bench-compiler-dacapo-solaris-m7_eighth", timelimit: "1:00:00" } - ${m7_eighth.default} ${bench-dacapo-timing} ${labsjdk8} { name: "bench-compiler-dacapo-timing-solaris-m7_eighth", timelimit: "1:00:00" } - ${m7_eighth.default} ${bench-scala-dacapo} ${labsjdk8} { name: "bench-compiler-scala-dacapo-solaris-m7_eighth", timelimit: "1:00:00" } - ${m7_eighth.default} ${bench-scala-dacapo-timing} ${labsjdk8} { name: "bench-compiler-scala-dacapo-timing-solaris-m7_eighth", timelimit: "1:00:00" } - ${m7_eighth.default} ${bench-specjvm2008-Single} ${labsjdk8} { name: "bench-compiler-specjvm2008-Single-solaris-m7_eighth", timelimit: "3:10:00" } - ${m7_eighth.default} ${bench-specjvm2008-OneVM} ${labsjdk8} { name: "bench-compiler-specjvm2008-OneVM-solaris-m7_eighth", timelimit: "3:10:00" } - # GR-11609 ${m7_eighth.default} ${bench-specjbb2015} ${labsjdk8} { name: "bench-compiler-specjbb2015-solaris-m7_eighth" } - ${m7_eighth.default} ${bench-micros-graal-whitebox} ${labsjdk8} { name: "bench-compiler-jmh-micros-graal-whitebox-solaris-m7_eighth" } - ${m7_eighth.default} ${bench-micros-graal-dist} ${labsjdk8} { name: "bench-compiler-jmh-micros-graal-dist-solaris-m7_eighth" } + ${m7_eighth.default} ${bench-dacapo} ${oraclejdk8} { name: "bench-compiler-dacapo-solaris-m7_eighth", timelimit: "1:00:00" } + ${m7_eighth.default} ${bench-dacapo-timing} ${oraclejdk8} { name: "bench-compiler-dacapo-timing-solaris-m7_eighth", timelimit: "1:00:00" } + ${m7_eighth.default} ${bench-scala-dacapo} ${oraclejdk8} { name: "bench-compiler-scala-dacapo-solaris-m7_eighth", timelimit: "1:00:00" } + ${m7_eighth.default} ${bench-scala-dacapo-timing} ${oraclejdk8} { name: "bench-compiler-scala-dacapo-timing-solaris-m7_eighth", timelimit: "1:00:00" } + ${m7_eighth.default} ${bench-specjvm2008-Single} ${oraclejdk8} { name: "bench-compiler-specjvm2008-Single-solaris-m7_eighth", timelimit: "3:10:00" } + ${m7_eighth.default} ${bench-specjvm2008-OneVM} ${oraclejdk8} { name: "bench-compiler-specjvm2008-OneVM-solaris-m7_eighth", timelimit: "3:10:00" } + # GR-11609 ${m7_eighth.default} ${bench-specjbb2015} ${oraclejdk8} { name: "bench-compiler-specjbb2015-solaris-m7_eighth" } + ${m7_eighth.default} ${bench-micros-graal-whitebox} ${oraclejdk8} { name: "bench-compiler-jmh-micros-graal-whitebox-solaris-m7_eighth" } + ${m7_eighth.default} ${bench-micros-graal-dist} ${oraclejdk8} { name: "bench-compiler-jmh-micros-graal-dist-solaris-m7_eighth" } - ${m7_eighth.default-g1gc} ${bench-dacapo} ${labsjdk8} { targets : [weekly, bench], name: "bench-compiler-dacapo-g1gc-solaris-m7_eighth", timelimit: "1:00:00" } - ${m7_eighth.default-g1gc} ${bench-scala-dacapo} ${labsjdk8} { targets : [weekly, bench], name: "bench-compiler-scala-dacapo-g1gc-solaris-m7_eighth", timelimit: "1:00:00" } - ${m7_eighth.default-g1gc} ${bench-specjvm2008-Single} ${labsjdk8} { targets : [weekly, bench], name: "bench-compiler-specjvm2008-g1gc-Single-solaris-m7_eighth" } - # GR-11609 ${m7_eighth.default-g1gc} ${bench-specjbb2015} ${labsjdk8} { targets : [weekly, bench], name: "bench-compiler-specjbb2015-g1gc-solaris-m7_eighth" } + ${m7_eighth.default-g1gc} ${bench-dacapo} ${oraclejdk8} { targets : [weekly, bench], name: "bench-compiler-dacapo-g1gc-solaris-m7_eighth", timelimit: "1:00:00" } + ${m7_eighth.default-g1gc} ${bench-scala-dacapo} ${oraclejdk8} { targets : [weekly, bench], name: "bench-compiler-scala-dacapo-g1gc-solaris-m7_eighth", timelimit: "1:00:00" } + ${m7_eighth.default-g1gc} ${bench-specjvm2008-Single} ${oraclejdk8} { targets : [weekly, bench], name: "bench-compiler-specjvm2008-g1gc-Single-solaris-m7_eighth" } + # GR-11609 ${m7_eighth.default-g1gc} ${bench-specjbb2015} ${oraclejdk8} { targets : [weekly, bench], name: "bench-compiler-specjbb2015-g1gc-solaris-m7_eighth" } ] diff --git a/compiler/ci_common/x52-jfr.hocon b/compiler/ci_common/x52-jfr.hocon index a9bb75fe2051..58af40e7d322 100644 --- a/compiler/ci_common/x52-jfr.hocon +++ b/compiler/ci_common/x52-jfr.hocon @@ -100,10 +100,10 @@ x52.tmpfs10g-jfr : ${x52.default-jfr} { } builds += [ - ${x52.tmpfs10g-jfr} ${bench-dacapo-jfr} ${labsjdk8} { name: "bench-compiler-dacapo-linux-x52-jfr" } - ${x52.tmpfs10g-jfr} ${bench-scala-dacapo-jfr} ${labsjdk8} { name: "bench-compiler-scala-dacapo-linux-x52-jfr" } - ${x52.default-jfr} ${bench-specjvm2008-Single-jfr} ${labsjdk8} { name: "bench-compiler-specjvm2008-Single-linux-x52-jfr" } - ${x52.default-jfr} ${bench-specjbb2015-jfr} ${labsjdk8} { name: "bench-compiler-specjbb2015-linux-x52-jfr" } - ${x52.default-jfr} ${bench-renaissance-legacy-jfr} ${labsjdk8} { name: "bench-compiler-renaissance-legacy-linux-x52-jfr" } - ${x52.default-jfr} ${bench-spark-sql-perf-jfr} ${labsjdk8} { name: "bench-compiler-spark-sql-perf-linux-x52-jfr" } + ${x52.tmpfs10g-jfr} ${bench-dacapo-jfr} ${oraclejdk8} { name: "bench-compiler-dacapo-linux-x52-jfr" } + ${x52.tmpfs10g-jfr} ${bench-scala-dacapo-jfr} ${oraclejdk8} { name: "bench-compiler-scala-dacapo-linux-x52-jfr" } + ${x52.default-jfr} ${bench-specjvm2008-Single-jfr} ${oraclejdk8} { name: "bench-compiler-specjvm2008-Single-linux-x52-jfr" } + ${x52.default-jfr} ${bench-specjbb2015-jfr} ${oraclejdk8} { name: "bench-compiler-specjbb2015-linux-x52-jfr" } + ${x52.default-jfr} ${bench-renaissance-legacy-jfr} ${oraclejdk8} { name: "bench-compiler-renaissance-legacy-linux-x52-jfr" } + ${x52.default-jfr} ${bench-spark-sql-perf-jfr} ${oraclejdk8} { name: "bench-compiler-spark-sql-perf-linux-x52-jfr" } ] diff --git a/compiler/ci_common/x52.hocon b/compiler/ci_common/x52.hocon index f03a9f5e317a..a1dd95382b66 100644 --- a/compiler/ci_common/x52.hocon +++ b/compiler/ci_common/x52.hocon @@ -48,52 +48,52 @@ x52.tmpfs10g-libgraal-g1gc: ${x52.tmpfs10g-libgraal} { } builds += [ - ${x52.tmpfs10g} ${bench-dacapo-hwloc} ${labsjdk8} { name: "bench-compiler-dacapo-linux-x52" } - ${x52.tmpfs10g} ${bench-dacapo-timing-hwloc} ${labsjdk8} { name: "bench-compiler-dacapo-timing-linux-x52" } - ${x52.tmpfs10g} ${bench-dacapo-move-profiling-hwloc} ${labsjdk8} { name: "bench-compiler-dacapo-move-profiling-linux-x52" } - ${x52.tmpfs10g} ${bench-scala-dacapo-hwloc} ${labsjdk8} { name: "bench-compiler-scala-dacapo-linux-x52" } - ${x52.tmpfs10g} ${bench-scala-dacapo-timing-hwloc} ${labsjdk8} { name: "bench-compiler-scala-dacapo-timing-linux-x52" } - ${x52.tmpfs10g} ${bench-scala-dacapo-move-profiling-hwloc} ${labsjdk8} { name: "bench-compiler-scala-dacapo-move-profiling-linux-x52" } - ${x52.default} ${bench-specjvm2008-Single} ${labsjdk8} { name: "bench-compiler-specjvm2008-Single-linux-x52" } - ${x52.default} ${bench-specjvm2008-OneVM} ${labsjdk8} { name: "bench-compiler-specjvm2008-OneVM-linux-x52" } - ${x52.default} ${bench-specjbb2015} ${labsjdk8} { name: "bench-compiler-specjbb2015-linux-x52" } - ${x52.default} ${bench-micros-graal-whitebox} ${labsjdk8} { name: "bench-compiler-jmh-micros-graal-whitebox-linux-x52" } - ${x52.default} ${bench-micros-graal-dist} ${labsjdk8} { name: "bench-compiler-jmh-micros-graal-dist-linux-x52" } + ${x52.tmpfs10g} ${bench-dacapo-hwloc} ${oraclejdk8} { name: "bench-compiler-dacapo-linux-x52" } + ${x52.tmpfs10g} ${bench-dacapo-timing-hwloc} ${oraclejdk8} { name: "bench-compiler-dacapo-timing-linux-x52" } + ${x52.tmpfs10g} ${bench-dacapo-move-profiling-hwloc} ${oraclejdk8} { name: "bench-compiler-dacapo-move-profiling-linux-x52" } + ${x52.tmpfs10g} ${bench-scala-dacapo-hwloc} ${oraclejdk8} { name: "bench-compiler-scala-dacapo-linux-x52" } + ${x52.tmpfs10g} ${bench-scala-dacapo-timing-hwloc} ${oraclejdk8} { name: "bench-compiler-scala-dacapo-timing-linux-x52" } + ${x52.tmpfs10g} ${bench-scala-dacapo-move-profiling-hwloc} ${oraclejdk8} { name: "bench-compiler-scala-dacapo-move-profiling-linux-x52" } + ${x52.default} ${bench-specjvm2008-Single} ${oraclejdk8} { name: "bench-compiler-specjvm2008-Single-linux-x52" } + ${x52.default} ${bench-specjvm2008-OneVM} ${oraclejdk8} { name: "bench-compiler-specjvm2008-OneVM-linux-x52" } + ${x52.default} ${bench-specjbb2015} ${oraclejdk8} { name: "bench-compiler-specjbb2015-linux-x52" } + ${x52.default} ${bench-micros-graal-whitebox} ${oraclejdk8} { name: "bench-compiler-jmh-micros-graal-whitebox-linux-x52" } + ${x52.default} ${bench-micros-graal-dist} ${oraclejdk8} { name: "bench-compiler-jmh-micros-graal-dist-linux-x52" } - ${x52.tmpfs10g-g1gc} ${bench-dacapo-hwloc} ${labsjdk8} { targets : [weekly, bench], name: "bench-compiler-dacapo-g1gc-linux-x52" } - ${x52.tmpfs10g-g1gc} ${bench-scala-dacapo-hwloc} ${labsjdk8} { targets : [weekly, bench], name: "bench-compiler-scala-dacapo-g1gc-linux-x52" } - ${x52.tmpfs10g-g1gc} ${bench-specjvm2008-Single} ${labsjdk8} { targets : [weekly, bench], name: "bench-compiler-specjvm2008-g1gc-Single-linux-x52" } - ${x52.tmpfs10g-g1gc} ${bench-specjbb2015} ${labsjdk8} { targets : [weekly, bench], name: "bench-compiler-specjbb2015-g1gc-linux-x52" } + ${x52.tmpfs10g-g1gc} ${bench-dacapo-hwloc} ${oraclejdk8} { targets : [weekly, bench], name: "bench-compiler-dacapo-g1gc-linux-x52" } + ${x52.tmpfs10g-g1gc} ${bench-scala-dacapo-hwloc} ${oraclejdk8} { targets : [weekly, bench], name: "bench-compiler-scala-dacapo-g1gc-linux-x52" } + ${x52.tmpfs10g-g1gc} ${bench-specjvm2008-Single} ${oraclejdk8} { targets : [weekly, bench], name: "bench-compiler-specjvm2008-g1gc-Single-linux-x52" } + ${x52.tmpfs10g-g1gc} ${bench-specjbb2015} ${oraclejdk8} { targets : [weekly, bench], name: "bench-compiler-specjbb2015-g1gc-linux-x52" } - ${x52.default} ${bench-renaissance-legacy-hwloc} ${labsjdk8} { name: "bench-compiler-renaissance-legacy-linux-x52" } - ${x52.default-g1gc} ${bench-renaissance-legacy-hwloc} ${labsjdk8} { targets: [weekly, bench], name: "bench-compiler-renaissance-legacy-g1gc-linux-x52" } - ${x52.default} ${bench-spark-sql-perf} ${labsjdk8} { name: "bench-compiler-spark-sql-perf-linux-x52" } + ${x52.default} ${bench-renaissance-legacy-hwloc} ${oraclejdk8} { name: "bench-compiler-renaissance-legacy-linux-x52" } + ${x52.default-g1gc} ${bench-renaissance-legacy-hwloc} ${oraclejdk8} { targets: [weekly, bench], name: "bench-compiler-renaissance-legacy-g1gc-linux-x52" } + ${x52.default} ${bench-spark-sql-perf} ${oraclejdk8} { name: "bench-compiler-spark-sql-perf-linux-x52" } - ${x52.default} ${bench-specjbb2005} ${labsjdk8} { targets : [weekly, bench], name: "bench-compiler-specjbb2005-linux-x52"} - ${x52.default-g1gc} ${bench-specjbb2005} ${labsjdk8} { targets : [weekly, bench], name: "bench-compiler-specjbb2005-g1gc-linux-x52"} + ${x52.default} ${bench-specjbb2005} ${oraclejdk8} { targets : [weekly, bench], name: "bench-compiler-specjbb2005-linux-x52"} + ${x52.default-g1gc} ${bench-specjbb2005} ${oraclejdk8} { targets : [weekly, bench], name: "bench-compiler-specjbb2005-g1gc-linux-x52"} # LibGraal - ${x52.tmpfs10g-libgraal} ${bench-dacapo-hwloc} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-dacapo-libgraal-linux-x52" } - ${x52.tmpfs10g-libgraal} ${bench-dacapo-timing-hwloc} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-dacapo-timing-libgraal-linux-x52" } - ${x52.tmpfs10g-libgraal} ${bench-dacapo-move-profiling-hwloc} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-dacapo-move-profiling-libgraal-linux-x52" } - ${x52.tmpfs10g-libgraal} ${bench-scala-dacapo-hwloc} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-scala-dacapo-libgraal-linux-x52" } - ${x52.tmpfs10g-libgraal} ${bench-scala-dacapo-timing-hwloc} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-scala-dacapo-timing-libgraal-linux-x52" } - ${x52.tmpfs10g-libgraal} ${bench-scala-dacapo-move-profiling-hwloc} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-scala-dacapo-move-profiling-libgraal-linux-x52" } - ${x52.default-libgraal} ${bench-specjvm2008-Single} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-specjvm2008-Single-libgraal-linux-x52" } - ${x52.default-libgraal} ${bench-specjvm2008-OneVM} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-specjvm2008-OneVM-libgraal-linux-x52" } - ${x52.default-libgraal} ${bench-specjbb2015} ${labsjdk8} { targets: [weekly, bench], name: "bench-compiler-specjbb2015-libgraal-linux-x52" } - ${x52.default-libgraal} ${bench-micros-graal-whitebox} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-jmh-micros-graal-whitebox-libgraal-linux-x52" } - ${x52.default-libgraal} ${bench-micros-graal-dist} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-jmh-micros-graal-dist-libgraal-linux-x52" } + ${x52.tmpfs10g-libgraal} ${bench-dacapo-hwloc} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-dacapo-libgraal-linux-x52" } + ${x52.tmpfs10g-libgraal} ${bench-dacapo-timing-hwloc} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-dacapo-timing-libgraal-linux-x52" } + ${x52.tmpfs10g-libgraal} ${bench-dacapo-move-profiling-hwloc} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-dacapo-move-profiling-libgraal-linux-x52" } + ${x52.tmpfs10g-libgraal} ${bench-scala-dacapo-hwloc} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-scala-dacapo-libgraal-linux-x52" } + ${x52.tmpfs10g-libgraal} ${bench-scala-dacapo-timing-hwloc} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-scala-dacapo-timing-libgraal-linux-x52" } + ${x52.tmpfs10g-libgraal} ${bench-scala-dacapo-move-profiling-hwloc} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-scala-dacapo-move-profiling-libgraal-linux-x52" } + ${x52.default-libgraal} ${bench-specjvm2008-Single} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-specjvm2008-Single-libgraal-linux-x52" } + ${x52.default-libgraal} ${bench-specjvm2008-OneVM} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-specjvm2008-OneVM-libgraal-linux-x52" } + ${x52.default-libgraal} ${bench-specjbb2015} ${oraclejdk8} { targets: [weekly, bench], name: "bench-compiler-specjbb2015-libgraal-linux-x52" } + ${x52.default-libgraal} ${bench-micros-graal-whitebox} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-jmh-micros-graal-whitebox-libgraal-linux-x52" } + ${x52.default-libgraal} ${bench-micros-graal-dist} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-jmh-micros-graal-dist-libgraal-linux-x52" } - ${x52.tmpfs10g-libgraal-g1gc} ${bench-dacapo-hwloc} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-dacapo-libgraal-g1gc-linux-x52" } - ${x52.tmpfs10g-libgraal-g1gc} ${bench-scala-dacapo-hwloc} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-scala-dacapo-libgraal-g1gc-linux-x52" } - ${x52.tmpfs10g-libgraal-g1gc} ${bench-specjvm2008-Single} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-specjvm2008-libgraal-g1gc-Single-linux-x52" } - ${x52.tmpfs10g-libgraal-g1gc} ${bench-specjbb2015} ${labsjdk8} { targets: [weekly, bench], name: "bench-compiler-specjbb2015-libgraal-g1gc-linux-x52" } + ${x52.tmpfs10g-libgraal-g1gc} ${bench-dacapo-hwloc} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-dacapo-libgraal-g1gc-linux-x52" } + ${x52.tmpfs10g-libgraal-g1gc} ${bench-scala-dacapo-hwloc} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-scala-dacapo-libgraal-g1gc-linux-x52" } + ${x52.tmpfs10g-libgraal-g1gc} ${bench-specjvm2008-Single} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-specjvm2008-libgraal-g1gc-Single-linux-x52" } + ${x52.tmpfs10g-libgraal-g1gc} ${bench-specjbb2015} ${oraclejdk8} { targets: [weekly, bench], name: "bench-compiler-specjbb2015-libgraal-g1gc-linux-x52" } - ${x52.default-libgraal} ${bench-renaissance-legacy-hwloc} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-renaissance-legacy-libgraal-linux-x52" } - ${x52.default-libgraal-g1gc} ${bench-renaissance-legacy-hwloc} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-renaissance-legacy-libgraal-g1gc-linux-x52" } - ${x52.default-libgraal} ${bench-spark-sql-perf} ${labsjdk8} { targets: [daily, bench], name: "bench-compiler-spark-sql-perf-libgraal-linux-x52" } + ${x52.default-libgraal} ${bench-renaissance-legacy-hwloc} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-renaissance-legacy-libgraal-linux-x52" } + ${x52.default-libgraal-g1gc} ${bench-renaissance-legacy-hwloc} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-renaissance-legacy-libgraal-g1gc-linux-x52" } + ${x52.default-libgraal} ${bench-spark-sql-perf} ${oraclejdk8} { targets: [daily, bench], name: "bench-compiler-spark-sql-perf-libgraal-linux-x52" } - ${x52.default-libgraal} ${bench-specjbb2005} ${labsjdk8} { targets: [weekly, bench], name: "bench-compiler-specjbb2005-libgraal-linux-x52" } - ${x52.default-libgraal-g1gc} ${bench-specjbb2005} ${labsjdk8} { targets: [weekly, bench], name: "bench-compiler-specjbb2005-libgraal-g1gc-linux-x52" } + ${x52.default-libgraal} ${bench-specjbb2005} ${oraclejdk8} { targets: [weekly, bench], name: "bench-compiler-specjbb2005-libgraal-linux-x52" } + ${x52.default-libgraal-g1gc} ${bench-specjbb2005} ${oraclejdk8} { targets: [weekly, bench], name: "bench-compiler-specjbb2005-libgraal-g1gc-linux-x52" } ] diff --git a/compiler/ci_includes/deploy.hocon b/compiler/ci_includes/deploy.hocon index ec1d5aaf105b..5af0c7e75707 100644 --- a/compiler/ci_includes/deploy.hocon +++ b/compiler/ci_includes/deploy.hocon @@ -25,6 +25,6 @@ deploy-sdk-truffle-compiler-tools-sulong : ${compilerCommon} { } builds += [ - ${deploy-sdk-truffle-compiler-tools-sulong} ${linux-amd64} ${linux-deploy} ${labsjdk8} {name: "postmerge-deploy-binaries-linux-amd64"} - ${deploy-sdk-truffle-compiler-tools-sulong} ${darwin-amd64} ${darwin-deploy} ${labsjdk8} {name: "postmerge-deploy-binaries-darwin-amd64"} + ${deploy-sdk-truffle-compiler-tools-sulong} ${linux-amd64} ${linux-deploy} ${oraclejdk8} {name: "postmerge-deploy-binaries-linux-amd64"} + ${deploy-sdk-truffle-compiler-tools-sulong} ${darwin-amd64} ${darwin-deploy} ${oraclejdk8} {name: "postmerge-deploy-binaries-darwin-amd64"} ] diff --git a/compiler/ci_includes/m7_eighth-c1.hocon b/compiler/ci_includes/m7_eighth-c1.hocon index 5e5806e84c55..f309c3a81ac9 100644 --- a/compiler/ci_includes/m7_eighth-c1.hocon +++ b/compiler/ci_includes/m7_eighth-c1.hocon @@ -1,6 +1,6 @@ # Eigth of a M7 processor with 4 cores, 8 threads each -m7_eighth.c1 : ${labsjdk8} { +m7_eighth.c1 : ${oraclejdk8} { targets: [weekly] capabilities: [solaris, m7_eighth] environment : { diff --git a/compiler/ci_includes/m7_eighth-c2.hocon b/compiler/ci_includes/m7_eighth-c2.hocon index 5503aae8e447..9e563583aa98 100644 --- a/compiler/ci_includes/m7_eighth-c2.hocon +++ b/compiler/ci_includes/m7_eighth-c2.hocon @@ -1,6 +1,6 @@ # Eigth of a M7 processor with 4 cores, 8 threads each -m7_eighth.c2 : ${labsjdk8} { +m7_eighth.c2 : ${oraclejdk8} { targets: [weekly] capabilities: [solaris, m7_eighth] environment : { diff --git a/compiler/ci_includes/x52-c1.hocon b/compiler/ci_includes/x52-c1.hocon index 56eae8607287..7febea735770 100644 --- a/compiler/ci_includes/x52-c1.hocon +++ b/compiler/ci_includes/x52-c1.hocon @@ -1,5 +1,5 @@ -x52.c1 : ${labsjdk8} { +x52.c1 : ${oraclejdk8} { capabilities: [linux, x52, no_frequency_scaling] environment : { JVM_CONFIG : "default" diff --git a/compiler/ci_includes/x52-c2-jfr.hocon b/compiler/ci_includes/x52-c2-jfr.hocon index 892b65aca638..e0a1589bed90 100644 --- a/compiler/ci_includes/x52-c2-jfr.hocon +++ b/compiler/ci_includes/x52-c2-jfr.hocon @@ -14,9 +14,9 @@ x52.c2-tmpfs10g-jfr : ${x52.c2-jfr} { } builds += [ - ${x52.c2-tmpfs10g-jfr} ${bench-dacapo-jfr} ${labsjdk8} { targets: [bench, weekly], name: "bench-compiler-dacapo-linux-x52-c2-jfr" } - ${x52.c2-tmpfs10g-jfr} ${bench-scala-dacapo-jfr} ${labsjdk8} { targets: [bench, weekly], name: "bench-compiler-scala-dacapo-linux-x52-c2-jfr" } - ${x52.c2-jfr} ${bench-specjvm2008-Single-jfr} ${labsjdk8} { targets: [bench, weekly], name: "bench-compiler-specjvm2008-Single-linux-x52-c2-jfr" } - ${x52.c2-jfr} ${bench-specjbb2015-jfr} ${labsjdk8} { targets: [bench, weekly], name: "bench-compiler-specjbb2015-linux-x52-c2-jfr" } - ${x52.c2-jfr} ${bench-renaissance-legacy-jfr} ${labsjdk8} { targets: [bench, weekly], name: "bench-compiler-renaissance-legacy-linux-x52-c2-jfr" } + ${x52.c2-tmpfs10g-jfr} ${bench-dacapo-jfr} ${oraclejdk8} { targets: [bench, weekly], name: "bench-compiler-dacapo-linux-x52-c2-jfr" } + ${x52.c2-tmpfs10g-jfr} ${bench-scala-dacapo-jfr} ${oraclejdk8} { targets: [bench, weekly], name: "bench-compiler-scala-dacapo-linux-x52-c2-jfr" } + ${x52.c2-jfr} ${bench-specjvm2008-Single-jfr} ${oraclejdk8} { targets: [bench, weekly], name: "bench-compiler-specjvm2008-Single-linux-x52-c2-jfr" } + ${x52.c2-jfr} ${bench-specjbb2015-jfr} ${oraclejdk8} { targets: [bench, weekly], name: "bench-compiler-specjbb2015-linux-x52-c2-jfr" } + ${x52.c2-jfr} ${bench-renaissance-legacy-jfr} ${oraclejdk8} { targets: [bench, weekly], name: "bench-compiler-renaissance-legacy-linux-x52-c2-jfr" } ] diff --git a/compiler/ci_includes/x52-c2.hocon b/compiler/ci_includes/x52-c2.hocon index 36cf4801b010..2c605f3e39e3 100644 --- a/compiler/ci_includes/x52-c2.hocon +++ b/compiler/ci_includes/x52-c2.hocon @@ -126,17 +126,17 @@ bench-specjbb2015-forks-c2 : ${bench-specjbb2015} ${weeklys-bench-notifications} } builds += [ - ${x52.c2-tmpfs10g} ${bench-dacapo-hwloc-forks-c2} ${labsjdk8} { name: "bench-forks-compiler-dacapo-linux-x52-c2" } - ${x52.c2-tmpfs10g} ${bench-scala-dacapo-hwloc-forks-c2} ${labsjdk8} { name: "bench-forks-compiler-scala-dacapo-linux-x52-c2" } - ${x52.c2} ${bench-specjvm2008-Single-forks-c2-batch0} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-c2-batch0" } - ${x52.c2} ${bench-specjvm2008-Single-forks-c2-batch1} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-c2-batch1" } - ${x52.c2} ${bench-specjvm2008-Single-forks-c2-batch2} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-c2-batch2" } - ${x52.c2} ${bench-specjvm2008-Single-forks-c2-batch3} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-c2-batch3" } - ${x52.c2} ${bench-specjvm2008-Single-forks-c2-batch4} ${labsjdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-c2-batch4" } - ${x52.c2-tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-c2-batch0} ${labsjdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-c2-batch0" } - ${x52.c2-tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-c2-batch1} ${labsjdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-c2-batch1" } - ${x52.c2-tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-c2-batch2} ${labsjdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-c2-batch2" } - ${x52.c2-tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-c2-batch3} ${labsjdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-c2-batch3" } - ${x52.c2} ${bench-specjbb2005-forks-c2} ${labsjdk8} { name: "bench-forks-compiler-specjbb2005-linux-x52-c2" } - ${x52.c2} ${bench-specjbb2015-forks-c2} ${labsjdk8} { name: "bench-forks-compiler-specjbb2015-linux-x52-c2" } + ${x52.c2-tmpfs10g} ${bench-dacapo-hwloc-forks-c2} ${oraclejdk8} { name: "bench-forks-compiler-dacapo-linux-x52-c2" } + ${x52.c2-tmpfs10g} ${bench-scala-dacapo-hwloc-forks-c2} ${oraclejdk8} { name: "bench-forks-compiler-scala-dacapo-linux-x52-c2" } + ${x52.c2} ${bench-specjvm2008-Single-forks-c2-batch0} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-c2-batch0" } + ${x52.c2} ${bench-specjvm2008-Single-forks-c2-batch1} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-c2-batch1" } + ${x52.c2} ${bench-specjvm2008-Single-forks-c2-batch2} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-c2-batch2" } + ${x52.c2} ${bench-specjvm2008-Single-forks-c2-batch3} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-c2-batch3" } + ${x52.c2} ${bench-specjvm2008-Single-forks-c2-batch4} ${oraclejdk8} { name: "bench-forks-compiler-specjvm2008-Single-linux-x52-c2-batch4" } + ${x52.c2-tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-c2-batch0} ${oraclejdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-c2-batch0" } + ${x52.c2-tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-c2-batch1} ${oraclejdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-c2-batch1" } + ${x52.c2-tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-c2-batch2} ${oraclejdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-c2-batch2" } + ${x52.c2-tmpfs10g} ${bench-renaissance-legacy-hwloc-forks-c2-batch3} ${oraclejdk8} { name: "bench-forks-compiler-renaissance-legacy-linux-x52-c2-batch3" } + ${x52.c2} ${bench-specjbb2005-forks-c2} ${oraclejdk8} { name: "bench-forks-compiler-specjbb2005-linux-x52-c2" } + ${x52.c2} ${bench-specjbb2015-forks-c2} ${oraclejdk8} { name: "bench-forks-compiler-specjbb2015-linux-x52-c2" } ] diff --git a/compiler/docs/Debugging.md b/compiler/docs/Debugging.md index aadc13da03f6..14521be9883f 100644 --- a/compiler/docs/Debugging.md +++ b/compiler/docs/Debugging.md @@ -1,15 +1,15 @@ -This pages covers the various mechanisms currently available for debugging Graal. +This pages covers the various mechanisms currently available for debugging the GraalVM compiler. ## IDE Support -All the parts of Graal written in Java can be debugged with a standard Java debugger. +All the parts of the GraalVM compiler (henceforth just "compiler") written in Java can be debugged with a standard Java debugger. While debugging with Eclipse is described here, it should not be too hard to adapt these instructions for another debugger. The `mx eclipseinit` command not only creates Eclipse project configurations but also creates an Eclipse launch configuration (in `mx.compiler/eclipse-launches/compiler-attach-localhost-8000.launch`) that can be used to debug all -Graal code running in the VM. This launch configuration requires you to start the VM with the `-d` +compiler code running in the VM. This launch configuration requires you to start the VM with the `-d` global option which puts the VM into a state waiting for a remote debugger to attach to port `8000`: ``` @@ -34,7 +34,7 @@ At this point you can set breakpoints and perform all other normal Java debuggin ## Logging -In addition to IDE debugging, Graal includes support for *printf* style debugging. +In addition to IDE debugging, there is support for *printf* style debugging. The simplest is to place temporary usages of `System.out` where ever you need them. For more permanent logging statements, use the `log(...)` methods in @@ -66,16 +66,16 @@ taken when such objects can be exposed to multiple threads. There are assertion guarding against use in a thread different from the one in which it was instantiated. -## JVMCI and Graal specific options +## JVMCI and compiler specific options -JVMCI and Graal options are specified by the `jvmci.*` and `graal.*` system properties +JVMCI and GraalVM compiler options are specified by the `jvmci.*` and `graal.*` system properties respectively. These must be specified on the JVM command line. Modifications to these properties by -application code are not seen by JVMCI and Graal. A listing of all supported properties can be +application code are not seen by JVMCI and the compiler. A listing of all supported properties can be obtained with `-XX:+JVMCIPrintProperties`. ## Metrics -Graal supports metrics in the form of counters, timers and memory trackers. +The compiler supports metrics in the form of counters, timers and memory trackers. Each metric has a unique name. Metrics are collected per-compilation. At shutdown, they are aggregated across all compilations and reported to the console. This ouput can be redirected to a file via the `-Dgraal.AggregatedMetricsFile` option. @@ -210,7 +210,7 @@ since metric registration is lazy. For example, to see all the metrics availabl ## Dumping -In addition to logging, Graal provides support for generating (or dumping) more detailed +In addition to logging, there is support for generating (or dumping) more detailed visualizations of certain compiler data structures. Currently, there is support for dumping: * HIR graphs (i.e., instances of @@ -248,15 +248,15 @@ To see the compiler data structures used while compiling `Node.updateUsages`, us > mx vm -XX:+UseJVMCICompiler -XX:+BootstrapJVMCI -XX:-TieredCompilation -Dgraal.Dump= -Dgraal.MethodFilter=Node.updateUsages -version Bootstrapping JVMCI....Dumping debug output in /Users/dsimon/graal/graal/compiler/dumps/1497910458736 ................................................ in 38177 ms (compiled 5206 methods) -java version "1.8.0_121" -Java(TM) SE Runtime Environment (build 1.8.0_121-b13) -Java HotSpot(TM) 64-Bit Server VM (build 25.71-b01-internal-jvmci-0.26, mixed mode) +java version "1.8.0_212" +Java(TM) SE Runtime Environment (build 1.8.0_212-b31) +Java HotSpot(TM) 64-Bit Server VM (build 25.212-b31-jvmci-20-b01, mixed mode) > find dumps/1497910458736 -type f dumps/1497910458736/HotSpotCompilation-539[org.graalvm.compiler.graph.Node.updateUsages(Node, Node)].bgv dumps/1497910458736/HotSpotCompilation-539[org.graalvm.compiler.graph.Node.updateUsages(Node, Node)].cfg ``` -As you become familiar with the scope names used in Graal, you can refine the `-Dgraal.Dump` option +As you become familiar with the scope names used in the compiler, you can refine the `-Dgraal.Dump` option to limit the amount of dump output generated. For example, the `"CodeGen"` and `"CodeInstall"` scopes are active during code generation and installation respectively. To see the machine code (in the C1Visualizer) produced during these scopes: diff --git a/compiler/docs/Examples.md b/compiler/docs/Examples.md deleted file mode 100644 index 40bfb0f8db16..000000000000 --- a/compiler/docs/Examples.md +++ /dev/null @@ -1,22 +0,0 @@ -This documents describes options available in Graal that are commonly helpful. -It complements the detailed information in [Debugging](Debugging.md) which should be read first. - -## Graal scenarios - -Add `-Dgraal.Timers=CompilationTime` to measure the time spent in compilation. - -Add `-XX:JVMCIThreads=1` to have a single JVMCI compiler thread. This simplifies -debugging in an IDE by ensuring a breakpoint in Graal code is hit by a single thread. - -Use `-XX:+BootstrapJVMCI` to stress-test the compiler without having to specify an application. -To force *all* bootstrap compilations to go through Graal, add `-XX:-TieredCompilation` as well. - -Use `-Dgraal.Dump= -Dgraal.MethodFilter=MyClass.someMethod` to see the compiler graphs in -IGV when compiling `MyClass.someMethod`. If you want the graphs sent immediately to IGV, ensure it is running (`mx igv`). -To have the graphs written to disk instead (e.g., to share), add `-Dgraal.PrintIdealGraphFile=true`. -To disable the dumping of LIR, register allocation and code generation info to `*.cfg` files readable by the C1Visualizer, -add `-Dgraal.PrintBackendCFG=false`. - -## GraalTruffle scenarios - -Add `-Dgraaldebug.timer.PartialEvaluationTime=true` to measure the time spent in partial evaluation. diff --git a/compiler/docs/IDEs.md b/compiler/docs/IDEs.md index 720421c8e9be..430f1cebd19d 100644 --- a/compiler/docs/IDEs.md +++ b/compiler/docs/IDEs.md @@ -37,9 +37,9 @@ To make IntelliJ work the same way as Eclipse with respect to Problems View and ### Eclipse -This section describes how to set up Eclipse for Graal development. For convenience, `$GRAAL` denotes your local Graal repository. +This section describes how to set up Eclipse for development. For convenience, `$GRAAL` denotes your local repository. -Eclipse can be downloaded [here](http://download.eclipse.org/eclipse/downloads/). The currently recommended version for Graal development is 4.7.3a ("Oxygen"). +Eclipse can be downloaded [here](http://download.eclipse.org/eclipse/downloads/). The currently recommended version for development is 4.7.3a ("Oxygen"). Once you have installed Eclipse, if you have multiple Java versions on your computer, you should edit [eclipse.ini](http://wiki.eclipse.org/Eclipse.ini) to [specify the JVM](http://wiki.eclipse.org/Eclipse.ini#Specifying_the_JVM) that Eclipse will be run with. It must be run with a JDK 9 or later VM. For example: ``` @@ -47,7 +47,7 @@ Once you have installed Eclipse, if you have multiple Java versions on your comp /usr/lib/jvm/jdk-9.0.4/bin/java ``` -When first launching Eclipse, you should create a new workspace for Graal development. Select the parent of `$GRAAL` as the workspace as you will also be importing projects from the suites that Graal depends on. +When first launching Eclipse, you should create a new workspace for development. Select the parent of `$GRAAL` as the workspace as you will also be importing projects from the suites that the compiler depends on. The configurations created by the `mx eclipseinit` command binds projects to Execution Environments or JREs corresponding to the Java compliance level of the projects. You need to configure these Execution Environments and JREs as follows: @@ -65,8 +65,8 @@ Run `mx eclipseinit` to create the Eclipse project configurations for all the Ja 4. Under **Projects** select all the projects. 5. Click **Finish** to complete the import. -Any time Eclipse updates a class file needed by the Graal runtime, the updated classes are automatically deployed to the right place so that the next execution of the VM will see the changes. +Any time Eclipse updates a class file used by the compiler, the updated classes are automatically deployed to the right place so that the next execution of the VM will see the changes. -> After updating your Graal sources and re-running `mx eclipseint`, a new Eclipse projects made be created and old ones removed. This usually results in an Eclipse error message indicating that a project is missing another required Java project. To handle this, you simply need repeat the steps above for importing projects. +> After updating your sources and re-running `mx eclipseint`, new Eclipse projects made be created and old ones removed. This usually results in an Eclipse error message indicating that a project is missing another required Java project. To handle this, you simply need repeat the steps above for importing projects. -In order to debug Graal with Eclipse, you should launch Graal using the `-d` global option as described [Debugging](Debugging.md). +In order to debug with Eclipse, you should launch using the `-d` global option as described in [Debugging](Debugging.md). diff --git a/compiler/mx.compiler/mx_compiler.py b/compiler/mx.compiler/mx_compiler.py index df75c8a8efe0..2dd6140e8e39 100644 --- a/compiler/mx.compiler/mx_compiler.py +++ b/compiler/mx.compiler/mx_compiler.py @@ -315,7 +315,7 @@ def verify_jvmci_ci_versions(args): If the ci.hocon files use a -dev version, it allows the travis ones to use the previous version. For example, if ci.hocon uses jvmci-0.24-dev, travis may use either jvmci-0.24-dev or jvmci-0.23 """ - version_pattern = re.compile(r'^(?!\s*#).*jvmci-(?P\d*\.\d*)(?P-dev)?') + version_pattern = re.compile(r'^(?!\s*#).*jvmci-(?P\d*)(?:\.|-b)(?P\d*)(?P-dev)?') def _grep_version(files, msg): version = None @@ -326,7 +326,9 @@ def _grep_version(files, msg): for line in open(filename): m = version_pattern.search(line) if m: - new_version = m.group('version') + new_major = m.group('major') + new_minor = m.group('minor') + new_version = (new_major, new_minor) new_dev = bool(m.group('dev')) if (version and version != new_version) or (dev is not None and dev != new_dev): mx.abort( @@ -353,13 +355,13 @@ def _grep_version(files, msg): if hocon_version != travis_version or hocon_dev != travis_dev: versions_ok = False if not travis_dev and hocon_dev: - next_travis_version = [int(a) for a in travis_version.split('.')] - next_travis_version[-1] += 1 - next_travis_version_str = '.'.join((str(a) for a in next_travis_version)) - if next_travis_version_str == hocon_version: + travis_major, travis_minor = travis_version # pylint: disable=unpacking-non-sequence + next_travis_minor = str(int(travis_minor) + 1) + next_travis_version = (travis_major, next_travis_minor) + if next_travis_version == hocon_version: versions_ok = True if not versions_ok: - mx.abort("Travis and ci.hocon JVMCI versions do not match: {0} vs. {1}".format(travis_version + ('-dev' if travis_dev else ''), hocon_version + ('-dev' if hocon_dev else ''))) + mx.abort("Travis and ci.hocon JVMCI versions do not match: {0} vs. {1}".format(str(travis_version) + ('-dev' if travis_dev else ''), str(hocon_version) + ('-dev' if hocon_dev else ''))) mx.log('JVMCI versions are ok!') @@ -592,7 +594,7 @@ def compiler_gate_benchmark_runner(tasks, extraVMarguments=None, prefix=''): # ensure benchmark counters still work if mx.get_arch() != 'aarch64': # GR-8364 Exclude benchmark counters on AArch64 with Task(prefix + 'DaCapo_pmd:BenchmarkCounters', tasks, tags=GraalTags.test) as t: - if t: _gate_dacapo('pmd', 1, _remove_empty_entries(extraVMarguments) + ['-XX:+UseJVMCICompiler', '-Dgraal.LIRProfileMoves=true', '-Dgraal.GenericDynamicCounters=true', '-XX:JVMCICounterSize=10']) + if t: _gate_dacapo('pmd', 1, _remove_empty_entries(extraVMarguments) + ['-XX:+UseJVMCICompiler', '-Dgraal.LIRProfileMoves=true', '-Dgraal.GenericDynamicCounters=true', '-Dgraal.TimedDynamicCounters=1000', '-XX:JVMCICounterSize=10']) # ensure -Xcomp still works with Task(prefix + 'XCompMode:product', tasks, tags=GraalTags.test) as t: @@ -610,6 +612,12 @@ def compiler_gate_benchmark_runner(tasks, extraVMarguments=None, prefix=''): if t: _gate_dacapo('pmd', 4, _remove_empty_entries(extraVMarguments) + ['-XX:+UseJVMCICompiler', '-Xmx256M', '-XX:+UseConcMarkSweepGC', '-XX:+CMSIncrementalMode'], threads=4, force_serial_gc=False, set_start_heap_size=False) + if prefix != '': + # ensure G1 still works with libgraal + with Task(prefix + 'DaCapo_pmd:G1', tasks, tags=cms) as t: + if t: _gate_dacapo('pmd', 4, _remove_empty_entries(extraVMarguments) + ['-XX:+UseJVMCICompiler', '-Xmx256M', '-XX:+UseG1GC'], threads=4, force_serial_gc=False, set_start_heap_size=False) + + graal_unit_test_runs = [ UnitTestRun('UnitTests', [], tags=GraalTags.test + GraalTags.coverage), @@ -1162,7 +1170,7 @@ def makegraaljdk(args): mx_sdk.register_graalvm_component(mx_sdk.GraalVmJvmciComponent( suite=_suite, - name='Graal compiler', + name='GraalVM compiler', short_name='cmp', dir_name='graal', license_files=[], diff --git a/compiler/mx.compiler/mx_graal_tools.py b/compiler/mx.compiler/mx_graal_tools.py index 56a8c12c6413..c4416a3c96fb 100644 --- a/compiler/mx.compiler/mx_graal_tools.py +++ b/compiler/mx.compiler/mx_graal_tools.py @@ -70,8 +70,8 @@ def _igvJdkVersionCheck(version): def igv(args): """(obsolete) informs about IGV""" mx.warn( - """IGV (idealgraphvisualizer) is distributed as part of GraalVM EE, available from - https://www.oracle.com/technetwork/oracle-labs/program-languages/downloads/index.html + """IGV (idealgraphvisualizer) is available from + https://www.oracle.com/technetwork/graalvm/downloads/index.html Please download the distribution and run bin/idealgraphvisualizer from the GraalVM EE installation. diff --git a/compiler/mx.compiler/mx_updategraalinopenjdk.py b/compiler/mx.compiler/mx_updategraalinopenjdk.py index bcecffcca5a7..e311999f3250 100644 --- a/compiler/mx.compiler/mx_updategraalinopenjdk.py +++ b/compiler/mx.compiler/mx_updategraalinopenjdk.py @@ -61,6 +61,9 @@ def _find_version_base_project(versioned_project): mx.abort('Multi-release jar versioned project {} must extend package(s) from another project'.format(versioned_project)) return base_project +def _is_git_repo(jdkrepo): + git_dir = join(jdkrepo, '.git') + return True if exists(git_dir) else False SuiteJDKInfo = namedtuple('SuiteJDKInfo', 'name includes excludes') GraalJDKModule = namedtuple('GraalJDKModule', 'name suites') @@ -113,6 +116,7 @@ def updategraalinopenjdk(args): blacklist = ['"Classpath" exception'] jdkrepo = args.jdkrepo + git_repo = _is_git_repo(jdkrepo) for m in graal_modules: m_src_dir = join(jdkrepo, 'src', m.name) @@ -127,9 +131,12 @@ def run_output(args, cwd=None): for m in graal_modules: m_src_dir = join('src', m.name) mx.log('Checking ' + m_src_dir) - out = run_output(['hg', 'status', m_src_dir], cwd=jdkrepo) + if git_repo: + out = run_output(['git', 'status', '-s', m_src_dir], cwd=jdkrepo) + else: + out = run_output(['hg', 'status', m_src_dir], cwd=jdkrepo) if out: - mx.abort(jdkrepo + ' is not "hg clean":' + '\n' + out[:min(200, len(out))] + '...') + mx.abort(jdkrepo + ' is not "clean":' + '\n' + out[:min(200, len(out))] + '...') for dirpath, _, filenames in os.walk(join(jdkrepo, 'make')): for filename in filenames: @@ -255,7 +262,7 @@ def run_output(args, cwd=None): with open(dst_file, 'w') as fp: fp.write(contents) - def replace_lines(filename, begin_lines, end_line, replace_lines, old_line_check, preserve_indent=False): + def replace_lines(filename, begin_lines, end_line, replace_lines, old_line_check, preserve_indent=False, append_mode=False): mx.log('Updating ' + filename + '...') old_lines = [] new_lines = [] @@ -280,8 +287,9 @@ def replace_lines(filename, begin_lines, end_line, replace_lines, old_line_check lstripped_line = line.lstrip() indent = len(line) - len(lstripped_line) - for replace in replace_lines: - new_lines.append(' ' * indent + replace) + if not append_mode: + for replace in replace_lines: + new_lines.append(' ' * indent + replace) for line in lines: stripped_line = line.strip() @@ -291,6 +299,12 @@ def replace_lines(filename, begin_lines, end_line, replace_lines, old_line_check new_lines.append(line) else: old_line_check(line) + if append_mode: + new_lines.append(line) + if append_mode and not line_in_def: + # reach end line and append new lines + for replace in replace_lines: + new_lines.append(replace) else: new_lines.append(line) with open(filename, 'w') as fp: @@ -313,6 +327,20 @@ def single_column_with_continuation(line): old_line_check = single_column_with_continuation replace_lines(CompileJavaModules_gmk, begin_lines, end_line, new_lines, old_line_check, preserve_indent=True) + if args.version == 11: + # add aot exclude + out = run_output(['grep', 'jdk.aot_EXCLUDES', CompileJavaModules_gmk], cwd=jdkrepo) + if out: + # replace existing exclude setting + begin_lines = ['jdk.aot_EXCLUDES += \\'] + end_line = '#' + new_lines = ['jdk.tools.jaotc.test \\\n'] + replace_lines(CompileJavaModules_gmk, begin_lines, end_line, new_lines, old_line_check, preserve_indent=True) + else: + # append exclude setting after jdk.internal.vm.compiler_EXCLUDES + new_lines = ['\n', 'jdk.aot_EXCLUDES += \\\n', ' jdk.tools.jaotc.test \\\n', ' #\n', '\n'] # indent is inlined + replace_lines(CompileJavaModules_gmk, begin_lines, end_line, new_lines, old_line_check, preserve_indent=True, append_mode=True) + # Update 'SRC' in the 'Compile graalunit tests' section of make/test/JtregGraalUnit.gmk # to include all test packages. JtregGraalUnit_gmk = join(jdkrepo, 'make', 'test', 'JtregGraalUnit.gmk') # pylint: disable=invalid-name @@ -323,26 +351,30 @@ def single_column_with_continuation(line): jdk_internal_vm_compiler_test_SRC.discard('org.graalvm.micro.benchmarks') for pkg in sorted(jdk_internal_vm_compiler_test_SRC): new_lines.append('$(SRC_DIR)/' + pkg + '/src \\\n') - begin_lines = ['### Compile graalunit tests', 'SRC := \\'] + if args.version == 11: + begin_lines = ['### Compile and build graalunit tests', 'SRC := \\'] + else: + begin_lines = ['### Compile graalunit tests', 'SRC := \\'] end_line = ', \\' old_line_check = single_column_with_continuation replace_lines(JtregGraalUnit_gmk, begin_lines, end_line, new_lines, old_line_check, preserve_indent=True) - mx.log('Adding new files to HG...') overwritten = '' - for m in graal_modules: - m_src_dir = join('src', m.name) - out = run_output(['hg', 'log', '-r', 'last(keyword("Update Graal"))', '--template', '{rev}', m_src_dir], cwd=jdkrepo) - last_graal_update = out.strip() - if last_graal_update: - overwritten += run_output(['hg', 'diff', '-r', last_graal_update, '-r', 'tip', m_src_dir], cwd=jdkrepo) - mx.run(['hg', 'add', m_src_dir], cwd=jdkrepo) - mx.log('Removing old files from HG...') - for m in graal_modules: - m_src_dir = join('src', m.name) - out = run_output(['hg', 'status', '-dn', m_src_dir], cwd=jdkrepo) - if out: - mx.run(['hg', 'rm'] + out.split(), cwd=jdkrepo) + if not git_repo: + mx.log('Adding new files to HG...') + for m in graal_modules: + m_src_dir = join('src', m.name) + out = run_output(['hg', 'log', '-r', 'last(keyword("Update Graal"))', '--template', '{rev}', m_src_dir], cwd=jdkrepo) + last_graal_update = out.strip() + if last_graal_update: + overwritten += run_output(['hg', 'diff', '-r', last_graal_update, '-r', 'tip', m_src_dir], cwd=jdkrepo) + mx.run(['hg', 'add', m_src_dir], cwd=jdkrepo) + mx.log('Removing old files from HG...') + for m in graal_modules: + m_src_dir = join('src', m.name) + out = run_output(['hg', 'status', '-dn', m_src_dir], cwd=jdkrepo) + if out: + mx.run(['hg', 'rm'] + out.split(), cwd=jdkrepo) out = run_output(['git', 'tag', '-l', 'JDK-*'], cwd=mx_compiler._suite.vc_dir) last_jdk_tag = sorted(out.split(), reverse=True)[0] diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index 75d7f9c4217e..e0b83fb09804 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -4,7 +4,7 @@ "sourceinprojectwhitelist" : [], "groupId" : "org.graalvm.compiler", - "version" : "1.0.0-rc18", + "version" : "20.0.0-beta.01", "release" : False, "url" : "http://www.graalvm.org/", "developer" : { @@ -423,6 +423,7 @@ "subDir" : "src", "sourceDirs" : ["src"], "dependencies" : [ + "org.graalvm.libgraal", "sdk:GRAAL_SDK", "JVMCI_HOTSPOT", ], @@ -2268,6 +2269,7 @@ }, "GRAAL_PROCESSOR_COMMON" : { + "subDir": "src", "dependencies" : ["org.graalvm.compiler.processor"], "maven": False, }, @@ -2398,7 +2400,7 @@ "JVMCI_HOTSPOT", ], "allowsJavadocWarnings": True, - "description": "The Graal compiler and the Graal-truffle optimizer.", + "description": "The GraalVM compiler and the Graal-truffle optimizer.", "maven" : { "artifactId" : "compiler", }, diff --git a/compiler/src/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ProbabilityDirectiveTest.java b/compiler/src/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ProbabilityDirectiveTest.java index 581898dfd77e..fad658b05395 100644 --- a/compiler/src/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ProbabilityDirectiveTest.java +++ b/compiler/src/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ProbabilityDirectiveTest.java @@ -24,6 +24,8 @@ */ package org.graalvm.compiler.api.directives.test; +import jdk.vm.ci.meta.ResolvedJavaMethod; + import org.graalvm.compiler.api.directives.GraalDirectives; import org.graalvm.compiler.core.test.GraalCompilerTest; import org.graalvm.compiler.graph.iterators.NodeIterable; @@ -37,6 +39,15 @@ public class ProbabilityDirectiveTest extends GraalCompilerTest { + /** + * Called before a test is compiled. + */ + @Override + protected void before(ResolvedJavaMethod method) { + // don't let -Xcomp pollute profile + method.reprofile(); + } + public static int branchProbabilitySnippet(int arg) { if (GraalDirectives.injectBranchProbability(0.125, arg > 0)) { GraalDirectives.controlFlowAnchor(); // prevent removal of the if diff --git a/compiler/src/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64AsmOptions.java b/compiler/src/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64AsmOptions.java index ff7492f70fac..519e40d31850 100644 --- a/compiler/src/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64AsmOptions.java +++ b/compiler/src/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64AsmOptions.java @@ -27,6 +27,7 @@ public class AMD64AsmOptions { public static final boolean UseNormalNop = false; public static final boolean UseAddressNop = true; + public static final boolean UseIntelNops = true; public static final boolean UseIncDec = true; public static final boolean UseXmmLoadAndClearUpper = true; public static final boolean UseXmmRegToRegMoveAll = true; diff --git a/compiler/src/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java b/compiler/src/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java index 3a24900afddb..3307dff4b756 100644 --- a/compiler/src/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java +++ b/compiler/src/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java @@ -29,6 +29,7 @@ import static jdk.vm.ci.amd64.AMD64.XMM; import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD; import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseAddressNop; +import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseIntelNops; import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseNormalNop; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.AND; @@ -2295,125 +2296,10 @@ public void nop(int count) { } if (UseAddressNop) { - // - // Using multi-bytes nops "0x0F 0x1F [Address]" for AMD. - // 1: 0x90 - // 2: 0x66 0x90 - // 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding) - // 4: 0x0F 0x1F 0x40 0x00 - // 5: 0x0F 0x1F 0x44 0x00 0x00 - // 6: 0x66 0x0F 0x1F 0x44 0x00 0x00 - // 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 - // 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - - // The rest coding is AMD specific - use consecutive Address nops - - // 12: 0x66 0x0F 0x1F 0x44 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00 - // 13: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00 - // 14: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 - // 15: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 - // 16: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 - // Size prefixes (0x66) are added for larger sizes - - while (i >= 22) { - i -= 11; - emitByte(0x66); // size prefix - emitByte(0x66); // size prefix - emitByte(0x66); // size prefix - addrNop8(); - } - // Generate first nop for size between 21-12 - switch (i) { - case 21: - i -= 11; - emitByte(0x66); // size prefix - emitByte(0x66); // size prefix - emitByte(0x66); // size prefix - addrNop8(); - break; - case 20: - case 19: - i -= 10; - emitByte(0x66); // size prefix - emitByte(0x66); // size prefix - addrNop8(); - break; - case 18: - case 17: - i -= 9; - emitByte(0x66); // size prefix - addrNop8(); - break; - case 16: - case 15: - i -= 8; - addrNop8(); - break; - case 14: - case 13: - i -= 7; - addrNop7(); - break; - case 12: - i -= 6; - emitByte(0x66); // size prefix - addrNop5(); - break; - default: - assert i < 12; - } - - // Generate second nop for size between 11-1 - switch (i) { - case 11: - emitByte(0x66); // size prefix - emitByte(0x66); // size prefix - emitByte(0x66); // size prefix - addrNop8(); - break; - case 10: - emitByte(0x66); // size prefix - emitByte(0x66); // size prefix - addrNop8(); - break; - case 9: - emitByte(0x66); // size prefix - addrNop8(); - break; - case 8: - addrNop8(); - break; - case 7: - addrNop7(); - break; - case 6: - emitByte(0x66); // size prefix - addrNop5(); - break; - case 5: - addrNop5(); - break; - case 4: - addrNop4(); - break; - case 3: - // Don't use "0x0F 0x1F 0x00" - need patching safe padding - emitByte(0x66); // size prefix - emitByte(0x66); // size prefix - emitByte(0x90); // nop - break; - case 2: - emitByte(0x66); // size prefix - emitByte(0x90); // nop - break; - case 1: - emitByte(0x90); // nop - break; - default: - assert i == 0; + if (UseIntelNops) { + intelNops(i); + } else { + amdNops(i); } return; } @@ -2484,6 +2370,222 @@ public void nop(int count) { } } + private void amdNops(int count) { + int i = count; + // + // Using multi-bytes nops "0x0F 0x1F [Address]" for AMD. + // 1: 0x90 + // 2: 0x66 0x90 + // 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding) + // 4: 0x0F 0x1F 0x40 0x00 + // 5: 0x0F 0x1F 0x44 0x00 0x00 + // 6: 0x66 0x0F 0x1F 0x44 0x00 0x00 + // 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 + // 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 + // 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 + // 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 + // 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 + + // The rest coding is AMD specific - use consecutive Address nops + + // 12: 0x66 0x0F 0x1F 0x44 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00 + // 13: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00 + // 14: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 + // 15: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 + // 16: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 + // Size prefixes (0x66) are added for larger sizes + + while (i >= 22) { + i -= 11; + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + addrNop8(); + } + // Generate first nop for size between 21-12 + switch (i) { + case 21: + i -= 11; + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + addrNop8(); + break; + case 20: + case 19: + i -= 10; + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + addrNop8(); + break; + case 18: + case 17: + i -= 9; + emitByte(0x66); // size prefix + addrNop8(); + break; + case 16: + case 15: + i -= 8; + addrNop8(); + break; + case 14: + case 13: + i -= 7; + addrNop7(); + break; + case 12: + i -= 6; + emitByte(0x66); // size prefix + addrNop5(); + break; + default: + assert i < 12; + } + + // Generate second nop for size between 11-1 + switch (i) { + case 11: + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + addrNop8(); + break; + case 10: + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + addrNop8(); + break; + case 9: + emitByte(0x66); // size prefix + addrNop8(); + break; + case 8: + addrNop8(); + break; + case 7: + addrNop7(); + break; + case 6: + emitByte(0x66); // size prefix + addrNop5(); + break; + case 5: + addrNop5(); + break; + case 4: + addrNop4(); + break; + case 3: + // Don't use "0x0F 0x1F 0x00" - need patching safe padding + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + emitByte(0x90); // nop + break; + case 2: + emitByte(0x66); // size prefix + emitByte(0x90); // nop + break; + case 1: + emitByte(0x90); // nop + break; + default: + assert i == 0; + } + } + + @SuppressWarnings("fallthrough") + private void intelNops(int count) { + // + // Using multi-bytes nops "0x0F 0x1F [address]" for Intel + // 1: 0x90 + // 2: 0x66 0x90 + // 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding) + // 4: 0x0F 0x1F 0x40 0x00 + // 5: 0x0F 0x1F 0x44 0x00 0x00 + // 6: 0x66 0x0F 0x1F 0x44 0x00 0x00 + // 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 + // 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 + // 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 + // 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 + // 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 + + // The rest coding is Intel specific - don't use consecutive address nops + + // 12: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90 + // 13: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90 + // 14: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90 + // 15: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90 + + int i = count; + while (i >= 15) { + // For Intel don't generate consecutive addess nops (mix with regular nops) + i -= 15; + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + addrNop8(); + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + emitByte(0x90); + // nop + } + switch (i) { + case 14: + emitByte(0x66); // size prefix + // fall through + case 13: + emitByte(0x66); // size prefix + // fall through + case 12: + addrNop8(); + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + emitByte(0x66); // size prefix + emitByte(0x90); + // nop + break; + case 11: + emitByte(0x66); // size prefix + // fall through + case 10: + emitByte(0x66); // size prefix + // fall through + case 9: + emitByte(0x66); // size prefix + // fall through + case 8: + addrNop8(); + break; + case 7: + addrNop7(); + break; + case 6: + emitByte(0x66); // size prefix + // fall through + case 5: + addrNop5(); + break; + case 4: + addrNop4(); + break; + case 3: + // Don't use "0x0F 0x1F 0x00" - need patching safe padding + emitByte(0x66); // size prefix + // fall through + case 2: + emitByte(0x66); // size prefix + // fall through + case 1: + emitByte(0x90); + // nop + break; + default: + assert i == 0; + } + } + public final void orl(Register dst, Register src) { OR.rmOp.emit(this, DWORD, dst, src); } diff --git a/compiler/src/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Assembler.java b/compiler/src/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Assembler.java index e01c6e8e0edf..1a9f9c4279ff 100644 --- a/compiler/src/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Assembler.java +++ b/compiler/src/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Assembler.java @@ -30,6 +30,8 @@ import java.util.Map; import java.util.function.Consumer; +import org.graalvm.compiler.debug.GraalError; + import jdk.vm.ci.code.Register; import jdk.vm.ci.code.StackSlot; import jdk.vm.ci.code.TargetDescription; @@ -164,7 +166,7 @@ private void checkAndClearLabelsWithPatches() throws InternalError { Label label = labelsWithPatches; while (label != null) { if (label.patchPositions != null) { - throw new InternalError("Label used by instructions at following offsets has not been bound: " + label.patchPositions); + throw new GraalError("Label used by instructions at following offsets has not been bound: %s", label.patchPositions); } Label next = label.nextWithPatches; label.nextWithPatches = null; diff --git a/compiler/src/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Buffer.java b/compiler/src/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Buffer.java index 127040313e39..b7722906cafc 100644 --- a/compiler/src/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Buffer.java +++ b/compiler/src/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Buffer.java @@ -24,12 +24,13 @@ */ package org.graalvm.compiler.asm; -import org.graalvm.compiler.core.common.NumUtil; - import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; +import org.graalvm.compiler.core.common.NumUtil; +import org.graalvm.compiler.serviceprovider.BufferUtil; + /** * Code buffer management for the assembler. */ @@ -48,7 +49,7 @@ public int position() { public void setPosition(int position) { assert position >= 0 && position <= data.limit(); - data.position(position); + BufferUtil.asBaseBuffer(data).position(position); } /** @@ -93,7 +94,7 @@ protected void ensureSize(int length) { byte[] newBuf = Arrays.copyOf(data.array(), length * 4); ByteBuffer newData = ByteBuffer.wrap(newBuf); newData.order(data.order()); - newData.position(data.position()); + BufferUtil.asBaseBuffer(newData).position(data.position()); data = newData; } } @@ -170,6 +171,6 @@ public int getInt(int pos) { } public void reset() { - data.clear(); + BufferUtil.asBaseBuffer(data).clear(); } } diff --git a/compiler/src/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Label.java b/compiler/src/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Label.java index 7c333c3719c2..717320195543 100644 --- a/compiler/src/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Label.java +++ b/compiler/src/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Label.java @@ -26,6 +26,8 @@ import java.util.ArrayList; +import org.graalvm.compiler.debug.GraalError; + /** * This class represents a label within assembly code. */ @@ -71,7 +73,9 @@ public int getBlockId() { * {@link #addPatchAt(int, Assembler)}. */ protected void bind(int pos, Assembler asm) { - assert pos >= 0; + if (pos < 0) { + throw new GraalError("Cannot bind label to negative position %d", pos); + } this.position = pos; if (patchPositions != null) { for (int i = 0; i < patchPositions.size(); ++i) { diff --git a/compiler/src/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DataSection.java b/compiler/src/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DataSection.java index 3e41177f2fee..f687e1761d16 100644 --- a/compiler/src/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DataSection.java +++ b/compiler/src/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DataSection.java @@ -33,6 +33,7 @@ import java.util.function.BiConsumer; import org.graalvm.compiler.code.DataSection.Data; +import org.graalvm.compiler.serviceprovider.BufferUtil; import jdk.vm.ci.code.site.DataSectionReference; import jdk.vm.ci.meta.SerializableConstant; @@ -376,11 +377,11 @@ public void buildDataSection(ByteBuffer buffer, Patches patch, BiConsumer= sectionSize; int start = buffer.position(); for (Data d : dataItems) { - buffer.position(start + d.ref.getOffset()); + BufferUtil.asBaseBuffer(buffer).position(start + d.ref.getOffset()); onEmit.accept(d.ref, d.getSize()); d.emit(buffer, patch); } - buffer.position(start + sectionSize); + BufferUtil.asBaseBuffer(buffer).position(start + sectionSize); } public Data findData(DataSectionReference ref) { diff --git a/compiler/src/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java b/compiler/src/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java index 85787be7f041..785c9a11e2d2 100644 --- a/compiler/src/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java +++ b/compiler/src/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java @@ -450,6 +450,13 @@ public Value emitUMulHigh(Value a, Value b) { } } + public Value emitBinaryMemory(VexRVMOp op, OperandSize size, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) { + assert (size.isXmmType() && supportAVX()); + Variable result = getLIRGen().newVariable(LIRKind.combine(a)); + getLIRGen().append(new AMD64VectorBinary.AVXBinaryMemoryOp(op, getRegisterSize(result), result, a, location, state)); + return result; + } + public Value emitBinaryMemory(AMD64RMOp op, OperandSize size, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) { Variable result = getLIRGen().newVariable(LIRKind.combine(a)); getLIRGen().append(new AMD64Binary.MemoryTwoOp(op, size, result, a, location, state)); @@ -1339,7 +1346,7 @@ public Value emitRound(Value value, RoundingMode mode) { return result; } - private boolean supportAVX() { + public boolean supportAVX() { TargetDescription target = getLIRGen().target(); return ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX); } diff --git a/compiler/src/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java b/compiler/src/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java index 4ba7792ecc53..0a6fe4b00c62 100644 --- a/compiler/src/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java +++ b/compiler/src/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java @@ -33,11 +33,18 @@ import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VADDSD; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VADDSS; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VMULSD; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VMULSS; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VSUBSD; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VSUBSS; import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD; import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.QWORD; import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SD; import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SS; +import org.graalvm.compiler.asm.amd64.AMD64Assembler; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp; @@ -463,12 +470,22 @@ private ComplexMatchResult binaryRead(AMD64RMOp op, OperandSize size, ValueNode getState(access)); } + private ComplexMatchResult binaryRead(AMD64Assembler.VexRVMOp op, OperandSize size, ValueNode value, LIRLowerableAccess access) { + assert size == SS || size == SD; + return builder -> getArithmeticLIRGenerator().emitBinaryMemory(op, size, getLIRGeneratorTool().asAllocatable(operand(value)), (AMD64AddressValue) operand(access.getAddress()), + getState(access)); + } + @MatchRule("(Add value Read=access)") @MatchRule("(Add value FloatingRead=access)") public ComplexMatchResult addMemory(ValueNode value, LIRLowerableAccess access) { OperandSize size = getMemorySize(access); if (size.isXmmType()) { - return binaryRead(SSEOp.ADD, size, value, access); + if (getArithmeticLIRGenerator().supportAVX()) { + return binaryRead(size == SS ? VADDSS : VADDSD, size, value, access); + } else { + return binaryRead(SSEOp.ADD, size, value, access); + } } else { return binaryRead(ADD.getRMOpcode(size), size, value, access); } @@ -479,7 +496,11 @@ public ComplexMatchResult addMemory(ValueNode value, LIRLowerableAccess access) public ComplexMatchResult subMemory(ValueNode value, LIRLowerableAccess access) { OperandSize size = getMemorySize(access); if (size.isXmmType()) { - return binaryRead(SSEOp.SUB, size, value, access); + if (getArithmeticLIRGenerator().supportAVX()) { + return binaryRead(size == SS ? VSUBSS : VSUBSD, size, value, access); + } else { + return binaryRead(SSEOp.SUB, size, value, access); + } } else { return binaryRead(SUB.getRMOpcode(size), size, value, access); } @@ -490,7 +511,11 @@ public ComplexMatchResult subMemory(ValueNode value, LIRLowerableAccess access) public ComplexMatchResult mulMemory(ValueNode value, LIRLowerableAccess access) { OperandSize size = getMemorySize(access); if (size.isXmmType()) { - return binaryRead(SSEOp.MUL, size, value, access); + if (getArithmeticLIRGenerator().supportAVX()) { + return binaryRead(size == SS ? VMULSS : VMULSD, size, value, access); + } else { + return binaryRead(SSEOp.MUL, size, value, access); + } } else { return binaryRead(AMD64RMOp.IMUL, size, value, access); } diff --git a/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java b/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java index a0ef2861369b..ce0becf52fac 100644 --- a/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java +++ b/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java @@ -29,7 +29,7 @@ import org.graalvm.compiler.options.OptionType; /** - * This class encapsulates options that control the behavior of the Graal compiler. + * This class encapsulates options that control the behavior of the GraalVM compiler. */ // @formatter:off public final class GraalOptions { @@ -237,9 +237,6 @@ public final class GraalOptions { @Option(help = "", type = OptionType.Debug) public static final OptionKey OptImplicitNullChecks = new OptionKey<>(true); - @Option(help = "", type = OptionType.Debug) - public static final OptionKey OptClearNonLiveLocals = new OptionKey<>(true); - @Option(help = "", type = OptionType.Debug) public static final OptionKey OptLoopTransform = new OptionKey<>(true); diff --git a/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java b/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java index 0a6a2062bcb8..d21cec5945d3 100644 --- a/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java +++ b/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java @@ -270,6 +270,7 @@ public static void runTest(InvariantsTool tool) { verifiers.add(new VerifySystemPropertyUsage()); verifiers.add(new VerifyInstanceOfUsage()); verifiers.add(new VerifyGraphAddUsage()); + verifiers.add(new VerifyBufferUsage()); verifiers.add(new VerifyGetOptionsUsage()); verifiers.add(new VerifyUnsafeAccess()); diff --git a/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CustomizedBytecodePatternTest.java b/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CustomizedBytecodePatternTest.java index 2bc208d0ae56..06cc6e26b616 100644 --- a/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CustomizedBytecodePatternTest.java +++ b/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CustomizedBytecodePatternTest.java @@ -24,14 +24,44 @@ */ package org.graalvm.compiler.core.test; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Method; +import java.security.ProtectionDomain; + import org.objectweb.asm.Opcodes; +import sun.misc.Unsafe; + public abstract class CustomizedBytecodePatternTest extends GraalCompilerTest implements Opcodes { protected Class getClass(String className) throws ClassNotFoundException { return new CachedLoader(CustomizedBytecodePatternTest.class.getClassLoader(), className).findClass(className); } + /** + * @param className + * @param lookUp lookup object with boot class load capability (required for jdk 9 and above) + * @return loaded class + * @throws ClassNotFoundException + */ + protected Class getClassBL(String className, MethodHandles.Lookup lookUp) throws ClassNotFoundException { + byte[] gen = generateClass(className.replace('.', '/')); + Method defineClass = null; + Class loadedClass = null; + try { + if (Java8OrEarlier) { + defineClass = Unsafe.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class, ClassLoader.class, ProtectionDomain.class); + loadedClass = (Class) defineClass.invoke(UNSAFE, className, gen, 0, gen.length, null, null); + } else { + defineClass = MethodHandles.lookup().getClass().getDeclaredMethod("defineClass", byte[].class); + loadedClass = (Class) defineClass.invoke(lookUp, gen); + } + } catch (Exception e) { + throw new ClassNotFoundException(); + } + return loadedClass; + } + private class CachedLoader extends ClassLoader { final String className; diff --git a/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java b/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java index 37ac142b4577..d96d7f572761 100644 --- a/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java +++ b/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java @@ -150,9 +150,9 @@ import jdk.vm.ci.meta.SpeculationLog; /** - * Base class for Graal compiler unit tests. + * Base class for compiler unit tests. *

- * White box tests for Graal compiler transformations use this pattern: + * White box tests for compiler transformations use this pattern: *

    *
  1. Create a graph by {@linkplain #parseEager parsing} a method.
  2. *
  3. Manually modify the graph (e.g. replace a parameter node with a constant).
  4. diff --git a/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBufferUsage.java b/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBufferUsage.java new file mode 100644 index 000000000000..45238b2d9f02 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBufferUsage.java @@ -0,0 +1,88 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.graalvm.compiler.core.common.type.ObjectStamp; +import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.nodes.java.MethodCallTargetNode; +import org.graalvm.compiler.nodes.spi.CoreProviders; +import org.graalvm.compiler.phases.VerifyPhase; +import org.graalvm.compiler.serviceprovider.BufferUtil; + +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; + +/** + * See {@link BufferUtil}. + */ +public class VerifyBufferUsage extends VerifyPhase { + + private final Set bufferTypes = new HashSet<>(Arrays.asList( + "Ljava/nio/Buffer;", + "Ljava/nio/ByteBuffer;", + "Ljava/nio/ShortBuffer;", + "Ljava/nio/CharBuffer;", + "Ljava/nio/IntBuffer;", + "Ljava/nio/LongBuffer;", + "Ljava/nio/FloatBuffer;", + "Ljava/nio/DoubleBuffer;", + "Ljava/nio/MappedByteBuffer;")); + + private final Set bufferMethods = new HashSet<>(Arrays.asList( + "position", + "limit", + "mark", + "reset", + "clear", + "flip", + "rewind")); + + @Override + protected void verify(StructuredGraph graph, CoreProviders context) { + ResolvedJavaMethod caller = graph.method(); + for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) { + ResolvedJavaMethod callee = t.targetMethod(); + String calleeClassName = callee.getDeclaringClass().getName(); + String calleeName = callee.getName(); + if (bufferTypes.contains(calleeClassName) && + bufferMethods.contains(calleeName) && + !callee.getSignature().getReturnKind().isPrimitive()) { + StackTraceElement e = caller.asStackTraceElement(t.invoke().bci()); + ResolvedJavaType receiverType = ((ObjectStamp) t.arguments().get(0).stamp(NodeView.DEFAULT)).type(); + if (!receiverType.getName().equals("Ljava/nio/Buffer;")) { + throw new VerificationError( + "%s: Cast receiver of type %s to java.nio.Buffer for call to %s to avoid problems with co-variant overloads added by https://bugs.openjdk.java.net/browse/JDK-4774077", + e, receiverType.toJavaName(), + callee.format("%H.%n(%p)")); + } + } + } + } +} diff --git a/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalServiceThread.java b/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalServiceThread.java new file mode 100644 index 000000000000..700e29d0e310 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalServiceThread.java @@ -0,0 +1,65 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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; + +/** + * This is a utility class for Threads started by the compiler itself. In certain execution + * environments extra work must be done for these threads to execute correctly and this class + * provides hooks for this work. + */ +public class GraalServiceThread extends Thread { + private final Runnable runnable; + + public GraalServiceThread(Runnable runnable) { + super(); + this.runnable = runnable; + } + + @Override + public final void run() { + beforeRun(); + try { + runnable.run(); + } finally { + afterRun(); + } + } + + /** + * Substituted by {@code com.oracle.svm.graal.hotspot.libgraal. + * Target_org_graalvm_compiler_truffle_common_TruffleCompilerRuntimeInstance} to attach to the + * peer runtime if required. + */ + private void afterRun() { + } + + /** + * Substituted by {@code com.oracle.svm.graal.hotspot.libgraal. + * Target_org_graalvm_compiler_truffle_common_TruffleCompilerRuntimeInstance} to attach to the + * peer runtime if required. + */ + private void beforeRun() { + } +} diff --git a/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyMidTier.java b/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyMidTier.java index 20aa66a177b3..8437c01badc5 100644 --- a/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyMidTier.java +++ b/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyMidTier.java @@ -35,6 +35,7 @@ import org.graalvm.compiler.phases.common.LoopSafepointInsertionPhase; import org.graalvm.compiler.phases.common.LoweringPhase; import org.graalvm.compiler.phases.common.RemoveValueProxyPhase; +import org.graalvm.compiler.phases.common.WriteBarrierAdditionPhase; import org.graalvm.compiler.phases.tiers.MidTierContext; public class EconomyMidTier extends PhaseSuite { @@ -53,5 +54,7 @@ public EconomyMidTier(OptionValues options) { appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER)); appendPhase(new FrameStateAssignmentPhase()); + + appendPhase(new WriteBarrierAdditionPhase()); } } diff --git a/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/MidTier.java b/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/MidTier.java index e30b450b93a9..46af9b91038c 100644 --- a/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/MidTier.java +++ b/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/MidTier.java @@ -24,9 +24,6 @@ */ package org.graalvm.compiler.core.phases; -import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.GuardTargets; -import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.NonDeoptGuardTargets; -import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.Options.MitigateSpeculativeExecutionAttacks; import static org.graalvm.compiler.core.common.GraalOptions.ConditionalElimination; import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode; import static org.graalvm.compiler.core.common.GraalOptions.OptDeoptimizationGrouping; @@ -35,6 +32,9 @@ 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; +import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.GuardTargets; +import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.NonDeoptGuardTargets; +import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.Options.MitigateSpeculativeExecutionAttacks; import org.graalvm.compiler.loop.DefaultLoopPolicies; import org.graalvm.compiler.loop.LoopPolicies; @@ -56,6 +56,7 @@ import org.graalvm.compiler.phases.common.LoopSafepointInsertionPhase; import org.graalvm.compiler.phases.common.LoweringPhase; 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 { @@ -109,6 +110,8 @@ public MidTier(OptionValues options) { } appendPhase(canonicalizer); + + appendPhase(new WriteBarrierAdditionPhase()); } public LoopPolicies createLoopPolicies() { diff --git a/compiler/src/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java b/compiler/src/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java index 61b6e5fb3934..fbeddaf6a8a6 100644 --- a/compiler/src/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java +++ b/compiler/src/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java @@ -28,6 +28,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.text.SimpleDateFormat; +import java.util.Date; import org.graalvm.collections.EconomicMap; import org.graalvm.compiler.options.EnumOptionKey; @@ -119,7 +121,7 @@ public enum PrintGraphTarget { public static final OptionKey MetricsThreadFilter = new OptionKey<>(null); @Option(help = "Enable debug output for stub code generation and snippet preparation.", type = OptionType.Debug) public static final OptionKey DebugStubsAndSnippets = new OptionKey<>(false); - @Option(help = "Send Graal compiler IR to dump handlers on error.", type = OptionType.Debug) + @Option(help = "Send compiler IR to dump handlers on error.", type = OptionType.Debug) public static final OptionKey DumpOnError = new OptionKey<>(false); @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug) public static final OptionKey InterceptBailout = new OptionKey<>(false); @@ -203,7 +205,9 @@ public static Path getDumpDirectory(OptionValues options) throws IOException { if (DumpPath.hasBeenSet(options)) { dumpDir = Paths.get(DumpPath.getValue(options)); } else { - dumpDir = Paths.get(DumpPath.getValue(options), String.valueOf(GraalServices.getGlobalTimeStamp())); + Date date = new Date(GraalServices.getGlobalTimeStamp()); + SimpleDateFormat formatter = new SimpleDateFormat( "YYYY.MM.dd.HH.mm.ss.SSS" ); + dumpDir = Paths.get(DumpPath.getValue(options), formatter.format(date)); } dumpDir = dumpDir.toAbsolutePath(); if (!Files.exists(dumpDir)) { diff --git a/compiler/src/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java b/compiler/src/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java index 9d8a901a2361..6f06b339c926 100644 --- a/compiler/src/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java +++ b/compiler/src/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java @@ -44,6 +44,7 @@ import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider; import org.graalvm.compiler.hotspot.meta.HotSpotConstantFieldProvider; import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider; +import org.graalvm.compiler.hotspot.meta.HotSpotGCProvider; import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider; import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins; import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider; @@ -135,7 +136,8 @@ public HotSpotBackend createBackend(HotSpotGraalRuntimeProvider graalRuntime, Co lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, target); } HotSpotStampProvider stampProvider = new HotSpotStampProvider(); - Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider); + HotSpotGCProvider gc = new HotSpotGCProvider(config); + Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, gc); try (InitTimer rt = timer("create SnippetReflection provider")) { snippetReflection = createSnippetReflection(graalRuntime, constantReflection, wordTypes); @@ -154,8 +156,7 @@ public HotSpotBackend createBackend(HotSpotGraalRuntimeProvider graalRuntime, Co suites = createSuites(config, graalRuntime, compilerConfiguration, plugins, replacements); } providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers, - snippetReflection, wordTypes, - plugins); + snippetReflection, wordTypes, plugins, gc); replacements.setProviders(providers); } try (InitTimer rt = timer("instantiate backend")) { diff --git a/compiler/src/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java b/compiler/src/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java index b02c660817eb..c3bdef1043fc 100644 --- a/compiler/src/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java +++ b/compiler/src/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java @@ -40,6 +40,7 @@ import org.graalvm.compiler.hotspot.HotSpotReplacementsImpl; import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider; import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider; +import org.graalvm.compiler.hotspot.meta.HotSpotGCProvider; import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider; import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins; import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider; @@ -129,7 +130,8 @@ public HotSpotBackend createBackend(HotSpotGraalRuntimeProvider graalRuntime, Co lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, target); } HotSpotStampProvider stampProvider = new HotSpotStampProvider(); - Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider); + HotSpotGCProvider gc = new HotSpotGCProvider(config); + Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, gc); try (InitTimer rt = timer("create SnippetReflection provider")) { snippetReflection = createSnippetReflection(graalRuntime, constantReflection, wordTypes); @@ -148,8 +150,7 @@ public HotSpotBackend createBackend(HotSpotGraalRuntimeProvider graalRuntime, Co suites = createSuites(config, graalRuntime, compilerConfiguration, plugins, registers, replacements, options); } providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers, - snippetReflection, wordTypes, - plugins); + snippetReflection, wordTypes, plugins, gc); replacements.setProviders(providers); } try (InitTimer rt = timer("instantiate backend")) { diff --git a/compiler/src/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java b/compiler/src/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java index 6dd1a96408f7..2743a328e9e8 100644 --- a/compiler/src/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java +++ b/compiler/src/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java @@ -24,8 +24,8 @@ */ package org.graalvm.compiler.hotspot.amd64; -import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; import static org.graalvm.compiler.hotspot.HotSpotBackend.Options.GraalArithmeticStubs; +import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier; import org.graalvm.compiler.api.replacements.Snippet; import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; @@ -46,7 +46,6 @@ import org.graalvm.compiler.replacements.amd64.AMD64ConvertSnippets; import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode; import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation; -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; @@ -67,9 +66,12 @@ public AMD64HotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAcc @Override public void initialize(OptionValues options, Iterable factories, HotSpotProviders providers, GraalHotSpotVMConfig config) { convertSnippets = new AMD64ConvertSnippets.Templates(options, factories, providers, providers.getSnippetReflection(), providers.getCodeCache().getTarget()); - profileSnippets = ProfileNode.Options.ProbabilisticProfiling.getValue(options) && !JavaVersionUtil.Java8OrEarlier && GeneratePIC.getValue(options) - ? new ProbabilisticProfileSnippets.Templates(options, factories, providers, providers.getCodeCache().getTarget()) - : null; + if (Java8OrEarlier) { + // AOT only introduced in JDK 9 + profileSnippets = null; + } else { + profileSnippets = new ProbabilisticProfileSnippets.Templates(options, factories, providers, providers.getCodeCache().getTarget()); + } mathSnippets = new AMD64X87MathSnippets.Templates(options, factories, providers, providers.getSnippetReflection(), providers.getCodeCache().getTarget()); super.initialize(options, factories, providers, config); } diff --git a/compiler/src/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java b/compiler/src/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java index 510f5487c3e2..f12597d5f9bd 100644 --- a/compiler/src/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java +++ b/compiler/src/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java @@ -57,7 +57,7 @@ public void testStringUTF16ToBytes() throws ClassNotFoundException { Class javaclass = Class.forName("java.lang.StringUTF16"); ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "toBytes", char[].class, int.class, int.class); - StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext()); + StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null); assertInGraph(graph, NewArrayNode.class); assertInGraph(graph, ArrayCopyCallNode.class); @@ -88,7 +88,7 @@ public void testStringUTF16getChars() throws ClassNotFoundException { Class javaclass = Class.forName("java.lang.StringUTF16"); ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "getChars", byte[].class, int.class, int.class, char[].class, int.class); - StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext()); + StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null); assertInGraph(graph, ArrayCopyCallNode.class); InstalledCode code = getCode(caller, graph); diff --git a/compiler/src/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java b/compiler/src/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java index 5c3f1363994f..c7197f13eba2 100644 --- a/compiler/src/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java +++ b/compiler/src/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java @@ -38,6 +38,7 @@ import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider; import org.graalvm.compiler.hotspot.meta.HotSpotConstantFieldProvider; import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider; +import org.graalvm.compiler.hotspot.meta.HotSpotGCProvider; import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider; import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins; import org.graalvm.compiler.hotspot.meta.HotSpotLoweringProvider; @@ -101,7 +102,8 @@ public HotSpotBackend createBackend(HotSpotGraalRuntimeProvider runtime, Compile HotSpotForeignCallsProvider foreignCalls = new SPARCHotSpotForeignCallsProvider(jvmciRuntime, runtime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters); LoweringProvider lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, constantReflection, target); HotSpotStampProvider stampProvider = new HotSpotStampProvider(); - Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider); + HotSpotGCProvider gc = new HotSpotGCProvider(config); + Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, gc); HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes); BytecodeProvider bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection); HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, bytecodeProvider, target); @@ -109,8 +111,7 @@ public HotSpotBackend createBackend(HotSpotGraalRuntimeProvider runtime, Compile 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); + snippetReflection, wordTypes, plugins, gc); replacements.setProviders(providers); return createBackend(config, runtime, providers); diff --git a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java index 42e9dc4e9f2d..42b96beec7a5 100644 --- a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java +++ b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java @@ -97,6 +97,7 @@ import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess; import org.graalvm.compiler.serviceprovider.JavaVersionUtil; import org.graalvm.libgraal.LibGraal; +import org.graalvm.libgraal.LibGraalScope; import org.graalvm.libgraal.OptionsEncoder; import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; @@ -940,6 +941,7 @@ static native long compileMethodInLibgraal(long isolateThread, /** * Compiles a method and gathers some statistics. */ + @SuppressWarnings("try") private void compileMethod(HotSpotResolvedJavaMethod method, int counter, LibGraalParams libgraal) { try { long start = System.currentTimeMillis(); @@ -950,32 +952,33 @@ private void compileMethod(HotSpotResolvedJavaMethod method, int counter, LibGra HotSpotInstalledCode installedCode; if (libgraal != null) { HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime(); - long methodHandle = LibGraal.translate(runtime, method); - long isolateThread = LibGraal.getIsolateThread(); - - StackTraceBuffer stackTraceBuffer = libgraal.getStackTraceBuffer(); - - long stackTraceBufferAddress = stackTraceBuffer.getAddress(); - long installedCodeHandle = compileMethodInLibgraal(isolateThread, - methodHandle, - useProfilingInfo, - installAsDefault, - libgraal.options.getAddress(), - libgraal.options.size, - libgraal.options.hash, - stackTraceBufferAddress, - stackTraceBuffer.size); - - installedCode = LibGraal.unhand(runtime, HotSpotInstalledCode.class, installedCodeHandle); - if (installedCode == null) { - int length = UNSAFE.getInt(stackTraceBufferAddress); - byte[] data = new byte[length]; - UNSAFE.copyMemory(null, stackTraceBufferAddress + Integer.BYTES, data, ARRAY_BYTE_BASE_OFFSET, length); - String stackTrace = new String(data).trim(); - println("CompileTheWorld (%d) : Error compiling method: %s", counter, method.format("%H.%n(%p):%r")); - println(stackTrace); + try (LibGraalScope scope = new LibGraalScope(runtime)) { + long methodHandle = LibGraal.translate(runtime, method); + long isolateThread = LibGraalScope.getIsolateThread(); + + StackTraceBuffer stackTraceBuffer = libgraal.getStackTraceBuffer(); + + long stackTraceBufferAddress = stackTraceBuffer.getAddress(); + long installedCodeHandle = compileMethodInLibgraal(isolateThread, + methodHandle, + useProfilingInfo, + installAsDefault, + libgraal.options.getAddress(), + libgraal.options.size, + libgraal.options.hash, + stackTraceBufferAddress, + stackTraceBuffer.size); + + installedCode = LibGraal.unhand(runtime, HotSpotInstalledCode.class, installedCodeHandle); + if (installedCode == null) { + int length = UNSAFE.getInt(stackTraceBufferAddress); + byte[] data = new byte[length]; + UNSAFE.copyMemory(null, stackTraceBufferAddress + Integer.BYTES, data, ARRAY_BYTE_BASE_OFFSET, length); + String stackTrace = new String(data).trim(); + println("CompileTheWorld (%d) : Error compiling method: %s", counter, method.format("%H.%n(%p):%r")); + println(stackTrace); + } } - } else { int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI; HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, 0L); diff --git a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalCompilerTest.java b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalCompilerTest.java index 12676cefeaee..9ecbf3220514 100644 --- a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalCompilerTest.java +++ b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalCompilerTest.java @@ -43,7 +43,7 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; /** - * A Graal compiler test that needs access to the {@link HotSpotGraalRuntimeProvider}. + * A compiler test that needs access to the {@link HotSpotGraalRuntimeProvider}. */ public abstract class HotSpotGraalCompilerTest extends GraalCompilerTest { @@ -73,7 +73,7 @@ protected InstalledCode compileAndInstallSubstitution(Class c, String methodN HotSpotProviders providers = rt.getHostBackend().getProviders(); CompilationIdentifier compilationId = runtime().getHostBackend().getCompilationIdentifier(method); OptionValues options = getInitialOptions(); - StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, compilationId, getDebugContext(options)); + StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, compilationId, getDebugContext(options), null); if (graph != null) { return getCode(method, graph, true, true, graph.getOptions()); } diff --git a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java index 1610de397860..125a2adf7362 100644 --- a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java +++ b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java @@ -72,7 +72,7 @@ public void test() throws ClassNotFoundException { if (plugin instanceof MethodSubstitutionPlugin) { ResolvedJavaMethod method = CheckGraalIntrinsics.resolveIntrinsic(getMetaAccess(), intrinsic); if (!method.isNative()) { - StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, INVALID_COMPILATION_ID, debug); + StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, INVALID_COMPILATION_ID, debug, null); getCode(method, graph); } } diff --git a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierAdditionTest.java b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierAdditionTest.java index 42d757405743..e2db4ec3f4fd 100644 --- a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierAdditionTest.java +++ b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierAdditionTest.java @@ -32,13 +32,12 @@ import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase; -import org.graalvm.compiler.hotspot.gc.g1.G1PostWriteBarrier; -import org.graalvm.compiler.hotspot.gc.g1.G1PreWriteBarrier; -import org.graalvm.compiler.hotspot.gc.g1.G1ReferentFieldReadBarrier; -import org.graalvm.compiler.hotspot.gc.shared.SerialWriteBarrier; -import org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; +import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier; +import org.graalvm.compiler.nodes.gc.SerialWriteBarrier; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; import org.graalvm.compiler.nodes.graphbuilderconf.NodeIntrinsicPluginFactory; import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType; @@ -50,6 +49,7 @@ 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; import org.graalvm.compiler.phases.common.inlining.InliningPhase; import org.graalvm.compiler.phases.common.inlining.policy.InlineEverythingPolicy; import org.graalvm.compiler.phases.tiers.HighTierContext; @@ -311,7 +311,7 @@ private void testHelper(final String snippetName, final int expectedBarriers) th new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext); new GuardLoweringPhase().apply(graph, midContext); new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext); - new WriteBarrierAdditionPhase(config).apply(graph); + new WriteBarrierAdditionPhase().apply(graph, midContext); debug.dump(DebugContext.BASIC_LEVEL, graph, "After Write Barrier Addition"); int barriers = 0; diff --git a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java deleted file mode 100644 index 44564fe6c299..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java +++ /dev/null @@ -1,737 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.compiler.hotspot.test; - -import java.util.List; - -import org.graalvm.collections.EconomicMap; -import org.graalvm.compiler.debug.DebugCloseable; -import org.graalvm.compiler.debug.DebugContext; -import org.graalvm.compiler.debug.DebugContext.Scope; -import org.graalvm.compiler.debug.DebugDumpScope; -import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; -import org.graalvm.compiler.hotspot.gc.g1.G1ArrayRangePostWriteBarrier; -import org.graalvm.compiler.hotspot.gc.g1.G1ArrayRangePreWriteBarrier; -import org.graalvm.compiler.hotspot.gc.g1.G1PostWriteBarrier; -import org.graalvm.compiler.hotspot.gc.g1.G1PreWriteBarrier; -import org.graalvm.compiler.hotspot.gc.shared.SerialArrayRangeWriteBarrier; -import org.graalvm.compiler.hotspot.gc.shared.SerialWriteBarrier; -import org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase; -import org.graalvm.compiler.hotspot.phases.WriteBarrierVerificationPhase; -import org.graalvm.compiler.nodes.AbstractBeginNode; -import org.graalvm.compiler.nodes.AbstractMergeNode; -import org.graalvm.compiler.nodes.FieldLocationIdentity; -import org.graalvm.compiler.nodes.FixedNode; -import org.graalvm.compiler.nodes.FixedWithNextNode; -import org.graalvm.compiler.nodes.LoopBeginNode; -import org.graalvm.compiler.nodes.LoopExitNode; -import org.graalvm.compiler.nodes.StructuredGraph; -import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; -import org.graalvm.compiler.nodes.memory.WriteNode; -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.LoopSafepointInsertionPhase; -import org.graalvm.compiler.phases.common.LoweringPhase; -import org.graalvm.compiler.phases.graph.ReentrantNodeIterator; -import org.graalvm.compiler.phases.graph.ReentrantNodeIterator.NodeIteratorClosure; -import org.graalvm.compiler.phases.tiers.HighTierContext; -import org.graalvm.compiler.phases.tiers.MidTierContext; -import org.graalvm.word.LocationIdentity; -import org.junit.Assert; -import org.junit.Test; - -import jdk.vm.ci.meta.ResolvedJavaField; - -/** - * The following tests validate the write barrier verification phase. For every tested snippet, an - * array of write barrier indices and the total write barrier number are passed as parameters. The - * indices denote the barriers that will be manually removed. The write barrier verification phase - * runs after the write barrier removal and depending on the result an assertion might be generated. - * The tests anticipate the presence or not of an assertion generated by the verification phase. - */ -public class WriteBarrierVerificationTest extends HotSpotGraalCompilerTest { - - public static int barrierIndex; - - private final GraalHotSpotVMConfig config = runtime().getVMConfig(); - - public static class Container { - - public Container a; - public Container b; - } - - private static native void safepoint(); - - public static void test1Snippet(Container main) { - Container temp1 = new Container(); - Container temp2 = new Container(); - barrierIndex = 0; - safepoint(); - barrierIndex = 1; - main.a = temp1; - safepoint(); - barrierIndex = 2; - main.b = temp2; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test1() { - test("test1Snippet", 2, new int[]{1}); - } - - @Test(expected = AssertionError.class) - public void test2() { - test("test1Snippet", 2, new int[]{2}); - } - - public static void test2Snippet(Container main) { - Container temp1 = new Container(); - Container temp2 = new Container(); - barrierIndex = 0; - safepoint(); - barrierIndex = 1; - main.a = temp1; - barrierIndex = 2; - main.b = temp2; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test3() { - test("test2Snippet", 2, new int[]{1}); - } - - @Test - public void test4() { - test("test2Snippet", 2, new int[]{2}); - } - - public static void test3Snippet(Container main, boolean test) { - Container temp1 = new Container(); - Container temp2 = new Container(); - barrierIndex = 0; - safepoint(); - for (int i = 0; i < 10; i++) { - if (test) { - barrierIndex = 1; - main.a = temp1; - barrierIndex = 2; - main.b = temp2; - } else { - barrierIndex = 3; - main.a = temp1; - barrierIndex = 4; - main.b = temp2; - } - } - } - - @Test(expected = AssertionError.class) - public void test5() { - test("test3Snippet", 4, new int[]{1, 2}); - } - - @Test(expected = AssertionError.class) - public void test6() { - test("test3Snippet", 4, new int[]{3, 4}); - } - - @Test(expected = AssertionError.class) - public void test7() { - test("test3Snippet", 4, new int[]{1}); - } - - @Test - public void test8() { - test("test3Snippet", 4, new int[]{2}); - } - - @Test(expected = AssertionError.class) - public void test9() { - test("test3Snippet", 4, new int[]{3}); - } - - @Test - public void test10() { - test("test3Snippet", 4, new int[]{4}); - } - - public static void test4Snippet(Container main, boolean test) { - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - barrierIndex = 1; - main.a = temp1; - for (int i = 0; i < 10; i++) { - if (test) { - barrierIndex = 2; - main.a = temp1; - barrierIndex = 3; - main.b = temp2; - } else { - barrierIndex = 4; - main.a = temp2; - barrierIndex = 5; - main.b = temp1; - } - } - } - - @Test(expected = AssertionError.class) - public void test11() { - test("test4Snippet", 5, new int[]{2, 3}); - } - - @Test(expected = AssertionError.class) - public void test12() { - test("test4Snippet", 5, new int[]{4, 5}); - } - - @Test(expected = AssertionError.class) - public void test13() { - test("test4Snippet", 5, new int[]{1}); - } - - public static void test5Snippet(Container main) { - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - barrierIndex = 1; - main.a = temp1; - if (main.a == main.b) { - barrierIndex = 2; - main.a = temp1; - barrierIndex = 3; - main.b = temp2; - } else { - barrierIndex = 4; - main.a = temp2; - barrierIndex = 5; - main.b = temp1; - } - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test14() { - test("test5Snippet", 5, new int[]{1}); - } - - @Test - public void test15() { - test("test5Snippet", 5, new int[]{2}); - } - - @Test - public void test16() { - test("test5Snippet", 5, new int[]{4}); - } - - @Test - public void test17() { - test("test5Snippet", 5, new int[]{3}); - } - - @Test - public void test18() { - test("test5Snippet", 5, new int[]{5}); - } - - @Test - public void test19() { - test("test5Snippet", 5, new int[]{2, 3}); - } - - @Test - public void test20() { - test("test5Snippet", 5, new int[]{4, 5}); - } - - public static void test6Snippet(Container main, boolean test) { - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - barrierIndex = 1; - main.a = temp1; - if (test) { - barrierIndex = 2; - main.a = temp1; - barrierIndex = 3; - main.b = temp1.a.a; - } else { - barrierIndex = 4; - main.a = temp2; - barrierIndex = 5; - main.b = temp2.a.a; - } - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test21() { - test("test6Snippet", 5, new int[]{1}); - } - - @Test(expected = AssertionError.class) - public void test22() { - test("test6Snippet", 5, new int[]{1, 2}); - } - - @Test - public void test23() { - test("test6Snippet", 5, new int[]{3}); - } - - @Test - public void test24() { - test("test6Snippet", 5, new int[]{4}); - } - - public static void test7Snippet(Container main, boolean test) { - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - barrierIndex = 1; - main.a = temp1; - if (test) { - barrierIndex = 2; - main.a = temp1; - } - barrierIndex = 3; - main.b = temp2; - safepoint(); - } - - @Test - public void test25() { - test("test7Snippet", 3, new int[]{2}); - } - - @Test - public void test26() { - test("test7Snippet", 3, new int[]{3}); - } - - @Test - public void test27() { - test("test7Snippet", 3, new int[]{2, 3}); - } - - @Test(expected = AssertionError.class) - public void test28() { - test("test7Snippet", 3, new int[]{1}); - } - - public static void test8Snippet(Container main, boolean test) { - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - if (test) { - barrierIndex = 1; - main.a = temp1; - } - barrierIndex = 2; - main.b = temp2; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test29() { - test("test8Snippet", 2, new int[]{1}); - } - - @Test(expected = AssertionError.class) - public void test30() { - test("test8Snippet", 2, new int[]{2}); - } - - @Test(expected = AssertionError.class) - public void test31() { - test("test8Snippet", 2, new int[]{1, 2}); - } - - public static void test9Snippet(Container main1, Container main2, boolean test) { - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - if (test) { - barrierIndex = 1; - main1.a = temp1; - } else { - barrierIndex = 2; - main2.a = temp1; - } - barrierIndex = 3; - main1.b = temp2; - barrierIndex = 4; - main2.b = temp2; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test32() { - test("test9Snippet", 4, new int[]{1}); - } - - @Test(expected = AssertionError.class) - public void test33() { - test("test9Snippet", 4, new int[]{2}); - } - - @Test(expected = AssertionError.class) - public void test34() { - test("test9Snippet", 4, new int[]{3}); - } - - @Test(expected = AssertionError.class) - public void test35() { - test("test9Snippet", 4, new int[]{4}); - } - - @Test(expected = AssertionError.class) - public void test36() { - test("test9Snippet", 4, new int[]{1, 2}); - } - - @Test(expected = AssertionError.class) - public void test37() { - test("test9Snippet", 4, new int[]{3, 4}); - } - - public static void test10Snippet(Container main1, Container main2, boolean test) { - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - if (test) { - barrierIndex = 1; - main1.a = temp1; - barrierIndex = 2; - main2.a = temp2; - } else { - barrierIndex = 3; - main2.a = temp1; - } - barrierIndex = 4; - main1.b = temp2; - barrierIndex = 5; - main2.b = temp2; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test38() { - test("test10Snippet", 5, new int[]{1}); - } - - @Test(expected = AssertionError.class) - public void test39() { - test("test10Snippet", 5, new int[]{2}); - } - - @Test(expected = AssertionError.class) - public void test40() { - test("test10Snippet", 5, new int[]{3}); - } - - @Test(expected = AssertionError.class) - public void test41() { - test("test10Snippet", 5, new int[]{4}); - } - - @Test - public void test42() { - test("test10Snippet", 5, new int[]{5}); - } - - @Test(expected = AssertionError.class) - public void test43() { - test("test10Snippet", 5, new int[]{1, 2}); - } - - @Test(expected = AssertionError.class) - public void test44() { - test("test10Snippet", 5, new int[]{1, 2, 3}); - } - - @Test(expected = AssertionError.class) - public void test45() { - test("test10Snippet", 5, new int[]{3, 4}); - } - - public static void test11Snippet(Container main1, Container main2, Container main3, boolean test) { - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - if (test) { - barrierIndex = 1; - main1.a = temp1; - barrierIndex = 2; - main3.a = temp1; - if (!test) { - barrierIndex = 3; - main2.a = temp2; - } else { - barrierIndex = 4; - main1.a = temp2; - barrierIndex = 5; - main3.a = temp2; - } - } else { - barrierIndex = 6; - main1.b = temp2; - for (int i = 0; i < 10; i++) { - barrierIndex = 7; - main3.a = temp1; - } - barrierIndex = 8; - main3.b = temp2; - } - barrierIndex = 9; - main1.b = temp2; - barrierIndex = 10; - main2.b = temp2; - barrierIndex = 11; - main3.b = temp2; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test46() { - test("test11Snippet", 11, new int[]{1}); - } - - @Test(expected = AssertionError.class) - public void test47() { - test("test11Snippet", 11, new int[]{2}); - } - - @Test(expected = AssertionError.class) - public void test48() { - test("test11Snippet", 11, new int[]{3}); - } - - @Test(expected = AssertionError.class) - public void test49() { - test("test11Snippet", 11, new int[]{6}); - } - - @Test(expected = AssertionError.class) - public void test50() { - test("test11Snippet", 11, new int[]{7}); - } - - @Test(expected = AssertionError.class) - public void test51() { - test("test11Snippet", 11, new int[]{8}); - } - - @Test(expected = AssertionError.class) - public void test52() { - test("test11Snippet", 11, new int[]{9}); - } - - @Test(expected = AssertionError.class) - public void test53() { - test("test11Snippet", 11, new int[]{10}); - } - - @Test - public void test54() { - test("test11Snippet", 11, new int[]{4}); - } - - @Test - public void test55() { - test("test11Snippet", 11, new int[]{5}); - } - - @Test - public void test56() { - test("test11Snippet", 11, new int[]{11}); - } - - public static void test12Snippet(Container main, Container main1, boolean test) { - Container temp1 = new Container(); - Container temp2 = new Container(); - barrierIndex = 0; - safepoint(); - barrierIndex = 7; - main1.a = temp1; - for (int i = 0; i < 10; i++) { - if (test) { - barrierIndex = 1; - main.a = temp1; - barrierIndex = 2; - main.b = temp2; - } else { - barrierIndex = 3; - main.a = temp1; - barrierIndex = 4; - main.b = temp2; - } - } - barrierIndex = 5; - main.a = temp1; - barrierIndex = 6; - main.b = temp1; - barrierIndex = 8; - main1.b = temp1; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test57() { - test("test12Snippet", 8, new int[]{5}); - } - - @Test - public void test58() { - test("test12Snippet", 8, new int[]{6}); - } - - @Test(expected = AssertionError.class) - public void test59() { - test("test12Snippet", 8, new int[]{7}); - } - - @Test(expected = AssertionError.class) - public void test60() { - test("test12Snippet", 8, new int[]{8}); - } - - public static void test13Snippet(Object[] a, Object[] b) { - System.arraycopy(a, 0, b, 0, a.length); - } - - private interface GraphPredicate { - int apply(StructuredGraph graph); - } - - private void test(final String snippet, final int expectedBarriers, final int... removedBarrierIndices) { - GraphPredicate noCheck = noArg -> expectedBarriers; - testPredicate(snippet, noCheck, removedBarrierIndices); - } - - @SuppressWarnings("try") - private void testPredicate(final String snippet, final GraphPredicate expectedBarriers, final int... removedBarrierIndices) { - DebugContext debug = getDebugContext(); - try (DebugCloseable d = debug.disableIntercept(); DebugContext.Scope s = debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet))) { - final StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES, debug); - HighTierContext highTierContext = getDefaultHighTierContext(); - createInliningPhase().apply(graph, highTierContext); - - MidTierContext midTierContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo()); - - new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext); - new GuardLoweringPhase().apply(graph, midTierContext); - new LoopSafepointInsertionPhase().apply(graph); - new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, highTierContext); - - new WriteBarrierAdditionPhase(config).apply(graph); - - int barriers = 0; - // First, the total number of expected barriers is checked. - if (config.useG1GC) { - barriers = graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count() + - graph.getNodes().filter(G1ArrayRangePreWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePostWriteBarrier.class).count(); - Assert.assertTrue(expectedBarriers.apply(graph) * 2 == barriers); - } else { - barriers = graph.getNodes().filter(SerialWriteBarrier.class).count() + graph.getNodes().filter(SerialArrayRangeWriteBarrier.class).count(); - Assert.assertTrue(expectedBarriers.apply(graph) == barriers); - } - ResolvedJavaField barrierIndexField = getMetaAccess().lookupJavaField(WriteBarrierVerificationTest.class.getDeclaredField("barrierIndex")); - LocationIdentity barrierIdentity = new FieldLocationIdentity(barrierIndexField); - // Iterate over all write nodes and remove barriers according to input indices. - NodeIteratorClosure closure = new NodeIteratorClosure() { - - @Override - protected Boolean processNode(FixedNode node, Boolean currentState) { - if (node instanceof WriteNode) { - WriteNode write = (WriteNode) node; - LocationIdentity obj = write.getLocationIdentity(); - if (obj.equals(barrierIdentity)) { - /* - * A "barrierIndex" variable was found and is checked against the input - * barrier array. - */ - if (eliminateBarrier(write.value().asJavaConstant().asInt(), removedBarrierIndices)) { - return true; - } - } - } else if (node instanceof SerialWriteBarrier || node instanceof G1PostWriteBarrier) { - // Remove flagged write barriers. - if (currentState) { - graph.removeFixed(((FixedWithNextNode) node)); - return false; - } - } - return currentState; - } - - private boolean eliminateBarrier(int index, int[] map) { - for (int i = 0; i < map.length; i++) { - if (map[i] == index) { - return true; - } - } - return false; - } - - @Override - protected EconomicMap processLoop(LoopBeginNode loop, Boolean initialState) { - return ReentrantNodeIterator.processLoop(this, loop, initialState).exitStates; - } - - @Override - protected Boolean merge(AbstractMergeNode merge, List states) { - return false; - } - - @Override - protected Boolean afterSplit(AbstractBeginNode node, Boolean oldState) { - return false; - } - }; - - try (Scope disabled = debug.disable()) { - ReentrantNodeIterator.apply(closure, graph.start(), false); - new WriteBarrierVerificationPhase(config).apply(graph); - } catch (AssertionError error) { - /* - * Catch assertion, test for expected one and re-throw in order to validate unit - * test. - */ - Assert.assertTrue(error.getMessage().contains("Write barrier must be present")); - throw error; - } - } catch (Throwable e) { - throw debug.handle(e); - } - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java index e7fe1ef16fbf..2b991866e9b4 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java @@ -183,11 +183,19 @@ protected HotSpotCompilationRequestResult performCompilation(DebugContext debug) } - public CompilationTask(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalCompiler compiler, HotSpotCompilationRequest request, boolean useProfilingInfo, boolean installAsDefault) { + public CompilationTask(HotSpotJVMCIRuntime jvmciRuntime, + HotSpotGraalCompiler compiler, + HotSpotCompilationRequest request, + boolean useProfilingInfo, + boolean installAsDefault) { this(jvmciRuntime, compiler, request, useProfilingInfo, false, installAsDefault); } - public CompilationTask(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalCompiler compiler, HotSpotCompilationRequest request, boolean useProfilingInfo, boolean shouldRetainLocalVariables, + public CompilationTask(HotSpotJVMCIRuntime jvmciRuntime, + HotSpotGraalCompiler compiler, + HotSpotCompilationRequest request, + boolean useProfilingInfo, + boolean shouldRetainLocalVariables, boolean installAsDefault) { this.jvmciRuntime = jvmciRuntime; this.compiler = compiler; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationWatchDog.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationWatchDog.java index 344c36487a19..607d2da5d857 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationWatchDog.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationWatchDog.java @@ -28,6 +28,7 @@ import java.util.Arrays; +import org.graalvm.compiler.core.GraalServiceThread; import org.graalvm.compiler.debug.TTY; import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.OptionKey; @@ -49,10 +50,10 @@ * dog reports a long running compilation. Every * {@link Options#CompilationWatchDogStackTraceInterval} seconds after that point in time where the * same compilation is still executing, the watch dog takes a stack trace of the compiler thread. If - * more than {@value Options#NonFatalIdenticalCompilationSnapshots} contiguous identical stack - * traces are seen, the watch dog reports a stuck compilation and exits the VM. + * more than {@link Options#NonFatalIdenticalCompilationSnapshots} contiguous identical stack traces + * are seen, the watch dog reports a stuck compilation and exits the VM. */ -class CompilationWatchDog extends Thread implements AutoCloseable { +class CompilationWatchDog implements Runnable, AutoCloseable { public static class Options { // @formatter:off @@ -112,9 +113,6 @@ private enum WatchDogState { CompilationWatchDog(Thread compilerThread, long startDelayMilliseconds, long stackTraceIntervalMilliseconds, int nonFatalIdenticalCompilationSnapshots) { this.compilerThread = compilerThread; - this.setName("WatchDog" + getId() + "[" + compilerThread.getName() + "]"); - this.setPriority(Thread.MAX_PRIORITY); - this.setDaemon(true); this.startDelayMilliseconds = startDelayMilliseconds; this.stackTraceIntervalMilliseconds = stackTraceIntervalMilliseconds; this.nonFatalIdenticalCompilationSnapshots = nonFatalIdenticalCompilationSnapshots; @@ -185,7 +183,7 @@ private static double secs(long ms) { @Override public String toString() { - return getName(); + return "WatchDog[" + compilerThread.getName() + "]"; } @Override @@ -305,12 +303,16 @@ static CompilationWatchDog watch(ResolvedJavaMethod method, int id, OptionValues // Lazily get a watch dog thread for the current compiler thread CompilationWatchDog watchDog = WATCH_DOGS.get(); if (watchDog == null) { - Thread currentThread = currentThread(); + Thread currentThread = Thread.currentThread(); long stackTraceIntervalMilliseconds = ms(Options.CompilationWatchDogStackTraceInterval.getValue(options)); int nonFatalIdenticalCompilationSnapshots = Options.NonFatalIdenticalCompilationSnapshots.getValue(options); watchDog = new CompilationWatchDog(currentThread, startDelayMilliseconds, stackTraceIntervalMilliseconds, nonFatalIdenticalCompilationSnapshots); WATCH_DOGS.set(watchDog); - watchDog.start(); + GraalServiceThread thread = new GraalServiceThread(watchDog); + thread.setName(thread.getId() + " " + watchDog.toString()); + thread.setPriority(Thread.MAX_PRIORITY); + thread.setDaemon(true); + thread.start(); } watchDog.startCompilation(method, id); return watchDog; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java index f804df682157..3fbe65164f3a 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java @@ -53,9 +53,9 @@ import jdk.vm.ci.common.InitTimer; /** - * A factory that creates the {@link CompilerConfiguration} the Graal compiler will use. Each - * factory must have a unique {@link #name} and {@link #autoSelectionPriority}. The latter imposes a - * total ordering between factories for the purpose of auto-selecting the factory to use. + * A factory that creates the {@link CompilerConfiguration} the compiler will use. Each factory must + * have a unique {@link #name} and {@link #autoSelectionPriority}. The latter imposes a total + * ordering between factories for the purpose of auto-selecting the factory to use. */ public abstract class CompilerConfigurationFactory implements Comparable { @@ -67,11 +67,11 @@ enum ShowConfigurationLevel { static class Options { // @formatter:off - @Option(help = "Names the Graal compiler configuration to use. If omitted, the compiler configuration " + + @Option(help = "Names the compiler configuration to use. If omitted, the compiler configuration " + "with the highest auto-selection priority is used. To see the set of available configurations, " + "supply the value 'help' to this option.", type = OptionType.Expert) public static final OptionKey CompilerConfiguration = new OptionKey<>(null); - @Option(help = "Writes to the VM log information about the Graal compiler configuration selected.", type = OptionType.User) + @Option(help = "Writes to the VM log information about the compiler configuration selected.", type = OptionType.User) public static final OptionKey ShowConfiguration = new EnumOptionKey<>(ShowConfigurationLevel.none); // @formatter:on } @@ -195,7 +195,7 @@ public static CompilerConfigurationFactory selectFactory(String name, OptionValu try (InitTimer t = timer("CompilerConfigurationFactory.selectFactory")) { String value = name == null ? Options.CompilerConfiguration.getValue(options) : name; if ("help".equals(value)) { - System.out.println("The available Graal compiler configurations are:"); + System.out.println("The available compiler configurations are:"); for (CompilerConfigurationFactory candidate : getAllCandidates()) { System.out.println(" " + candidate.name); } @@ -208,7 +208,7 @@ public static CompilerConfigurationFactory selectFactory(String name, OptionValu } } if (factory == null) { - throw new GraalError("Graal compiler configuration '%s' not found. Available configurations are: %s", value, + throw new GraalError("Compiler configuration '%s' not found. Available configurations are: %s", value, getAllCandidates().stream().map(c -> c.name).collect(Collectors.joining(", "))); } } else { @@ -247,7 +247,7 @@ public static CompilerConfigurationFactory selectFactory(String name, OptionValu private static void printConfigInfo(CompilerConfigurationFactory factory) { URL location = factory.getClass().getResource(factory.getClass().getSimpleName() + ".class"); - TTY.printf("Using Graal compiler configuration '%s' provided by %s loaded from %s%n", factory.name, factory.getClass().getName(), location); + TTY.printf("Using compiler configuration '%s' provided by %s loaded from %s%n", factory.name, factory.getClass().getName(), location); } private static List phaseNames(PhaseSuite suite) { diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java index 9eeeee148ac9..672a8ff461bf 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java @@ -48,6 +48,7 @@ import org.graalvm.compiler.java.GraphBuilderPhase; import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory; import org.graalvm.compiler.lir.phases.LIRSuites; +import org.graalvm.compiler.nodes.Cancellable; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; @@ -74,7 +75,7 @@ import jdk.vm.ci.runtime.JVMCICompiler; import sun.misc.Unsafe; -public class HotSpotGraalCompiler implements GraalJVMCICompiler { +public class HotSpotGraalCompiler implements GraalJVMCICompiler, Cancellable { private static final Unsafe UNSAFE = GraalUnsafeAccess.getUnsafe(); private final HotSpotJVMCIRuntime jvmciRuntime; @@ -86,7 +87,7 @@ public class HotSpotGraalCompiler implements GraalJVMCICompiler { HotSpotGraalCompiler(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalRuntimeProvider graalRuntime, OptionValues options) { this.jvmciRuntime = jvmciRuntime; this.graalRuntime = graalRuntime; - // It is sufficient to have one compilation counter object per Graal compiler object. + // It is sufficient to have one compilation counter object per compiler object. this.compilationCounters = Options.CompilationCountLimit.getValue(options) > 0 ? new CompilationCounters(options) : null; this.bootstrapWatchDog = graalRuntime.isBootstrapping() && !DebugOptions.BootstrapInitializeOnly.getValue(options) ? BootstrapWatchDog.maybeCreate(graalRuntime) : null; } @@ -164,19 +165,31 @@ private boolean shouldRetainLocalVariables(long envAddress) { return false; } + @Override + public boolean isCancelled() { + return graalRuntime.isShutdown(); + } + public StructuredGraph createGraph(ResolvedJavaMethod method, int entryBCI, boolean useProfilingInfo, CompilationIdentifier compilationId, OptionValues options, DebugContext debug) { HotSpotBackend backend = graalRuntime.getHostBackend(); HotSpotProviders providers = backend.getProviders(); final boolean isOSR = entryBCI != JVMCICompiler.INVOCATION_ENTRY_BCI; - StructuredGraph graph = method.isNative() || isOSR ? null : providers.getReplacements().getIntrinsicGraph(method, compilationId, debug); + StructuredGraph graph = method.isNative() || isOSR ? null : providers.getReplacements().getIntrinsicGraph(method, compilationId, debug, this); if (graph == null) { SpeculationLog speculationLog = method.getSpeculationLog(); if (speculationLog != null) { speculationLog.collectFailedSpeculations(); } - graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.ifTrue(OptAssumptions.getValue(options))).method(method).entryBCI(entryBCI).speculationLog( - speculationLog).useProfilingInfo(useProfilingInfo).compilationId(compilationId).build(); + // @formatter:off + graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.ifTrue(OptAssumptions.getValue(options))). + method(method). + cancellable(this). + entryBCI(entryBCI). + speculationLog(speculationLog). + useProfilingInfo(useProfilingInfo). + compilationId(compilationId).build(); + // @formatter:on } return graph; } @@ -219,7 +232,11 @@ public CompilationResult compileHelper(CompilationResultBuilderFactory crbf, Com return result; } - public CompilationResult compile(ResolvedJavaMethod method, int entryBCI, boolean useProfilingInfo, boolean shouldRetainLocalVariables, CompilationIdentifier compilationId, + public CompilationResult compile(ResolvedJavaMethod method, + int entryBCI, + boolean useProfilingInfo, + boolean shouldRetainLocalVariables, + CompilationIdentifier compilationId, DebugContext debug) { StructuredGraph graph = createGraph(method, entryBCI, useProfilingInfo, compilationId, debug.getOptions(), debug); CompilationResult result = new CompilationResult(compilationId); diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java index be5074f18cf5..799baed154aa 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java @@ -129,8 +129,6 @@ private static boolean checkArrayIndexScaleInvariants(MetaAccessProvider metaAcc */ private AtomicReference optionsRef = new AtomicReference<>(); - private final HotSpotGraalCompiler compiler; - private final DiagnosticsOutputDirectory outputDirectory; private final Map compilationProblemsPerAction; @@ -161,7 +159,6 @@ private static boolean checkArrayIndexScaleInvariants(MetaAccessProvider metaAcc CompilerConfiguration compilerConfiguration = compilerConfigurationFactory.createCompilerConfiguration(); compilerConfigurationName = compilerConfigurationFactory.getName(); - compiler = new HotSpotGraalCompiler(jvmciRuntime, this, options); if (IS_AOT) { management = null; } else { @@ -367,7 +364,11 @@ public String getCompilerConfigurationName() { } private long runtimeStartTime; - private boolean shutdown; + + /** + * Called from compiler threads to check whether to bail out of a compilation. + */ + private volatile boolean shutdown; /** * Take action related to entering a new execution phase. @@ -394,6 +395,16 @@ void shutdown() { BenchmarkCounters.shutdown(runtime(), optionsRef.get(), runtimeStartTime); outputDirectory.close(); + + shutdownLibGraal(); + } + + /** + * Substituted by + * {@code com.oracle.svm.graal.hotspot.libgraal.Target_org_graalvm_compiler_hotspot_HotSpotGraalRuntime} + * to call {@code org.graalvm.nativeimage.VMRuntime.shutdown()}. + */ + private static void shutdownLibGraal() { } void clearMetrics() { @@ -580,6 +591,7 @@ private void dumpMethod(HotSpotResolvedJavaMethod hotSpotMethod, String filter, extra.put(DebugOptions.PrintGraphHost, host); extra.put(DebugOptions.PrintGraphPort, port); OptionValues compileOptions = new OptionValues(getOptions(), extra); + HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) runtime().getCompiler(); compiler.compileMethod(new HotSpotCompilationRequest(hotSpotMethod, -1, 0L), false, compileOptions); } diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java index 8c2fbda0674c..4d8f8a24becc 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java @@ -41,6 +41,7 @@ import org.graalvm.compiler.graph.NodeSourcePosition; import org.graalvm.compiler.hotspot.meta.HotSpotWordOperationPlugin; import org.graalvm.compiler.hotspot.word.HotSpotOperation; +import org.graalvm.compiler.nodes.Cancellable; import org.graalvm.compiler.nodes.Invoke; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; @@ -91,7 +92,7 @@ public void registerMethodSubstitution(MethodSubstitutionPlugin plugin, Resolved } @Override - public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug) { + public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug, Cancellable cancellable) { boolean useEncodedGraphs = UseEncodedGraphs.getValue(debug.getOptions()); if (IS_IN_NATIVE_IMAGE || useEncodedGraphs) { HotSpotReplacementsImpl replacements = (HotSpotReplacementsImpl) providers.getReplacements(); @@ -101,13 +102,13 @@ public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationI if (useEncodedGraphs) { replacements.registerMethodSubstitution(msp, method, ROOT_COMPILATION, debug.getOptions()); } - StructuredGraph methodSubstitution = replacements.getMethodSubstitution(msp, method, ROOT_COMPILATION, StructuredGraph.AllowAssumptions.YES, debug.getOptions()); + StructuredGraph methodSubstitution = replacements.getMethodSubstitution(msp, method, ROOT_COMPILATION, StructuredGraph.AllowAssumptions.YES, cancellable, debug.getOptions()); methodSubstitution.resetDebug(debug); return methodSubstitution; } return null; } - return super.getIntrinsicGraph(method, compilationId, debug); + return super.getIntrinsicGraph(method, compilationId, debug, cancellable); } @Override @@ -122,7 +123,7 @@ public StructuredGraph getSubstitution(ResolvedJavaMethod targetMethod, int invo } // This assumes the normal path creates the graph using // GraphBuilderConfiguration.getSnippetDefault with omits exception edges - StructuredGraph subst = getMethodSubstitution(msPlugin, targetMethod, INLINE_AFTER_PARSING, StructuredGraph.AllowAssumptions.NO, options); + StructuredGraph subst = getMethodSubstitution(msPlugin, targetMethod, INLINE_AFTER_PARSING, StructuredGraph.AllowAssumptions.NO, null, options); return subst; } } @@ -232,7 +233,7 @@ private StructuredGraph getEncodedSnippet(ResolvedJavaMethod method, Object[] ar @Override public StructuredGraph getMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context, - StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) { + StructuredGraph.AllowAssumptions allowAssumptions, Cancellable cancellable, OptionValues options) { boolean useEncodedGraphs = UseEncodedGraphs.getValue(options); if (IS_IN_NATIVE_IMAGE || useEncodedGraphs) { if (!IS_IN_NATIVE_IMAGE) { @@ -242,7 +243,7 @@ public StructuredGraph getMethodSubstitution(MethodSubstitutionPlugin plugin, Re if (getEncodedSnippets() == null) { throw GraalError.shouldNotReachHere("encoded snippets not found"); } - return getEncodedSnippets().getMethodSubstitutionGraph(plugin, original, this, context, allowAssumptions, options); + return getEncodedSnippets().getMethodSubstitutionGraph(plugin, original, this, context, allowAssumptions, cancellable, options); } return null; } diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java index c6b23cea4d57..cd35883cdcf7 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java @@ -41,9 +41,8 @@ */ public final class JVMCIVersionCheck { - // 0.57 introduces HotSpotJVMCIRuntime.excludeFromJVMCICompilation - private static final int JVMCI8_MIN_MAJOR_VERSION = 0; - private static final int JVMCI8_MIN_MINOR_VERSION = 57; + private static final int JVMCI8_MIN_MAJOR_VERSION = 19; + private static final int JVMCI8_MIN_MINOR_VERSION = 1; private static void failVersionCheck(Map props, boolean exit, String reason, Object... args) { Formatter errorMessage = new Formatter().format(reason, args); @@ -55,7 +54,7 @@ private static void failVersionCheck(Map props, boolean exit, St errorMessage.format("Currently used VM configuration is: %s%n", vmName); if (props.get("java.specification.version").compareTo("1.9") < 0) { errorMessage.format("Download the latest JVMCI JDK 8 from " + - "http://www.oracle.com/technetwork/oracle-labs/program-languages/downloads/index.html or " + + "https://www.oracle.com/technetwork/graalvm/downloads/index.html or " + "https://github.com/graalvm/openjdk8-jvmci-builder/releases"); } else { errorMessage.format("Download JDK 11 or later."); @@ -156,6 +155,14 @@ private boolean parseSeparator() { return false; } + private static String getJVMCIVersionString(int major, int minor) { + if (major >= 19) { + return String.format("%d-b%02d", major, minor); + } else { + return String.format("%d.%d", major, minor); + } + } + private void run(boolean exitOnFailure, int jvmci8MinMajorVersion, int jvmci8MinMinorVersion) { // Don't use regular expressions to minimize Graal startup time if (javaSpecVersion.compareTo("1.9") < 0) { @@ -180,8 +187,8 @@ private void run(boolean exitOnFailure, int jvmci8MinMajorVersion, int jvmci8Min if (major > jvmci8MinMajorVersion || (major >= jvmci8MinMajorVersion && minor >= jvmci8MinMinorVersion)) { return; } - failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %d.%d < %d.%d.%n", - major, minor, jvmci8MinMajorVersion, jvmci8MinMinorVersion); + failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %s < %s.%n", + getJVMCIVersionString(major, minor), getJVMCIVersionString(jvmci8MinMajorVersion, jvmci8MinMinorVersion)); return; } } diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java index 5369f2554b20..e4d33d8c4afa 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java @@ -66,6 +66,7 @@ import org.graalvm.compiler.java.GraphBuilderPhase; import org.graalvm.compiler.nodeinfo.Verbosity; import org.graalvm.compiler.nodes.CallTargetNode; +import org.graalvm.compiler.nodes.Cancellable; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.EncodedGraph; import org.graalvm.compiler.nodes.FrameState; @@ -283,24 +284,30 @@ static class EncodedSnippets { } StructuredGraph getMethodSubstitutionGraph(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, ReplacementsImpl replacements, IntrinsicContext.CompilationContext context, - StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) { + StructuredGraph.AllowAssumptions allowAssumptions, Cancellable cancellable, OptionValues options) { Integer startOffset = snippetStartOffsets.get(plugin.toString() + context); if (startOffset == null) { throw GraalError.shouldNotReachHere("plugin graph not found: " + plugin + " with " + context); } ResolvedJavaType accessingClass = replacements.getProviders().getMetaAccess().lookupJavaType(plugin.getDeclaringClass()); - return decodeGraph(original, accessingClass, startOffset, replacements, context, allowAssumptions, options); + return decodeGraph(original, accessingClass, startOffset, replacements, context, allowAssumptions, cancellable, options); } @SuppressWarnings("try") - private StructuredGraph decodeGraph(ResolvedJavaMethod method, ResolvedJavaType accessingClass, int startOffset, ReplacementsImpl replacements, - IntrinsicContext.CompilationContext context, StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) { + private StructuredGraph decodeGraph(ResolvedJavaMethod method, + ResolvedJavaType accessingClass, + int startOffset, + ReplacementsImpl replacements, + IntrinsicContext.CompilationContext context, + StructuredGraph.AllowAssumptions allowAssumptions, + Cancellable cancellable, + OptionValues options) { Providers providers = replacements.getProviders(); EncodedGraph encodedGraph = new SymbolicEncodedGraph(snippetEncoding, startOffset, snippetObjects, snippetNodeClasses, methodKey(method), accessingClass, method.getDeclaringClass()); try (DebugContext debug = replacements.openDebugContext("SVMSnippet_", method, options)) { - StructuredGraph result = new StructuredGraph.Builder(options, debug, allowAssumptions).method(method).setIsSubstitution(true).build(); + StructuredGraph result = new StructuredGraph.Builder(options, debug, allowAssumptions).cancellable(cancellable).method(method).setIsSubstitution(true).build(); PEGraphDecoder graphDecoder = new SubstitutionGraphDecoder(providers, result, replacements, null, method, context, encodedGraph); graphDecoder.decode(method, result.isSubstitution(), encodedGraph.trackNodeSourcePosition()); @@ -432,7 +439,7 @@ private boolean verifySnippetEncodeDecode(ResolvedJavaMethod method, ResolvedJav 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.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()); diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java index 6b3664b72f67..c0555d0c1c44 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java @@ -38,6 +38,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; +import org.graalvm.compiler.core.GraalServiceThread; import org.graalvm.compiler.core.common.SuppressFBWarnings; import org.graalvm.compiler.debug.CSVUtil; import org.graalvm.compiler.debug.GraalError; @@ -445,7 +446,7 @@ protected void patternFound(int index) { enabled = true; } if (Options.TimedDynamicCounters.getValue(options) > 0) { - Thread thread = new Thread() { + Thread thread = new GraalServiceThread(new Runnable() { long lastTime = System.nanoTime(); @Override @@ -462,7 +463,7 @@ public void run() { } } } - }; + }); thread.setDaemon(true); thread.setPriority(Thread.MAX_PRIORITY); thread.start(); diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/BarrierSet.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/BarrierSet.java deleted file mode 100644 index e66ffdfac5d5..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/BarrierSet.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.compiler.hotspot.gc.shared; - -import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; -import org.graalvm.compiler.nodes.StructuredGraph; -import org.graalvm.compiler.nodes.extended.ArrayRangeWrite; -import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode; -import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode; -import org.graalvm.compiler.nodes.memory.ReadNode; -import org.graalvm.compiler.nodes.memory.WriteNode; - -public abstract class BarrierSet { - private final GraalHotSpotVMConfig vmConfig; - - protected BarrierSet(GraalHotSpotVMConfig vmConfig) { - this.vmConfig = vmConfig; - } - - public final GraalHotSpotVMConfig getVMConfig() { - return vmConfig; - } - - public abstract void addReadNodeBarriers(ReadNode node, StructuredGraph graph); - - public abstract void addWriteNodeBarriers(WriteNode node, StructuredGraph graph); - - public abstract void addAtomicReadWriteNodeBarriers(LoweredAtomicReadAndWriteNode node, StructuredGraph graph); - - public abstract void addCASBarriers(AbstractCompareAndSwapNode node, StructuredGraph graph); - - public abstract void addArrayRangeBarriers(ArrayRangeWrite write, StructuredGraph graph); -} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/CardTableBarrierSet.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/CardTableBarrierSet.java deleted file mode 100644 index 4d157c5bd9b4..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/CardTableBarrierSet.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.compiler.hotspot.gc.shared; - -import org.graalvm.compiler.debug.GraalError; -import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; -import org.graalvm.compiler.nodes.StructuredGraph; -import org.graalvm.compiler.nodes.ValueNode; -import org.graalvm.compiler.nodes.extended.ArrayRangeWrite; -import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode; -import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode; -import org.graalvm.compiler.nodes.memory.FixedAccessNode; -import org.graalvm.compiler.nodes.memory.HeapAccess; -import org.graalvm.compiler.nodes.memory.ReadNode; -import org.graalvm.compiler.nodes.memory.WriteNode; -import org.graalvm.compiler.nodes.memory.address.AddressNode; -import org.graalvm.compiler.nodes.type.StampTool; - -public class CardTableBarrierSet extends BarrierSet { - - public CardTableBarrierSet(GraalHotSpotVMConfig vmConfig) { - super(vmConfig); - } - - @Override - public void addReadNodeBarriers(ReadNode node, StructuredGraph graph) { - // Nothing to do here. - } - - @Override - public void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) { - HeapAccess.BarrierType barrierType = node.getBarrierType(); - switch (barrierType) { - case NONE: - // nothing to do - break; - case FIELD: - case ARRAY: - case UNKNOWN: - boolean precise = barrierType != HeapAccess.BarrierType.FIELD; - boolean init = node.getLocationIdentity().isInit(); - if (!init || !getVMConfig().useDeferredInitBarriers) { - addSerialPostWriteBarrier(node, node.getAddress(), node.value(), precise, graph); - } - break; - default: - throw new GraalError("unexpected barrier type: " + barrierType); - } - } - - @Override - public void addAtomicReadWriteNodeBarriers(LoweredAtomicReadAndWriteNode node, StructuredGraph graph) { - HeapAccess.BarrierType barrierType = node.getBarrierType(); - switch (barrierType) { - case NONE: - // nothing to do - break; - case FIELD: - case ARRAY: - case UNKNOWN: - boolean precise = barrierType != HeapAccess.BarrierType.FIELD; - addSerialPostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); - break; - default: - throw new GraalError("unexpected barrier type: " + barrierType); - } - } - - @Override - public void addCASBarriers(AbstractCompareAndSwapNode node, StructuredGraph graph) { - HeapAccess.BarrierType barrierType = node.getBarrierType(); - switch (barrierType) { - case NONE: - // nothing to do - break; - case FIELD: - case ARRAY: - case UNKNOWN: - boolean precise = barrierType != HeapAccess.BarrierType.FIELD; - addSerialPostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); - break; - default: - throw new GraalError("unexpected barrier type: " + barrierType); - } - } - - @Override - public void addArrayRangeBarriers(ArrayRangeWrite write, StructuredGraph graph) { - SerialArrayRangeWriteBarrier serialArrayRangeWriteBarrier = graph.add(new SerialArrayRangeWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride())); - graph.addAfterFixed(write.asNode(), serialArrayRangeWriteBarrier); - } - - protected void addSerialPostWriteBarrier(FixedAccessNode node, AddressNode address, ValueNode value, boolean precise, StructuredGraph graph) { - final boolean alwaysNull = StampTool.isPointerAlwaysNull(value); - if (alwaysNull) { - // Serial barrier isn't needed for null value - return; - } - graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(address, precise))); - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java index c1013cd60562..e7a286d4b082 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java @@ -26,7 +26,6 @@ import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; import static org.graalvm.compiler.core.common.GraalOptions.AlwaysInlineVTableStubs; -import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; import static org.graalvm.compiler.core.common.GraalOptions.InlineVTableStubs; import static org.graalvm.compiler.core.common.GraalOptions.OmitHotExceptionStacktrace; import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.OSR_MIGRATION_END; @@ -39,6 +38,7 @@ import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HUB_WRITE_LOCATION; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.KLASS_LAYOUT_HELPER_LOCATION; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION; +import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier; import static org.graalvm.word.LocationIdentity.any; import java.lang.ref.Reference; @@ -60,13 +60,6 @@ import org.graalvm.compiler.graph.NodeInputList; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; -import org.graalvm.compiler.hotspot.gc.g1.G1ArrayRangePostWriteBarrier; -import org.graalvm.compiler.hotspot.gc.g1.G1ArrayRangePreWriteBarrier; -import org.graalvm.compiler.hotspot.gc.g1.G1PostWriteBarrier; -import org.graalvm.compiler.hotspot.gc.g1.G1PreWriteBarrier; -import org.graalvm.compiler.hotspot.gc.g1.G1ReferentFieldReadBarrier; -import org.graalvm.compiler.hotspot.gc.shared.SerialArrayRangeWriteBarrier; -import org.graalvm.compiler.hotspot.gc.shared.SerialWriteBarrier; import org.graalvm.compiler.hotspot.nodes.BeginLockScopeNode; import org.graalvm.compiler.hotspot.nodes.HotSpotCompressionNode; import org.graalvm.compiler.hotspot.nodes.HotSpotDirectCallTargetNode; @@ -82,6 +75,8 @@ import org.graalvm.compiler.hotspot.replacements.AssertionSnippets; import org.graalvm.compiler.hotspot.replacements.ClassGetHubNode; import org.graalvm.compiler.hotspot.replacements.HashCodeSnippets; +import org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets; +import org.graalvm.compiler.hotspot.replacements.HotSpotSerialWriteBarrierSnippets; import org.graalvm.compiler.hotspot.replacements.HubGetClassNode; import org.graalvm.compiler.hotspot.replacements.IdentityHashCodeNode; import org.graalvm.compiler.hotspot.replacements.InstanceOfSnippets; @@ -92,7 +87,6 @@ import org.graalvm.compiler.hotspot.replacements.ObjectCloneSnippets; import org.graalvm.compiler.hotspot.replacements.StringToBytesSnippets; import org.graalvm.compiler.hotspot.replacements.UnsafeLoadSnippets; -import org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets; import org.graalvm.compiler.hotspot.replacements.aot.ResolveConstantSnippets; import org.graalvm.compiler.hotspot.replacements.arraycopy.HotSpotArraycopySnippets; import org.graalvm.compiler.hotspot.replacements.profiling.ProfileSnippets; @@ -135,6 +129,13 @@ import org.graalvm.compiler.nodes.extended.OSRStartNode; import org.graalvm.compiler.nodes.extended.RawLoadNode; import org.graalvm.compiler.nodes.extended.StoreHubNode; +import org.graalvm.compiler.nodes.gc.G1ArrayRangePostWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1ArrayRangePreWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier; +import org.graalvm.compiler.nodes.gc.SerialArrayRangeWriteBarrier; +import org.graalvm.compiler.nodes.gc.SerialWriteBarrier; import org.graalvm.compiler.nodes.java.ClassIsAssignableFromNode; import org.graalvm.compiler.nodes.java.DynamicNewArrayNode; import org.graalvm.compiler.nodes.java.DynamicNewInstanceNode; @@ -164,7 +165,6 @@ import org.graalvm.compiler.replacements.arraycopy.ArrayCopySnippets; import org.graalvm.compiler.replacements.arraycopy.ArrayCopyWithDelayedLoweringNode; import org.graalvm.compiler.replacements.nodes.AssertionNode; -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; import org.graalvm.word.LocationIdentity; import jdk.vm.ci.code.TargetDescription; @@ -191,7 +191,8 @@ public class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider protected InstanceOfSnippets.Templates instanceofSnippets; protected NewObjectSnippets.Templates newObjectSnippets; protected MonitorSnippets.Templates monitorSnippets; - protected WriteBarrierSnippets.Templates writeBarrierSnippets; + protected HotSpotSerialWriteBarrierSnippets.Templates serialWriteBarrierSnippets; + protected HotSpotG1WriteBarrierSnippets.Templates g1WriteBarrierSnippets; protected LoadExceptionObjectSnippets.Templates exceptionObjectSnippets; protected UnsafeLoadSnippets.Templates unsafeLoadSnippets; protected AssertionSnippets.Templates assertionSnippets; @@ -220,7 +221,8 @@ public void initialize(OptionValues options, Iterable fact instanceofSnippets = new InstanceOfSnippets.Templates(options, factories, runtime, providers, target); newObjectSnippets = new NewObjectSnippets.Templates(options, factories, runtime, providers, target, config); monitorSnippets = new MonitorSnippets.Templates(options, factories, runtime, providers, target, config.useFastLocking); - writeBarrierSnippets = new WriteBarrierSnippets.Templates(options, factories, runtime, providers, target, config); + g1WriteBarrierSnippets = new HotSpotG1WriteBarrierSnippets.Templates(options, factories, runtime, providers, target, config); + serialWriteBarrierSnippets = new HotSpotSerialWriteBarrierSnippets.Templates(options, factories, runtime, providers, target, config); exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(options, factories, providers, target); unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(options, factories, providers, target); assertionSnippets = new AssertionSnippets.Templates(options, factories, providers, target); @@ -228,11 +230,14 @@ public void initialize(OptionValues options, Iterable fact stringToBytesSnippets = new StringToBytesSnippets.Templates(options, factories, providers, target); hashCodeSnippets = new HashCodeSnippets.Templates(options, factories, providers, target); resolveConstantSnippets = new ResolveConstantSnippets.Templates(options, factories, providers, target); - if (!JavaVersionUtil.Java8OrEarlier && GeneratePIC.getValue(options)) { - profileSnippets = new ProfileSnippets.Templates(options, factories, providers, target); - } objectCloneSnippets = new ObjectCloneSnippets.Templates(options, factories, providers, target); foreignCallSnippets = new ForeignCallSnippets.Templates(options, factories, providers, target); + if (Java8OrEarlier) { + // AOT only introduced in JDK 9 + profileSnippets = null; + } else { + profileSnippets = new ProfileSnippets.Templates(options, factories, providers, target); + } } public ArrayCopySnippets.Templates getArraycopySnippets() { @@ -340,19 +345,19 @@ public void lower(Node n, LoweringTool tool) { } else if (n instanceof ArrayCopyWithDelayedLoweringNode) { arraycopySnippets.lower((ArrayCopyWithDelayedLoweringNode) n, tool); } else if (n instanceof G1PreWriteBarrier) { - writeBarrierSnippets.lower((G1PreWriteBarrier) n, registers, tool); + g1WriteBarrierSnippets.lower((G1PreWriteBarrier) n, tool); } else if (n instanceof G1PostWriteBarrier) { - writeBarrierSnippets.lower((G1PostWriteBarrier) n, registers, tool); + g1WriteBarrierSnippets.lower((G1PostWriteBarrier) n, tool); } else if (n instanceof G1ReferentFieldReadBarrier) { - writeBarrierSnippets.lower((G1ReferentFieldReadBarrier) n, registers, tool); + g1WriteBarrierSnippets.lower((G1ReferentFieldReadBarrier) n, tool); } else if (n instanceof SerialWriteBarrier) { - writeBarrierSnippets.lower((SerialWriteBarrier) n, tool); + serialWriteBarrierSnippets.lower((SerialWriteBarrier) n, tool); } else if (n instanceof SerialArrayRangeWriteBarrier) { - writeBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool); + serialWriteBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool); } else if (n instanceof G1ArrayRangePreWriteBarrier) { - writeBarrierSnippets.lower((G1ArrayRangePreWriteBarrier) n, registers, tool); + g1WriteBarrierSnippets.lower((G1ArrayRangePreWriteBarrier) n, tool); } else if (n instanceof G1ArrayRangePostWriteBarrier) { - writeBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, registers, tool); + g1WriteBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, tool); } else if (n instanceof NewMultiArrayNode) { if (graph.getGuardsStage().areFrameStatesAtDeopts()) { newObjectSnippets.lower((NewMultiArrayNode) n, tool); diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGCProvider.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGCProvider.java new file mode 100644 index 000000000000..64e30af01d71 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGCProvider.java @@ -0,0 +1,53 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.graalvm.compiler.hotspot.meta; + +import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; +import org.graalvm.compiler.nodes.gc.BarrierSet; +import org.graalvm.compiler.nodes.gc.CardTableBarrierSet; +import org.graalvm.compiler.nodes.gc.G1BarrierSet; +import org.graalvm.compiler.nodes.spi.GCProvider; + +public class HotSpotGCProvider implements GCProvider { + private final BarrierSet barrierSet; + + public HotSpotGCProvider(GraalHotSpotVMConfig config) { + this.barrierSet = createBarrierSet(config); + } + + @Override + public BarrierSet getBarrierSet() { + return barrierSet; + } + + private static BarrierSet createBarrierSet(GraalHotSpotVMConfig config) { + boolean useDeferredInitBarriers = config.useDeferredInitBarriers; + if (config.useG1GC) { + return new G1BarrierSet(useDeferredInitBarriers); + } else { + return new CardTableBarrierSet(useDeferredInitBarriers); + } + } +} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java index b7beda5f0a7c..50af753f7898 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java @@ -81,24 +81,24 @@ import static org.graalvm.compiler.hotspot.HotSpotHostBackend.THROW_DELAYED_STACKOVERFLOW_ERROR; import static org.graalvm.compiler.hotspot.HotSpotHostBackend.UNCOMMON_TRAP_HANDLER; import static org.graalvm.compiler.hotspot.replacements.AssertionSnippets.ASSERTION_VM_MESSAGE_C; +import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.G1WBPOSTCALL; +import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.G1WBPRECALL; +import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.VALIDATE_OBJECT; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_END_LOCATION; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_TOP_LOCATION; +import static org.graalvm.compiler.hotspot.replacements.Log.LOG_OBJECT; +import static org.graalvm.compiler.hotspot.replacements.Log.LOG_PRIMITIVE; +import static org.graalvm.compiler.hotspot.replacements.Log.LOG_PRINTF; import static org.graalvm.compiler.hotspot.replacements.MonitorSnippets.MONITORENTER; import static org.graalvm.compiler.hotspot.replacements.MonitorSnippets.MONITOREXIT; import static org.graalvm.compiler.hotspot.replacements.NewObjectSnippets.DYNAMIC_NEW_INSTANCE; import static org.graalvm.compiler.hotspot.replacements.NewObjectSnippets.DYNAMIC_NEW_INSTANCE_OR_NULL; import static org.graalvm.compiler.hotspot.replacements.ThreadSubstitutions.THREAD_IS_INTERRUPTED; -import static org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets.G1WBPOSTCALL; -import static org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets.G1WBPRECALL; -import static org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets.VALIDATE_OBJECT; import static org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub.EXCEPTION_HANDLER_FOR_PC; import static org.graalvm.compiler.hotspot.stubs.StubUtil.VM_MESSAGE_C; import static org.graalvm.compiler.hotspot.stubs.UnwindExceptionToCallerStub.EXCEPTION_HANDLER_FOR_RETURN_ADDRESS; import static org.graalvm.compiler.nodes.java.ForeignCallDescriptors.REGISTER_FINALIZER; -import static org.graalvm.compiler.replacements.Log.LOG_OBJECT; -import static org.graalvm.compiler.replacements.Log.LOG_PRIMITIVE; -import static org.graalvm.compiler.replacements.Log.LOG_PRINTF; import static org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode.BinaryOperation.POW; import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.COS; import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.EXP; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotProviders.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotProviders.java index a21cf1bc1f0c..68777a7f0891 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotProviders.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotProviders.java @@ -50,17 +50,18 @@ public class HotSpotProviders extends Providers { private final SnippetReflectionProvider snippetReflection; private final HotSpotWordTypes wordTypes; private final Plugins graphBuilderPlugins; + private final HotSpotGCProvider gc; public HotSpotProviders(MetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantField, - HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, SuitesProvider suites, - HotSpotRegistersProvider registers, - SnippetReflectionProvider snippetReflection, HotSpotWordTypes wordTypes, Plugins graphBuilderPlugins) { - super(metaAccess, codeCache, constantReflection, constantField, foreignCalls, lowerer, replacements, new HotSpotStampProvider()); + HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, SuitesProvider suites, HotSpotRegistersProvider registers, + SnippetReflectionProvider snippetReflection, HotSpotWordTypes wordTypes, Plugins graphBuilderPlugins, HotSpotGCProvider gc) { + super(metaAccess, codeCache, constantReflection, constantField, foreignCalls, lowerer, replacements, new HotSpotStampProvider(), gc); this.suites = suites; this.registers = registers; this.snippetReflection = snippetReflection; this.wordTypes = wordTypes; this.graphBuilderPlugins = graphBuilderPlugins; + this.gc = gc; } @Override @@ -93,52 +94,55 @@ public HotSpotWordTypes getWordTypes() { return wordTypes; } + @Override + public HotSpotGCProvider getGC() { + return gc; + } + @Override public Providers copyWith(MetaAccessProvider substitution) { return new HotSpotProviders(substitution, getCodeCache(), getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), getLowerer(), getReplacements(), getSuites(), - getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC()); } @Override public Providers copyWith(CodeCacheProvider substitution) { return new HotSpotProviders(getMetaAccess(), (HotSpotCodeCacheProvider) substitution, getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), getLowerer(), getReplacements(), - getSuites(), - getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + getSuites(), getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC()); } @Override public Providers copyWith(ConstantReflectionProvider substitution) { return new HotSpotProviders(getMetaAccess(), getCodeCache(), substitution, getConstantFieldProvider(), getForeignCalls(), getLowerer(), getReplacements(), getSuites(), - getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC()); } @Override public Providers copyWith(ConstantFieldProvider substitution) { return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), substitution, getForeignCalls(), getLowerer(), getReplacements(), getSuites(), - getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC()); } @Override public Providers copyWith(ForeignCallsProvider substitution) { return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), getConstantFieldProvider(), (HotSpotForeignCallsProvider) substitution, getLowerer(), getReplacements(), - getSuites(), - getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + getSuites(), getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC()); } @Override public Providers copyWith(LoweringProvider substitution) { return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), substitution, getReplacements(), getSuites(), - getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC()); } @Override public Providers copyWith(Replacements substitution) { return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), getLowerer(), substitution, getSuites(), - getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins()); + getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC()); } public Providers copyWith(Plugins substitution) { return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), getLowerer(), getReplacements(), getSuites(), - getRegisters(), getSnippetReflection(), getWordTypes(), substitution); + getRegisters(), getSnippetReflection(), getWordTypes(), substitution, getGC()); } } diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSuitesProvider.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSuitesProvider.java index c5de83e66418..82648e11c025 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSuitesProvider.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSuitesProvider.java @@ -39,8 +39,6 @@ import org.graalvm.compiler.hotspot.lir.VerifyMaxRegisterSizePhase; import org.graalvm.compiler.hotspot.phases.AheadOfTimeVerificationPhase; import org.graalvm.compiler.hotspot.phases.LoadJavaMirrorWithKlassPhase; -import org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase; -import org.graalvm.compiler.hotspot.phases.WriteBarrierVerificationPhase; import org.graalvm.compiler.hotspot.phases.aot.AOTInliningPolicy; import org.graalvm.compiler.hotspot.phases.aot.EliminateRedundantInitializationPhase; import org.graalvm.compiler.hotspot.phases.aot.ReplaceConstantNodesPhase; @@ -112,11 +110,6 @@ public Suites createSuites(OptionValues options) { } } - ret.getMidTier().appendPhase(new WriteBarrierAdditionPhase(config)); - if (VerifyPhases.getValue(options)) { - ret.getMidTier().appendPhase(new WriteBarrierVerificationPhase(config)); - } - return ret; } diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/VMErrorNode.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/VMErrorNode.java index 27eed593202c..9ac52a95ea2a 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/VMErrorNode.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/VMErrorNode.java @@ -38,7 +38,6 @@ import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; -import org.graalvm.compiler.replacements.Log; import org.graalvm.compiler.replacements.nodes.CStringConstant; import jdk.vm.ci.code.CodeUtil; @@ -46,8 +45,8 @@ import jdk.vm.ci.meta.Value; /** - * Causes the VM to exit with a description of the current Java location and an optional - * {@linkplain Log#printf(String, long) formatted} error message specified. + * Causes the VM to exit with a description of the current Java location and an optional printf + * formatted error message specified. */ @NodeInfo(cycles = CYCLES_UNKNOWN, size = SIZE_UNKNOWN) public final class VMErrorNode extends DeoptimizingStubCall implements LIRLowerable { diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierAdditionPhase.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierAdditionPhase.java deleted file mode 100644 index 9d7346948c51..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierAdditionPhase.java +++ /dev/null @@ -1,93 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.compiler.hotspot.phases; - -import org.graalvm.compiler.debug.DebugCloseable; -import org.graalvm.compiler.graph.Node; -import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; -import org.graalvm.compiler.hotspot.gc.g1.G1BarrierSet; -import org.graalvm.compiler.hotspot.gc.shared.BarrierSet; -import org.graalvm.compiler.hotspot.gc.shared.CardTableBarrierSet; -import org.graalvm.compiler.nodes.StructuredGraph; -import org.graalvm.compiler.nodes.extended.ArrayRangeWrite; -import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode; -import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode; -import org.graalvm.compiler.nodes.memory.ReadNode; -import org.graalvm.compiler.nodes.memory.WriteNode; -import org.graalvm.compiler.phases.Phase; - -public class WriteBarrierAdditionPhase extends Phase { - - private BarrierSet barrierSet; - - public WriteBarrierAdditionPhase(GraalHotSpotVMConfig config) { - this.barrierSet = createBarrierSet(config); - } - - @SuppressWarnings("try") - @Override - protected void run(StructuredGraph graph) { - for (Node n : graph.getNodes()) { - try (DebugCloseable scope = n.graph().withNodeSourcePosition(n)) { - if (n instanceof ReadNode) { - barrierSet.addReadNodeBarriers((ReadNode) n, graph); - } else if (n instanceof WriteNode) { - barrierSet.addWriteNodeBarriers((WriteNode) n, graph); - } else if (n instanceof LoweredAtomicReadAndWriteNode) { - LoweredAtomicReadAndWriteNode loweredAtomicReadAndWriteNode = (LoweredAtomicReadAndWriteNode) n; - barrierSet.addAtomicReadWriteNodeBarriers(loweredAtomicReadAndWriteNode, graph); - } else if (n instanceof AbstractCompareAndSwapNode) { - barrierSet.addCASBarriers((AbstractCompareAndSwapNode) n, graph); - } else if (n instanceof ArrayRangeWrite) { - ArrayRangeWrite node = (ArrayRangeWrite) n; - if (node.writesObjectArray()) { - barrierSet.addArrayRangeBarriers(node, graph); - } - } - } - } - } - - @Override - public boolean checkContract() { - return false; - } - - private BarrierSet createBarrierSet(GraalHotSpotVMConfig config) { - if (config.useG1GC) { - return createG1BarrierSet(config); - } else { - return createCardTableBarrierSet(config); - } - } - - protected BarrierSet createCardTableBarrierSet(GraalHotSpotVMConfig config) { - return new CardTableBarrierSet(config); - } - - protected BarrierSet createG1BarrierSet(GraalHotSpotVMConfig config) { - return new G1BarrierSet(config); - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierVerificationPhase.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierVerificationPhase.java deleted file mode 100644 index 6978b16c013e..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierVerificationPhase.java +++ /dev/null @@ -1,207 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.graalvm.compiler.hotspot.phases; - -import java.util.Iterator; - -import org.graalvm.compiler.debug.GraalError; -import org.graalvm.compiler.graph.Node; -import org.graalvm.compiler.graph.NodeFlood; -import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; -import org.graalvm.compiler.hotspot.gc.g1.G1PostWriteBarrier; -import org.graalvm.compiler.hotspot.gc.shared.ArrayRangeWriteBarrier; -import org.graalvm.compiler.hotspot.gc.shared.ObjectWriteBarrier; -import org.graalvm.compiler.hotspot.gc.shared.SerialWriteBarrier; -import org.graalvm.compiler.nodeinfo.Verbosity; -import org.graalvm.compiler.nodes.DeoptimizingNode; -import org.graalvm.compiler.nodes.FixedWithNextNode; -import org.graalvm.compiler.nodes.LoopBeginNode; -import org.graalvm.compiler.nodes.StructuredGraph; -import org.graalvm.compiler.nodes.ValueNode; -import org.graalvm.compiler.nodes.extended.ArrayRangeWrite; -import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode; -import org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode; -import org.graalvm.compiler.nodes.java.ValueCompareAndSwapNode; -import org.graalvm.compiler.nodes.memory.FixedAccessNode; -import org.graalvm.compiler.nodes.memory.HeapAccess; -import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType; -import org.graalvm.compiler.nodes.memory.ReadNode; -import org.graalvm.compiler.nodes.memory.WriteNode; -import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; -import org.graalvm.compiler.nodes.type.StampTool; -import org.graalvm.compiler.nodes.util.GraphUtil; -import org.graalvm.compiler.phases.Phase; - -/** - * Verification phase that checks if, for every write, at least one write barrier is present at all - * paths leading to the previous safepoint. For every write, necessitating a write barrier, a - * bottom-up traversal of the graph is performed up to the previous safepoints via all possible - * paths. If, for a certain path, no write barrier satisfying the processed write is found, an - * assertion is generated. - */ -public class WriteBarrierVerificationPhase extends Phase { - - private final GraalHotSpotVMConfig config; - - public WriteBarrierVerificationPhase(GraalHotSpotVMConfig config) { - this.config = config; - } - - @Override - protected void run(StructuredGraph graph) { - processWrites(graph); - } - - private void processWrites(StructuredGraph graph) { - for (Node node : graph.getNodes()) { - if (isObjectWrite(node) || isObjectArrayRangeWrite(node)) { - if (node instanceof WriteNode) { - WriteNode writeNode = (WriteNode) node; - if (StampTool.isPointerAlwaysNull(writeNode.value())) { - continue; - } - } - validateWrite(node); - } - } - } - - private void validateWrite(Node write) { - /* - * The currently validated write is checked in order to discover if it has an appropriate - * attached write barrier. - */ - if (hasAttachedBarrier((FixedWithNextNode) write)) { - return; - } - NodeFlood frontier = write.graph().createNodeFlood(); - expandFrontier(frontier, write); - Iterator iterator = frontier.iterator(); - while (iterator.hasNext()) { - Node currentNode = iterator.next(); - if (isSafepoint(currentNode)) { - throw new AssertionError("Write barrier must be present " + write.toString(Verbosity.All) + " / " + write.inputs()); - } - if (useG1GC()) { - if (!(currentNode instanceof G1PostWriteBarrier) || (!validateBarrier((FixedAccessNode) write, (ObjectWriteBarrier) currentNode))) { - expandFrontier(frontier, currentNode); - } - } else { - if (!(currentNode instanceof SerialWriteBarrier) || (!validateBarrier((FixedAccessNode) write, (ObjectWriteBarrier) currentNode)) || - ((currentNode instanceof SerialWriteBarrier) && !validateBarrier((FixedAccessNode) write, (ObjectWriteBarrier) currentNode))) { - expandFrontier(frontier, currentNode); - } - } - } - } - - private boolean useG1GC() { - return config.useG1GC; - } - - private boolean hasAttachedBarrier(FixedWithNextNode node) { - final Node next = node.next(); - final Node previous = node.predecessor(); - boolean validatePreBarrier = useG1GC() && (isObjectWrite(node) || !((ArrayRangeWrite) node).isInitialization()); - if (node instanceof WriteNode) { - WriteNode writeNode = (WriteNode) node; - if (config.useDeferredInitBarriers && writeNode.getLocationIdentity().isInit()) { - return true; - } - if (writeNode.getLocationIdentity().isInit()) { - validatePreBarrier = false; - } - } - if (isObjectWrite(node)) { - return (isObjectBarrier(node, next) || StampTool.isPointerAlwaysNull(getValueWritten(node))) && (!validatePreBarrier || isObjectBarrier(node, previous)); - } else if (isObjectArrayRangeWrite(node)) { - return (isArrayBarrier(node, next) || StampTool.isPointerAlwaysNull(getValueWritten(node))) && (!validatePreBarrier || isArrayBarrier(node, previous)); - } else { - return true; - } - } - - private static boolean isObjectBarrier(FixedWithNextNode node, final Node next) { - return next instanceof ObjectWriteBarrier && validateBarrier((FixedAccessNode) node, (ObjectWriteBarrier) next); - } - - private static boolean isArrayBarrier(FixedWithNextNode node, final Node next) { - return (next instanceof ArrayRangeWriteBarrier) && ((ArrayRangeWrite) node).getAddress() == ((ArrayRangeWriteBarrier) next).getAddress(); - } - - private static boolean isObjectWrite(Node node) { - // Read nodes with barrier attached (G1 Ref field) are not validated yet. - return node instanceof FixedAccessNode && ((HeapAccess) node).getBarrierType() != BarrierType.NONE && !(node instanceof ReadNode); - } - - private static boolean isObjectArrayRangeWrite(Node node) { - return node instanceof ArrayRangeWrite && ((ArrayRangeWrite) node).writesObjectArray(); - } - - private static void expandFrontier(NodeFlood frontier, Node node) { - for (Node previousNode : node.cfgPredecessors()) { - if (previousNode != null) { - frontier.add(previousNode); - } - } - } - - private static boolean isSafepoint(Node node) { - if (node instanceof FixedAccessNode) { - // Implicit null checks on reads or writes do not count. - return false; - } - /* - * LoopBegin nodes are also treated as safepoints since a bottom-up analysis is performed - * and loop safepoints are placed before LoopEnd nodes. Possible elimination of write - * barriers inside loops, derived from writes outside loops, can not be permitted. - */ - return ((node instanceof DeoptimizingNode) && ((DeoptimizingNode) node).canDeoptimize()) || (node instanceof LoopBeginNode); - } - - private static ValueNode getValueWritten(FixedWithNextNode write) { - if (write instanceof WriteNode) { - return ((WriteNode) write).value(); - } else if (write instanceof LogicCompareAndSwapNode) { - return ((LogicCompareAndSwapNode) write).getNewValue(); - } else if (write instanceof LoweredAtomicReadAndWriteNode) { - return ((LoweredAtomicReadAndWriteNode) write).getNewValue(); - } else { - throw GraalError.shouldNotReachHere(String.format("unexpected write node %s", write)); - } - } - - private static boolean validateBarrier(FixedAccessNode write, ObjectWriteBarrier barrier) { - assert write instanceof WriteNode || write instanceof LogicCompareAndSwapNode || write instanceof ValueCompareAndSwapNode || - write instanceof LoweredAtomicReadAndWriteNode : "Node must be of type requiring a write barrier " + write; - if (!barrier.usePrecise()) { - if (barrier.getAddress() instanceof OffsetAddressNode && write.getAddress() instanceof OffsetAddressNode) { - return GraphUtil.unproxify(((OffsetAddressNode) barrier.getAddress()).getBase()) == GraphUtil.unproxify(((OffsetAddressNode) write.getAddress()).getBase()); - } - } - return barrier.getAddress() == write.getAddress(); - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotG1WriteBarrierSnippets.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotG1WriteBarrierSnippets.java new file mode 100644 index 000000000000..0d58d963c4c3 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotG1WriteBarrierSnippets.java @@ -0,0 +1,238 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.graalvm.compiler.hotspot.replacements; + +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS; +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_VMCONFIG; + +import org.graalvm.compiler.core.common.CompressEncoding; +import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; +import org.graalvm.compiler.debug.DebugHandlersFactory; +import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; +import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl; +import org.graalvm.compiler.hotspot.meta.HotSpotProviders; +import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider; +import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode; +import org.graalvm.compiler.hotspot.nodes.HotSpotCompressionNode; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.gc.G1ArrayRangePostWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1ArrayRangePreWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier; +import org.graalvm.compiler.nodes.spi.LoweringTool; +import org.graalvm.compiler.options.OptionValues; +import org.graalvm.compiler.replacements.ReplacementsUtil; +import org.graalvm.compiler.replacements.SnippetCounter.Group; +import org.graalvm.compiler.replacements.SnippetCounter.Group.Factory; +import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates; +import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo; +import org.graalvm.compiler.replacements.gc.G1WriteBarrierSnippets; +import org.graalvm.compiler.word.Word; + +import jdk.vm.ci.code.Register; +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.meta.JavaKind; + +public final class HotSpotG1WriteBarrierSnippets extends G1WriteBarrierSnippets { + public static final ForeignCallDescriptor G1WBPRECALL = new ForeignCallDescriptor("write_barrier_pre", void.class, Object.class); + public static final ForeignCallDescriptor G1WBPOSTCALL = new ForeignCallDescriptor("write_barrier_post", void.class, Word.class); + public static final ForeignCallDescriptor VALIDATE_OBJECT = new ForeignCallDescriptor("validate_object", boolean.class, Word.class, Word.class); + + private final GraalHotSpotVMConfig config; + private final Register threadRegister; + + public HotSpotG1WriteBarrierSnippets(GraalHotSpotVMConfig config, HotSpotRegistersProvider registers) { + this.config = config; + this.threadRegister = registers.getThreadRegister(); + } + + @Override + protected Word getThread() { + return HotSpotReplacementsUtil.registerAsWord(threadRegister); + } + + @Override + protected int wordSize() { + return HotSpotReplacementsUtil.wordSize(); + } + + @Override + protected int objectArrayIndexScale() { + return ReplacementsUtil.arrayIndexScale(INJECTED_METAACCESS, JavaKind.Object); + } + + @Override + protected int satbQueueMarkingOffset() { + return HotSpotReplacementsUtil.g1SATBQueueMarkingOffset(INJECTED_VMCONFIG); + } + + @Override + protected int satbQueueBufferOffset() { + return HotSpotReplacementsUtil.g1SATBQueueBufferOffset(INJECTED_VMCONFIG); + } + + @Override + protected int satbQueueIndexOffset() { + return HotSpotReplacementsUtil.g1SATBQueueIndexOffset(INJECTED_VMCONFIG); + } + + @Override + protected int cardQueueBufferOffset() { + return HotSpotReplacementsUtil.g1CardQueueBufferOffset(INJECTED_VMCONFIG); + } + + @Override + protected int cardQueueIndexOffset() { + return HotSpotReplacementsUtil.g1CardQueueIndexOffset(INJECTED_VMCONFIG); + } + + @Override + protected byte dirtyCardValue() { + return HotSpotReplacementsUtil.dirtyCardValue(INJECTED_VMCONFIG); + } + + @Override + protected byte youngCardValue() { + return HotSpotReplacementsUtil.g1YoungCardValue(INJECTED_VMCONFIG); + } + + @Override + protected long cardTableAddress() { + return GraalHotSpotVMConfigNode.cardTableAddress(); + } + + @Override + protected boolean isCardTableAddressConstant() { + return GraalHotSpotVMConfigNode.isCardTableAddressConstant(); + } + + @Override + protected int cardTableShift() { + return HotSpotReplacementsUtil.cardTableShift(INJECTED_VMCONFIG); + } + + @Override + protected int logOfHeapRegionGrainBytes() { + return GraalHotSpotVMConfigNode.logOfHeapRegionGrainBytes(); + } + + @Override + protected ForeignCallDescriptor preWriteBarrierCallDescriptor() { + return G1WBPRECALL; + } + + @Override + protected ForeignCallDescriptor postWriteBarrierCallDescriptor() { + return G1WBPOSTCALL; + } + + @Override + protected boolean verifyOops() { + return HotSpotReplacementsUtil.verifyOops(INJECTED_VMCONFIG); + } + + @Override + protected boolean verifyBarrier() { + return ReplacementsUtil.REPLACEMENTS_ASSERTIONS_ENABLED || config.verifyBeforeGC || config.verifyAfterGC; + } + + @Override + protected long gcTotalCollectionsAddress() { + return HotSpotReplacementsUtil.gcTotalCollectionsAddress(INJECTED_VMCONFIG); + } + + @Override + protected ForeignCallDescriptor verifyOopCallDescriptor() { + return HotSpotForeignCallsProviderImpl.VERIFY_OOP; + } + + @Override + protected ForeignCallDescriptor validateObjectCallDescriptor() { + return VALIDATE_OBJECT; + } + + @Override + protected ForeignCallDescriptor printfCallDescriptor() { + return Log.LOG_PRINTF; + } + + public static class Templates extends AbstractTemplates { + private final SnippetInfo g1PreWriteBarrier; + private final SnippetInfo g1ReferentReadBarrier; + private final SnippetInfo g1PostWriteBarrier; + private final SnippetInfo g1ArrayRangePreWriteBarrier; + private final SnippetInfo g1ArrayRangePostWriteBarrier; + + private final G1WriteBarrierLowerer lowerer; + + public Templates(OptionValues options, Iterable factories, Group.Factory factory, HotSpotProviders providers, TargetDescription target, GraalHotSpotVMConfig config) { + super(options, factories, providers, providers.getSnippetReflection(), target); + this.lowerer = new HotspotG1WriteBarrierLowerer(config, factory); + + HotSpotG1WriteBarrierSnippets receiver = new HotSpotG1WriteBarrierSnippets(config, providers.getRegisters()); + g1PreWriteBarrier = snippet(G1WriteBarrierSnippets.class, "g1PreWriteBarrier", null, receiver, GC_INDEX_LOCATION, GC_LOG_LOCATION); + g1ReferentReadBarrier = g1PreWriteBarrier; + g1PostWriteBarrier = snippet(G1WriteBarrierSnippets.class, "g1PostWriteBarrier", null, receiver, GC_CARD_LOCATION, GC_INDEX_LOCATION, GC_LOG_LOCATION); + g1ArrayRangePreWriteBarrier = snippet(G1WriteBarrierSnippets.class, "g1ArrayRangePreWriteBarrier", null, receiver, GC_INDEX_LOCATION, GC_LOG_LOCATION); + g1ArrayRangePostWriteBarrier = snippet(G1WriteBarrierSnippets.class, "g1ArrayRangePostWriteBarrier", null, receiver, GC_CARD_LOCATION, GC_INDEX_LOCATION, GC_LOG_LOCATION); + } + + public void lower(G1PreWriteBarrier barrier, LoweringTool tool) { + lowerer.lower(this, g1PreWriteBarrier, barrier, tool); + } + + public void lower(G1ReferentFieldReadBarrier barrier, LoweringTool tool) { + lowerer.lower(this, g1ReferentReadBarrier, barrier, tool); + } + + public void lower(G1PostWriteBarrier barrier, LoweringTool tool) { + lowerer.lower(this, g1PostWriteBarrier, barrier, tool); + } + + public void lower(G1ArrayRangePreWriteBarrier barrier, LoweringTool tool) { + lowerer.lower(this, g1ArrayRangePreWriteBarrier, barrier, tool); + } + + public void lower(G1ArrayRangePostWriteBarrier barrier, LoweringTool tool) { + lowerer.lower(this, g1ArrayRangePostWriteBarrier, barrier, tool); + } + } + + static final class HotspotG1WriteBarrierLowerer extends G1WriteBarrierLowerer { + private final CompressEncoding oopEncoding; + + HotspotG1WriteBarrierLowerer(GraalHotSpotVMConfig config, Factory factory) { + super(factory); + oopEncoding = config.useCompressedOops ? config.getOopEncoding() : null; + } + + @Override + public ValueNode uncompress(ValueNode expected) { + assert oopEncoding != null; + return HotSpotCompressionNode.uncompress(expected, oopEncoding); + } + } +} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotSerialWriteBarrierSnippets.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotSerialWriteBarrierSnippets.java new file mode 100644 index 000000000000..685c3a3750b7 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotSerialWriteBarrierSnippets.java @@ -0,0 +1,97 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.graalvm.compiler.hotspot.replacements; + +import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_VMCONFIG; + +import org.graalvm.compiler.debug.DebugHandlersFactory; +import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; +import org.graalvm.compiler.hotspot.meta.HotSpotProviders; +import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode; +import org.graalvm.compiler.nodes.gc.SerialArrayRangeWriteBarrier; +import org.graalvm.compiler.nodes.gc.SerialWriteBarrier; +import org.graalvm.compiler.nodes.spi.LoweringTool; +import org.graalvm.compiler.options.OptionValues; +import org.graalvm.compiler.replacements.ReplacementsUtil; +import org.graalvm.compiler.replacements.SnippetCounter.Group; +import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates; +import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo; +import org.graalvm.compiler.replacements.gc.SerialWriteBarrierSnippets; + +import jdk.vm.ci.code.TargetDescription; + +public class HotSpotSerialWriteBarrierSnippets extends SerialWriteBarrierSnippets { + private final GraalHotSpotVMConfig config; + + public HotSpotSerialWriteBarrierSnippets(GraalHotSpotVMConfig config) { + this.config = config; + } + + @Override + public boolean isCardTableAddressConstant() { + return GraalHotSpotVMConfigNode.isCardTableAddressConstant(); + } + + @Override + public long cardTableAddress() { + return GraalHotSpotVMConfigNode.cardTableAddress(); + } + + @Override + public int cardTableShift() { + return HotSpotReplacementsUtil.cardTableShift(INJECTED_VMCONFIG); + } + + @Override + public boolean verifyBarrier() { + return ReplacementsUtil.REPLACEMENTS_ASSERTIONS_ENABLED || config.verifyBeforeGC || config.verifyAfterGC; + } + + public static class Templates extends AbstractTemplates { + private final SnippetInfo serialImpreciseWriteBarrier; + private final SnippetInfo serialPreciseWriteBarrier; + private final SnippetInfo serialArrayRangeWriteBarrier; + + private final SerialWriteBarrierLowerer lowerer; + + public Templates(OptionValues options, Iterable factories, Group.Factory factory, HotSpotProviders providers, TargetDescription target, GraalHotSpotVMConfig config) { + super(options, factories, providers, providers.getSnippetReflection(), target); + this.lowerer = new SerialWriteBarrierLowerer(factory); + + HotSpotSerialWriteBarrierSnippets receiver = new HotSpotSerialWriteBarrierSnippets(config); + serialImpreciseWriteBarrier = snippet(SerialWriteBarrierSnippets.class, "serialImpreciseWriteBarrier", null, receiver, GC_CARD_LOCATION); + serialPreciseWriteBarrier = snippet(SerialWriteBarrierSnippets.class, "serialPreciseWriteBarrier", null, receiver, GC_CARD_LOCATION); + serialArrayRangeWriteBarrier = snippet(SerialWriteBarrierSnippets.class, "serialArrayRangeWriteBarrier", null, receiver); + } + + public void lower(SerialWriteBarrier barrier, LoweringTool tool) { + lowerer.lower(this, serialPreciseWriteBarrier, serialImpreciseWriteBarrier, barrier, tool); + } + + public void lower(SerialArrayRangeWriteBarrier barrier, LoweringTool tool) { + lowerer.lower(this, serialArrayRangeWriteBarrier, barrier, tool); + } + } +} diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/Log.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/Log.java similarity index 99% rename from compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/Log.java rename to compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/Log.java index 571fe2f763bd..57758e18625c 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/Log.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/Log.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package org.graalvm.compiler.replacements; +package org.graalvm.compiler.hotspot.replacements; import static org.graalvm.compiler.replacements.nodes.CStringConstant.cstring; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java index c655c15f0c7c..0caedabffce6 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java @@ -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,7 +122,6 @@ import org.graalvm.compiler.nodes.type.StampTool; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.common.inlining.InliningUtil; -import org.graalvm.compiler.replacements.Log; import org.graalvm.compiler.replacements.SnippetCounter; import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates; import org.graalvm.compiler.replacements.SnippetTemplate.Arguments; @@ -753,7 +752,8 @@ public Counters(SnippetCounter.Group.Factory factory) { public static class Templates extends AbstractTemplates { private final SnippetInfo monitorenter = snippet(MonitorSnippets.class, "monitorenter"); - private final SnippetInfo monitorexit = snippet(MonitorSnippets.class, "monitorexit"); + private final SnippetInfo monitorexit = snippet(MonitorSnippets.class, "monitorexit", DISPLACED_MARK_WORD_LOCATION, OBJECT_MONITOR_OWNER_LOCATION, OBJECT_MONITOR_CXQ_LOCATION, + OBJECT_MONITOR_ENTRY_LIST_LOCATION, OBJECT_MONITOR_RECURSION_LOCATION, OBJECT_MONITOR_SUCC_LOCATION); private final SnippetInfo monitorenterStub = snippet(MonitorSnippets.class, "monitorenterStub"); private final SnippetInfo monitorexitStub = snippet(MonitorSnippets.class, "monitorexitStub"); private final SnippetInfo initCounter = snippet(MonitorSnippets.class, "initCounter"); diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java index 94548593d0c0..81248cd27ee0 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java @@ -38,6 +38,7 @@ import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_MULTI_ARRAY; import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_MULTI_ARRAY_OR_NULL; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_ARRAY_KLASS_LOCATION; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_STATE_LOCATION; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HUB_WRITE_LOCATION; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.PROTOTYPE_MARK_WORD_LOCATION; @@ -714,9 +715,10 @@ static class Counters { public static class Templates extends AbstractTemplates { - private final SnippetInfo allocateInstance = snippet(NewObjectSnippets.class, "allocateInstance", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION); + private final SnippetInfo allocateInstance = snippet(NewObjectSnippets.class, "allocateInstance", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION, + PROTOTYPE_MARK_WORD_LOCATION); private final SnippetInfo allocateInstancePIC = snippet(NewObjectSnippets.class, "allocateInstancePIC", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, - TLAB_END_LOCATION); + TLAB_END_LOCATION, PROTOTYPE_MARK_WORD_LOCATION); private final SnippetInfo allocateArray = snippet(NewObjectSnippets.class, "allocateArray", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION); private final SnippetInfo allocateArrayPIC = snippet(NewObjectSnippets.class, "allocateArrayPIC", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION); private final SnippetInfo allocatePrimitiveArrayPIC = snippet(NewObjectSnippets.class, "allocatePrimitiveArrayPIC", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, @@ -724,7 +726,7 @@ public static class Templates extends AbstractTemplates { private final SnippetInfo allocateArrayDynamic = snippet(NewObjectSnippets.class, "allocateArrayDynamic", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION); private final SnippetInfo allocateInstanceDynamic = snippet(NewObjectSnippets.class, "allocateInstanceDynamic", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, - TLAB_END_LOCATION); + TLAB_END_LOCATION, PROTOTYPE_MARK_WORD_LOCATION, CLASS_STATE_LOCATION); private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray", TLAB_TOP_LOCATION, TLAB_END_LOCATION); private final SnippetInfo newmultiarrayPIC = snippet(NewObjectSnippets.class, "newmultiarrayPIC", TLAB_TOP_LOCATION, TLAB_END_LOCATION); private final SnippetInfo verifyHeap = snippet(NewObjectSnippets.class, "verifyHeap"); diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java deleted file mode 100644 index aa1ee487e185..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java +++ /dev/null @@ -1,621 +0,0 @@ -/* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.compiler.hotspot.replacements; - -import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD; -import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG; -import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.cardTableShift; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.dirtyCardValue; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.g1CardQueueBufferOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.g1CardQueueIndexOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.g1SATBQueueBufferOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.g1SATBQueueIndexOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.g1SATBQueueMarkingOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.g1YoungCardValue; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.verifyOop; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.verifyOops; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.wordSize; -import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FREQUENT_PROBABILITY; -import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LIKELY_PROBABILITY; -import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY; -import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability; -import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER; - -import org.graalvm.compiler.api.replacements.Snippet; -import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter; -import org.graalvm.compiler.core.common.CompressEncoding; -import org.graalvm.compiler.core.common.GraalOptions; -import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; -import org.graalvm.compiler.debug.DebugHandlersFactory; -import org.graalvm.compiler.graph.Node.ConstantNodeParameter; -import org.graalvm.compiler.graph.Node.NodeIntrinsic; -import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; -import org.graalvm.compiler.hotspot.gc.g1.G1ArrayRangePostWriteBarrier; -import org.graalvm.compiler.hotspot.gc.g1.G1ArrayRangePreWriteBarrier; -import org.graalvm.compiler.hotspot.gc.g1.G1PostWriteBarrier; -import org.graalvm.compiler.hotspot.gc.g1.G1PreWriteBarrier; -import org.graalvm.compiler.hotspot.gc.g1.G1ReferentFieldReadBarrier; -import org.graalvm.compiler.hotspot.gc.shared.SerialArrayRangeWriteBarrier; -import org.graalvm.compiler.hotspot.gc.shared.SerialWriteBarrier; -import org.graalvm.compiler.hotspot.meta.HotSpotProviders; -import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider; -import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode; -import org.graalvm.compiler.hotspot.nodes.HotSpotCompressionNode; -import org.graalvm.compiler.hotspot.nodes.VMErrorNode; -import org.graalvm.compiler.nodes.NamedLocationIdentity; -import org.graalvm.compiler.nodes.NodeView; -import org.graalvm.compiler.nodes.PiNode; -import org.graalvm.compiler.nodes.SnippetAnchorNode; -import org.graalvm.compiler.nodes.StructuredGraph; -import org.graalvm.compiler.nodes.ValueNode; -import org.graalvm.compiler.nodes.extended.FixedValueAnchorNode; -import org.graalvm.compiler.nodes.extended.ForeignCallNode; -import org.graalvm.compiler.nodes.extended.MembarNode; -import org.graalvm.compiler.nodes.extended.NullCheckNode; -import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType; -import org.graalvm.compiler.nodes.memory.address.AddressNode; -import org.graalvm.compiler.nodes.memory.address.AddressNode.Address; -import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; -import org.graalvm.compiler.nodes.spi.LoweringTool; -import org.graalvm.compiler.nodes.type.NarrowOopStamp; -import org.graalvm.compiler.options.OptionValues; -import org.graalvm.compiler.replacements.Log; -import org.graalvm.compiler.replacements.ReplacementsUtil; -import org.graalvm.compiler.replacements.SnippetCounter; -import org.graalvm.compiler.replacements.SnippetCounter.Group; -import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates; -import org.graalvm.compiler.replacements.SnippetTemplate.Arguments; -import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo; -import org.graalvm.compiler.replacements.Snippets; -import org.graalvm.compiler.replacements.nodes.AssertionNode; -import org.graalvm.compiler.replacements.nodes.DirectStoreNode; -import org.graalvm.compiler.word.Word; -import org.graalvm.word.LocationIdentity; -import org.graalvm.word.Pointer; -import org.graalvm.word.UnsignedWord; -import org.graalvm.word.WordFactory; - -import jdk.vm.ci.code.Register; -import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.meta.JavaKind; - -public class WriteBarrierSnippets implements Snippets { - - static class Counters { - Counters(SnippetCounter.Group.Factory factory) { - Group countersWriteBarriers = factory.createSnippetCounterGroup("WriteBarriers"); - serialWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "serialWriteBarrier", "Number of Serial Write Barriers"); - g1AttemptedPreWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1AttemptedPreWriteBarrier", "Number of attempted G1 Pre Write Barriers"); - g1EffectivePreWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1EffectivePreWriteBarrier", "Number of effective G1 Pre Write Barriers"); - g1ExecutedPreWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1ExecutedPreWriteBarrier", "Number of executed G1 Pre Write Barriers"); - g1AttemptedPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1AttemptedPostWriteBarrier", "Number of attempted G1 Post Write Barriers"); - g1EffectiveAfterXORPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1EffectiveAfterXORPostWriteBarrier", - "Number of effective G1 Post Write Barriers (after passing the XOR test)"); - g1EffectiveAfterNullPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1EffectiveAfterNullPostWriteBarrier", - "Number of effective G1 Post Write Barriers (after passing the NULL test)"); - g1ExecutedPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1ExecutedPostWriteBarrier", "Number of executed G1 Post Write Barriers"); - - } - - final SnippetCounter serialWriteBarrierCounter; - final SnippetCounter g1AttemptedPreWriteBarrierCounter; - final SnippetCounter g1EffectivePreWriteBarrierCounter; - final SnippetCounter g1ExecutedPreWriteBarrierCounter; - final SnippetCounter g1AttemptedPostWriteBarrierCounter; - final SnippetCounter g1EffectiveAfterXORPostWriteBarrierCounter; - final SnippetCounter g1EffectiveAfterNullPostWriteBarrierCounter; - final SnippetCounter g1ExecutedPostWriteBarrierCounter; - } - - public static final LocationIdentity GC_CARD_LOCATION = NamedLocationIdentity.mutable("GC-Card"); - public static final LocationIdentity GC_LOG_LOCATION = NamedLocationIdentity.mutable("GC-Log"); - public static final LocationIdentity GC_INDEX_LOCATION = NamedLocationIdentity.mutable("GC-Index"); - - private static void serialWriteBarrier(Pointer ptr, Counters counters) { - counters.serialWriteBarrierCounter.inc(); - final long startAddress = GraalHotSpotVMConfigNode.cardTableAddress(); - Word base = (Word) ptr.unsignedShiftRight(cardTableShift(INJECTED_VMCONFIG)); - if (((int) startAddress) == startAddress && GraalHotSpotVMConfigNode.isCardTableAddressConstant()) { - base.writeByte((int) startAddress, (byte) 0, GC_CARD_LOCATION); - } else { - base.writeByte(WordFactory.unsigned(startAddress), (byte) 0, GC_CARD_LOCATION); - } - } - - @Snippet - public static void serialImpreciseWriteBarrier(Object object, @ConstantParameter boolean verifyBarrier, @ConstantParameter Counters counters) { - if (verifyBarrier) { - verifyNotArray(object); - } - serialWriteBarrier(Word.objectToTrackedPointer(object), counters); - } - - @Snippet - public static void serialPreciseWriteBarrier(Address address, @ConstantParameter Counters counters) { - serialWriteBarrier(Word.fromAddress(address), counters); - } - - @Snippet - public static void serialArrayRangeWriteBarrier(Address address, int length, @ConstantParameter int elementStride) { - if (length == 0) { - return; - } - int cardShift = cardTableShift(INJECTED_VMCONFIG); - final long cardStart = GraalHotSpotVMConfigNode.cardTableAddress(); - long start = getPointerToFirstArrayElement(address, length, elementStride) >>> cardShift; - long end = getPointerToLastArrayElement(address, length, elementStride) >>> cardShift; - long count = end - start + 1; - while (count-- > 0) { - DirectStoreNode.storeBoolean((start + cardStart) + count, false, JavaKind.Boolean); - } - } - - @Snippet - public static void g1PreWriteBarrier(Address address, Object object, Object expectedObject, @ConstantParameter boolean doLoad, @ConstantParameter boolean nullCheck, - @ConstantParameter Register threadRegister, @ConstantParameter boolean trace, @ConstantParameter Counters counters) { - if (nullCheck) { - NullCheckNode.nullCheck(address); - } - Word thread = registerAsWord(threadRegister); - verifyOop(object); - Object fixedExpectedObject = FixedValueAnchorNode.getObject(expectedObject); - Word field = Word.fromAddress(address); - Pointer previousOop = Word.objectToTrackedPointer(fixedExpectedObject); - byte markingValue = thread.readByte(g1SATBQueueMarkingOffset(INJECTED_VMCONFIG)); - int gcCycle = 0; - if (trace) { - Pointer gcTotalCollectionsAddress = WordFactory.pointer(HotSpotReplacementsUtil.gcTotalCollectionsAddress(INJECTED_VMCONFIG)); - gcCycle = (int) gcTotalCollectionsAddress.readLong(0); - log(trace, "[%d] G1-Pre Thread %p Object %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(object).rawValue()); - log(trace, "[%d] G1-Pre Thread %p Expected Object %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(fixedExpectedObject).rawValue()); - log(trace, "[%d] G1-Pre Thread %p Field %p\n", gcCycle, thread.rawValue(), field.rawValue()); - log(trace, "[%d] G1-Pre Thread %p Marking %d\n", gcCycle, thread.rawValue(), markingValue); - log(trace, "[%d] G1-Pre Thread %p DoLoad %d\n", gcCycle, thread.rawValue(), doLoad ? 1L : 0L); - } - counters.g1AttemptedPreWriteBarrierCounter.inc(); - // If the concurrent marker is enabled, the barrier is issued. - if (probability(NOT_FREQUENT_PROBABILITY, markingValue != (byte) 0)) { - // If the previous value has to be loaded (before the write), the load is issued. - // The load is always issued except the cases of CAS and referent field. - if (probability(LIKELY_PROBABILITY, doLoad)) { - previousOop = Word.objectToTrackedPointer(field.readObject(0, BarrierType.NONE)); - if (trace) { - log(trace, "[%d] G1-Pre Thread %p Previous Object %p\n ", gcCycle, thread.rawValue(), previousOop.rawValue()); - verifyOop(previousOop.toObject()); - } - } - counters.g1EffectivePreWriteBarrierCounter.inc(); - // If the previous value is null the barrier should not be issued. - if (probability(FREQUENT_PROBABILITY, previousOop.notEqual(0))) { - counters.g1ExecutedPreWriteBarrierCounter.inc(); - // If the thread-local SATB buffer is full issue a native call which will - // initialize a new one and add the entry. - Word indexAddress = thread.add(g1SATBQueueIndexOffset(INJECTED_VMCONFIG)); - Word indexValue = indexAddress.readWord(0); - if (probability(FREQUENT_PROBABILITY, indexValue.notEqual(0))) { - Word bufferAddress = thread.readWord(g1SATBQueueBufferOffset(INJECTED_VMCONFIG)); - Word nextIndex = indexValue.subtract(wordSize()); - Word logAddress = bufferAddress.add(nextIndex); - // Log the object to be marked as well as update the SATB's buffer next index. - logAddress.writeWord(0, previousOop, GC_LOG_LOCATION); - indexAddress.writeWord(0, nextIndex, GC_INDEX_LOCATION); - } else { - g1PreBarrierStub(G1WBPRECALL, previousOop.toObject()); - } - } - } - } - - @Snippet - public static void g1PostWriteBarrier(Address address, Object object, Object value, @ConstantParameter boolean usePrecise, @ConstantParameter boolean verifyBarrier, - @ConstantParameter Register threadRegister, @ConstantParameter boolean trace, @ConstantParameter Counters counters) { - Word thread = registerAsWord(threadRegister); - Object fixedValue = FixedValueAnchorNode.getObject(value); - verifyOop(object); - verifyOop(fixedValue); - validateObject(object, fixedValue); - Pointer oop; - if (usePrecise) { - oop = Word.fromAddress(address); - } else { - if (verifyBarrier) { - verifyNotArray(object); - } - oop = Word.objectToTrackedPointer(object); - } - int gcCycle = 0; - if (trace) { - Pointer gcTotalCollectionsAddress = WordFactory.pointer(HotSpotReplacementsUtil.gcTotalCollectionsAddress(INJECTED_VMCONFIG)); - gcCycle = (int) gcTotalCollectionsAddress.readLong(0); - log(trace, "[%d] G1-Post Thread: %p Object: %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(object).rawValue()); - log(trace, "[%d] G1-Post Thread: %p Field: %p\n", gcCycle, thread.rawValue(), oop.rawValue()); - } - Pointer writtenValue = Word.objectToTrackedPointer(fixedValue); - // The result of the xor reveals whether the installed pointer crosses heap regions. - // In case it does the write barrier has to be issued. - final int logOfHeapRegionGrainBytes = GraalHotSpotVMConfigNode.logOfHeapRegionGrainBytes(); - UnsignedWord xorResult = (oop.xor(writtenValue)).unsignedShiftRight(logOfHeapRegionGrainBytes); - - // Calculate the address of the card to be enqueued to the - // thread local card queue. - UnsignedWord cardBase = oop.unsignedShiftRight(cardTableShift(INJECTED_VMCONFIG)); - final long startAddress = GraalHotSpotVMConfigNode.cardTableAddress(); - int displacement = 0; - if (((int) startAddress) == startAddress && GraalHotSpotVMConfigNode.isCardTableAddressConstant()) { - displacement = (int) startAddress; - } else { - cardBase = cardBase.add(WordFactory.unsigned(startAddress)); - } - Word cardAddress = (Word) cardBase.add(displacement); - - counters.g1AttemptedPostWriteBarrierCounter.inc(); - if (probability(FREQUENT_PROBABILITY, xorResult.notEqual(0))) { - counters.g1EffectiveAfterXORPostWriteBarrierCounter.inc(); - - // If the written value is not null continue with the barrier addition. - if (probability(FREQUENT_PROBABILITY, writtenValue.notEqual(0))) { - byte cardByte = cardAddress.readByte(0, GC_CARD_LOCATION); - counters.g1EffectiveAfterNullPostWriteBarrierCounter.inc(); - - // If the card is already dirty, (hence already enqueued) skip the insertion. - if (probability(NOT_FREQUENT_PROBABILITY, cardByte != g1YoungCardValue(INJECTED_VMCONFIG))) { - MembarNode.memoryBarrier(STORE_LOAD, GC_CARD_LOCATION); - byte cardByteReload = cardAddress.readByte(0, GC_CARD_LOCATION); - if (probability(NOT_FREQUENT_PROBABILITY, cardByteReload != dirtyCardValue(INJECTED_VMCONFIG))) { - log(trace, "[%d] G1-Post Thread: %p Card: %p \n", gcCycle, thread.rawValue(), WordFactory.unsigned((int) cardByte).rawValue()); - cardAddress.writeByte(0, (byte) 0, GC_CARD_LOCATION); - counters.g1ExecutedPostWriteBarrierCounter.inc(); - - // If the thread local card queue is full, issue a native call which will - // initialize a new one and add the card entry. - Word indexAddress = thread.add(g1CardQueueIndexOffset(INJECTED_VMCONFIG)); - Word indexValue = thread.readWord(g1CardQueueIndexOffset(INJECTED_VMCONFIG)); - if (probability(FREQUENT_PROBABILITY, indexValue.notEqual(0))) { - Word bufferAddress = thread.readWord(g1CardQueueBufferOffset(INJECTED_VMCONFIG)); - Word nextIndex = indexValue.subtract(wordSize()); - Word logAddress = bufferAddress.add(nextIndex); - // Log the object to be scanned as well as update - // the card queue's next index. - logAddress.writeWord(0, cardAddress, GC_LOG_LOCATION); - indexAddress.writeWord(0, nextIndex, GC_INDEX_LOCATION); - } else { - g1PostBarrierStub(G1WBPOSTCALL, cardAddress); - } - } - } - } - } - } - - private static void verifyNotArray(Object object) { - if (object != null) { - // Manually build the null check and cast because we're in snippet that's lowered late. - AssertionNode.assertion(false, !PiNode.piCastNonNull(object, SnippetAnchorNode.anchor()).getClass().isArray(), "imprecise card mark used with array"); - } - } - - @Snippet - public static void g1ArrayRangePreWriteBarrier(Address address, int length, @ConstantParameter int elementStride, @ConstantParameter Register threadRegister) { - Word thread = registerAsWord(threadRegister); - byte markingValue = thread.readByte(g1SATBQueueMarkingOffset(INJECTED_VMCONFIG)); - // If the concurrent marker is not enabled or the vector length is zero, return. - if (markingValue == (byte) 0 || length == 0) { - return; - } - Word bufferAddress = thread.readWord(g1SATBQueueBufferOffset(INJECTED_VMCONFIG)); - Word indexAddress = thread.add(g1SATBQueueIndexOffset(INJECTED_VMCONFIG)); - long indexValue = indexAddress.readWord(0).rawValue(); - final int scale = ReplacementsUtil.arrayIndexScale(INJECTED_METAACCESS, JavaKind.Object); - long start = getPointerToFirstArrayElement(address, length, elementStride); - - for (int i = 0; i < length; i++) { - Word arrElemPtr = WordFactory.pointer(start + i * scale); - Pointer oop = Word.objectToTrackedPointer(arrElemPtr.readObject(0, BarrierType.NONE)); - verifyOop(oop.toObject()); - if (oop.notEqual(0)) { - if (indexValue != 0) { - indexValue = indexValue - wordSize(); - Word logAddress = bufferAddress.add(WordFactory.unsigned(indexValue)); - // Log the object to be marked as well as update the SATB's buffer next index. - logAddress.writeWord(0, oop, GC_LOG_LOCATION); - indexAddress.writeWord(0, WordFactory.unsigned(indexValue), GC_INDEX_LOCATION); - } else { - g1PreBarrierStub(G1WBPRECALL, oop.toObject()); - } - } - } - } - - @Snippet - public static void g1ArrayRangePostWriteBarrier(Address address, int length, @ConstantParameter int elementStride, @ConstantParameter Register threadRegister) { - if (length == 0) { - return; - } - Word thread = registerAsWord(threadRegister); - Word bufferAddress = thread.readWord(g1CardQueueBufferOffset(INJECTED_VMCONFIG)); - Word indexAddress = thread.add(g1CardQueueIndexOffset(INJECTED_VMCONFIG)); - long indexValue = thread.readWord(g1CardQueueIndexOffset(INJECTED_VMCONFIG)).rawValue(); - - int cardShift = cardTableShift(INJECTED_VMCONFIG); - final long cardStart = GraalHotSpotVMConfigNode.cardTableAddress(); - long start = getPointerToFirstArrayElement(address, length, elementStride) >>> cardShift; - long end = getPointerToLastArrayElement(address, length, elementStride) >>> cardShift; - long count = end - start + 1; - - while (count-- > 0) { - Word cardAddress = WordFactory.unsigned((start + cardStart) + count); - byte cardByte = cardAddress.readByte(0, GC_CARD_LOCATION); - // If the card is already dirty, (hence already enqueued) skip the insertion. - if (probability(NOT_FREQUENT_PROBABILITY, cardByte != g1YoungCardValue(INJECTED_VMCONFIG))) { - MembarNode.memoryBarrier(STORE_LOAD, GC_CARD_LOCATION); - byte cardByteReload = cardAddress.readByte(0, GC_CARD_LOCATION); - if (probability(NOT_FREQUENT_PROBABILITY, cardByteReload != dirtyCardValue(INJECTED_VMCONFIG))) { - cardAddress.writeByte(0, (byte) 0, GC_CARD_LOCATION); - // If the thread local card queue is full, issue a native call which will - // initialize a new one and add the card entry. - if (indexValue != 0) { - indexValue = indexValue - wordSize(); - Word logAddress = bufferAddress.add(WordFactory.unsigned(indexValue)); - // Log the object to be scanned as well as update - // the card queue's next index. - logAddress.writeWord(0, cardAddress, GC_LOG_LOCATION); - indexAddress.writeWord(0, WordFactory.unsigned(indexValue), GC_INDEX_LOCATION); - } else { - g1PostBarrierStub(G1WBPOSTCALL, cardAddress); - } - } - } - } - } - - private static long getPointerToFirstArrayElement(Address address, int length, int elementStride) { - long result = Word.fromAddress(address).rawValue(); - if (elementStride < 0) { - // the address points to the place after the last array element - result = result + elementStride * length; - } - return result; - } - - private static long getPointerToLastArrayElement(Address address, int length, int elementStride) { - long result = Word.fromAddress(address).rawValue(); - if (elementStride < 0) { - // the address points to the place after the last array element - result = result + elementStride; - } else { - result = result + (length - 1) * elementStride; - } - return result; - } - - public static final ForeignCallDescriptor G1WBPRECALL = new ForeignCallDescriptor("write_barrier_pre", void.class, Object.class); - - @NodeIntrinsic(ForeignCallNode.class) - private static native void g1PreBarrierStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object); - - public static final ForeignCallDescriptor G1WBPOSTCALL = new ForeignCallDescriptor("write_barrier_post", void.class, Word.class); - - @NodeIntrinsic(ForeignCallNode.class) - public static native void g1PostBarrierStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word card); - - public static class Templates extends AbstractTemplates { - - private final SnippetInfo serialImpreciseWriteBarrier = snippet(WriteBarrierSnippets.class, "serialImpreciseWriteBarrier", GC_CARD_LOCATION); - private final SnippetInfo serialPreciseWriteBarrier = snippet(WriteBarrierSnippets.class, "serialPreciseWriteBarrier", GC_CARD_LOCATION); - private final SnippetInfo serialArrayRangeWriteBarrier = snippet(WriteBarrierSnippets.class, "serialArrayRangeWriteBarrier"); - private final SnippetInfo g1PreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PreWriteBarrier", GC_INDEX_LOCATION, GC_LOG_LOCATION); - private final SnippetInfo g1ReferentReadBarrier = g1PreWriteBarrier; - private final SnippetInfo g1PostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PostWriteBarrier", GC_CARD_LOCATION, GC_INDEX_LOCATION, GC_LOG_LOCATION); - private final SnippetInfo g1ArrayRangePreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePreWriteBarrier", GC_INDEX_LOCATION, GC_LOG_LOCATION); - private final SnippetInfo g1ArrayRangePostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePostWriteBarrier", GC_CARD_LOCATION, GC_INDEX_LOCATION, GC_LOG_LOCATION); - - private final CompressEncoding oopEncoding; - private final Counters counters; - private final boolean verifyBarrier; - private final long gcTotalCollectionsAddress; - - public Templates(OptionValues options, Iterable factories, Group.Factory factory, HotSpotProviders providers, TargetDescription target, - GraalHotSpotVMConfig config) { - super(options, factories, providers, providers.getSnippetReflection(), target); - this.oopEncoding = config.useCompressedOops ? config.getOopEncoding() : null; - this.verifyBarrier = ReplacementsUtil.REPLACEMENTS_ASSERTIONS_ENABLED || config.verifyBeforeGC || config.verifyAfterGC; - this.gcTotalCollectionsAddress = config.gcTotalCollectionsAddress(); - this.counters = new Counters(factory); - } - - public boolean traceBarrier(StructuredGraph graph) { - long startCycle = GraalOptions.GCDebugStartCycle.getValue(graph.getOptions()); - return startCycle > 0 && ((Pointer) WordFactory.pointer(gcTotalCollectionsAddress)).readLong(0) > startCycle; - } - - public void lower(SerialWriteBarrier writeBarrier, LoweringTool tool) { - Arguments args; - if (writeBarrier.usePrecise()) { - args = new Arguments(serialPreciseWriteBarrier, writeBarrier.graph().getGuardsStage(), tool.getLoweringStage()); - args.add("address", writeBarrier.getAddress()); - } else { - args = new Arguments(serialImpreciseWriteBarrier, writeBarrier.graph().getGuardsStage(), tool.getLoweringStage()); - OffsetAddressNode address = (OffsetAddressNode) writeBarrier.getAddress(); - args.add("object", address.getBase()); - args.addConst("verifyBarrier", verifyBarrier); - } - args.addConst("counters", counters); - template(writeBarrier, args).instantiate(providers.getMetaAccess(), writeBarrier, DEFAULT_REPLACER, args); - } - - public void lower(SerialArrayRangeWriteBarrier arrayRangeWriteBarrier, LoweringTool tool) { - Arguments args = new Arguments(serialArrayRangeWriteBarrier, arrayRangeWriteBarrier.graph().getGuardsStage(), tool.getLoweringStage()); - args.add("address", arrayRangeWriteBarrier.getAddress()); - args.add("length", arrayRangeWriteBarrier.getLength()); - args.addConst("elementStride", arrayRangeWriteBarrier.getElementStride()); - template(arrayRangeWriteBarrier, args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args); - } - - public void lower(G1PreWriteBarrier writeBarrierPre, HotSpotRegistersProvider registers, LoweringTool tool) { - Arguments args = new Arguments(g1PreWriteBarrier, writeBarrierPre.graph().getGuardsStage(), tool.getLoweringStage()); - AddressNode address = writeBarrierPre.getAddress(); - args.add("address", address); - if (address instanceof OffsetAddressNode) { - args.add("object", ((OffsetAddressNode) address).getBase()); - } else { - args.add("object", null); - } - - ValueNode expected = writeBarrierPre.getExpectedObject(); - if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) { - assert oopEncoding != null; - expected = HotSpotCompressionNode.uncompress(expected, oopEncoding); - } - args.add("expectedObject", expected); - - args.addConst("doLoad", writeBarrierPre.doLoad()); - args.addConst("nullCheck", writeBarrierPre.getNullCheck()); - args.addConst("threadRegister", registers.getThreadRegister()); - args.addConst("trace", traceBarrier(writeBarrierPre.graph())); - args.addConst("counters", counters); - template(writeBarrierPre, args).instantiate(providers.getMetaAccess(), writeBarrierPre, DEFAULT_REPLACER, args); - } - - public void lower(G1ReferentFieldReadBarrier readBarrier, HotSpotRegistersProvider registers, LoweringTool tool) { - Arguments args = new Arguments(g1ReferentReadBarrier, readBarrier.graph().getGuardsStage(), tool.getLoweringStage()); - AddressNode address = readBarrier.getAddress(); - args.add("address", address); - if (address instanceof OffsetAddressNode) { - args.add("object", ((OffsetAddressNode) address).getBase()); - } else { - args.add("object", null); - } - - ValueNode expected = readBarrier.getExpectedObject(); - if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) { - assert oopEncoding != null; - expected = HotSpotCompressionNode.uncompress(expected, oopEncoding); - } - - args.add("expectedObject", expected); - args.addConst("doLoad", readBarrier.doLoad()); - args.addConst("nullCheck", false); - args.addConst("threadRegister", registers.getThreadRegister()); - args.addConst("trace", traceBarrier(readBarrier.graph())); - args.addConst("counters", counters); - template(readBarrier, args).instantiate(providers.getMetaAccess(), readBarrier, DEFAULT_REPLACER, args); - } - - public void lower(G1PostWriteBarrier writeBarrierPost, HotSpotRegistersProvider registers, LoweringTool tool) { - StructuredGraph graph = writeBarrierPost.graph(); - if (writeBarrierPost.alwaysNull()) { - graph.removeFixed(writeBarrierPost); - return; - } - Arguments args = new Arguments(g1PostWriteBarrier, graph.getGuardsStage(), tool.getLoweringStage()); - AddressNode address = writeBarrierPost.getAddress(); - args.add("address", address); - if (address instanceof OffsetAddressNode) { - args.add("object", ((OffsetAddressNode) address).getBase()); - } else { - assert writeBarrierPost.usePrecise() : "found imprecise barrier that's not an object access " + writeBarrierPost; - args.add("object", null); - } - - ValueNode value = writeBarrierPost.getValue(); - if (value.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) { - assert oopEncoding != null; - value = HotSpotCompressionNode.uncompress(value, oopEncoding); - } - args.add("value", value); - - args.addConst("usePrecise", writeBarrierPost.usePrecise()); - args.addConst("verifyBarrier", verifyBarrier); - args.addConst("threadRegister", registers.getThreadRegister()); - args.addConst("trace", traceBarrier(writeBarrierPost.graph())); - args.addConst("counters", counters); - template(writeBarrierPost, args).instantiate(providers.getMetaAccess(), writeBarrierPost, DEFAULT_REPLACER, args); - } - - public void lower(G1ArrayRangePreWriteBarrier arrayRangeWriteBarrier, HotSpotRegistersProvider registers, LoweringTool tool) { - Arguments args = new Arguments(g1ArrayRangePreWriteBarrier, arrayRangeWriteBarrier.graph().getGuardsStage(), tool.getLoweringStage()); - args.add("address", arrayRangeWriteBarrier.getAddress()); - args.add("length", arrayRangeWriteBarrier.getLength()); - args.addConst("elementStride", arrayRangeWriteBarrier.getElementStride()); - args.addConst("threadRegister", registers.getThreadRegister()); - template(arrayRangeWriteBarrier, args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args); - } - - public void lower(G1ArrayRangePostWriteBarrier arrayRangeWriteBarrier, HotSpotRegistersProvider registers, LoweringTool tool) { - Arguments args = new Arguments(g1ArrayRangePostWriteBarrier, arrayRangeWriteBarrier.graph().getGuardsStage(), tool.getLoweringStage()); - args.add("address", arrayRangeWriteBarrier.getAddress()); - args.add("length", arrayRangeWriteBarrier.getLength()); - args.addConst("elementStride", arrayRangeWriteBarrier.getElementStride()); - args.addConst("threadRegister", registers.getThreadRegister()); - template(arrayRangeWriteBarrier, args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args); - } - } - - /** - * Log method of debugging purposes. - */ - public static void log(boolean enabled, String format, long value) { - if (enabled) { - Log.printf(format, value); - } - } - - public static void log(boolean enabled, String format, long value1, long value2) { - if (enabled) { - Log.printf(format, value1, value2); - } - } - - public static void log(boolean enabled, String format, long value1, long value2, long value3) { - if (enabled) { - Log.printf(format, value1, value2, value3); - } - } - - /** - * Validation helper method which performs sanity checks on write operations. The addresses of - * both the object and the value being written are checked in order to determine if they reside - * in a valid heap region. If an object is stale, an invalid access is performed in order to - * prematurely crash the VM and debug the stack trace of the faulty method. - */ - public static void validateObject(Object parent, Object child) { - if (verifyOops(INJECTED_VMCONFIG) && child != null) { - Word parentWord = Word.objectToTrackedPointer(parent); - Word childWord = Word.objectToTrackedPointer(child); - if (!validateOop(VALIDATE_OBJECT, parentWord, childWord)) { - log(true, "Verification ERROR, Parent: %p Child: %p\n", parentWord.rawValue(), childWord.rawValue()); - VMErrorNode.vmError("Verification ERROR, Parent: %p\n", parentWord.rawValue()); - } - } - } - - public static final ForeignCallDescriptor VALIDATE_OBJECT = new ForeignCallDescriptor("validate_object", boolean.class, Word.class, Word.class); - - @NodeIntrinsic(ForeignCallNode.class) - private static native boolean validateOop(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word parent, Word object); - -} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java index 05f8208628b1..754abccd0649 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java @@ -39,7 +39,7 @@ import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.nodes.StubForeignCallNode; import org.graalvm.compiler.hotspot.nodes.VMErrorNode; -import org.graalvm.compiler.replacements.Log; +import org.graalvm.compiler.hotspot.replacements.Log; import org.graalvm.compiler.word.Word; import org.graalvm.word.WordFactory; diff --git a/compiler/src/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java b/compiler/src/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java index 5a64cc11dba5..b77151f43928 100644 --- a/compiler/src/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java +++ b/compiler/src/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java @@ -43,7 +43,6 @@ import org.graalvm.compiler.bytecode.Bytecode; import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode; -import org.graalvm.compiler.core.common.GraalOptions; import org.graalvm.compiler.core.common.PermanentBailoutException; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.core.common.type.StampPair; @@ -146,7 +145,7 @@ public FrameStateBuilder(GraphBuilderTool tool, Bytecode code, StructuredGraph g this.monitorIds = EMPTY_MONITOR_ARRAY; this.graph = graph; - this.clearNonLiveLocals = GraalOptions.OptClearNonLiveLocals.getValue(graph.getOptions()) && !shouldRetainLocalVariables; + this.clearNonLiveLocals = !shouldRetainLocalVariables; this.canVerifyKind = true; } @@ -275,8 +274,6 @@ private FrameStateBuilder(FrameStateBuilder other) { clearNonLiveLocals = other.clearNonLiveLocals; monitorIds = other.monitorIds.length == 0 ? other.monitorIds : other.monitorIds.clone(); - assert locals.length == code.getMaxLocals(); - assert stack.length == Math.max(1, code.getMaxStackSize()); assert lockedObjects.length == monitorIds.length; } @@ -791,7 +788,7 @@ public void pushReturn(JavaKind slotKind, ValueNode x) { public ValueNode pop(JavaKind slotKind) { if (slotKind.needsTwoSlots()) { ValueNode s = xpop(); - assert s == TWO_SLOT_MARKER; + assert s == TWO_SLOT_MARKER : s; } ValueNode x = xpop(); assert verifyKind(slotKind, x); @@ -835,7 +832,7 @@ public ValueNode[] popArguments(int argSize) { /* Ignore second slot of two-slot value. */ x = xpop(); } - assert x != null && x != TWO_SLOT_MARKER; + assert x != null && x != TWO_SLOT_MARKER : x; result[i] = x; } return result; diff --git a/compiler/src/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/TrichotomyFloats.java b/compiler/src/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/TrichotomyFloats.java new file mode 100644 index 000000000000..06b536b32b25 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/TrichotomyFloats.java @@ -0,0 +1,131 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.jtt.optimize; + +import org.junit.Test; + +import org.graalvm.compiler.jtt.JTTTest; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/* + * Tests comparison-based canonicalizations for floats. + */ +@RunWith(Parameterized.class) +public class TrichotomyFloats extends JTTTest { + + public static int test0(float x, float y) { + return x < y ? -1 : (x == y ? 0 : 1); + } + + public static int test1(float x, float y) { + return x < y ? 1 : (x == y ? 0 : -1); + } + + public static int test2(float x, float y) { + return x == y ? 0 : (x < y ? -1 : 1); + } + + public static int test3(float x, float y) { + return x == y ? 0 : (x < y ? 1 : -1); + } + + public static int test4(float x, float y) { + return x == y ? 0 : (x > y ? -1 : 1); + } + + public static int test5(float x, float y) { + return x == y ? 0 : (x > y ? 1 : -1); + } + + public static int test6(float x, float y) { + return x < y ? 1 : (x > y ? -1 : 0); + } + + public static int test7(float x, float y) { + return x < y ? -1 : (x > y ? 1 : 0); + } + + @Parameter(value = 0) public float x; + @Parameter(value = 1) public float y; + + @Parameters(name = "x = {0}, y = {1}") + public static Collection data() { + List parameters = new ArrayList<>(); + float[] floats = {Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NaN, 0f, -1f, Float.MIN_VALUE, Float.MAX_VALUE}; + for (float f1 : floats) { + for (float f2 : floats) { + parameters.add(new Object[]{f1, f2}); + } + } + return parameters; + } + + @Test + public void run0() { + runTest("test0", x, y); + } + + @Test + public void run1() { + runTest("test1", x, y); + } + + @Test + public void run2() { + runTest("test2", x, y); + } + + @Test + public void run3() { + runTest("test3", x, y); + } + + @Test + public void run4() { + runTest("test4", x, y); + } + + @Test + public void run5() { + runTest("test5", x, y); + } + + @Test + public void run6() { + runTest("test6", x, y); + } + + @Test + public void run7() { + runTest("test7", x, y); + } +} diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java index e7cecd6cdd03..0be031817976 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java @@ -40,6 +40,7 @@ import org.graalvm.compiler.bytecode.Bytes; import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode; import org.graalvm.compiler.core.common.calc.Condition; +import org.graalvm.compiler.core.common.type.FloatStamp; import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.StampFactory; @@ -58,9 +59,11 @@ import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.calc.CompareNode; import org.graalvm.compiler.nodes.calc.ConditionalNode; +import org.graalvm.compiler.nodes.calc.FloatLessThanNode; import org.graalvm.compiler.nodes.calc.IntegerBelowNode; import org.graalvm.compiler.nodes.calc.IntegerEqualsNode; import org.graalvm.compiler.nodes.calc.IntegerLessThanNode; +import org.graalvm.compiler.nodes.calc.IntegerLowerThanNode; import org.graalvm.compiler.nodes.calc.IsNullNode; import org.graalvm.compiler.nodes.calc.NormalizeCompareNode; import org.graalvm.compiler.nodes.calc.ObjectEqualsNode; @@ -980,25 +983,32 @@ private ValueNode canonicalizeConditionalCascade(SimplifierTool tool, ValueNode return graph().unique(new NormalizeCompareNode(x, y, stackKind, false)); } else if (cond1 == Condition.LT && cond2 == Condition.EQ && c1 == 1 && c2 == 0 && c3 == -1) { // x < y ? 1 : (x == y ? 0 : -1) => y cmp x - return graph().unique(new NormalizeCompareNode(y, x, stackKind, false)); + return graph().unique(new NormalizeCompareNode(y, x, stackKind, true)); } else if (cond1 == Condition.EQ && cond2 == Condition.LT && c1 == 0 && c2 == -1 && c3 == 1) { // x == y ? 0 : (x < y ? -1 : 1) => x cmp y return graph().unique(new NormalizeCompareNode(x, y, stackKind, false)); } else if (cond1 == Condition.EQ && cond2 == Condition.LT && c1 == 0 && c2 == 1 && c3 == -1) { // x == y ? 0 : (x < y ? 1 : -1) => y cmp x - return graph().unique(new NormalizeCompareNode(y, x, stackKind, false)); + return graph().unique(new NormalizeCompareNode(y, x, stackKind, true)); } else if (cond1 == Condition.EQ && cond2 == Condition.GT && c1 == 0 && c2 == -1 && c3 == 1) { // x == y ? 0 : (x > y ? -1 : 1) => y cmp x return graph().unique(new NormalizeCompareNode(y, x, stackKind, false)); } else if (cond1 == Condition.EQ && cond2 == Condition.GT && c1 == 0 && c2 == 1 && c3 == -1) { // x == y ? 0 : (x > y ? 1 : -1) => x cmp y - return graph().unique(new NormalizeCompareNode(x, y, stackKind, false)); - } else if (cond1 == Condition.LT && cond2 == Condition.GT && c1 == 1 && c2 == -1 && c3 == 0) { - // x < y ? 1 : (x > y ? -1 : 0) => y cmp x - return graph().unique(new NormalizeCompareNode(y, x, stackKind, false)); - } else if (cond1 == Condition.LT && cond2 == Condition.GT && c1 == -1 && c2 == 1 && c3 == 0) { - // x < y ? -1 : (x > y ? 1 : 0) => x cmp y - return graph().unique(new NormalizeCompareNode(x, y, stackKind, false)); + return graph().unique(new NormalizeCompareNode(x, y, stackKind, true)); + } else { + boolean floatComparisonWithoutNaN = condition() instanceof FloatLessThanNode && + ((FloatStamp) x.stamp(NodeView.from(tool))).isNonNaN() && + ((FloatStamp) y.stamp(NodeView.from(tool))).isNonNaN(); + if (condition() instanceof IntegerLowerThanNode || floatComparisonWithoutNaN) { + if (cond1 == Condition.LT && cond2 == Condition.GT && c1 == 1 && c2 == -1 && c3 == 0) { + // x < y ? 1 : (x > y ? -1 : 0) => y cmp x + return graph().unique(new NormalizeCompareNode(y, x, stackKind, false)); + } else if (cond1 == Condition.LT && cond2 == Condition.GT && c1 == -1 && c2 == 1 && c3 == 0) { + // x < y ? -1 : (x > y ? 1 : 0) => x cmp y + return graph().unique(new NormalizeCompareNode(x, y, stackKind, false)); + } + } } } } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ReinterpretNode.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ReinterpretNode.java index 120c14b9b601..5d187ba80bc3 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ReinterpretNode.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ReinterpretNode.java @@ -44,6 +44,7 @@ import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; +import org.graalvm.compiler.serviceprovider.BufferUtil; import jdk.vm.ci.code.CodeUtil; import jdk.vm.ci.meta.JavaKind; @@ -83,7 +84,7 @@ private static SerializableConstant evalConst(Stamp stamp, SerializableConstant ByteBuffer buffer = ByteBuffer.wrap(new byte[c.getSerializedSize()]).order(ByteOrder.nativeOrder()); c.serialize(buffer); - buffer.rewind(); + BufferUtil.asBaseBuffer(buffer).rewind(); SerializableConstant ret = ((ArithmeticStamp) stamp).deserialize(buffer); assert !buffer.hasRemaining(); diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ArrayRangeWrite.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ArrayRangeWrite.java index acf096583577..0209378be43f 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ArrayRangeWrite.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ArrayRangeWrite.java @@ -25,8 +25,8 @@ package org.graalvm.compiler.nodes.extended; import org.graalvm.compiler.graph.NodeInterface; -import org.graalvm.compiler.nodes.FixedWithNextNode; import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.memory.FixedAccessNode; import org.graalvm.compiler.nodes.memory.address.AddressNode; public interface ArrayRangeWrite extends NodeInterface { @@ -52,5 +52,5 @@ public interface ArrayRangeWrite extends NodeInterface { int getElementStride(); @Override - FixedWithNextNode asNode(); + FixedAccessNode asNode(); } diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/ArrayRangeWriteBarrier.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/ArrayRangeWriteBarrier.java similarity index 86% rename from compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/ArrayRangeWriteBarrier.java rename to compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/ArrayRangeWriteBarrier.java index fe4b2faa1a94..91340cd898ef 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/ArrayRangeWriteBarrier.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/ArrayRangeWriteBarrier.java @@ -22,11 +22,9 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package org.graalvm.compiler.hotspot.gc.shared; +package org.graalvm.compiler.nodes.gc; import org.graalvm.compiler.graph.NodeClass; -import org.graalvm.compiler.hotspot.nodes.WriteBarrier; -import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.memory.address.AddressNode; @@ -36,22 +34,16 @@ public abstract class ArrayRangeWriteBarrier extends WriteBarrier implements Lowerable { public static final NodeClass TYPE = NodeClass.create(ArrayRangeWriteBarrier.class); - @Input(InputType.Association) AddressNode address; @Input ValueNode length; private final int elementStride; protected ArrayRangeWriteBarrier(NodeClass c, AddressNode address, ValueNode length, int elementStride) { - super(c); - this.address = address; + super(c, address); this.length = length; this.elementStride = elementStride; } - public AddressNode getAddress() { - return address; - } - public ValueNode getLength() { return length; } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/BarrierSet.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/BarrierSet.java new file mode 100644 index 000000000000..6c7c7e2a876f --- /dev/null +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/BarrierSet.java @@ -0,0 +1,32 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.gc; + +import org.graalvm.compiler.nodes.memory.FixedAccessNode; + +public interface BarrierSet { + void addBarriers(FixedAccessNode n); +} diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/CardTableBarrierSet.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/CardTableBarrierSet.java new file mode 100644 index 000000000000..ceb41e972a94 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/CardTableBarrierSet.java @@ -0,0 +1,190 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.gc; + +import org.graalvm.compiler.core.common.type.AbstractObjectStamp; +import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.extended.ArrayRangeWrite; +import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode; +import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode; +import org.graalvm.compiler.nodes.memory.FixedAccessNode; +import org.graalvm.compiler.nodes.memory.HeapAccess; +import org.graalvm.compiler.nodes.memory.ReadNode; +import org.graalvm.compiler.nodes.memory.WriteNode; +import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType; +import org.graalvm.compiler.nodes.memory.address.AddressNode; +import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; +import org.graalvm.compiler.nodes.type.StampTool; +import org.graalvm.compiler.nodes.util.GraphUtil; + +public class CardTableBarrierSet implements BarrierSet { + private final boolean useDeferredInitBarriers; + + public CardTableBarrierSet(boolean useDeferredInitBarriers) { + this.useDeferredInitBarriers = useDeferredInitBarriers; + } + + @Override + public void addBarriers(FixedAccessNode n) { + if (n instanceof ReadNode) { + // nothing to do + } else if (n instanceof WriteNode) { + WriteNode write = (WriteNode) n; + addWriteBarrier(write, write.value()); + } else if (n instanceof LoweredAtomicReadAndWriteNode) { + LoweredAtomicReadAndWriteNode atomic = (LoweredAtomicReadAndWriteNode) n; + addWriteBarrier(atomic, atomic.getNewValue()); + } else if (n instanceof AbstractCompareAndSwapNode) { + AbstractCompareAndSwapNode cmpSwap = (AbstractCompareAndSwapNode) n; + addWriteBarrier(cmpSwap, cmpSwap.getNewValue()); + } else if (n instanceof ArrayRangeWrite) { + addArrayRangeBarriers((ArrayRangeWrite) n); + } else { + GraalError.guarantee(n.getBarrierType() == BarrierType.NONE, "missed a node that requires a GC barrier: %s", n.getClass()); + } + } + + public boolean needsBarrier(FixedAccessNode n) { + if (n instanceof ReadNode) { + return false; + } else if (n instanceof WriteNode) { + WriteNode write = (WriteNode) n; + return needsWriteBarrier(write, write.value()); + } else if (n instanceof LoweredAtomicReadAndWriteNode) { + LoweredAtomicReadAndWriteNode atomic = (LoweredAtomicReadAndWriteNode) n; + return needsWriteBarrier(atomic, atomic.getNewValue()); + } else if (n instanceof AbstractCompareAndSwapNode) { + AbstractCompareAndSwapNode cmpSwap = (AbstractCompareAndSwapNode) n; + return needsWriteBarrier(cmpSwap, cmpSwap.getNewValue()); + } else if (n instanceof ArrayRangeWrite) { + return needsWriteBarrier((ArrayRangeWrite) n); + } else { + GraalError.guarantee(n.getBarrierType() == BarrierType.NONE, "missed a node that requires a GC barrier: %s", n.getClass()); + return false; + } + } + + public boolean hasBarrier(FixedAccessNode n) { + if (n instanceof ReadNode) { + return false; + } else if (n instanceof WriteNode) { + WriteNode write = (WriteNode) n; + return hasWriteBarrier(write); + } else if (n instanceof LoweredAtomicReadAndWriteNode) { + LoweredAtomicReadAndWriteNode atomic = (LoweredAtomicReadAndWriteNode) n; + return hasWriteBarrier(atomic); + } else if (n instanceof AbstractCompareAndSwapNode) { + AbstractCompareAndSwapNode cmpSwap = (AbstractCompareAndSwapNode) n; + return hasWriteBarrier(cmpSwap); + } else if (n instanceof ArrayRangeWrite) { + return hasWriteBarrier((ArrayRangeWrite) n); + } else { + GraalError.guarantee(n.getBarrierType() == BarrierType.NONE, "missed a node that requires a GC barrier: %s", n.getClass()); + return false; + } + } + + public boolean isMatchingBarrier(FixedAccessNode n, WriteBarrier barrier) { + if (n instanceof ReadNode) { + return false; + } else if (n instanceof WriteNode || n instanceof LoweredAtomicReadAndWriteNode || n instanceof AbstractCompareAndSwapNode || n instanceof ArrayRangeWrite) { + return barrier instanceof SerialWriteBarrier && matches(n, (SerialWriteBarrier) barrier); + } else { + throw GraalError.shouldNotReachHere("Unexpected node: " + n.getClass()); + } + } + + public void addArrayRangeBarriers(ArrayRangeWrite write) { + if (needsWriteBarrier(write)) { + StructuredGraph graph = write.asNode().graph(); + SerialArrayRangeWriteBarrier serialArrayRangeWriteBarrier = graph.add(new SerialArrayRangeWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride())); + graph.addAfterFixed(write.asNode(), serialArrayRangeWriteBarrier); + } + } + + private void addWriteBarrier(FixedAccessNode node, ValueNode writtenValue) { + if (needsWriteBarrier(node, writtenValue)) { + addSerialPostWriteBarrier(node, node.getAddress(), node.graph()); + } + } + + public boolean needsWriteBarrier(FixedAccessNode node, ValueNode writtenValue) { + assert !(node instanceof ArrayRangeWrite); + HeapAccess.BarrierType barrierType = node.getBarrierType(); + switch (barrierType) { + case NONE: + return false; + case FIELD: + case ARRAY: + case UNKNOWN: + return isNonNullObjectValue(writtenValue) && !isDeferredInit(node); + default: + throw new GraalError("unexpected barrier type: " + barrierType); + } + } + + public static boolean needsWriteBarrier(ArrayRangeWrite write) { + return write.writesObjectArray(); + } + + private static boolean hasWriteBarrier(FixedAccessNode node) { + return node.next() instanceof SerialWriteBarrier && matches(node, (SerialWriteBarrier) node.next()); + } + + private static boolean hasWriteBarrier(ArrayRangeWrite write) { + FixedAccessNode node = write.asNode(); + return node.next() instanceof SerialArrayRangeWriteBarrier && matches(write, (SerialArrayRangeWriteBarrier) node.next()); + } + + private static void addSerialPostWriteBarrier(FixedAccessNode node, AddressNode address, StructuredGraph graph) { + boolean precise = node.getBarrierType() != HeapAccess.BarrierType.FIELD; + graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(address, precise))); + } + + private static boolean isNonNullObjectValue(ValueNode value) { + return value.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp && !StampTool.isPointerAlwaysNull(value); + } + + private boolean isDeferredInit(FixedAccessNode node) { + return node.getLocationIdentity().isInit() && useDeferredInitBarriers; + } + + private static boolean matches(FixedAccessNode node, SerialWriteBarrier barrier) { + if (!barrier.usePrecise()) { + if (barrier.getAddress() instanceof OffsetAddressNode && node.getAddress() instanceof OffsetAddressNode) { + return GraphUtil.unproxify(((OffsetAddressNode) barrier.getAddress()).getBase()) == GraphUtil.unproxify(((OffsetAddressNode) node.getAddress()).getBase()); + } + } + return barrier.getAddress() == node.getAddress(); + } + + private static boolean matches(ArrayRangeWrite node, SerialArrayRangeWriteBarrier barrier) { + return barrier.getAddress() == node.getAddress() && node.getLength() == barrier.getLength() && node.getElementStride() == barrier.getElementStride(); + } +} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ArrayRangePostWriteBarrier.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1ArrayRangePostWriteBarrier.java similarity index 94% rename from compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ArrayRangePostWriteBarrier.java rename to compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1ArrayRangePostWriteBarrier.java index eeb5ed328a04..ed5c9d16ee4e 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ArrayRangePostWriteBarrier.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1ArrayRangePostWriteBarrier.java @@ -23,13 +23,12 @@ * questions. */ -package org.graalvm.compiler.hotspot.gc.g1; +package org.graalvm.compiler.nodes.gc; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.graph.NodeClass; -import org.graalvm.compiler.hotspot.gc.shared.ArrayRangeWriteBarrier; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.memory.address.AddressNode; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ArrayRangePreWriteBarrier.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1ArrayRangePreWriteBarrier.java similarity index 94% rename from compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ArrayRangePreWriteBarrier.java rename to compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1ArrayRangePreWriteBarrier.java index fe3329a45dc2..5ff8da49dbff 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ArrayRangePreWriteBarrier.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1ArrayRangePreWriteBarrier.java @@ -23,13 +23,12 @@ * questions. */ -package org.graalvm.compiler.hotspot.gc.g1; +package org.graalvm.compiler.nodes.gc; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.graph.NodeClass; -import org.graalvm.compiler.hotspot.gc.shared.ArrayRangeWriteBarrier; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.memory.address.AddressNode; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1BarrierSet.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1BarrierSet.java similarity index 53% rename from compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1BarrierSet.java rename to compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1BarrierSet.java index 92cef81157c3..f67da02218c9 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1BarrierSet.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1BarrierSet.java @@ -23,11 +23,11 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package org.graalvm.compiler.hotspot.gc.g1; +package org.graalvm.compiler.nodes.gc; +import org.graalvm.compiler.core.common.type.AbstractObjectStamp; import org.graalvm.compiler.debug.GraalError; -import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; -import org.graalvm.compiler.hotspot.gc.shared.BarrierSet; +import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.extended.ArrayRangeWrite; @@ -37,25 +37,46 @@ import org.graalvm.compiler.nodes.memory.HeapAccess; import org.graalvm.compiler.nodes.memory.ReadNode; import org.graalvm.compiler.nodes.memory.WriteNode; +import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType; import org.graalvm.compiler.nodes.memory.address.AddressNode; import org.graalvm.compiler.nodes.type.StampTool; -public class G1BarrierSet extends BarrierSet { +public class G1BarrierSet implements BarrierSet { + private final boolean useDeferredInitBarriers; - public G1BarrierSet(GraalHotSpotVMConfig vmConfig) { - super(vmConfig); + public G1BarrierSet(boolean useDeferredInitBarriers) { + this.useDeferredInitBarriers = useDeferredInitBarriers; } @Override - public void addReadNodeBarriers(ReadNode node, StructuredGraph graph) { + public void addBarriers(FixedAccessNode n) { + if (n instanceof ReadNode) { + addReadNodeBarriers((ReadNode) n); + } else if (n instanceof WriteNode) { + WriteNode write = (WriteNode) n; + addWriteBarriers(write, write.value(), null, true, write.getNullCheck()); + } else if (n instanceof LoweredAtomicReadAndWriteNode) { + LoweredAtomicReadAndWriteNode atomic = (LoweredAtomicReadAndWriteNode) n; + addWriteBarriers(atomic, atomic.getNewValue(), null, true, atomic.getNullCheck()); + } else if (n instanceof AbstractCompareAndSwapNode) { + AbstractCompareAndSwapNode cmpSwap = (AbstractCompareAndSwapNode) n; + addWriteBarriers(cmpSwap, cmpSwap.getNewValue(), cmpSwap.getExpectedValue(), false, false); + } else if (n instanceof ArrayRangeWrite) { + addArrayRangeBarriers((ArrayRangeWrite) n); + } else { + GraalError.guarantee(n.getBarrierType() == BarrierType.NONE, "missed a node that requires a GC barrier: %s", n.getClass()); + } + } + + private static void addReadNodeBarriers(ReadNode node) { if (node.getBarrierType() == HeapAccess.BarrierType.WEAK_FIELD) { + StructuredGraph graph = node.graph(); G1ReferentFieldReadBarrier barrier = graph.add(new G1ReferentFieldReadBarrier(node.getAddress(), node, false)); graph.addAfterFixed(node, barrier); } } - @Override - public void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) { + private void addWriteBarriers(FixedAccessNode node, ValueNode writtenValue, ValueNode expectedValue, boolean doLoad, boolean nullCheck) { HeapAccess.BarrierType barrierType = node.getBarrierType(); switch (barrierType) { case NONE: @@ -64,15 +85,18 @@ public void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) { case FIELD: case ARRAY: case UNKNOWN: - boolean init = node.getLocationIdentity().isInit(); - if (!init || !getVMConfig().useDeferredInitBarriers) { + if (isObjectValue(writtenValue)) { + StructuredGraph graph = node.graph(); + boolean init = node.getLocationIdentity().isInit(); if (!init) { // The pre barrier does nothing if the value being read is null, so it can // be explicitly skipped when this is an initializing store. - addG1PreWriteBarrier(node, node.getAddress(), null, true, node.getNullCheck(), graph); + addG1PreWriteBarrier(node, node.getAddress(), expectedValue, doLoad, nullCheck, graph); + } + if (!init || !useDeferredInitBarriers) { + boolean precise = barrierType != HeapAccess.BarrierType.FIELD; + addG1PostWriteBarrier(node, node.getAddress(), writtenValue, precise, graph); } - boolean precise = barrierType != HeapAccess.BarrierType.FIELD; - addG1PostWriteBarrier(node, node.getAddress(), node.value(), precise, graph); } break; default: @@ -80,56 +104,20 @@ public void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) { } } - @Override - public void addAtomicReadWriteNodeBarriers(LoweredAtomicReadAndWriteNode node, StructuredGraph graph) { - HeapAccess.BarrierType barrierType = node.getBarrierType(); - switch (barrierType) { - case NONE: - // nothing to do - break; - case FIELD: - case ARRAY: - case UNKNOWN: - boolean precise = barrierType != HeapAccess.BarrierType.FIELD; - addG1PreWriteBarrier(node, node.getAddress(), null, true, node.getNullCheck(), graph); - addG1PostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); - break; - default: - throw new GraalError("unexpected barrier type: " + barrierType); - } - } - - @Override - public void addCASBarriers(AbstractCompareAndSwapNode node, StructuredGraph graph) { - HeapAccess.BarrierType barrierType = node.getBarrierType(); - switch (barrierType) { - case NONE: - // nothing to do - break; - case FIELD: - case ARRAY: - case UNKNOWN: - boolean precise = barrierType != HeapAccess.BarrierType.FIELD; - addG1PreWriteBarrier(node, node.getAddress(), node.getExpectedValue(), false, false, graph); - addG1PostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); - break; - default: - throw new GraalError("unexpected barrier type: " + barrierType); + private static void addArrayRangeBarriers(ArrayRangeWrite write) { + if (write.writesObjectArray()) { + StructuredGraph graph = write.asNode().graph(); + if (!write.isInitialization()) { + // The pre barrier does nothing if the value being read is null, so it can + // be explicitly skipped when this is an initializing store. + G1ArrayRangePreWriteBarrier g1ArrayRangePreWriteBarrier = graph.add(new G1ArrayRangePreWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride())); + graph.addBeforeFixed(write.asNode(), g1ArrayRangePreWriteBarrier); + } + G1ArrayRangePostWriteBarrier g1ArrayRangePostWriteBarrier = graph.add(new G1ArrayRangePostWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride())); + graph.addAfterFixed(write.asNode(), g1ArrayRangePostWriteBarrier); } } - @Override - public void addArrayRangeBarriers(ArrayRangeWrite write, StructuredGraph graph) { - if (!write.isInitialization()) { - // The pre barrier does nothing if the value being read is null, so it can - // be explicitly skipped when this is an initializing store. - G1ArrayRangePreWriteBarrier g1ArrayRangePreWriteBarrier = graph.add(new G1ArrayRangePreWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride())); - graph.addBeforeFixed(write.asNode(), g1ArrayRangePreWriteBarrier); - } - G1ArrayRangePostWriteBarrier g1ArrayRangePostWriteBarrier = graph.add(new G1ArrayRangePostWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride())); - graph.addAfterFixed(write.asNode(), g1ArrayRangePostWriteBarrier); - } - private static void addG1PreWriteBarrier(FixedAccessNode node, AddressNode address, ValueNode value, boolean doLoad, boolean nullCheck, StructuredGraph graph) { G1PreWriteBarrier preBarrier = graph.add(new G1PreWriteBarrier(address, value, doLoad, nullCheck)); preBarrier.setStateBefore(node.stateBefore()); @@ -142,4 +130,8 @@ private static void addG1PostWriteBarrier(FixedAccessNode node, AddressNode addr final boolean alwaysNull = StampTool.isPointerAlwaysNull(value); graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(address, value, precise, alwaysNull))); } + + private static boolean isObjectValue(ValueNode value) { + return value.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp; + } } diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1PostWriteBarrier.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1PostWriteBarrier.java similarity index 95% rename from compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1PostWriteBarrier.java rename to compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1PostWriteBarrier.java index ed472c7c2717..c6b60a414fe9 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1PostWriteBarrier.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1PostWriteBarrier.java @@ -22,13 +22,12 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package org.graalvm.compiler.hotspot.gc.g1; +package org.graalvm.compiler.nodes.gc; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.graph.NodeClass; -import org.graalvm.compiler.hotspot.gc.shared.ObjectWriteBarrier; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.memory.address.AddressNode; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1PreWriteBarrier.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1PreWriteBarrier.java similarity index 96% rename from compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1PreWriteBarrier.java rename to compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1PreWriteBarrier.java index dff775db3af0..8409e67e6634 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1PreWriteBarrier.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1PreWriteBarrier.java @@ -23,13 +23,12 @@ * questions. */ -package org.graalvm.compiler.hotspot.gc.g1; +package org.graalvm.compiler.nodes.gc; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.graph.NodeClass; -import org.graalvm.compiler.hotspot.gc.shared.ObjectWriteBarrier; import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.DeoptimizingNode; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ReferentFieldReadBarrier.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1ReferentFieldReadBarrier.java similarity index 95% rename from compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ReferentFieldReadBarrier.java rename to compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1ReferentFieldReadBarrier.java index 62fbfcb5c2c4..27035ffb123c 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ReferentFieldReadBarrier.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1ReferentFieldReadBarrier.java @@ -22,13 +22,12 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package org.graalvm.compiler.hotspot.gc.g1; +package org.graalvm.compiler.nodes.gc; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.graph.NodeClass; -import org.graalvm.compiler.hotspot.gc.shared.ObjectWriteBarrier; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.memory.address.AddressNode; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/ObjectWriteBarrier.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/ObjectWriteBarrier.java similarity index 85% rename from compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/ObjectWriteBarrier.java rename to compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/ObjectWriteBarrier.java index 99cc23d8f4b9..2b2e57e13a72 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/ObjectWriteBarrier.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/ObjectWriteBarrier.java @@ -22,11 +22,9 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package org.graalvm.compiler.hotspot.gc.shared; +package org.graalvm.compiler.nodes.gc; import org.graalvm.compiler.graph.NodeClass; -import org.graalvm.compiler.hotspot.nodes.WriteBarrier; -import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.memory.address.AddressNode; @@ -35,13 +33,11 @@ public abstract class ObjectWriteBarrier extends WriteBarrier { public static final NodeClass TYPE = NodeClass.create(ObjectWriteBarrier.class); - @Input(InputType.Association) protected AddressNode address; @OptionalInput protected ValueNode value; protected final boolean precise; protected ObjectWriteBarrier(NodeClass c, AddressNode address, ValueNode value, boolean precise) { - super(c); - this.address = address; + super(c, address); this.value = value; this.precise = precise; } @@ -50,10 +46,6 @@ public ValueNode getValue() { return value; } - public AddressNode getAddress() { - return address; - } - public boolean usePrecise() { return precise; } diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/SerialArrayRangeWriteBarrier.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/SerialArrayRangeWriteBarrier.java similarity index 97% rename from compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/SerialArrayRangeWriteBarrier.java rename to compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/SerialArrayRangeWriteBarrier.java index 6faec6303fe0..7987a6b7a8e0 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/SerialArrayRangeWriteBarrier.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/SerialArrayRangeWriteBarrier.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package org.graalvm.compiler.hotspot.gc.shared; +package org.graalvm.compiler.nodes.gc; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/SerialWriteBarrier.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/SerialWriteBarrier.java similarity index 97% rename from compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/SerialWriteBarrier.java rename to compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/SerialWriteBarrier.java index 6cc3a5e7d428..ae27e5697274 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/SerialWriteBarrier.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/SerialWriteBarrier.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package org.graalvm.compiler.hotspot.gc.shared; +package org.graalvm.compiler.nodes.gc; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_4; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/WriteBarrier.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/WriteBarrier.java similarity index 83% rename from compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/WriteBarrier.java rename to compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/WriteBarrier.java index 472142513b02..4f3b1f6b1de5 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/WriteBarrier.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/WriteBarrier.java @@ -22,12 +22,14 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package org.graalvm.compiler.hotspot.nodes; +package org.graalvm.compiler.nodes.gc; 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.FixedWithNextNode; +import org.graalvm.compiler.nodes.memory.address.AddressNode; import org.graalvm.compiler.nodes.spi.Lowerable; import org.graalvm.compiler.nodes.spi.LoweringTool; @@ -35,9 +37,11 @@ public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(WriteBarrier.class); + @Input(InputType.Association) AddressNode address; - protected WriteBarrier(NodeClass c) { + protected WriteBarrier(NodeClass c, AddressNode address) { super(c, StampFactory.forVoid()); + this.address = address; } @Override @@ -45,4 +49,8 @@ public void lower(LoweringTool tool) { assert graph().getGuardsStage().areFrameStatesAtDeopts(); tool.getLowerer().lower(this, tool); } + + public AddressNode getAddress() { + return address; + } } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java index 95d6e4ff5131..ede75083b63f 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java @@ -192,7 +192,12 @@ public boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, I 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, StructuredGraph.AllowAssumptions.ifNonNull(b.getAssumptions()), b.getOptions()); + StructuredGraph subst = b.getReplacements().getMethodSubstitution(this, + targetMethod, + INLINE_AFTER_PARSING, + StructuredGraph.AllowAssumptions.ifNonNull(b.getAssumptions()), + null /* cancellable */, + b.getOptions()); if (subst == null) { throw new GraalError("No graphs found for substitution %s", this); } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java index ee1168cc4fe9..5fd6164bd3fe 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java @@ -274,4 +274,8 @@ public static MethodCallTargetNode find(StructuredGraph graph, ResolvedJavaMetho } return null; } + + public void setJavaTypeProfile(JavaTypeProfile profile) { + this.profile = profile; + } } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatableAccessNode.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatableAccessNode.java index 4511219701ae..8efc8df593dc 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatableAccessNode.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatableAccessNode.java @@ -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 @@ -52,7 +52,7 @@ protected FloatableAccessNode(NodeClass c, Addres super(c, address, location, stamp, guard, barrierType, nullCheck, stateBefore); } - public abstract FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess); + public abstract FloatingAccessNode asFloatingNode(); protected boolean forceFixed; diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java index 9b16ea74322d..db9598a50e03 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java @@ -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 @@ -24,6 +24,7 @@ */ package org.graalvm.compiler.nodes.memory; +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; import static org.graalvm.compiler.nodes.NamedLocationIdentity.ARRAY_LENGTH_LOCATION; @@ -43,6 +44,7 @@ import org.graalvm.compiler.nodes.FrameState; import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.ValueNodeUtil; import org.graalvm.compiler.nodes.extended.GuardingNode; import org.graalvm.compiler.nodes.memory.address.AddressNode; import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; @@ -60,10 +62,12 @@ * Reads an {@linkplain FixedAccessNode accessed} value. */ @NodeInfo(nameTemplate = "Read#{p#location/s}", cycles = CYCLES_2, size = SIZE_1) -public class ReadNode extends FloatableAccessNode implements LIRLowerableAccess, Canonicalizable, Virtualizable, GuardingNode { +public class ReadNode extends FloatableAccessNode implements LIRLowerableAccess, Canonicalizable, Virtualizable, GuardingNode, MemoryAccess { public static final NodeClass TYPE = NodeClass.create(ReadNode.class); + @OptionalInput(Memory) MemoryNode lastLocationAccess; + public ReadNode(AddressNode address, LocationIdentity location, Stamp stamp, BarrierType barrierType) { this(TYPE, address, location, stamp, null, barrierType, false, null); } @@ -71,6 +75,18 @@ public ReadNode(AddressNode address, LocationIdentity location, Stamp stamp, Bar protected ReadNode(NodeClass c, AddressNode address, LocationIdentity location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean nullCheck, FrameState stateBefore) { super(c, address, location, stamp, guard, barrierType, nullCheck, stateBefore); + this.lastLocationAccess = null; + } + + @Override + public MemoryNode getLastLocationAccess() { + return lastLocationAccess; + } + + @Override + public void setLastLocationAccess(MemoryNode newlla) { + updateUsages(ValueNodeUtil.asNode(lastLocationAccess), ValueNodeUtil.asNode(newlla)); + lastLocationAccess = newlla; } @Override @@ -96,7 +112,7 @@ public Node canonical(CanonicalizerTool tool) { @SuppressWarnings("try") @Override - public FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess) { + public FloatingAccessNode asFloatingNode() { try (DebugCloseable position = withNodeSourcePosition()) { return graph().unique(new FloatingReadNode(getAddress(), getLocationIdentity(), lastLocationAccess, stamp(NodeView.DEFAULT), getGuard(), getBarrierType())); } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProviders.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProviders.java index 027ca0b40d2e..d488ed1ea438 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProviders.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProviders.java @@ -45,4 +45,6 @@ public interface CoreProviders { StampProvider getStampProvider(); ForeignCallsProvider getForeignCalls(); + + GCProvider getGC(); } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProvidersDelegate.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProvidersDelegate.java index 8d95fe98d4b0..63a63bcfcf20 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProvidersDelegate.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProvidersDelegate.java @@ -72,4 +72,9 @@ public StampProvider getStampProvider() { public ForeignCallsProvider getForeignCalls() { return providers.getForeignCalls(); } + + @Override + public GCProvider getGC() { + return providers.getGC(); + } } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProvidersImpl.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProvidersImpl.java index aaaf176d8978..59e4ad92642b 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProvidersImpl.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProvidersImpl.java @@ -38,9 +38,10 @@ public class CoreProvidersImpl implements CoreProviders { protected final Replacements replacements; protected final StampProvider stampProvider; protected final ForeignCallsProvider foreignCalls; + protected final GCProvider gc; protected CoreProvidersImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider, LoweringProvider lowerer, - Replacements replacements, StampProvider stampProvider, ForeignCallsProvider foreignCalls) { + Replacements replacements, StampProvider stampProvider, ForeignCallsProvider foreignCalls, GCProvider gc) { this.metaAccess = metaAccess; this.constantReflection = constantReflection; this.constantFieldProvider = constantFieldProvider; @@ -48,6 +49,7 @@ protected CoreProvidersImpl(MetaAccessProvider metaAccess, ConstantReflectionPro this.replacements = replacements; this.stampProvider = stampProvider; this.foreignCalls = foreignCalls; + this.gc = gc; } @Override @@ -84,4 +86,9 @@ public StampProvider getStampProvider() { public ForeignCallsProvider getForeignCalls() { return foreignCalls; } + + @Override + public GCProvider getGC() { + return gc; + } } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DelegatingReplacements.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DelegatingReplacements.java index 630321e5b16d..44c70abdfe0f 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DelegatingReplacements.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DelegatingReplacements.java @@ -29,6 +29,7 @@ import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.graph.NodeSourcePosition; +import org.graalvm.compiler.nodes.Cancellable; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderPlugin; @@ -76,8 +77,8 @@ public void registerSnippet(ResolvedJavaMethod method, ResolvedJavaMethod origin @Override public StructuredGraph getMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context, - StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) { - return delegate.getMethodSubstitution(plugin, original, context, allowAssumptions, options); + StructuredGraph.AllowAssumptions allowAssumptions, Cancellable cancellable, OptionValues options) { + return delegate.getMethodSubstitution(plugin, original, context, allowAssumptions, cancellable, options); } @Override @@ -91,8 +92,8 @@ public StructuredGraph getSubstitution(ResolvedJavaMethod method, int invokeBci, } @Override - public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug) { - return delegate.getIntrinsicGraph(method, compilationId, debug); + public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug, Cancellable cancellable) { + return delegate.getIntrinsicGraph(method, compilationId, debug, cancellable); } @Override diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/GCProvider.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/GCProvider.java new file mode 100644 index 000000000000..d06cfbcefd0d --- /dev/null +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/GCProvider.java @@ -0,0 +1,32 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.spi; + +import org.graalvm.compiler.nodes.gc.BarrierSet; + +public interface GCProvider { + /** Returns the barrier set that is used to insert the needed read/write barriers. */ + BarrierSet getBarrierSet(); +} diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/Replacements.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/Replacements.java index 66a9d825e3bd..278d7cbba539 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/Replacements.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/Replacements.java @@ -30,6 +30,7 @@ import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.graph.NodeSourcePosition; +import org.graalvm.compiler.nodes.Cancellable; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderPlugin; @@ -86,11 +87,12 @@ StructuredGraph getSnippet(ResolvedJavaMethod method, ResolvedJavaMethod recursi * @param original the method being substituted * @param context the kind of inlining to be performed for the substitution * @param allowAssumptions + * @param cancellable * @param options * @return the method substitution graph, if any, that is derived from {@code method} */ StructuredGraph getMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context, - StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options); + StructuredGraph.AllowAssumptions allowAssumptions, Cancellable cancellable, OptionValues options); /** * Registers a plugin as a substitution. @@ -115,9 +117,10 @@ StructuredGraph getMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJ * @param method * @param compilationId * @param debug + * @param cancellable * @return an intrinsic graph that can be compiled and installed for {@code method} or null */ - StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug); + StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug, Cancellable cancellable); /** * Determines if there may be a diff --git a/compiler/src/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java b/compiler/src/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java index 42eddf08ee5b..94cc209f3b7f 100644 --- a/compiler/src/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java +++ b/compiler/src/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java @@ -67,15 +67,12 @@ public static Iterable getOptionsLoader() { */ loader = ClassLoader.getSystemClassLoader(); } - Iterable result = ServiceLoader.load(OptionDescriptors.class, loader); - if (IS_BUILDING_NATIVE_IMAGE) { - ArrayList optionDescriptors = new ArrayList<>(); - for (OptionDescriptors descriptors : result) { - optionDescriptors.add(descriptors); - } - OptionsParser.cachedOptionDescriptors = optionDescriptors; - } - return result; + return ServiceLoader.load(OptionDescriptors.class, loader); + } + + public static void setCachedOptionDescriptors(List cachedOptionDescriptors) { + assert IS_BUILDING_NATIVE_IMAGE : "Used to pre-initialize the option descriptors during native image generation"; + OptionsParser.cachedOptionDescriptors = cachedOptionDescriptors; } /** diff --git a/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java b/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java index 0344666be6a2..d49d52d5150a 100644 --- a/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java +++ b/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java @@ -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 @@ -381,7 +381,8 @@ private static void processFloatable(FloatableAccessNode accessNode, MemoryMapIm assert accessNode.getNullCheck() == false; MemoryNode lastLocationAccess = state.getLastLocationAccess(locationIdentity); try (DebugCloseable position = accessNode.withNodeSourcePosition()) { - FloatingAccessNode floatingNode = accessNode.asFloatingNode(lastLocationAccess); + FloatingAccessNode floatingNode = accessNode.asFloatingNode(); + assert floatingNode.getLastLocationAccess() == lastLocationAccess; graph.replaceFixedWithFloating(accessNode, floatingNode); } } diff --git a/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/WriteBarrierAdditionPhase.java b/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/WriteBarrierAdditionPhase.java new file mode 100644 index 000000000000..ce64bd7e2bad --- /dev/null +++ b/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/WriteBarrierAdditionPhase.java @@ -0,0 +1,50 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.debug.DebugCloseable; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.nodes.gc.BarrierSet; +import org.graalvm.compiler.nodes.memory.FixedAccessNode; +import org.graalvm.compiler.phases.BasePhase; +import org.graalvm.compiler.phases.tiers.MidTierContext; + +public class WriteBarrierAdditionPhase extends BasePhase { + @SuppressWarnings("try") + @Override + protected void run(StructuredGraph graph, MidTierContext context) { + BarrierSet barrierSet = context.getGC().getBarrierSet(); + for (FixedAccessNode n : graph.getNodes().filter(FixedAccessNode.class)) { + try (DebugCloseable scope = n.graph().withNodeSourcePosition(n)) { + barrierSet.addBarriers(n); + } + } + } + + @Override + public boolean checkContract() { + return false; + } +} diff --git a/compiler/src/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java b/compiler/src/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java index bc79fcdbb4b7..6bff186ff232 100644 --- a/compiler/src/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java +++ b/compiler/src/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java @@ -29,6 +29,7 @@ import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; import org.graalvm.compiler.nodes.spi.CoreProviders; import org.graalvm.compiler.nodes.spi.CoreProvidersImpl; +import org.graalvm.compiler.nodes.spi.GCProvider; import org.graalvm.compiler.nodes.spi.LoweringProvider; import org.graalvm.compiler.nodes.spi.Replacements; import org.graalvm.compiler.nodes.spi.StampProvider; @@ -45,19 +46,19 @@ public class Providers extends CoreProvidersImpl implements CodeGenProviders { private final CodeCacheProvider codeCache; public Providers(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider, - ForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, StampProvider stampProvider) { - super(metaAccess, constantReflection, constantFieldProvider, lowerer, replacements, stampProvider, foreignCalls); + ForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, StampProvider stampProvider, GCProvider gc) { + super(metaAccess, constantReflection, constantFieldProvider, lowerer, replacements, stampProvider, foreignCalls, gc); this.codeCache = codeCache; } public Providers(Providers copyFrom) { this(copyFrom.getMetaAccess(), copyFrom.getCodeCache(), copyFrom.getConstantReflection(), copyFrom.getConstantFieldProvider(), copyFrom.getForeignCalls(), copyFrom.getLowerer(), - copyFrom.getReplacements(), copyFrom.getStampProvider()); + copyFrom.getReplacements(), copyFrom.getStampProvider(), copyFrom.getGC()); } public Providers(CoreProviders copyFrom) { this(copyFrom.getMetaAccess(), null, copyFrom.getConstantReflection(), copyFrom.getConstantFieldProvider(), null, copyFrom.getLowerer(), copyFrom.getReplacements(), - copyFrom.getStampProvider()); + copyFrom.getStampProvider(), copyFrom.getGC()); } @Override @@ -67,41 +68,46 @@ public CodeCacheProvider getCodeCache() { public Providers copyWith(MetaAccessProvider substitution) { assert this.getClass() == Providers.class : "must override"; - return new Providers(substitution, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider); + return new Providers(substitution, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider, gc); } public Providers copyWith(CodeCacheProvider substitution) { assert this.getClass() == Providers.class : "must override"; - return new Providers(metaAccess, substitution, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider); + return new Providers(metaAccess, substitution, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider, gc); } public Providers copyWith(ConstantReflectionProvider substitution) { assert this.getClass() == Providers.class : "must override"; - return new Providers(metaAccess, codeCache, substitution, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider); + return new Providers(metaAccess, codeCache, substitution, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider, gc); } public Providers copyWith(ConstantFieldProvider substitution) { assert this.getClass() == Providers.class : "must override"; - return new Providers(metaAccess, codeCache, constantReflection, substitution, foreignCalls, lowerer, replacements, stampProvider); + return new Providers(metaAccess, codeCache, constantReflection, substitution, foreignCalls, lowerer, replacements, stampProvider, gc); } public Providers copyWith(ForeignCallsProvider substitution) { assert this.getClass() == Providers.class : "must override"; - return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, substitution, lowerer, replacements, stampProvider); + return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, substitution, lowerer, replacements, stampProvider, gc); } public Providers copyWith(LoweringProvider substitution) { assert this.getClass() == Providers.class : "must override"; - return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, substitution, replacements, stampProvider); + return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, substitution, replacements, stampProvider, gc); } public Providers copyWith(Replacements substitution) { assert this.getClass() == Providers.class : "must override in " + getClass(); - return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, substitution, stampProvider); + return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, substitution, stampProvider, gc); } public Providers copyWith(StampProvider substitution) { assert this.getClass() == Providers.class : "must override"; - return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, substitution); + return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, substitution, gc); + } + + public Providers copyWith(GCProvider substitution) { + assert this.getClass() == Providers.class : "must override"; + return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider, substitution); } } diff --git a/compiler/src/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/InvokerSignatureMismatchTest.java b/compiler/src/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/InvokerSignatureMismatchTest.java new file mode 100644 index 000000000000..cd4e13852516 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/InvokerSignatureMismatchTest.java @@ -0,0 +1,184 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.test; + +import static org.graalvm.compiler.test.SubprocessUtil.getVMCommandLine; +import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments; + +import org.junit.Test; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Type; + +import java.io.File; +import java.lang.invoke.MethodHandles; +import java.util.List; + +import org.graalvm.compiler.core.test.CustomizedBytecodePatternTest; +import org.graalvm.compiler.test.SubprocessUtil; +import org.graalvm.compiler.test.SubprocessUtil.Subprocess; + +import jdk.vm.ci.meta.ResolvedJavaMethod; + +public class InvokerSignatureMismatchTest { + + @Test + public void test() throws Throwable { + List args = withoutDebuggerArguments(getVMCommandLine()); + String classPath = System.getProperty("java.class.path"); + classPath = classPath + File.pathSeparator + TestISMBL.class.getProtectionDomain().getCodeSource().getLocation().getPath(); + args.add("-Xbootclasspath/a:" + classPath); + args.add("-XX:-TieredCompilation"); + args.add("-XX:+EnableJVMCI"); + args.add("-XX:+UseJVMCICompiler"); + + args.add(TestISMBL.class.getName()); + Subprocess proc = SubprocessUtil.java(args); + if (proc.exitCode != 0) { + System.out.println(proc); + } + } +} + +class TestISMBL extends CustomizedBytecodePatternTest { + + public static void main(String[] args) { + try { + new TestISMBL().test(); + } catch (Throwable e) { + e.printStackTrace(); + System.exit(1); + } + System.exit(0); + } + + private void test() throws Throwable { + getClass("java/lang/invoke/MHHelper"); + Class testClass = getClass("ISMTest"); + + ResolvedJavaMethod mL = getResolvedJavaMethod(testClass, "mainLink"); + ResolvedJavaMethod mI = getResolvedJavaMethod(testClass, "mainInvoke"); + executeActual(mL, null, 100); + executeActual(mI, null, 100); + } + + @Override + protected Class getClass(String className) throws ClassNotFoundException { + if (className.equals("java/lang/invoke/MHHelper")) { + return super.getClassBL(className, MethodHandles.lookup()); + } else { + return super.getClass(className); + } + } + + @Override + protected byte[] generateClass(String className) { + String[] exceptions = new String[]{"java/lang/Throwable"}; + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + cw.visit(52, ACC_SUPER | ACC_PUBLIC, className, null, "java/lang/Object", null); + + if (className.equals("java/lang/invoke/MHHelper")) { + MethodVisitor internalMemberName = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "internalMemberName", "(Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;", null, exceptions); + internalMemberName.visitCode(); + internalMemberName.visitVarInsn(ALOAD, 0); + internalMemberName.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "internalMemberName", "()Ljava/lang/invoke/MemberName;", false); + internalMemberName.visitInsn(ARETURN); + internalMemberName.visitMaxs(1, 1); + internalMemberName.visitEnd(); + + MethodVisitor linkToStatic = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "linkToStatic", "(FLjava/lang/Object;)I", null, exceptions); + linkToStatic.visitCode(); + linkToStatic.visitVarInsn(FLOAD, 0); + linkToStatic.visitVarInsn(ALOAD, 1); + linkToStatic.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandle", "linkToStatic", "(FLjava/lang/Object;)I", false); + linkToStatic.visitInsn(IRETURN); + linkToStatic.visitMaxs(1, 1); + linkToStatic.visitEnd(); + + MethodVisitor invokeBasicI = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "invokeBasicI", "(Ljava/lang/invoke/MethodHandle;F)I", null, exceptions); + invokeBasicI.visitCode(); + invokeBasicI.visitVarInsn(ALOAD, 0); + invokeBasicI.visitVarInsn(FLOAD, 1); + invokeBasicI.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invokeBasic", "(F)I", false); + invokeBasicI.visitInsn(IRETURN); + invokeBasicI.visitMaxs(1, 1); + invokeBasicI.visitEnd(); + + } else { + assert className.equals("ISMTest") : className; + cw.visitField(ACC_FINAL | ACC_STATIC, "INT_MH", "Ljava/lang/invoke/MethodHandle;", null, null).visitAnnotation("Ljava/lang/invoke/Stable.class;", true).visitEnd(); + MethodVisitor clinit = cw.visitMethod(ACC_STATIC, "", "()V", null, exceptions); + clinit.visitCode(); + clinit.visitInsn(ACONST_NULL); + clinit.visitVarInsn(ASTORE, 0); + clinit.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandles", "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", false); + clinit.visitLdcInsn(Type.getObjectType(className)); + clinit.visitLdcInsn("bodyI"); + clinit.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); + clinit.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); + clinit.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodType", "methodType", "(Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/MethodType;", false); + clinit.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandles$Lookup", "findStatic", + "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;", false); + clinit.visitFieldInsn(PUTSTATIC, className, "INT_MH", "Ljava/lang/invoke/MethodHandle;"); + clinit.visitInsn(RETURN); + clinit.visitMaxs(1, 1); + clinit.visitEnd(); + + MethodVisitor mainLink = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "mainLink", "(I)I", null, exceptions); + mainLink.visitCode(); + mainLink.visitFieldInsn(GETSTATIC, className, "INT_MH", "Ljava/lang/invoke/MethodHandle;"); + mainLink.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MHHelper", "internalMemberName", "(Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;", false); + mainLink.visitVarInsn(ASTORE, 1); + mainLink.visitVarInsn(ILOAD, 0); + mainLink.visitInsn(I2F); + mainLink.visitVarInsn(ALOAD, 1); + mainLink.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MHHelper", "linkToStatic", "(FLjava/lang/Object;)I", false); + mainLink.visitInsn(IRETURN); + mainLink.visitMaxs(1, 1); + mainLink.visitEnd(); + + MethodVisitor mainInvoke = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "mainInvoke", "(I)I", null, exceptions); + mainInvoke.visitCode(); + mainInvoke.visitFieldInsn(GETSTATIC, className, "INT_MH", "Ljava/lang/invoke/MethodHandle;"); + mainInvoke.visitVarInsn(ILOAD, 0); + mainInvoke.visitInsn(I2F); + mainInvoke.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MHHelper", "invokeBasicI", "(Ljava/lang/invoke/MethodHandle;F)I", false); + mainInvoke.visitInsn(IRETURN); + mainInvoke.visitMaxs(1, 1); + mainInvoke.visitEnd(); + + MethodVisitor bodyI = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "bodyI", "(I)I", null, null); + bodyI.visitCode(); + bodyI.visitVarInsn(ILOAD, 0); + bodyI.visitIntInsn(SIPUSH, 1023); + bodyI.visitInsn(IAND); + bodyI.visitInsn(IRETURN); + bodyI.visitMaxs(1, 1); + bodyI.visitEnd(); + } + cw.visitEnd(); + return cw.toByteArray(); + } +} diff --git a/compiler/src/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/RootMethodSubstitutionTest.java b/compiler/src/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/RootMethodSubstitutionTest.java index c110f3b4ae1e..2fb453b7ac3f 100644 --- a/compiler/src/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/RootMethodSubstitutionTest.java +++ b/compiler/src/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/RootMethodSubstitutionTest.java @@ -34,6 +34,7 @@ import org.graalvm.compiler.core.target.Backend; import org.graalvm.compiler.core.test.GraalCompilerTest; import org.graalvm.compiler.debug.DebugContext; +import org.graalvm.compiler.nodes.Cancellable; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; @@ -51,7 +52,7 @@ /** * Exercise - * {@link org.graalvm.compiler.nodes.spi.Replacements#getIntrinsicGraph(ResolvedJavaMethod, CompilationIdentifier, DebugContext)} + * {@link org.graalvm.compiler.nodes.spi.Replacements#getIntrinsicGraph(ResolvedJavaMethod, CompilationIdentifier, DebugContext, Cancellable)} * with regular method substitutions and encoded graphs. */ @RunWith(Parameterized.class) @@ -113,7 +114,7 @@ public static List data() { private StructuredGraph getIntrinsicGraph(boolean useEncodedGraphs) { OptionValues options = new OptionValues(getDebugContext().getOptions(), GraalOptions.UseEncodedGraphs, useEncodedGraphs); DebugContext debugContext = DebugContext.create(options, getDebugContext().getDescription(), getDebugHandlersFactories()); - return getReplacements().getIntrinsicGraph(method, CompilationIdentifier.INVALID_COMPILATION_ID, debugContext); + return getReplacements().getIntrinsicGraph(method, CompilationIdentifier.INVALID_COMPILATION_ID, debugContext, null); } StructuredGraph expectedGraph; diff --git a/compiler/src/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompressInflateTest.java b/compiler/src/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompressInflateTest.java index 8d0a6ab5d742..121077b66278 100644 --- a/compiler/src/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompressInflateTest.java +++ b/compiler/src/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompressInflateTest.java @@ -114,7 +114,7 @@ public void testStringLatin1InflateByteByte() throws ClassNotFoundException { Class javaclass = Class.forName("java.lang.StringLatin1"); ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "inflate", byte[].class, int.class, byte[].class, int.class, int.class); - StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext()); + StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null); assertInGraph(graph, AMD64StringLatin1InflateNode.class); InstalledCode code = getCode(caller, graph); @@ -152,7 +152,7 @@ public void testStringLatin1InflateByteChar() throws ClassNotFoundException { Class javaclass = Class.forName("java.lang.StringLatin1"); ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "inflate", byte[].class, int.class, char[].class, int.class, int.class); - StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext()); + StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null); assertInGraph(graph, AMD64StringLatin1InflateNode.class); InstalledCode code = getCode(caller, graph); @@ -217,7 +217,7 @@ public void testStringUTF16CompressByteByte() throws ClassNotFoundException { Class javaclass = Class.forName("java.lang.StringUTF16"); ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "compress", byte[].class, int.class, byte[].class, int.class, int.class); - StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext()); + StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null); assertInGraph(graph, AMD64StringUTF16CompressNode.class); InstalledCode code = getCode(caller, graph); @@ -253,7 +253,7 @@ public void testStringUTF16CompressCharByte() throws ClassNotFoundException { Class javaclass = Class.forName("java.lang.StringUTF16"); ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "compress", char[].class, int.class, byte[].class, int.class, int.class); - StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext()); + StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null); assertInGraph(graph, AMD64StringUTF16CompressNode.class); InstalledCode code = getCode(caller, graph); @@ -299,7 +299,7 @@ private class TestMethods { TestMethods(String testmname, Class javaclass, Class intrinsicClass, String javamname, Class... params) { javamethod = getResolvedJavaMethod(javaclass, javamname, params); testmethod = getResolvedJavaMethod(testmname); - testgraph = getReplacements().getIntrinsicGraph(javamethod, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext()); + testgraph = getReplacements().getIntrinsicGraph(javamethod, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null); assertInGraph(testgraph, intrinsicClass); assert javamethod != null; diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java index dea1265bd83e..edefeab8fee2 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java @@ -89,7 +89,7 @@ private EncodedGraph createGraph(ResolvedJavaMethod method, MethodSubstitutionPl if (isSubstitution && (UseEncodedGraphs.getValue(options) || IS_IN_NATIVE_IMAGE)) { // These must go through Replacements to find the graph to use. graphToEncode = providers.getReplacements().getMethodSubstitution(plugin, method, INLINE_AFTER_PARSING, allowAssumptions, - options); + null, options); } else { graphToEncode = buildGraph(method, plugin, intrinsicBytecodeProvider, isSubstitution); } @@ -123,7 +123,8 @@ private StructuredGraph buildGraph(ResolvedJavaMethod method, MethodSubstitution // @formatter:on try (DebugContext.Scope scope = debug.scope("createGraph", graphToEncode)) { IntrinsicContext initialIntrinsicContext = intrinsicBytecodeProvider != null - ? new IntrinsicContext(method, plugin.getSubstitute(providers.getMetaAccess()), intrinsicBytecodeProvider, INLINE_AFTER_PARSING) : null; + ? new IntrinsicContext(method, plugin.getSubstitute(providers.getMetaAccess()), intrinsicBytecodeProvider, INLINE_AFTER_PARSING) + : null; GraphBuilderPhase.Instance graphBuilderPhaseInstance = createGraphBuilderPhaseInstance(initialIntrinsicContext); graphBuilderPhaseInstance.apply(graphToEncode); new CanonicalizerPhase().apply(graphToEncode, providers); diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java index 62460ffb0b01..199a7b999c1e 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java @@ -67,6 +67,7 @@ import org.graalvm.compiler.java.GraphBuilderPhase.Instance; import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase; import org.graalvm.compiler.nodes.CallTargetNode; +import org.graalvm.compiler.nodes.Cancellable; import org.graalvm.compiler.nodes.Invoke; import org.graalvm.compiler.nodes.StateSplit; import org.graalvm.compiler.nodes.StructuredGraph; @@ -262,7 +263,7 @@ public void registerSnippet(ResolvedJavaMethod method, ResolvedJavaMethod origin @Override public StructuredGraph getMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context, - StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) { + StructuredGraph.AllowAssumptions allowAssumptions, Cancellable cancellable, OptionValues options) { // Method substitutions are parsed by the BytecodeParser. return null; } @@ -329,7 +330,7 @@ public StructuredGraph getSubstitution(ResolvedJavaMethod method, int invokeBci, @SuppressWarnings("try") @Override - public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug) { + public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug, Cancellable cancellable) { MethodSubstitutionPlugin msPlugin = getMethodSubstitution(method); if (msPlugin != null) { ResolvedJavaMethod substMethod = msPlugin.getSubstitute(providers.getMetaAccess()); diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java index e520db4d48f0..df8b18c8fbfd 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java @@ -633,6 +633,10 @@ protected AbstractTemplates(OptionValues options, Iterable } } + public Providers getProviders() { + return providers; + } + public static Method findMethod(Class declaringClass, String methodName, Method except) { for (Method m : declaringClass.getDeclaredMethods()) { if (m.getName().equals(methodName) && !m.equals(except)) { @@ -698,7 +702,7 @@ private DebugContext openDebugContext(DebugContext outer, Arguments args) { * Gets a template for a given key, creating it first if necessary. */ @SuppressWarnings("try") - protected SnippetTemplate template(ValueNode replacee, final Arguments args) { + public SnippetTemplate template(ValueNode replacee, final Arguments args) { StructuredGraph graph = replacee.graph(); DebugContext outer = graph.getDebug(); SnippetTemplate template = Options.UseSnippetTemplateCache.getValue(options) && args.cacheable ? templates.get(args.cacheKey) : null; diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/gc/G1WriteBarrierSnippets.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/gc/G1WriteBarrierSnippets.java new file mode 100644 index 000000000000..222ffe9cbbd7 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/gc/G1WriteBarrierSnippets.java @@ -0,0 +1,524 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.gc; + +import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD; +import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FREQUENT_PROBABILITY; +import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LIKELY_PROBABILITY; +import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY; +import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability; + +import org.graalvm.compiler.api.replacements.Snippet; +import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter; +import org.graalvm.compiler.core.common.GraalOptions; +import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; +import org.graalvm.compiler.graph.Node.ConstantNodeParameter; +import org.graalvm.compiler.graph.Node.NodeIntrinsic; +import org.graalvm.compiler.nodes.NamedLocationIdentity; +import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.extended.FixedValueAnchorNode; +import org.graalvm.compiler.nodes.extended.ForeignCallNode; +import org.graalvm.compiler.nodes.extended.MembarNode; +import org.graalvm.compiler.nodes.extended.NullCheckNode; +import org.graalvm.compiler.nodes.gc.G1ArrayRangePostWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1ArrayRangePreWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier; +import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier; +import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType; +import org.graalvm.compiler.nodes.memory.address.AddressNode; +import org.graalvm.compiler.nodes.memory.address.AddressNode.Address; +import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; +import org.graalvm.compiler.nodes.spi.LoweringTool; +import org.graalvm.compiler.nodes.type.NarrowOopStamp; +import org.graalvm.compiler.replacements.SnippetCounter; +import org.graalvm.compiler.replacements.SnippetCounter.Group; +import org.graalvm.compiler.replacements.SnippetTemplate; +import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates; +import org.graalvm.compiler.replacements.SnippetTemplate.Arguments; +import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo; +import org.graalvm.compiler.replacements.Snippets; +import org.graalvm.compiler.replacements.nodes.AssertionNode; +import org.graalvm.compiler.replacements.nodes.CStringConstant; +import org.graalvm.compiler.word.Word; +import org.graalvm.word.LocationIdentity; +import org.graalvm.word.Pointer; +import org.graalvm.word.UnsignedWord; +import org.graalvm.word.WordFactory; + +public abstract class G1WriteBarrierSnippets extends WriteBarrierSnippets implements Snippets { + + public static final LocationIdentity GC_LOG_LOCATION = NamedLocationIdentity.mutable("GC-Log"); + public static final LocationIdentity GC_INDEX_LOCATION = NamedLocationIdentity.mutable("GC-Index"); + + public static class Counters { + Counters(SnippetCounter.Group.Factory factory) { + Group countersWriteBarriers = factory.createSnippetCounterGroup("G1 WriteBarriers"); + g1AttemptedPreWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1AttemptedPreWriteBarrier", "Number of attempted G1 Pre Write Barriers"); + g1EffectivePreWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1EffectivePreWriteBarrier", "Number of effective G1 Pre Write Barriers"); + g1ExecutedPreWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1ExecutedPreWriteBarrier", "Number of executed G1 Pre Write Barriers"); + g1AttemptedPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1AttemptedPostWriteBarrier", "Number of attempted G1 Post Write Barriers"); + g1EffectiveAfterXORPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1EffectiveAfterXORPostWriteBarrier", + "Number of effective G1 Post Write Barriers (after passing the XOR test)"); + g1EffectiveAfterNullPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1EffectiveAfterNullPostWriteBarrier", + "Number of effective G1 Post Write Barriers (after passing the NULL test)"); + g1ExecutedPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1ExecutedPostWriteBarrier", "Number of executed G1 Post Write Barriers"); + } + + final SnippetCounter g1AttemptedPreWriteBarrierCounter; + final SnippetCounter g1EffectivePreWriteBarrierCounter; + final SnippetCounter g1ExecutedPreWriteBarrierCounter; + final SnippetCounter g1AttemptedPostWriteBarrierCounter; + final SnippetCounter g1EffectiveAfterXORPostWriteBarrierCounter; + final SnippetCounter g1EffectiveAfterNullPostWriteBarrierCounter; + final SnippetCounter g1ExecutedPostWriteBarrierCounter; + } + + @Snippet + public void g1PreWriteBarrier(Address address, Object object, Object expectedObject, @ConstantParameter boolean doLoad, @ConstantParameter boolean nullCheck, + @ConstantParameter int traceStartCycle, @ConstantParameter Counters counters) { + if (nullCheck) { + NullCheckNode.nullCheck(address); + } + Word thread = getThread(); + verifyOop(object); + Object fixedExpectedObject = FixedValueAnchorNode.getObject(expectedObject); + Word field = Word.fromAddress(address); + Pointer previousOop = Word.objectToTrackedPointer(fixedExpectedObject); + byte markingValue = thread.readByte(satbQueueMarkingOffset()); + + boolean trace = isTracingActive(traceStartCycle); + int gcCycle = 0; + if (trace) { + Pointer gcTotalCollectionsAddress = WordFactory.pointer(gcTotalCollectionsAddress()); + gcCycle = (int) gcTotalCollectionsAddress.readLong(0); + log(trace, "[%d] G1-Pre Thread %p Object %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(object).rawValue()); + log(trace, "[%d] G1-Pre Thread %p Expected Object %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(fixedExpectedObject).rawValue()); + log(trace, "[%d] G1-Pre Thread %p Field %p\n", gcCycle, thread.rawValue(), field.rawValue()); + log(trace, "[%d] G1-Pre Thread %p Marking %d\n", gcCycle, thread.rawValue(), markingValue); + log(trace, "[%d] G1-Pre Thread %p DoLoad %d\n", gcCycle, thread.rawValue(), doLoad ? 1L : 0L); + } + + counters.g1AttemptedPreWriteBarrierCounter.inc(); + // If the concurrent marker is enabled, the barrier is issued. + if (probability(NOT_FREQUENT_PROBABILITY, markingValue != (byte) 0)) { + // If the previous value has to be loaded (before the write), the load is issued. + // The load is always issued except the cases of CAS and referent field. + if (probability(LIKELY_PROBABILITY, doLoad)) { + previousOop = Word.objectToTrackedPointer(field.readObject(0, BarrierType.NONE)); + if (trace) { + log(trace, "[%d] G1-Pre Thread %p Previous Object %p\n ", gcCycle, thread.rawValue(), previousOop.rawValue()); + verifyOop(previousOop.toObject()); + } + } + counters.g1EffectivePreWriteBarrierCounter.inc(); + // If the previous value is null the barrier should not be issued. + if (probability(FREQUENT_PROBABILITY, previousOop.notEqual(0))) { + counters.g1ExecutedPreWriteBarrierCounter.inc(); + // If the thread-local SATB buffer is full issue a native call which will + // initialize a new one and add the entry. + Word indexAddress = thread.add(satbQueueIndexOffset()); + Word indexValue = indexAddress.readWord(0); + if (probability(FREQUENT_PROBABILITY, indexValue.notEqual(0))) { + Word bufferAddress = thread.readWord(satbQueueBufferOffset()); + Word nextIndex = indexValue.subtract(wordSize()); + Word logAddress = bufferAddress.add(nextIndex); + // Log the object to be marked as well as update the SATB's buffer next index. + logAddress.writeWord(0, previousOop, GC_LOG_LOCATION); + indexAddress.writeWord(0, nextIndex, GC_INDEX_LOCATION); + } else { + g1PreBarrierStub(previousOop); + } + } + } + } + + @Snippet + public void g1PostWriteBarrier(Address address, Object object, Object value, @ConstantParameter boolean usePrecise, @ConstantParameter int traceStartCycle, + @ConstantParameter Counters counters) { + Word thread = getThread(); + Object fixedValue = FixedValueAnchorNode.getObject(value); + verifyOop(object); + verifyOop(fixedValue); + validateObject(object, fixedValue); + + Pointer oop; + if (usePrecise) { + oop = Word.fromAddress(address); + } else { + if (verifyBarrier()) { + verifyNotArray(object); + } + oop = Word.objectToTrackedPointer(object); + } + + boolean trace = isTracingActive(traceStartCycle); + int gcCycle = 0; + if (trace) { + Pointer gcTotalCollectionsAddress = WordFactory.pointer(gcTotalCollectionsAddress()); + gcCycle = (int) gcTotalCollectionsAddress.readLong(0); + log(trace, "[%d] G1-Post Thread: %p Object: %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(object).rawValue()); + log(trace, "[%d] G1-Post Thread: %p Field: %p\n", gcCycle, thread.rawValue(), oop.rawValue()); + } + Pointer writtenValue = Word.objectToTrackedPointer(fixedValue); + // The result of the xor reveals whether the installed pointer crosses heap regions. + // In case it does the write barrier has to be issued. + final int logOfHeapRegionGrainBytes = logOfHeapRegionGrainBytes(); + UnsignedWord xorResult = (oop.xor(writtenValue)).unsignedShiftRight(logOfHeapRegionGrainBytes); + + counters.g1AttemptedPostWriteBarrierCounter.inc(); + if (probability(FREQUENT_PROBABILITY, xorResult.notEqual(0))) { + counters.g1EffectiveAfterXORPostWriteBarrierCounter.inc(); + // If the written value is not null continue with the barrier addition. + if (probability(FREQUENT_PROBABILITY, writtenValue.notEqual(0))) { + // Calculate the address of the card to be enqueued to the + // thread local card queue. + UnsignedWord cardBase = oop.unsignedShiftRight(cardTableShift()); + final long startAddress = cardTableAddress(); + int displacement = 0; + if (((int) startAddress) == startAddress && isCardTableAddressConstant()) { + displacement = (int) startAddress; + } else { + cardBase = cardBase.add(WordFactory.unsigned(startAddress)); + } + Word cardAddress = (Word) cardBase.add(displacement); + + byte cardByte = cardAddress.readByte(0, GC_CARD_LOCATION); + counters.g1EffectiveAfterNullPostWriteBarrierCounter.inc(); + + // If the card is already dirty, (hence already enqueued) skip the insertion. + if (probability(NOT_FREQUENT_PROBABILITY, cardByte != youngCardValue())) { + MembarNode.memoryBarrier(STORE_LOAD, GC_CARD_LOCATION); + byte cardByteReload = cardAddress.readByte(0, GC_CARD_LOCATION); + if (probability(NOT_FREQUENT_PROBABILITY, cardByteReload != dirtyCardValue())) { + log(trace, "[%d] G1-Post Thread: %p Card: %p \n", gcCycle, thread.rawValue(), WordFactory.unsigned((int) cardByte).rawValue()); + cardAddress.writeByte(0, (byte) 0, GC_CARD_LOCATION); + counters.g1ExecutedPostWriteBarrierCounter.inc(); + + // If the thread local card queue is full, issue a native call which will + // initialize a new one and add the card entry. + Word indexValue = thread.readWord(cardQueueIndexOffset()); + if (probability(FREQUENT_PROBABILITY, indexValue.notEqual(0))) { + Word bufferAddress = thread.readWord(cardQueueBufferOffset()); + Word nextIndex = indexValue.subtract(wordSize()); + Word logAddress = bufferAddress.add(nextIndex); + Word indexAddress = thread.add(cardQueueIndexOffset()); + // Log the object to be scanned as well as update + // the card queue's next index. + logAddress.writeWord(0, cardAddress, GC_LOG_LOCATION); + indexAddress.writeWord(0, nextIndex, GC_INDEX_LOCATION); + } else { + g1PostBarrierStub(cardAddress); + } + } + } + } + } + } + + @Snippet + public void g1ArrayRangePreWriteBarrier(Address address, int length, @ConstantParameter int elementStride) { + Word thread = getThread(); + byte markingValue = thread.readByte(satbQueueMarkingOffset()); + // If the concurrent marker is not enabled or the vector length is zero, return. + if (markingValue == (byte) 0 || length == 0) { + return; + } + Word bufferAddress = thread.readWord(satbQueueBufferOffset()); + Word indexAddress = thread.add(satbQueueIndexOffset()); + long indexValue = indexAddress.readWord(0).rawValue(); + final int scale = objectArrayIndexScale(); + long start = getPointerToFirstArrayElement(address, length, elementStride); + + for (int i = 0; i < length; i++) { + Word arrElemPtr = WordFactory.pointer(start + i * scale); + Pointer oop = Word.objectToTrackedPointer(arrElemPtr.readObject(0, BarrierType.NONE)); + verifyOop(oop.toObject()); + if (oop.notEqual(0)) { + if (indexValue != 0) { + indexValue = indexValue - wordSize(); + Word logAddress = bufferAddress.add(WordFactory.unsigned(indexValue)); + // Log the object to be marked as well as update the SATB's buffer next index. + logAddress.writeWord(0, oop, GC_LOG_LOCATION); + indexAddress.writeWord(0, WordFactory.unsigned(indexValue), GC_INDEX_LOCATION); + } else { + g1PreBarrierStub(oop); + } + } + } + } + + @Snippet + public void g1ArrayRangePostWriteBarrier(Address address, int length, @ConstantParameter int elementStride) { + if (length == 0) { + return; + } + Word thread = getThread(); + Word bufferAddress = thread.readWord(cardQueueBufferOffset()); + Word indexAddress = thread.add(cardQueueIndexOffset()); + long indexValue = thread.readWord(cardQueueIndexOffset()).rawValue(); + + int cardShift = cardTableShift(); + final long cardStart = cardTableAddress(); + long start = getPointerToFirstArrayElement(address, length, elementStride) >>> cardShift; + long end = getPointerToLastArrayElement(address, length, elementStride) >>> cardShift; + long count = end - start + 1; + + while (count-- > 0) { + Word cardAddress = WordFactory.unsigned((start + cardStart) + count); + byte cardByte = cardAddress.readByte(0, GC_CARD_LOCATION); + // If the card is already dirty, (hence already enqueued) skip the insertion. + if (probability(NOT_FREQUENT_PROBABILITY, cardByte != youngCardValue())) { + MembarNode.memoryBarrier(STORE_LOAD, GC_CARD_LOCATION); + byte cardByteReload = cardAddress.readByte(0, GC_CARD_LOCATION); + if (probability(NOT_FREQUENT_PROBABILITY, cardByteReload != dirtyCardValue())) { + cardAddress.writeByte(0, (byte) 0, GC_CARD_LOCATION); + // If the thread local card queue is full, issue a native call which will + // initialize a new one and add the card entry. + if (indexValue != 0) { + indexValue = indexValue - wordSize(); + Word logAddress = bufferAddress.add(WordFactory.unsigned(indexValue)); + // Log the object to be scanned as well as update + // the card queue's next index. + logAddress.writeWord(0, cardAddress, GC_LOG_LOCATION); + indexAddress.writeWord(0, WordFactory.unsigned(indexValue), GC_INDEX_LOCATION); + } else { + g1PostBarrierStub(cardAddress); + } + } + } + } + } + + protected abstract Word getThread(); + + protected abstract int wordSize(); + + protected abstract int objectArrayIndexScale(); + + protected abstract int satbQueueMarkingOffset(); + + protected abstract int satbQueueBufferOffset(); + + protected abstract int satbQueueIndexOffset(); + + protected abstract int cardQueueBufferOffset(); + + protected abstract int cardQueueIndexOffset(); + + protected abstract byte dirtyCardValue(); + + protected abstract byte youngCardValue(); + + protected abstract long cardTableAddress(); + + protected abstract boolean isCardTableAddressConstant(); + + protected abstract int cardTableShift(); + + protected abstract int logOfHeapRegionGrainBytes(); + + protected abstract ForeignCallDescriptor preWriteBarrierCallDescriptor(); + + protected abstract ForeignCallDescriptor postWriteBarrierCallDescriptor(); + + // the data below is only needed for the verification logic + protected abstract boolean verifyOops(); + + protected abstract boolean verifyBarrier(); + + protected abstract long gcTotalCollectionsAddress(); + + protected abstract ForeignCallDescriptor verifyOopCallDescriptor(); + + protected abstract ForeignCallDescriptor validateObjectCallDescriptor(); + + protected abstract ForeignCallDescriptor printfCallDescriptor(); + + private boolean isTracingActive(int traceStartCycle) { + return traceStartCycle > 0 && ((Pointer) WordFactory.pointer(gcTotalCollectionsAddress())).readLong(0) > traceStartCycle; + } + + private void log(boolean enabled, String format, long value1, long value2, long value3) { + if (enabled) { + printf(printfCallDescriptor(), CStringConstant.cstring(format), value1, value2, value3); + } + } + + /** + * Validation helper method which performs sanity checks on write operations. The addresses of + * both the object and the value being written are checked in order to determine if they reside + * in a valid heap region. If an object is stale, an invalid access is performed in order to + * prematurely crash the VM and debug the stack trace of the faulty method. + */ + private void validateObject(Object parent, Object child) { + if (verifyOops() && child != null) { + Word parentWord = Word.objectToTrackedPointer(parent); + Word childWord = Word.objectToTrackedPointer(child); + boolean success = validateOop(validateObjectCallDescriptor(), parentWord, childWord); + AssertionNode.assertion(false, success, "Verification ERROR, Parent: %p Child: %p\n", parentWord.rawValue(), childWord.rawValue()); + } + } + + private void verifyOop(Object object) { + if (verifyOops()) { + verifyOopStub(verifyOopCallDescriptor(), object); + } + } + + private void g1PreBarrierStub(Pointer previousOop) { + g1PreBarrierStub(preWriteBarrierCallDescriptor(), previousOop.toObject()); + } + + private void g1PostBarrierStub(Word cardAddress) { + g1PostBarrierStub(postWriteBarrierCallDescriptor(), cardAddress); + } + + @NodeIntrinsic(ForeignCallNode.class) + private static native Object verifyOopStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object); + + @NodeIntrinsic(ForeignCallNode.class) + private static native boolean validateOop(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word parent, Word object); + + @NodeIntrinsic(ForeignCallNode.class) + private static native void g1PreBarrierStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object); + + @NodeIntrinsic(ForeignCallNode.class) + private static native void g1PostBarrierStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word card); + + @NodeIntrinsic(ForeignCallNode.class) + private static native void printf(@ConstantNodeParameter ForeignCallDescriptor logPrintf, Word format, long v1, long v2, long v3); + + public abstract static class G1WriteBarrierLowerer { + private final Counters counters; + + public G1WriteBarrierLowerer(Group.Factory factory) { + this.counters = new Counters(factory); + } + + public void lower(AbstractTemplates templates, SnippetInfo snippet, G1PreWriteBarrier barrier, LoweringTool tool) { + Arguments args = new Arguments(snippet, barrier.graph().getGuardsStage(), tool.getLoweringStage()); + AddressNode address = barrier.getAddress(); + args.add("address", address); + if (address instanceof OffsetAddressNode) { + args.add("object", ((OffsetAddressNode) address).getBase()); + } else { + args.add("object", null); + } + + ValueNode expected = barrier.getExpectedObject(); + if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) { + expected = uncompress(expected); + } + args.add("expectedObject", expected); + + args.addConst("doLoad", barrier.doLoad()); + args.addConst("nullCheck", barrier.getNullCheck()); + args.addConst("traceStartCycle", traceStartCycle(barrier.graph())); + args.addConst("counters", counters); + + templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, SnippetTemplate.DEFAULT_REPLACER, args); + } + + public void lower(AbstractTemplates templates, SnippetInfo snippet, G1ReferentFieldReadBarrier barrier, LoweringTool tool) { + Arguments args = new Arguments(snippet, barrier.graph().getGuardsStage(), tool.getLoweringStage()); + AddressNode address = barrier.getAddress(); + args.add("address", address); + if (address instanceof OffsetAddressNode) { + args.add("object", ((OffsetAddressNode) address).getBase()); + } else { + args.add("object", null); + } + + ValueNode expected = barrier.getExpectedObject(); + if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) { + expected = uncompress(expected); + } + + args.add("expectedObject", expected); + args.addConst("doLoad", barrier.doLoad()); + args.addConst("nullCheck", false); + args.addConst("traceStartCycle", traceStartCycle(barrier.graph())); + args.addConst("counters", counters); + + templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, SnippetTemplate.DEFAULT_REPLACER, args); + } + + public void lower(AbstractTemplates templates, SnippetInfo snippet, G1PostWriteBarrier barrier, LoweringTool tool) { + if (barrier.alwaysNull()) { + barrier.graph().removeFixed(barrier); + return; + } + + Arguments args = new Arguments(snippet, barrier.graph().getGuardsStage(), tool.getLoweringStage()); + AddressNode address = barrier.getAddress(); + args.add("address", address); + if (address instanceof OffsetAddressNode) { + args.add("object", ((OffsetAddressNode) address).getBase()); + } else { + assert barrier.usePrecise() : "found imprecise barrier that's not an object access " + barrier; + args.add("object", null); + } + + ValueNode value = barrier.getValue(); + if (value.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) { + value = uncompress(value); + } + args.add("value", value); + + args.addConst("usePrecise", barrier.usePrecise()); + args.addConst("traceStartCycle", traceStartCycle(barrier.graph())); + args.addConst("counters", counters); + + templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, SnippetTemplate.DEFAULT_REPLACER, args); + } + + public void lower(AbstractTemplates templates, SnippetInfo snippet, G1ArrayRangePreWriteBarrier barrier, LoweringTool tool) { + Arguments args = new Arguments(snippet, barrier.graph().getGuardsStage(), tool.getLoweringStage()); + args.add("address", barrier.getAddress()); + args.add("length", barrier.getLength()); + args.addConst("elementStride", barrier.getElementStride()); + + templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, SnippetTemplate.DEFAULT_REPLACER, args); + } + + public void lower(AbstractTemplates templates, SnippetInfo snippet, G1ArrayRangePostWriteBarrier barrier, LoweringTool tool) { + Arguments args = new Arguments(snippet, barrier.graph().getGuardsStage(), tool.getLoweringStage()); + args.add("address", barrier.getAddress()); + args.add("length", barrier.getLength()); + args.addConst("elementStride", barrier.getElementStride()); + + templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, SnippetTemplate.DEFAULT_REPLACER, args); + } + + private static int traceStartCycle(StructuredGraph graph) { + return GraalOptions.GCDebugStartCycle.getValue(graph.getOptions()); + } + + protected abstract ValueNode uncompress(ValueNode value); + } +} diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/gc/SerialWriteBarrierSnippets.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/gc/SerialWriteBarrierSnippets.java new file mode 100644 index 000000000000..51b1339baf80 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/gc/SerialWriteBarrierSnippets.java @@ -0,0 +1,138 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.gc; + +import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER; + +import org.graalvm.compiler.api.replacements.Snippet; +import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter; +import org.graalvm.compiler.nodes.gc.SerialArrayRangeWriteBarrier; +import org.graalvm.compiler.nodes.gc.SerialWriteBarrier; +import org.graalvm.compiler.nodes.memory.address.AddressNode.Address; +import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; +import org.graalvm.compiler.nodes.spi.LoweringTool; +import org.graalvm.compiler.replacements.SnippetCounter; +import org.graalvm.compiler.replacements.SnippetCounter.Group; +import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates; +import org.graalvm.compiler.replacements.SnippetTemplate.Arguments; +import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo; +import org.graalvm.compiler.replacements.Snippets; +import org.graalvm.compiler.replacements.nodes.DirectStoreNode; +import org.graalvm.compiler.word.Word; +import org.graalvm.word.Pointer; +import org.graalvm.word.WordFactory; + +import jdk.vm.ci.meta.JavaKind; + +public abstract class SerialWriteBarrierSnippets extends WriteBarrierSnippets implements Snippets { + + static class Counters { + Counters(SnippetCounter.Group.Factory factory) { + Group countersWriteBarriers = factory.createSnippetCounterGroup("Serial WriteBarriers"); + serialWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "serialWriteBarrier", "Number of Serial Write Barriers"); + } + + final SnippetCounter serialWriteBarrierCounter; + } + + @Snippet + public void serialImpreciseWriteBarrier(Object object, @ConstantParameter Counters counters) { + if (verifyBarrier()) { + verifyNotArray(object); + } + serialWriteBarrier(Word.objectToTrackedPointer(object), counters); + } + + @Snippet + public void serialPreciseWriteBarrier(Address address, @ConstantParameter Counters counters) { + serialWriteBarrier(Word.fromAddress(address), counters); + } + + @Snippet + public void serialArrayRangeWriteBarrier(Address address, int length, @ConstantParameter int elementStride) { + if (length == 0) { + return; + } + int cardShift = cardTableShift(); + final long cardStart = cardTableAddress(); + long start = getPointerToFirstArrayElement(address, length, elementStride) >>> cardShift; + long end = getPointerToLastArrayElement(address, length, elementStride) >>> cardShift; + long count = end - start + 1; + while (count-- > 0) { + DirectStoreNode.storeBoolean((start + cardStart) + count, false, JavaKind.Boolean); + } + } + + private void serialWriteBarrier(Pointer ptr, Counters counters) { + counters.serialWriteBarrierCounter.inc(); + final long startAddress = cardTableAddress(); + Word base = (Word) ptr.unsignedShiftRight(cardTableShift()); + if (((int) startAddress) == startAddress && isCardTableAddressConstant()) { + base.writeByte((int) startAddress, (byte) 0, GC_CARD_LOCATION); + } else { + base.writeByte(WordFactory.unsigned(startAddress), (byte) 0, GC_CARD_LOCATION); + } + } + + protected abstract boolean isCardTableAddressConstant(); + + protected abstract long cardTableAddress(); + + protected abstract int cardTableShift(); + + protected abstract boolean verifyBarrier(); + + public static class SerialWriteBarrierLowerer { + private final Counters counters; + + public SerialWriteBarrierLowerer(Group.Factory factory) { + this.counters = new Counters(factory); + } + + public void lower(AbstractTemplates templates, SnippetInfo preciseSnippet, SnippetInfo impreciseSnippet, SerialWriteBarrier barrier, LoweringTool tool) { + Arguments args; + if (barrier.usePrecise()) { + args = new Arguments(preciseSnippet, barrier.graph().getGuardsStage(), tool.getLoweringStage()); + args.add("address", barrier.getAddress()); + } else { + args = new Arguments(impreciseSnippet, barrier.graph().getGuardsStage(), tool.getLoweringStage()); + OffsetAddressNode address = (OffsetAddressNode) barrier.getAddress(); + args.add("object", address.getBase()); + } + args.addConst("counters", counters); + + templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, DEFAULT_REPLACER, args); + } + + public void lower(AbstractTemplates templates, SnippetInfo snippet, SerialArrayRangeWriteBarrier barrier, LoweringTool tool) { + Arguments args = new Arguments(snippet, barrier.graph().getGuardsStage(), tool.getLoweringStage()); + args.add("address", barrier.getAddress()); + args.add("length", barrier.getLength()); + args.addConst("elementStride", barrier.getElementStride()); + + templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, DEFAULT_REPLACER, args); + } + } +} diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/gc/WriteBarrierSnippets.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/gc/WriteBarrierSnippets.java new file mode 100644 index 000000000000..43571b3bfc53 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/gc/WriteBarrierSnippets.java @@ -0,0 +1,64 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.gc; + +import org.graalvm.compiler.nodes.NamedLocationIdentity; +import org.graalvm.compiler.nodes.PiNode; +import org.graalvm.compiler.nodes.SnippetAnchorNode; +import org.graalvm.compiler.nodes.memory.address.AddressNode.Address; +import org.graalvm.compiler.replacements.nodes.AssertionNode; +import org.graalvm.compiler.word.Word; +import org.graalvm.word.LocationIdentity; + +public abstract class WriteBarrierSnippets { + public static final LocationIdentity GC_CARD_LOCATION = NamedLocationIdentity.mutable("GC-Card"); + + protected static void verifyNotArray(Object object) { + if (object != null) { + // Manually build the null check and cast because we're in snippet that's lowered late. + AssertionNode.assertion(false, !PiNode.piCastNonNull(object, SnippetAnchorNode.anchor()).getClass().isArray(), "imprecise card mark used with array"); + } + } + + protected static long getPointerToFirstArrayElement(Address address, int length, int elementStride) { + long result = Word.fromAddress(address).rawValue(); + if (elementStride < 0) { + // the address points to the place after the last array element + result = result + elementStride * length; + } + return result; + } + + protected static long getPointerToLastArrayElement(Address address, int length, int elementStride) { + long result = Word.fromAddress(address).rawValue(); + if (elementStride < 0) { + // the address points to the place after the last array element + result = result + elementStride; + } else { + result = result + (length - 1) * elementStride; + } + return result; + } +} diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java index 07caec88b4d7..9840e8c02de4 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java @@ -206,7 +206,8 @@ private static InvokeNode getInvokeBasicTarget(GraphAdder adder, IntrinsicMethod StampPair returnStamp, ValueNode[] arguments) { ValueNode methodHandleNode = getReceiver(arguments); if (methodHandleNode.isConstant()) { - return getTargetInvokeNode(adder, intrinsicMethod, bci, returnStamp, arguments, methodHandleAccess.resolveInvokeBasicTarget(methodHandleNode.asJavaConstant(), true), original); + return getTargetInvokeNode(adder, intrinsicMethod, methodHandleAccess, bci, returnStamp, arguments, methodHandleAccess.resolveInvokeBasicTarget(methodHandleNode.asJavaConstant(), true), + original); } return null; } @@ -227,7 +228,7 @@ private static InvokeNode getLinkToTarget(GraphAdder adder, IntrinsicMethod intr StampPair returnStamp, ValueNode[] arguments) { ValueNode memberNameNode = getMemberName(arguments); if (memberNameNode.isConstant()) { - return getTargetInvokeNode(adder, intrinsicMethod, bci, returnStamp, arguments, methodHandleAccess.resolveLinkToTarget(memberNameNode.asJavaConstant()), original); + return getTargetInvokeNode(adder, intrinsicMethod, methodHandleAccess, bci, returnStamp, arguments, methodHandleAccess.resolveLinkToTarget(memberNameNode.asJavaConstant()), original); } return null; } @@ -241,9 +242,10 @@ private static InvokeNode getLinkToTarget(GraphAdder adder, IntrinsicMethod intr * * @return invoke node for the member name target */ - private static InvokeNode getTargetInvokeNode(GraphAdder adder, IntrinsicMethod intrinsicMethod, int bci, StampPair returnStamp, ValueNode[] originalArguments, ResolvedJavaMethod target, + private static InvokeNode getTargetInvokeNode(GraphAdder adder, IntrinsicMethod intrinsicMethod, MethodHandleAccessProvider methodHandleAccess, int bci, StampPair returnStamp, + ValueNode[] originalArguments, ResolvedJavaMethod target, ResolvedJavaMethod original) { - if (target == null) { + if (target == null || !isConsistentInfo(methodHandleAccess, original, target)) { return null; } @@ -390,4 +392,84 @@ private static InvokeNode createTargetInvokeNode(Assumptions assumptions, Intrin return new InvokeNode(callTarget, bci); } } + + /** + * Checks basic type consistency of low level method handle intrinsics. + * + * @param original declared method + * @param target resolved method + * @return true if original is type consistent with target + */ + private static boolean isConsistentInfo(MethodHandleAccessProvider methodHandleAccess, ResolvedJavaMethod original, ResolvedJavaMethod target) { + IntrinsicMethod originalIntrinsicMethod = methodHandleAccess.lookupMethodHandleIntrinsic(original); + assert originalIntrinsicMethod == IntrinsicMethod.INVOKE_BASIC || + originalIntrinsicMethod == IntrinsicMethod.LINK_TO_STATIC || + originalIntrinsicMethod == IntrinsicMethod.LINK_TO_SPECIAL || + originalIntrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL || + originalIntrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE; + IntrinsicMethod targetIntrinsicMethod = methodHandleAccess.lookupMethodHandleIntrinsic(target); + Signature originalSignature = original.getSignature(); + Signature targetSignature = target.getSignature(); + + boolean invokeThroughMHIntrinsic = originalIntrinsicMethod != null && targetIntrinsicMethod == null; + if (!invokeThroughMHIntrinsic) { + return (original.getName().equals(target.getName())) && (originalSignature.equals(targetSignature)); + } + + // Linkers have appendix argument which is not passed to callee. + int hasAppendix = (originalIntrinsicMethod == IntrinsicMethod.LINK_TO_STATIC || + originalIntrinsicMethod == IntrinsicMethod.LINK_TO_SPECIAL || + originalIntrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL || + originalIntrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE) ? 1 : 0; + if (originalSignature.getParameterCount(original.hasReceiver()) != (targetSignature.getParameterCount(target.hasReceiver()) + hasAppendix)) { + return false; // parameter count mismatch + } + int senderBase = 0; + int receiverBase = 0; + switch (originalIntrinsicMethod) { + case LINK_TO_VIRTUAL: + case LINK_TO_INTERFACE: + case LINK_TO_SPECIAL: { + if (target.isStatic()) { + return false; + } + if (originalSignature.getParameterKind(0).isPrimitive()) { + return false; // receiver should be an oop + } + senderBase = 1; // skip receiver + break; + } + case LINK_TO_STATIC: { + if (target.hasReceiver()) { + return false; + } + break; + } + case INVOKE_BASIC: { + if (target.isStatic()) { + if (targetSignature.getParameterKind(0).isPrimitive()) { + return false; // receiver should be an oop + } + receiverBase = 1; // skip receiver + } + break; + } + default: + break; + } + assert (targetSignature.getParameterCount(false) - receiverBase) == (originalSignature.getParameterCount(false) - senderBase - hasAppendix) : "argument count mismatch"; + int argCount = targetSignature.getParameterCount(false) - receiverBase; + for (int i = 0; i < argCount; i++) { + if (originalSignature.getParameterKind(senderBase + i).getStackKind() != targetSignature.getParameterKind(receiverBase + i).getStackKind()) { + return false; + } + } + // Only check the return type if the symbolic info has non-void return type. + // I.e. the return value of the resolved method can be dropped. + if (originalSignature.getReturnKind() != JavaKind.Void && + originalSignature.getReturnKind().getStackKind() != targetSignature.getReturnKind().getStackKind()) { + return false; + } + return true; // no mismatch found + } } diff --git a/compiler/src/org.graalvm.compiler.serviceprovider.jdk13/src/org/graalvm/compiler/serviceprovider/GraalServices.java b/compiler/src/org.graalvm.compiler.serviceprovider.jdk13/src/org/graalvm/compiler/serviceprovider/GraalServices.java index c751a241def2..3c42000f7fc5 100644 --- a/compiler/src/org.graalvm.compiler.serviceprovider.jdk13/src/org/graalvm/compiler/serviceprovider/GraalServices.java +++ b/compiler/src/org.graalvm.compiler.serviceprovider.jdk13/src/org/graalvm/compiler/serviceprovider/GraalServices.java @@ -88,7 +88,15 @@ public static Iterable load(Class service) { synchronized (servicesCache) { ArrayList providersList = new ArrayList<>(); for (S provider : providers) { - providersList.add(provider); + /* + * When building libgraal, we want providers that comes from the Graal community + * and enterprise modules but not those available on the native-image class + * path. + */ + Module module = provider.getClass().getModule(); + if (module.isNamed()) { + providersList.add(provider); + } } providers = providersList; servicesCache.put(service, providersList); @@ -100,7 +108,7 @@ public static Iterable load(Class service) { } protected static Iterable load0(Class service) { - Iterable iterable = ServiceLoader.load(service, GraalServices.class.getClassLoader()); + Iterable iterable = ServiceLoader.load(service); return new Iterable<>() { @Override public Iterator iterator() { @@ -135,7 +143,9 @@ public void remove() { * @param other all JVMCI packages will be opened to the module defining this class */ static void openJVMCITo(Class other) { - if (IS_IN_NATIVE_IMAGE) return; + if (IS_IN_NATIVE_IMAGE) { + return; + } Module jvmciModule = JVMCI_MODULE; Module otherModule = other.getModule(); diff --git a/compiler/src/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/BufferUtil.java b/compiler/src/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/BufferUtil.java new file mode 100644 index 000000000000..93c48de343dc --- /dev/null +++ b/compiler/src/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/BufferUtil.java @@ -0,0 +1,65 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.serviceprovider; + +import java.nio.Buffer; + +/** + * Covariant return types for some methods in the {@code java.nio.Buffer} were + * introduced in JDK 9. + * + * If calls to these methods are compiled with javac from JDK 9+ using {@code -target 8 -source 8} + * then the call sites will invoke the covariant methods in the subclass. For example: + * + *
    + * static void reset(ByteBuffer buf) {
    + *     buf.reset();
    + * }
    + * 
    + * + * will result in: + * + *
    + *    0: aload_0
    + *    1: invokevirtual #7  // Method java/nio/ByteBuffer.reset:()Ljava/nio/ByteBuffer;
    + *    4: pop
    + *    5: return
    + * 
    + * + * This will result in a {@link NoSuchMethodError} when run on JDK 8. The workaround for this is to + * {@linkplain #asBaseBuffer(Buffer) coerce} the receiver for calls to the covariant methods to + * {@link Buffer}. + */ +public final class BufferUtil { + + /** + * Coerces {@code obj} to be of type {@link Buffer}. This is required instead of a cast as + * {@code org.graalvm.compiler.core.test.VerifyBufferUsage} is based on Graal graphs which will + * have had redundant casts eliminated by the bytecode parser. + */ + public static Buffer asBaseBuffer(Buffer obj) { + return obj; + } +} diff --git a/compiler/src/org.graalvm.compiler.truffle.common.hotspot.libgraal/src/org/graalvm/compiler/truffle/common/hotspot/libgraal/SVMToHotSpot.java b/compiler/src/org.graalvm.compiler.truffle.common.hotspot.libgraal/src/org/graalvm/compiler/truffle/common/hotspot/libgraal/SVMToHotSpot.java index bd21b2366d63..1225b6911c95 100644 --- a/compiler/src/org.graalvm.compiler.truffle.common.hotspot.libgraal/src/org/graalvm/compiler/truffle/common/hotspot/libgraal/SVMToHotSpot.java +++ b/compiler/src/org.graalvm.compiler.truffle.common.hotspot.libgraal/src/org/graalvm/compiler/truffle/common/hotspot/libgraal/SVMToHotSpot.java @@ -96,6 +96,7 @@ enum Id { GetStackTraceElementMethodName(String.class, StackTraceElement.class), GetSuppliedString(String.class, Supplier.class), GetTargetName(String.class, Decision.class), + GetThrowableMessage(String.class, Throwable.class), GetTruffleCallBoundaryMethods(long[].class, HotSpotTruffleCompilerRuntime.class), GetURI(String.class, TruffleSourceLanguagePosition.class), IsCancelled(boolean.class, TruffleCompilationTask.class), diff --git a/compiler/src/org.graalvm.compiler.truffle.common/src/org/graalvm/compiler/truffle/common/TruffleCompilerListener.java b/compiler/src/org.graalvm.compiler.truffle.common/src/org/graalvm/compiler/truffle/common/TruffleCompilerListener.java index b8d3cbf8ad5e..7711c2f6e04d 100644 --- a/compiler/src/org.graalvm.compiler.truffle.common/src/org/graalvm/compiler/truffle/common/TruffleCompilerListener.java +++ b/compiler/src/org.graalvm.compiler.truffle.common/src/org/graalvm/compiler/truffle/common/TruffleCompilerListener.java @@ -32,7 +32,7 @@ public interface TruffleCompilerListener { /** - * Summary information for a Graal compiler graph. + * Summary information for a compiler graph. */ interface GraphInfo { /** diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler.hotspot.libgraal/src/org/graalvm/compiler/truffle/compiler/hotspot/libgraal/JNIExceptionWrapper.java b/compiler/src/org.graalvm.compiler.truffle.compiler.hotspot.libgraal/src/org/graalvm/compiler/truffle/compiler/hotspot/libgraal/JNIExceptionWrapper.java index adba2dd32cc5..be34bdfca199 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler.hotspot.libgraal/src/org/graalvm/compiler/truffle/compiler/hotspot/libgraal/JNIExceptionWrapper.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler.hotspot.libgraal/src/org/graalvm/compiler/truffle/compiler/hotspot/libgraal/JNIExceptionWrapper.java @@ -30,6 +30,7 @@ import static org.graalvm.compiler.truffle.common.hotspot.libgraal.SVMToHotSpot.Id.GetStackTraceElementFileName; import static org.graalvm.compiler.truffle.common.hotspot.libgraal.SVMToHotSpot.Id.GetStackTraceElementLineNumber; import static org.graalvm.compiler.truffle.common.hotspot.libgraal.SVMToHotSpot.Id.GetStackTraceElementMethodName; +import static org.graalvm.compiler.truffle.common.hotspot.libgraal.SVMToHotSpot.Id.GetThrowableMessage; import static org.graalvm.compiler.truffle.common.hotspot.libgraal.SVMToHotSpot.Id.UpdateStackTrace; import static org.graalvm.compiler.truffle.compiler.hotspot.libgraal.JNIExceptionWrapperGen.callCreateException; import static org.graalvm.compiler.truffle.compiler.hotspot.libgraal.JNIExceptionWrapperGen.callGetStackTrace; @@ -37,6 +38,7 @@ import static org.graalvm.compiler.truffle.compiler.hotspot.libgraal.JNIExceptionWrapperGen.callGetStackTraceElementFileName; import static org.graalvm.compiler.truffle.compiler.hotspot.libgraal.JNIExceptionWrapperGen.callGetStackTraceElementLineNumber; import static org.graalvm.compiler.truffle.compiler.hotspot.libgraal.JNIExceptionWrapperGen.callGetStackTraceElementMethodName; +import static org.graalvm.compiler.truffle.compiler.hotspot.libgraal.JNIExceptionWrapperGen.callGetThrowableMessage; import static org.graalvm.compiler.truffle.compiler.hotspot.libgraal.JNIExceptionWrapperGen.callUpdateStackTrace; import static org.graalvm.compiler.truffle.compiler.hotspot.libgraal.SVMToHotSpotUtil.isHotSpotCall; import static org.graalvm.compiler.truffle.compiler.hotspot.libgraal.JNIUtil.ExceptionCheck; @@ -73,6 +75,7 @@ final class JNIExceptionWrapper extends RuntimeException { private final boolean throwableRequiresStackTraceUpdate; private JNIExceptionWrapper(JNIEnv env, JThrowable throwableHandle) { + super(getMessage(env, throwableHandle)); this.throwableHandle = throwableHandle; this.throwableRequiresStackTraceUpdate = createMergedStackTrace(env); } @@ -278,11 +281,17 @@ private static JThrowable updateStackTrace(JNIEnv env, JThrowable throwableHandl return callUpdateStackTrace(env, throwableHandle, stackTraceHandle); } + @SVMToHotSpot(GetThrowableMessage) + private static String getMessage(JNIEnv env, JThrowable throwableHandle) { + JString message = callGetThrowableMessage(env, throwableHandle); + return createString(env, message); + } + /** * Gets the index of the first frame denoting the caller of * {@link #wrapAndThrowPendingJNIException(JNIEnv)} in {@code stackTrace}. * - * @returns {@code stackTrace.length} if no caller found + * @returns {@code 0} if no caller found */ private static int getIndexOfPropagateJNIExceptionFrame(StackTraceElement[] stackTrace) { for (int i = 0; i < stackTrace.length; i++) { @@ -291,6 +300,6 @@ private static int getIndexOfPropagateJNIExceptionFrame(StackTraceElement[] stac return i + 1; } } - return stackTrace.length; + return 0; } } diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler.hotspot/src/org/graalvm/compiler/truffle/compiler/hotspot/HotSpotTruffleCompilerImpl.java b/compiler/src/org.graalvm.compiler.truffle.compiler.hotspot/src/org/graalvm/compiler/truffle/compiler/hotspot/HotSpotTruffleCompilerImpl.java index c75a8da64e5f..51858efba9ae 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler.hotspot/src/org/graalvm/compiler/truffle/compiler/hotspot/HotSpotTruffleCompilerImpl.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler.hotspot/src/org/graalvm/compiler/truffle/compiler/hotspot/HotSpotTruffleCompilerImpl.java @@ -99,7 +99,7 @@ public final class HotSpotTruffleCompilerImpl extends TruffleCompilerImpl implem public static class Options { // @formatter:off - @Option(help = "Select a Graal compiler configuration for Truffle compilation (default: use Graal system compiler configuration).") + @Option(help = "Select a compiler configuration for Truffle compilation (default: use Graal system compiler configuration).") public static final OptionKey TruffleCompilerConfiguration = new OptionKey<>(null); // @formatter:on } diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilationResultBuilderFactory.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilationResultBuilderFactory.java index 1e2ae7762ad4..5a417a9d1986 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilationResultBuilderFactory.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilationResultBuilderFactory.java @@ -47,7 +47,7 @@ /** * A mechanism for Truffle to update a {@link CompilationResult} before it is - * {@linkplain CompilationResult#close() closed} by the Graal compiler. + * {@linkplain CompilationResult#close() closed} by the compiler. */ class TruffleCompilationResultBuilderFactory implements CompilationResultBuilderFactory { diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilerImpl.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilerImpl.java index a8ab6e247a04..7075271962b5 100644 --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilerImpl.java +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleCompilerImpl.java @@ -184,7 +184,7 @@ private ResolvedJavaType[] getSkippedExceptionTypes(TruffleCompilerRuntime runti } /** - * Gets the Graal compiler backend used for Truffle compilation. + * Gets the compiler backend used for Truffle compilation. */ public Backend getBackend() { return backend; diff --git a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/IgvSupport.java b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/IgvSupport.java index 8609eb2a4d5f..aa1b261f4a63 100644 --- a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/IgvSupport.java +++ b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/IgvSupport.java @@ -24,10 +24,11 @@ */ package org.graalvm.compiler.truffle.runtime.hotspot.libgraal; -import static org.graalvm.libgraal.LibGraal.getIsolateThread; +import static org.graalvm.libgraal.LibGraalScope.getIsolateThread; import java.io.Closeable; import java.io.IOException; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.channels.WritableByteChannel; import java.nio.file.Files; @@ -42,8 +43,10 @@ import org.graalvm.compiler.truffle.common.TruffleDebugContext; import org.graalvm.compiler.truffle.common.TruffleDebugJavaMethod; import org.graalvm.graphio.GraphOutput; +import org.graalvm.libgraal.LibGraalScope; import org.graalvm.libgraal.OptionsEncoder; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.services.Services; final class IgvSupport extends SVMObject implements TruffleDebugContext { @@ -52,13 +55,15 @@ final class IgvSupport extends SVMObject implements TruffleDebugContext { private static volatile Map versionProperties; private final SVMHotSpotTruffleCompiler owner; + private final LibGraalScope scope; private GraphOutput parentOutput; private IgvDumpChannel sharedChannel; - private IgvSupport(SVMHotSpotTruffleCompiler owner, long handle) { + private IgvSupport(LibGraalScope scope, SVMHotSpotTruffleCompiler owner, long handle) { super(handle); Objects.requireNonNull(owner, "Owner must be non null."); this.owner = owner; + this.scope = scope; } @Override @@ -131,7 +136,11 @@ public Closeable scope(String name, Object context) { @Override public void close() { - HotSpotToSVMCalls.closeDebugContext(getIsolateThread(), handle); + try { + HotSpotToSVMCalls.closeDebugContext(getIsolateThread(), handle); + } finally { + scope.close(); + } } @Override @@ -161,7 +170,8 @@ private static Path findReleaseFile() { static IgvSupport create(SVMHotSpotTruffleCompiler compiler, Map options, SVMTruffleCompilation compilation) { byte[] encodedOptions = OptionsEncoder.encode(options); - return new IgvSupport(compiler, HotSpotToSVMCalls.openDebugContext(getIsolateThread(), compiler.handle, compilation == null ? 0 : compilation.handle, encodedOptions)); + LibGraalScope scope = new LibGraalScope(HotSpotJVMCIRuntime.runtime()); + return new IgvSupport(scope, compiler, HotSpotToSVMCalls.openDebugContext(getIsolateThread(), compiler.handle, compilation == null ? 0 : compilation.handle, encodedOptions)); } private static final class IgvDumpChannel extends SVMObject implements WritableByteChannel { @@ -170,6 +180,13 @@ private static final class IgvDumpChannel extends SVMObject implements WritableB super(handle); } + /** + * See {@code org.graalvm.compiler.serviceprovider.BufferUtil}. + */ + static Buffer asBaseBuffer(Buffer obj) { + return obj; + } + @Override public int write(ByteBuffer src) throws IOException { if (src.hasArray()) { @@ -180,7 +197,7 @@ public int write(ByteBuffer src) throws IOException { int limit = src.limit(); int written = HotSpotToSVMCalls.dumpChannelWrite(getIsolateThread(), handle, src, capacity, pos, limit); if (written > 0) { - src.position(pos + written); + asBaseBuffer(src).position(pos + written); } return written; } diff --git a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/LibGraalTruffleRuntime.java b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/LibGraalTruffleRuntime.java index 3050aa76e9dd..b563fa8ab5ed 100644 --- a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/LibGraalTruffleRuntime.java +++ b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/LibGraalTruffleRuntime.java @@ -24,13 +24,14 @@ */ package org.graalvm.compiler.truffle.runtime.hotspot.libgraal; -import static org.graalvm.libgraal.LibGraal.getIsolateThread; +import static org.graalvm.libgraal.LibGraalScope.getIsolateThread; import java.util.Map; import org.graalvm.compiler.truffle.common.hotspot.HotSpotTruffleCompiler; import org.graalvm.compiler.truffle.runtime.hotspot.AbstractHotSpotTruffleRuntime; import org.graalvm.libgraal.LibGraal; +import org.graalvm.libgraal.LibGraalScope; import org.graalvm.libgraal.OptionsEncoder; import com.oracle.truffle.api.TruffleRuntime; @@ -46,43 +47,60 @@ final class LibGraalTruffleRuntime extends AbstractHotSpotTruffleRuntime { private final long handle; + @SuppressWarnings("try") LibGraalTruffleRuntime() { HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime(); runtime.registerNativeMethods(HotSpotToSVMCalls.class); MetaAccessProvider metaAccess = runtime.getHostJVMCIBackend().getMetaAccess(); HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) metaAccess.lookupJavaType(getClass()); - long classLoaderDelegate = LibGraal.translate(runtime, type); - handle = HotSpotToSVMCalls.initializeRuntime(getIsolateThread(), this, classLoaderDelegate); + try (LibGraalScope scope = new LibGraalScope(runtime)) { + long classLoaderDelegate = LibGraal.translate(runtime, type); + handle = HotSpotToSVMCalls.initializeRuntime(getIsolateThread(), this, classLoaderDelegate); + } } + @SuppressWarnings("try") @Override public HotSpotTruffleCompiler newTruffleCompiler() { - return new SVMHotSpotTruffleCompiler(HotSpotToSVMCalls.initializeCompiler(getIsolateThread(), handle)); + try (LibGraalScope scope = new LibGraalScope(HotSpotJVMCIRuntime.runtime())) { + return new SVMHotSpotTruffleCompiler(HotSpotToSVMCalls.initializeCompiler(getIsolateThread(), handle)); + } } + @SuppressWarnings("try") @Override protected String initLazyCompilerConfigurationName() { - return HotSpotToSVMCalls.getCompilerConfigurationFactoryName(getIsolateThread()); + try (LibGraalScope scope = new LibGraalScope(HotSpotJVMCIRuntime.runtime())) { + return HotSpotToSVMCalls.getCompilerConfigurationFactoryName(getIsolateThread()); + } } + @SuppressWarnings("try") @Override protected Map createInitialOptions() { - byte[] serializedOptions = HotSpotToSVMCalls.getInitialOptions(getIsolateThread(), handle); - return OptionsEncoder.decode(serializedOptions); + try (LibGraalScope scope = new LibGraalScope(HotSpotJVMCIRuntime.runtime())) { + byte[] serializedOptions = HotSpotToSVMCalls.getInitialOptions(getIsolateThread(), handle); + return OptionsEncoder.decode(serializedOptions); + } } + @SuppressWarnings("try") @Override public void log(String message) { - HotSpotToSVMCalls.log(getIsolateThread(), message); + try (LibGraalScope scope = new LibGraalScope(HotSpotJVMCIRuntime.runtime())) { + HotSpotToSVMCalls.log(getIsolateThread(), message); + } } /** * Clears JNI GlobalReferences to HotSpot objects held by object on SVM heap. NOTE: This method * is called reflectively by Truffle tests. */ - @SuppressWarnings("unused") + @SuppressWarnings({"unused", "try"}) private static void cleanNativeReferences() { - SVMObject.cleanHandles(); - HotSpotToSVMCalls.cleanReferences(getIsolateThread()); + try (LibGraalScope scope = new LibGraalScope(HotSpotJVMCIRuntime.runtime())) { + SVMObject.cleanHandles(); + HotSpotToSVMCalls.cleanReferences(getIsolateThread()); + } } } diff --git a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMCompilationResultInfo.java b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMCompilationResultInfo.java index 9aed2eb74ea3..230fb9fcd5ec 100644 --- a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMCompilationResultInfo.java +++ b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMCompilationResultInfo.java @@ -24,7 +24,7 @@ */ package org.graalvm.compiler.truffle.runtime.hotspot.libgraal; -import static org.graalvm.libgraal.LibGraal.getIsolateThread; +import static org.graalvm.libgraal.LibGraalScope.getIsolateThread; import org.graalvm.compiler.truffle.common.TruffleCompilerListener; diff --git a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMGraphInfo.java b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMGraphInfo.java index fb3ada5b8155..8bda68202ab1 100644 --- a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMGraphInfo.java +++ b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMGraphInfo.java @@ -24,7 +24,7 @@ */ package org.graalvm.compiler.truffle.runtime.hotspot.libgraal; -import static org.graalvm.libgraal.LibGraal.getIsolateThread; +import static org.graalvm.libgraal.LibGraalScope.getIsolateThread; import org.graalvm.compiler.truffle.common.TruffleCompilerListener; import org.graalvm.compiler.truffle.common.TruffleCompilerListener.GraphInfo; diff --git a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMHotSpotTruffleCompiler.java b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMHotSpotTruffleCompiler.java index 75171e10acb0..620ca82124b7 100644 --- a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMHotSpotTruffleCompiler.java +++ b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMHotSpotTruffleCompiler.java @@ -24,7 +24,7 @@ */ package org.graalvm.compiler.truffle.runtime.hotspot.libgraal; -import static org.graalvm.libgraal.LibGraal.getIsolateThread; +import static org.graalvm.libgraal.LibGraalScope.getIsolateThread; import java.lang.ref.Reference; import java.lang.ref.WeakReference; @@ -39,8 +39,11 @@ import org.graalvm.compiler.truffle.common.TruffleDebugContext; import org.graalvm.compiler.truffle.common.TruffleInliningPlan; import org.graalvm.compiler.truffle.common.hotspot.HotSpotTruffleCompiler; +import org.graalvm.libgraal.LibGraalScope; import org.graalvm.libgraal.OptionsEncoder; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; + /** * Encapsulates a handle to a {@link HotSpotTruffleCompiler} object in the SVM heap. */ @@ -54,7 +57,8 @@ final class SVMHotSpotTruffleCompiler extends SVMObject implements HotSpotTruffl @Override public TruffleCompilation openCompilation(CompilableTruffleAST compilable) { - SVMTruffleCompilation compilation = new SVMTruffleCompilation(this, HotSpotToSVMCalls.openCompilation(getIsolateThread(), handle, compilable)); + LibGraalScope scope = new LibGraalScope(HotSpotJVMCIRuntime.runtime()); + SVMTruffleCompilation compilation = new SVMTruffleCompilation(this, HotSpotToSVMCalls.openCompilation(getIsolateThread(), handle, compilable), scope); activeCompilations.put(compilable, new WeakReference<>(compilation)); return compilation; } @@ -75,24 +79,41 @@ public void doCompile(TruffleDebugContext debug, HotSpotToSVMCalls.doCompile(getIsolateThread(), handle, ((IgvSupport) debug).handle, ((SVMTruffleCompilation) compilation).handle, encodedOptions, inlining, task, listener); } + @SuppressWarnings("try") @Override public String getCompilerConfigurationName() { - return HotSpotToSVMCalls.getCompilerConfigurationName(getIsolateThread(), handle); + try (LibGraalScope scope = new LibGraalScope(HotSpotJVMCIRuntime.runtime())) { + return HotSpotToSVMCalls.getCompilerConfigurationName(getIsolateThread(), handle); + } } + @SuppressWarnings("try") @Override public void shutdown() { - HotSpotToSVMCalls.shutdown(getIsolateThread(), handle); + try (LibGraalScope scope = new LibGraalScope(HotSpotJVMCIRuntime.runtime())) { + HotSpotToSVMCalls.shutdown(getIsolateThread(), handle); + } } + @SuppressWarnings("try") @Override public void installTruffleCallBoundaryMethods() { - HotSpotToSVMCalls.installTruffleCallBoundaryMethods(getIsolateThread(), handle); + try (LibGraalScope scope = new LibGraalScope(HotSpotJVMCIRuntime.runtime())) { + HotSpotToSVMCalls.installTruffleCallBoundaryMethods(getIsolateThread(), handle); + } } + Integer pendingTransferToInterpreterOffset; + + @SuppressWarnings("try") @Override public int pendingTransferToInterpreterOffset() { - return HotSpotToSVMCalls.pendingTransferToInterpreterOffset(getIsolateThread(), handle); + if (pendingTransferToInterpreterOffset == null) { + try (LibGraalScope scope = new LibGraalScope(HotSpotJVMCIRuntime.runtime())) { + pendingTransferToInterpreterOffset = HotSpotToSVMCalls.pendingTransferToInterpreterOffset(getIsolateThread(), handle); + } + } + return pendingTransferToInterpreterOffset; } void closeCompilation(SVMTruffleCompilation compilation) { diff --git a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMObject.java b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMObject.java index 15afbba3f9f5..721de470508e 100644 --- a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMObject.java +++ b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMObject.java @@ -24,7 +24,7 @@ */ package org.graalvm.compiler.truffle.runtime.hotspot.libgraal; -import static org.graalvm.libgraal.LibGraal.getIsolateThread; +import static org.graalvm.libgraal.LibGraalScope.getIsolateThread; import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; diff --git a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMStringSupplier.java b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMStringSupplier.java index c982f4407996..85f885a4bde8 100644 --- a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMStringSupplier.java +++ b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMStringSupplier.java @@ -24,7 +24,7 @@ */ package org.graalvm.compiler.truffle.runtime.hotspot.libgraal; -import static org.graalvm.libgraal.LibGraal.getIsolateThread; +import static org.graalvm.libgraal.LibGraalScope.getIsolateThread; import java.util.function.Supplier; diff --git a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMToHotSpotEntryPoints.java b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMToHotSpotEntryPoints.java index 22b993f621f0..82b95788d108 100644 --- a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMToHotSpotEntryPoints.java +++ b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMToHotSpotEntryPoints.java @@ -58,6 +58,7 @@ import static org.graalvm.compiler.truffle.common.hotspot.libgraal.SVMToHotSpot.Id.GetStackTraceElementMethodName; import static org.graalvm.compiler.truffle.common.hotspot.libgraal.SVMToHotSpot.Id.GetSuppliedString; import static org.graalvm.compiler.truffle.common.hotspot.libgraal.SVMToHotSpot.Id.GetTargetName; +import static org.graalvm.compiler.truffle.common.hotspot.libgraal.SVMToHotSpot.Id.GetThrowableMessage; import static org.graalvm.compiler.truffle.common.hotspot.libgraal.SVMToHotSpot.Id.GetTruffleCallBoundaryMethods; import static org.graalvm.compiler.truffle.common.hotspot.libgraal.SVMToHotSpot.Id.GetURI; import static org.graalvm.compiler.truffle.common.hotspot.libgraal.SVMToHotSpot.Id.IsCancelled; @@ -465,6 +466,11 @@ static boolean shouldInline(Decision decision) { return decision.shouldInline(); } + @SVMToHotSpot(GetThrowableMessage) + static String getThrowableMessage(Throwable t) { + return t.getMessage(); + } + /*----------------------*/ /** diff --git a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMTruffleCompilation.java b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMTruffleCompilation.java index b0c4a8385169..f955f0d9f2b0 100644 --- a/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMTruffleCompilation.java +++ b/compiler/src/org.graalvm.compiler.truffle.runtime.hotspot.libgraal/src/org/graalvm/compiler/truffle/runtime/hotspot/libgraal/SVMTruffleCompilation.java @@ -24,20 +24,23 @@ */ package org.graalvm.compiler.truffle.runtime.hotspot.libgraal; -import static org.graalvm.libgraal.LibGraal.getIsolateThread; +import static org.graalvm.libgraal.LibGraalScope.getIsolateThread; import org.graalvm.compiler.truffle.common.CompilableTruffleAST; import org.graalvm.compiler.truffle.common.TruffleCompilation; +import org.graalvm.libgraal.LibGraalScope; final class SVMTruffleCompilation extends SVMObject implements TruffleCompilation { private final SVMHotSpotTruffleCompiler owner; private volatile CompilableTruffleAST cachedCompilableTruffleAST; private volatile String cachedId; + private final LibGraalScope scope; - SVMTruffleCompilation(SVMHotSpotTruffleCompiler owner, long handle) { + SVMTruffleCompilation(SVMHotSpotTruffleCompiler owner, long handle, LibGraalScope scope) { super(handle); this.owner = owner; + this.scope = scope; } @Override @@ -56,6 +59,7 @@ public void close() { owner.closeCompilation(this); } finally { HotSpotToSVMCalls.closeCompilation(getIsolateThread(), handle); + scope.close(); } } diff --git a/compiler/src/org.graalvm.compiler.truffle.runtime/src/org/graalvm/compiler/truffle/runtime/OptimizedCallTarget.java b/compiler/src/org.graalvm.compiler.truffle.runtime/src/org/graalvm/compiler/truffle/runtime/OptimizedCallTarget.java index 1d58f5b48e15..8c1abf234731 100644 --- a/compiler/src/org.graalvm.compiler.truffle.runtime/src/org/graalvm/compiler/truffle/runtime/OptimizedCallTarget.java +++ b/compiler/src/org.graalvm.compiler.truffle.runtime/src/org/graalvm/compiler/truffle/runtime/OptimizedCallTarget.java @@ -95,6 +95,9 @@ public abstract class OptimizedCallTarget implements CompilableTruffleAST, RootC private volatile SpeculationLog speculationLog; private volatile int callSitesKnown; + private static final AtomicReferenceFieldUpdater SPECULATION_LOG_UPDATER = AtomicReferenceFieldUpdater.newUpdater(OptimizedCallTarget.class, + SpeculationLog.class, "speculationLog"); + /** * When this field is not null, this {@link OptimizedCallTarget} is {@linkplain #isCompiling() * being compiled}.
    @@ -481,14 +484,14 @@ OptimizedCallTarget cloneUninitialized() { * this call target. Note that this may differ from the speculation log * {@linkplain CompilableTruffleAST#getCompilationSpeculationLog() used for compilation}. */ - public synchronized SpeculationLog getSpeculationLog() { + public SpeculationLog getSpeculationLog() { if (speculationLog == null) { - speculationLog = ((GraalTruffleRuntime) Truffle.getRuntime()).createSpeculationLog(); + SPECULATION_LOG_UPDATER.compareAndSet(this, null, ((GraalTruffleRuntime) Truffle.getRuntime()).createSpeculationLog()); } return speculationLog; } - synchronized void setSpeculationLog(SpeculationLog speculationLog) { + void setSpeculationLog(SpeculationLog speculationLog) { this.speculationLog = speculationLog; } diff --git a/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/libgraal/JNIExceptionWrapperTest.java b/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/libgraal/JNIExceptionWrapperTest.java new file mode 100644 index 000000000000..4144978fbbd1 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/libgraal/JNIExceptionWrapperTest.java @@ -0,0 +1,112 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.test.libgraal; + +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import com.oracle.truffle.api.nodes.RootNode; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; +import org.graalvm.compiler.core.CompilationWrapper; +import org.graalvm.compiler.truffle.common.CompilableTruffleAST; +import org.graalvm.compiler.truffle.common.TruffleCompilation; +import org.graalvm.compiler.truffle.common.TruffleCompiler; +import org.graalvm.compiler.truffle.common.TruffleCompilerListener; +import org.graalvm.compiler.truffle.common.TruffleDebugContext; +import org.graalvm.compiler.truffle.common.TruffleInliningPlan; +import org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl; +import org.graalvm.compiler.truffle.runtime.GraalTruffleRuntime; +import org.graalvm.compiler.truffle.runtime.OptimizedCallTarget; +import org.graalvm.compiler.truffle.runtime.SharedTruffleRuntimeOptions; +import org.graalvm.compiler.truffle.runtime.TruffleRuntimeOptions; +import org.junit.Test; + +public class JNIExceptionWrapperTest { + + @Test + @SuppressWarnings({"unused", "try"}) + public void testMergedStackTrace() throws Exception { + try (TruffleRuntimeOptions.TruffleRuntimeOptionsOverrideScope runtimeScope = TruffleRuntimeOptions.overrideOptions( + SharedTruffleRuntimeOptions.TruffleCompilationExceptionsAreThrown, true)) { + GraalTruffleRuntime runtime = GraalTruffleRuntime.getRuntime(); + OptimizedCallTarget compilable = (OptimizedCallTarget) runtime.createCallTarget(RootNode.createConstantNode(42)); + TruffleCompiler compiler = runtime.getTruffleCompiler(); + try (TruffleCompilation compilation = compiler.openCompilation(compilable)) { + Map options = new HashMap<>(); + options.put("CompilationFailureAction", CompilationWrapper.ExceptionAction.Silent); + options.put("TruffleCompilationExceptionsAreFatal", false); + try (TruffleDebugContext debug = compiler.openDebugContext(options, compilation)) { + compilable.getCompilationProfile(); + TruffleInliningPlan inliningPlan = runtime.createInliningPlan(compilable, null); + TestListener listener = new TestListener(); + compiler.doCompile(debug, compilation, options, inliningPlan, null, listener); + } + } catch (Throwable t) { + String message = t.getMessage(); + int runtimeIndex = findFrame(message, JNIExceptionWrapperTest.class, "testMergedStackTrace"); + assertNotEquals(message, -1, runtimeIndex); + int listenerIndex = findFrame(message, TestListener.class, "onTruffleTierFinished"); + assertNotEquals(message, -1, listenerIndex); + int compilerIndex = findFrame(message, TruffleCompilerImpl.class, "compileAST"); + assertNotEquals(message, -1, compilerIndex); + assertTrue(listenerIndex < compilerIndex); + assertTrue(compilerIndex < runtimeIndex); + } + } + } + + private static int findFrame(String message, Class clazz, String methodName) { + String[] lines = message.split("\n"); + Pattern pattern = Pattern.compile("at\\s+(.*/)?" + Pattern.quote(clazz.getName() + '.' + methodName)); + for (int i = 0; i < lines.length; i++) { + if (pattern.matcher(lines[i].trim()).find()) { + return i; + } + } + return -1; + } + + private static final class TestListener implements TruffleCompilerListener { + + @Override + public void onTruffleTierFinished(CompilableTruffleAST compilable, TruffleInliningPlan inliningPlan, GraphInfo graph) { + throw new RuntimeException("Expected exception"); + } + + @Override + public void onGraalTierFinished(CompilableTruffleAST compilable, GraphInfo graph) { + } + + @Override + public void onSuccess(CompilableTruffleAST compilable, TruffleInliningPlan inliningPlan, GraphInfo graphInfo, CompilationResultInfo compilationResultInfo) { + } + + @Override + public void onFailure(CompilableTruffleAST compilable, String reason, boolean bailout, boolean permanentBailout) { + } + } +} diff --git a/compiler/src/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java b/compiler/src/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java index 5bc5cdc8fbf5..a484c139411d 100644 --- a/compiler/src/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java +++ b/compiler/src/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java @@ -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 @@ -26,6 +26,7 @@ import java.util.ArrayList; +import org.graalvm.compiler.debug.DebugCloseable; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.nodes.ControlSinkNode; @@ -196,11 +197,14 @@ public boolean isCfgKill() { public void replaceWithSink(FixedWithNextNode node, ControlSinkNode sink) { add("kill if branch", new Effect() { + @SuppressWarnings("try") @Override public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - graph.addWithoutUnique(sink); - node.replaceAtPredecessor(sink); - GraphUtil.killCFG(node); + try (DebugCloseable position = graph.withNodeSourcePosition(node)) { + graph.addWithoutUnique(sink); + node.replaceAtPredecessor(sink); + GraphUtil.killCFG(node); + } } @Override @@ -221,33 +225,36 @@ public boolean isCfgKill() { * @param insertBefore * */ + @SuppressWarnings("try") public void replaceAtUsages(ValueNode node, ValueNode replacement, FixedNode insertBefore) { assert node != null && replacement != null : node + " " + replacement; assert !node.hasUsages() || node.stamp(NodeView.DEFAULT).isCompatible(replacement.stamp(NodeView.DEFAULT)) : "Replacement node stamp not compatible " + node.stamp(NodeView.DEFAULT) + " vs " + replacement.stamp(NodeView.DEFAULT); add("replace at usages", (graph, obsoleteNodes) -> { - assert node.isAlive(); - ValueNode replacementNode = graph.addOrUniqueWithInputs(replacement); - assert replacementNode.isAlive(); - assert insertBefore != null; - if (replacementNode instanceof FixedWithNextNode && ((FixedWithNextNode) replacementNode).next() == null) { - graph.addBeforeFixed(insertBefore, (FixedWithNextNode) replacementNode); - } - /* - * Keep the (better) stamp information when replacing a node with another one if the - * replacement has a less precise stamp than the original node. This can happen for - * example in the context of read nodes and unguarded pi nodes where the pi will be used - * to improve the stamp information of the read. Such a read might later be replaced - * with a read with a less precise stamp. - */ - if (node.hasUsages() && !node.stamp(NodeView.DEFAULT).equals(replacementNode.stamp(NodeView.DEFAULT))) { - replacementNode = graph.unique(new PiNode(replacementNode, node.stamp(NodeView.DEFAULT))); - } - node.replaceAtUsages(replacementNode); - if (node instanceof FixedWithNextNode) { - GraphUtil.unlinkFixedNode((FixedWithNextNode) node); + try (DebugCloseable position = graph.withNodeSourcePosition(node)) { + assert node.isAlive(); + ValueNode replacementNode = graph.addOrUniqueWithInputs(replacement); + assert replacementNode.isAlive(); + assert insertBefore != null; + if (replacementNode instanceof FixedWithNextNode && ((FixedWithNextNode) replacementNode).next() == null) { + graph.addBeforeFixed(insertBefore, (FixedWithNextNode) replacementNode); + } + /* + * Keep the (better) stamp information when replacing a node with another one if the + * replacement has a less precise stamp than the original node. This can happen for + * example in the context of read nodes and unguarded pi nodes where the pi will be + * used to improve the stamp information of the read. Such a read might later be + * replaced with a read with a less precise stamp. + */ + if (node.hasUsages() && !node.stamp(NodeView.DEFAULT).equals(replacementNode.stamp(NodeView.DEFAULT))) { + replacementNode = graph.unique(new PiNode(replacementNode, node.stamp(NodeView.DEFAULT))); + } + node.replaceAtUsages(replacementNode); + if (node instanceof FixedWithNextNode) { + GraphUtil.unlinkFixedNode((FixedWithNextNode) node); + } + obsoleteNodes.add(node); } - obsoleteNodes.add(node); }); } diff --git a/compiler/src/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java b/compiler/src/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java index 4c55da9b0e54..afccb0c079c3 100644 --- a/compiler/src/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java +++ b/compiler/src/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.channels.WritableByteChannel; import java.nio.charset.Charset; @@ -86,6 +87,13 @@ abstract class GraphProtocol MAJOR_VERSION || (major == MAJOR_VERSION && minor > MINOR_VERSION)) { throw new IllegalArgumentException("Unrecognized version " + major + "." + minor); @@ -328,7 +336,7 @@ private void flushEmbedded() throws IOException { } private void flush() throws IOException { - buffer.flip(); + asBaseBuffer(buffer).flip(); /* * Try not to let interrupted threads abort the write. There's still a race here but an * interrupt that's been pending for a long time shouldn't stop this writing. @@ -411,12 +419,12 @@ private int writeBytesRaw(ByteBuffer b) throws IOException { while (b.position() < limit) { int toWrite = Math.min(limit - b.position(), buffer.capacity()); ensureAvailable(toWrite); - b.limit(b.position() + toWrite); + asBaseBuffer(b).limit(b.position() + toWrite); try { buffer.put(b); written += toWrite; } finally { - b.limit(limit); + asBaseBuffer(b).limit(limit); } } return written; @@ -430,7 +438,7 @@ private void writeInts(int[] b) throws IOException { int sizeInBytes = b.length * 4; ensureAvailable(sizeInBytes); buffer.asIntBuffer().put(b); - buffer.position(buffer.position() + sizeInBytes); + asBaseBuffer(buffer).position(buffer.position() + sizeInBytes); } } @@ -442,7 +450,7 @@ private void writeDoubles(double[] b) throws IOException { int sizeInBytes = b.length * 8; ensureAvailable(sizeInBytes); buffer.asDoubleBuffer().put(b); - buffer.position(buffer.position() + sizeInBytes); + asBaseBuffer(buffer).position(buffer.position() + sizeInBytes); } } diff --git a/compiler/src/org.graalvm.graphio/src/org/graalvm/graphio/package-info.java b/compiler/src/org.graalvm.graphio/src/org/graalvm/graphio/package-info.java index c9f21194b5e7..117aefc3620b 100644 --- a/compiler/src/org.graalvm.graphio/src/org/graalvm/graphio/package-info.java +++ b/compiler/src/org.graalvm.graphio/src/org/graalvm/graphio/package-info.java @@ -63,8 +63,8 @@ * diamond.bgv file generated from the above diamond structure * graph. *

    - * The primary IGV focus is on graphs used by Graal compiler. As such they aren't plain - * graphs, but contain various compiler oriented attributes: + * The primary IGV focus is on graphs used by the compiler. As such they aren't plain graphs, + * but contain various compiler oriented attributes: *

      *
    • {@linkplain org.graalvm.graphio.GraphBlocks code blocks} information
    • *
    • {@linkplain org.graalvm.graphio.GraphElements method and fields} information
    • @@ -82,6 +82,6 @@ * singletonizer API pattern again - e.g. * no need to change your existing data structures, just implement the operations provided by the * interfaces you pass into the builder. By combining these interfaces together you can get as rich, - * colorful, source linked graphs as Graal compiler produces to describe its optimizations. + * colorful, source linked graphs as the compiler produces to describe its optimizations. */ package org.graalvm.graphio; diff --git a/compiler/src/org.graalvm.libgraal.jdk11/src/org/graalvm/libgraal/LibGraal.java b/compiler/src/org.graalvm.libgraal.jdk11/src/org/graalvm/libgraal/LibGraal.java index 743f8ffbcf2f..2ed6d04b4d7c 100644 --- a/compiler/src/org.graalvm.libgraal.jdk11/src/org/graalvm/libgraal/LibGraal.java +++ b/compiler/src/org.graalvm.libgraal.jdk11/src/org/graalvm/libgraal/LibGraal.java @@ -31,6 +31,8 @@ */ public class LibGraal { + static final long isolate = 0L; + private static IllegalStateException unavailable() { throw new IllegalStateException("libgraal is not available"); } @@ -39,16 +41,16 @@ public static boolean isAvailable() { return false; } - public static long getIsolate() { + public static boolean inLibGraal() { throw unavailable(); } - public static long getIsolateThread() { + public static long getIsolate() { throw unavailable(); } @SuppressWarnings("unused") - public static long[] registerNativeMethods(HotSpotJVMCIRuntime runtime, Class clazz) { + public static void registerNativeMethods(HotSpotJVMCIRuntime runtime, Class clazz) { throw unavailable(); } @@ -61,4 +63,24 @@ public static long translate(HotSpotJVMCIRuntime runtime, Object obj) { public static T unhand(HotSpotJVMCIRuntime runtime, Class type, long handle) { throw unavailable(); } + + @SuppressWarnings("unused") + static boolean isCurrentThreadAttached(HotSpotJVMCIRuntime runtime) { + throw unavailable(); + } + + @SuppressWarnings("unused") + static boolean attachCurrentThread(HotSpotJVMCIRuntime runtime) { + throw unavailable(); + } + + @SuppressWarnings("unused") + static void detachCurrentThread(HotSpotJVMCIRuntime runtime) { + throw unavailable(); + } + + @SuppressWarnings("unused") + static long getCurrentIsolateThread(long iso) { + throw unavailable(); + } } diff --git a/compiler/src/org.graalvm.libgraal.jdk13/src/org/graalvm/libgraal/LibGraal.java b/compiler/src/org.graalvm.libgraal.jdk13/src/org/graalvm/libgraal/LibGraal.java index b00027a11fee..2e9b82ee051a 100644 --- a/compiler/src/org.graalvm.libgraal.jdk13/src/org/graalvm/libgraal/LibGraal.java +++ b/compiler/src/org.graalvm.libgraal.jdk13/src/org/graalvm/libgraal/LibGraal.java @@ -33,66 +33,42 @@ public class LibGraal { public static boolean isAvailable() { - return isCurrentRuntime() || libgraalIsolate != 0L; + return inLibGraal() || isolate != 0L; } - public static boolean isCurrentRuntime() { + public static boolean inLibGraal() { return Services.IS_IN_NATIVE_IMAGE; } - public static long getIsolate() { - if (isCurrentRuntime() || !isAvailable()) { - throw new IllegalStateException(); - } - return libgraalIsolate; - } - - public static long getIsolateThread() { - if (isCurrentRuntime()) { - throw new IllegalStateException(); - } - return CURRENT_ISOLATE_THREAD.get(); - } - - @SuppressWarnings("unused") - public static long[] registerNativeMethods(HotSpotJVMCIRuntime runtime, Class clazz) { + public static void registerNativeMethods(HotSpotJVMCIRuntime runtime, Class clazz) { if (clazz.isPrimitive()) { throw new IllegalArgumentException(); } - if (isCurrentRuntime() || !isAvailable()) { + if (inLibGraal() || !isAvailable()) { throw new IllegalStateException(); } - // Waiting for https://bugs.openjdk.java.net/browse/JDK-8220623 - // return runtime.registerNativeMethods(clazz); - throw new IllegalStateException("Requires JDK-8220623"); + runtime.registerNativeMethods(clazz); } - @SuppressWarnings("unused") public static long translate(HotSpotJVMCIRuntime runtime, Object obj) { if (!isAvailable()) { throw new IllegalStateException(); } - // return runtime.translate(obj); - throw new IllegalStateException("Requires JDK-8220623"); + if (!inLibGraal() && LibGraalScope.currentScope.get() == null) { + throw new IllegalStateException("Not within a " + LibGraalScope.class.getName()); + } + return runtime.translate(obj); } - @SuppressWarnings("unused") public static T unhand(HotSpotJVMCIRuntime runtime, Class type, long handle) { if (!isAvailable()) { throw new IllegalStateException(); } - // return runtime.unhand(type, handle); - throw new IllegalStateException("Requires JDK-8220623"); - } - - private static final ThreadLocal CURRENT_ISOLATE_THREAD = new ThreadLocal<>() { - @Override - protected Long initialValue() { - return attachThread(libgraalIsolate); + if (!inLibGraal() && LibGraalScope.currentScope.get() == null) { + throw new IllegalStateException("Not within a " + LibGraalScope.class.getName()); } - }; - - private static final long libgraalIsolate = Services.IS_BUILDING_NATIVE_IMAGE ? 0L : initializeLibgraal(); + return runtime.unhand(type, handle); + } private static long initializeLibgraal() { try { @@ -101,20 +77,27 @@ private static long initializeLibgraal() { // below will fail on JDK13+. Services.initializeJVMCI(); - // Waiting for https://bugs.openjdk.java.net/browse/JDK-8220623 - // HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime(); - // long[] nativeInterface = runtime.registerNativeMethods(LibGraal.class); - // return nativeInterface[1]; - return 0L; + HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime(); + long[] nativeInterface = runtime.registerNativeMethods(LibGraal.class); + return nativeInterface[1]; } catch (UnsupportedOperationException e) { return 0L; } } - /** - * Attaches the current thread to a thread in {@code isolate}. - * - * @param isolate - */ - private static native long attachThread(long isolate); + static final long isolate = Services.IS_BUILDING_NATIVE_IMAGE ? 0L : initializeLibgraal(); + + static boolean isCurrentThreadAttached(HotSpotJVMCIRuntime runtime) { + return runtime.isCurrentThreadAttached(); + } + + static boolean attachCurrentThread(HotSpotJVMCIRuntime runtime) { + return runtime.attachCurrentThread(false); + } + + static void detachCurrentThread(HotSpotJVMCIRuntime runtime) { + runtime.detachCurrentThread(); + } + + static native long getCurrentIsolateThread(long iso); } diff --git a/compiler/src/org.graalvm.libgraal.jdk8/src/org/graalvm/libgraal/LibGraal.java b/compiler/src/org.graalvm.libgraal.jdk8/src/org/graalvm/libgraal/LibGraal.java index 38b35f8ac9bf..61b27f35c7dd 100644 --- a/compiler/src/org.graalvm.libgraal.jdk8/src/org/graalvm/libgraal/LibGraal.java +++ b/compiler/src/org.graalvm.libgraal.jdk8/src/org/graalvm/libgraal/LibGraal.java @@ -33,41 +33,30 @@ public class LibGraal { public static boolean isAvailable() { - return isCurrentRuntime() || libgraalIsolate != 0L; + return inLibGraal() || isolate != 0L; } - public static boolean isCurrentRuntime() { + public static boolean inLibGraal() { return Services.IS_IN_NATIVE_IMAGE; } - public static long getIsolate() { - if (isCurrentRuntime() || !isAvailable()) { - throw new IllegalStateException(); - } - return libgraalIsolate; - } - - public static long getIsolateThread() { - if (isCurrentRuntime()) { - throw new IllegalStateException(); - } - return CURRENT_ISOLATE_THREAD.get(); - } - - public static long[] registerNativeMethods(HotSpotJVMCIRuntime runtime, Class clazz) { + public static void registerNativeMethods(HotSpotJVMCIRuntime runtime, Class clazz) { if (clazz.isPrimitive()) { throw new IllegalArgumentException(); } - if (isCurrentRuntime() || !isAvailable()) { + if (inLibGraal() || !isAvailable()) { throw new IllegalStateException(); } - return runtime.registerNativeMethods(clazz); + runtime.registerNativeMethods(clazz); } public static long translate(HotSpotJVMCIRuntime runtime, Object obj) { if (!isAvailable()) { throw new IllegalStateException(); } + if (!inLibGraal() && LibGraalScope.currentScope.get() == null) { + throw new IllegalStateException("Not within a " + LibGraalScope.class.getName()); + } return runtime.translate(obj); } @@ -75,38 +64,35 @@ public static T unhand(HotSpotJVMCIRuntime runtime, Class type, long hand if (!isAvailable()) { throw new IllegalStateException(); } + if (!inLibGraal() && LibGraalScope.currentScope.get() == null) { + throw new IllegalStateException("Not within a " + LibGraalScope.class.getName()); + } return runtime.unhand(type, handle); } - private static final ThreadLocal CURRENT_ISOLATE_THREAD = new ThreadLocal() { - @Override - protected Long initialValue() { - return attachThread(libgraalIsolate); - } - }; - - private static final long libgraalIsolate = Services.IS_BUILDING_NATIVE_IMAGE ? 0L : initializeLibgraal(); - private static long initializeLibgraal() { try { HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime(); long[] nativeInterface = runtime.registerNativeMethods(LibGraal.class); return nativeInterface[1]; - } catch (UnsatisfiedLinkError e) { - // Remove once Graal depends on a jvmci release including GR-14941 - // since we can then rely solely on UnsupportedOperationException - // to indicate whether libgraal is available. All other exceptions - // raised here should then cause fail-fast behavior. - return 0L; } catch (UnsupportedOperationException e) { return 0L; } } - /** - * Attaches the current thread to a thread in {@code isolate}. - * - * @param isolate - */ - private static native long attachThread(long isolate); + static final long isolate = Services.IS_BUILDING_NATIVE_IMAGE ? 0L : initializeLibgraal(); + + static boolean isCurrentThreadAttached(HotSpotJVMCIRuntime runtime) { + return runtime.isCurrentThreadAttached(); + } + + static boolean attachCurrentThread(HotSpotJVMCIRuntime runtime) { + return runtime.attachCurrentThread(false); + } + + static void detachCurrentThread(HotSpotJVMCIRuntime runtime) { + runtime.detachCurrentThread(); + } + + static native long getCurrentIsolateThread(long iso); } diff --git a/compiler/src/org.graalvm.libgraal/src/org/graalvm/libgraal/LibGraal.java b/compiler/src/org.graalvm.libgraal/src/org/graalvm/libgraal/LibGraal.java index 6f9dd3514283..22b6842022e2 100644 --- a/compiler/src/org.graalvm.libgraal/src/org/graalvm/libgraal/LibGraal.java +++ b/compiler/src/org.graalvm.libgraal/src/org/graalvm/libgraal/LibGraal.java @@ -24,9 +24,8 @@ */ package org.graalvm.libgraal; +import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.c.function.CEntryPoint; -import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateContext; -import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateThreadContext; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; @@ -34,13 +33,25 @@ * Access to libgraal, a shared library containing an AOT compiled version of Graal produced by SVM. * The libgraal library is only available if: *
        - *
      • the current runtime is libgraal, or
      • + *
      • the {@linkplain #inLibGraal() current runtime} is libgraal, or
      • *
      • the HotSpot {@code UseJVMCINativeLibrary} flag is true and the current runtime includes the * relevant JVMCI API additions for accessing libgraal.
      • *
      * * The {@link #isAvailable()} method is provided to test these conditions. It must be used to guard - * usage of all other methods in this class. + * usage of all other methods in this class. In addition, only the following methods can be called + * from within libgraal: + *
        + *
      • {@link #isAvailable()}
      • + *
      • {@link #inLibGraal()}
      • + *
      • {@link #translate(HotSpotJVMCIRuntime, Object)}
      • + *
      • {@link #unhand(HotSpotJVMCIRuntime, Class, long)}
      • + *
      + * + * The typical usage of this class is to {@linkplain #registerNativeMethods link} and call + * {@link CEntryPoint}s in libgraal. Each call to a {@link CEntryPoint} requires an + * {@link IsolateThread} argument which can be {@linkplain LibGraalScope#getIsolateThread obtained} + * from a {@link LibGraalScope}. */ public class LibGraal { @@ -58,62 +69,27 @@ public static boolean isAvailable() { /** * Determines if the current runtime is libgraal. */ - public static boolean isCurrentRuntime() { - throw shouldNotReachHere(); - } - - /** - * Gets the libgraal isolate. - * - * This cannot be called from {@linkplain #isCurrentRuntime() within} libgraal. - * - * @returns a value that can be used for the {@link IsolateContext} argument of a {@code native} - * method {@link #registerNativeMethods linked} to a {@link CEntryPoint} function in - * libgraal - * @throws IllegalStateException if libgraal is {@linkplain #isAvailable() unavailable} or - * {@link #isCurrentRuntime()} returns true - */ - public static long getIsolate() { - throw shouldNotReachHere(); - } - - /** - * Gets a libgraal isolate thread associated with the current thread. This method attaches the - * current thread to an isolate thread first if necessary. - * - * This cannot be called from {@linkplain #isCurrentRuntime() within} libgraal. - * - * @returns a value that can be used for the {@link IsolateThreadContext} argument of a - * {@code native} method {@link #registerNativeMethods linked} to a {@link CEntryPoint} - * function in libgraal - * @throws IllegalStateException if libgraal is {@linkplain #isAvailable() unavailable} or - * {@link #isCurrentRuntime()} returns true - */ - public static long getIsolateThread() { + public static boolean inLibGraal() { throw shouldNotReachHere(); } /** * Links each native method in {@code clazz} to a {@link CEntryPoint} in libgraal. * - * This cannot be called from {@linkplain #isCurrentRuntime() within} libgraal. - * - * @return an array of 4 longs where the first value is the {@code JavaVM*} value representing - * the libgraal Java VM, and the remaining values are the first 3 pointers in the - * Invocation API function table (i.e., {@code JNIInvokeInterface}) + * This cannot be called from {@linkplain #inLibGraal() within} libgraal. * * @throws NullPointerException if {@code clazz == null} * @throws UnsupportedOperationException if libgraal is not enabled (i.e. * {@code -XX:-UseJVMCINativeLibrary}) - * @throws IllegalArgumentException if{@code clazz} is {@link Class#isPrimitive()} + * @throws IllegalArgumentException if {@code clazz} is {@link Class#isPrimitive()} * @throws IllegalStateException if libgraal is {@linkplain #isAvailable() unavailable} or - * {@link #isCurrentRuntime()} returns true + * {@link #inLibGraal()} returns true * @throws UnsatisfiedLinkError if there's a problem linking a native method in {@code clazz} * (no matching JNI symbol or the native method is already linked to a different * address) */ @SuppressWarnings("unused") - public static long[] registerNativeMethods(HotSpotJVMCIRuntime runtime, Class clazz) { + public static void registerNativeMethods(HotSpotJVMCIRuntime runtime, Class clazz) { throw shouldNotReachHere(); } @@ -146,4 +122,46 @@ public static long translate(HotSpotJVMCIRuntime runtime, Object obj) { public static T unhand(HotSpotJVMCIRuntime runtime, Class type, long handle) { throw shouldNotReachHere(); } + + static final long isolate; + static { + // Prevent javac from inlining this field. + isolate = 0L; + } + + /** + * Determines if the current thread is {@linkplain #attachCurrentThread(HotSpotJVMCIRuntime) + * attached} to the peer runtime. + */ + @SuppressWarnings("unused") + static boolean isCurrentThreadAttached(HotSpotJVMCIRuntime runtime) { + throw shouldNotReachHere(); + } + + /** + * Ensures the current thread is attached to the peer runtime. + * + * @return {@code true} if this call attached the current thread, {@code false} if the current + * thread was already attached + */ + @SuppressWarnings("unused") + static boolean attachCurrentThread(HotSpotJVMCIRuntime runtime) { + throw shouldNotReachHere(); + } + + /** + * Detaches the current thread from the peer runtime. + */ + @SuppressWarnings("unused") + static void detachCurrentThread(HotSpotJVMCIRuntime runtime) { + throw shouldNotReachHere(); + } + + /** + * Gets the isolate thread for the current thread (which must be attached to libgraal). + */ + @SuppressWarnings("unused") + static long getCurrentIsolateThread(long iso) { + throw shouldNotReachHere(); + } } diff --git a/compiler/src/org.graalvm.libgraal/src/org/graalvm/libgraal/LibGraalScope.java b/compiler/src/org.graalvm.libgraal/src/org/graalvm/libgraal/LibGraalScope.java new file mode 100644 index 000000000000..9a805688cfdd --- /dev/null +++ b/compiler/src/org.graalvm.libgraal/src/org/graalvm/libgraal/LibGraalScope.java @@ -0,0 +1,96 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.libgraal; + +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; + +/** + * Scope for calling CEntryPoints in libgraal. {@linkplain #LibGraalScope(HotSpotJVMCIRuntime) + * Opening} a scope attaches the current thread to libgraal and {@linkplain #close() closing} it + * detaches the current thread. + */ +public final class LibGraalScope implements AutoCloseable { + + static final ThreadLocal currentScope = new ThreadLocal<>(); + + private final LibGraalScope parent; + private final boolean topLevel; + private final HotSpotJVMCIRuntime runtime; + private final long isolateThread; + + /** + * Gets the isolate thread associated with the current thread. The current thread must be in an + * {@linkplain #LibGraalScope(HotSpotJVMCIRuntime) opened} scope. + * + * @returns a value that can be used for the IsolateThreadContext argument of a {@code native} + * method {@link LibGraal#registerNativeMethods linked} to a CEntryPoint function in + * libgraal + * @throws IllegalStateException if not the current thread is not attached to libgraal + */ + public static long getIsolateThread() { + LibGraalScope scope = currentScope.get(); + if (scope == null) { + throw new IllegalStateException("Cannot get isolate thread outside of a " + LibGraalScope.class.getSimpleName()); + } + return scope.isolateThread; + } + + /** + * Enters a scope for making calls into libgraal. If there is no existing libgraal scope for the + * current thread, the current thread is attached to libgraal. When the outer most scope is + * closed, the current thread is detached from libgraal. + * + * This must be used in a try-with-resources statement. + * + * This cannot be called from {@linkplain LibGraal#inLibGraal() within} libgraal. + * + * @throws IllegalStateException if libgraal is {@linkplain LibGraal#isAvailable() unavailable} + * or {@link LibGraal#inLibGraal()} returns true + */ + public LibGraalScope(HotSpotJVMCIRuntime runtime) { + if (LibGraal.inLibGraal() || !LibGraal.isAvailable()) { + throw new IllegalStateException(); + } + this.runtime = runtime; + parent = currentScope.get(); + boolean top = false; + if (parent == null) { + top = LibGraal.attachCurrentThread(runtime); + isolateThread = LibGraal.getCurrentIsolateThread(LibGraal.isolate); + } else { + isolateThread = parent.isolateThread; + } + topLevel = top; + currentScope.set(this); + } + + @Override + public void close() { + if (topLevel) { + LibGraal.detachCurrentThread(runtime); + } + currentScope.set(parent); + } +} diff --git a/docs/Publications.md b/docs/Publications.md index ad668160e037..7681d1df31c6 100644 --- a/docs/Publications.md +++ b/docs/Publications.md @@ -1,4 +1,4 @@ -This page describes various presentations and publications related to Graal and Truffle that were published by Oracle Labs and its academic collaborators. +This page describes various presentations and publications related to the GraalVM compiler and Truffle that were published by Oracle Labs and its academic collaborators. ## Truffle Tutorial @@ -16,21 +16,21 @@ PLDI 2016, June 13, 2016, Santa Barbara, CA [Video recording](https://youtu.be/FJY96_6Y3a4) [Slides](https://lafo.ssw.uni-linz.ac.at/pub/papers/2016_PLDI_Truffle.pdf) -## Graal Tutorial +## GraalVM Compiler Tutorial -This tutorial presents Graal, a high-performance dynamic compiler written in Java. Because it is highly configurable and extensible, it delivers excellent peak performance for a diverse set of managed languages including Java (beating the Java HotSpot server compiler), JavaScript (beating the V8 Crankshaft compiler), Ruby, and R. This lifts compiler research using Graal to a new level: researchers can evaluate new compiler optimizations immediately on many languages. If you are a language implementer who is curious how modern VMs like the Java HotSpot VM or the V8 JavaScript VM optimize your code, you will get all your questions answered too. +This tutorial presents the GraalVM compiler, a high-performance dynamic compiler written in Java. Because it is highly configurable and extensible, it delivers excellent peak performance for a diverse set of managed languages including Java (beating the Java HotSpot server compiler), JavaScript (beating the V8 Crankshaft compiler), Ruby, and R. This lifts compiler research to a new level: researchers can evaluate new compiler optimizations immediately on many languages. If you are a language implementer who is curious how modern VMs like the Java HotSpot VM or the V8 JavaScript VM optimize your code, you will get all your questions answered too. In detail, the tutorial covers the following topics: -* Key distinguishing features of Graal, -* Introduction to the Graal IR: basic properties, instructions, and optimization phases +* Key distinguishing features of the GraalVM compiler, +* Introduction to the compiler IR: basic properties, instructions, and optimization phases * Speculative optimizations: first-class support for optimistic optimizations and deoptimization -* Graal API: separation of the compiler from the VM +* JVMCI API: separation of the compiler from the VM * Snippets: expressing high-level semantics in low-level Java code -* Compiler intrinsics: use all your hardware instructions with Graal -* Using Graal for static analysis -* Custom compilations with Graal: integration of the compiler with an application or library -* Graal as a compiler for dynamic programming languages +* Compiler intrinsics: use all your hardware instructions +* Using the compiler for static analysis +* Custom compilations: integration of the compiler with an application or library +* GraalVM compiler as a compiler for dynamic programming languages PLDI 2017, June 18-23, Barcelona, Spain [Video recording](https://www.youtube.com/watch?v=5_Y3kc--eTI) @@ -88,16 +88,16 @@ In _Proceedings of the Conference on Programming Language Design and Implementat [Video recording](https://www.youtube.com/watch?v=8eff207KPkA&list=PLMTm6Ln7vQZZv6sQ0I4R7iaIjvSVhHXod&index=42) [DOI: 10.1145/3062341.3062381](https://doi.org/10.1145/3062341.3062381) -- Juan Fumero, Michel Steuwer, Lukas Stadler, Christophe Dubach -[**Just-In-Time GPU Compilation for Interpreted Languages with Partial Evaluation**](https://dl.acm.org/citation.cfm?id=3050761) -In _Proceedings of the 13th ACM International Conference on Virtual Execution Environments (VEE'17)_ +- Juan Fumero, Michel Steuwer, Lukas Stadler, Christophe Dubach +[**Just-In-Time GPU Compilation for Interpreted Languages with Partial Evaluation**](https://dl.acm.org/citation.cfm?id=3050761) +In _Proceedings of the 13th ACM International Conference on Virtual Execution Environments (VEE'17)_ [DOI: 10.1145/3050748.3050761](http://dx.doi.org/10.1145/3050748.3050761) - Michael Van De Vanter [**Building Flexible, Low-Overhead Tooling Support into a High-Performance Polyglot VM (Extended Abstract)**](http://vandevanter.net/mlvdv/publications/mlvdv-morevms-2017.pdf) _MoreVMs Workshop on Modern Language Runtimes, Ecosystems, and VMs_. -- Juan Fumero, Michel Steuwer, Lukas Stadler, Christophe Dubach. +- Juan Fumero, Michel Steuwer, Lukas Stadler, Christophe Dubach. [**OpenCL JIT Compilation for Dynamic Programming Languages**](https://github.com/jjfumero/jjfumero.github.io/blob/master/files/morevms17-final13.pdf) _MoreVMs Workshop on Modern Language Runtimes, Ecosystems, and VMs (MoreVMs'17)_ [Video recording](https://www.youtube.com/watch?v=6il8LnNegwg) @@ -190,16 +190,16 @@ Master's thesis, Johannes Kepler University Linz, November 2013. In _Proceedings of the Dynamic Languages Symposium (DLS)_. Describes the design of self-optimizing and self-specializing interpreter, and the application to JavaScript. -## Graal Papers +## GraalVM Compiler Papers ### 2018 -- James Clarkson, Juan Fumero, Michalis Papadimitriou, Foivos S. Zakkak, Maria Xekalaki, Christos Kotselidis, Mikel Luján +- James Clarkson, Juan Fumero, Michalis Papadimitriou, Foivos S. Zakkak, Maria Xekalaki, Christos Kotselidis, Mikel Luján [**Exploiting High-Performance Heterogeneous Hardware for Java Programs using Graal**](https://dl.acm.org/citation.cfm?id=3237016) In _Proceedings of the 15th International Conference on Managed Languages & Runtimes (ManLang'18)_ -- Juan Fumero, Christos Kotselidis. +- Juan Fumero, Christos Kotselidis. [**Using Compiler Snippets to Exploit Parallelism on Heterogeneous Hardware: A Java Reduction Case Study**](https://dl.acm.org/citation.cfm?id=3281292) In _Proceedings of the 10th ACM SIGPLAN International Workshop on Virtual Machines and Intermediate Languages (VMIL'18)_ @@ -296,7 +296,7 @@ In Proceedings of the 10th Workshop on Implementation, Compilation, Optimization [**Techniques and applications for guest-language safepoints**](http://dx.doi.org/10.1145/2843915.2843921) In Proceedings of the 10th Workshop on Implementation, Compilation, Optimization of Object-Oriented Languages, Programs and Systems (ICOOOLPS '15) -- Juan Fumero, Toomas Remmelg, Michel Steuwer and Christophe Dubach. +- Juan Fumero, Toomas Remmelg, Michel Steuwer and Christophe Dubach. [**Runtime Code Generation and Data Management for Heterogeneous Computing in Java**](https://dl.acm.org/citation.cfm?id=2807428) In _Proceedings of the Principles and Practices of Programming on The Java Platform (PPPJ '15)_ @@ -323,7 +323,7 @@ In Proceedings of the 9th International Workshop on Implementation, Compilation, In Proceedings of the 2014 International Conference on Generative Programming: Concepts and Experiences (GPCE 2014) - Gilles Duboscq, Thomas Würthinger, Hanspeter Mössenböck -[**Speculation without regret: reducing deoptimization meta-data in the Graal compiler**](http://dx.doi.org/10.1145/2647508.2647521) +[**Speculation without regret: reducing deoptimization meta-data in the GraalVM compiler**](http://dx.doi.org/10.1145/2647508.2647521) In Proceedings of the 2014 International Conference on Principles and Practices of Programming on the Java platform: Virtual machines, Languages, and Tools (PPPJ '14) - Thomas Würthinger @@ -350,7 +350,7 @@ In Proceedings of the 2014 International Conference on Principles and Practices [**Comparing points-to static analysis with runtime recorded profiling data**](http://dx.doi.org/10.1145/2647508.2647524) In Proceedings of the 2014 International Conference on Principles and Practices of Programming on the Java platform: Virtual machines, Languages, and Tools (PPPJ '14) -- Juan Jose Fumero, Michel Steuwer and Christophe Dubach. +- Juan Jose Fumero, Michel Steuwer and Christophe Dubach. [**A Composable Array Function Interface for Heterogeneous Computing in Java**](https://dl.acm.org/citation.cfm?id=2627381) In _Proceedings of ACM SIGPLAN International Workshop on Libraries, Languages, and Compilers for Array Programming (ARRAY'14)_ diff --git a/examples/ci.hocon b/examples/ci.hocon index 49dbca911890..969ea918d4f6 100644 --- a/examples/ci.hocon +++ b/examples/ci.hocon @@ -13,8 +13,8 @@ examplesGate : ${examplesCommon} { } builds += [ - ${linux-amd64} ${labsjdk8} ${examplesGate} ${eclipse} ${jdt} { name: "gate-examples-linux-8" }, - ${linux-amd64} ${oraclejdk11} ${examplesGate} ${eclipse} { name: "gate-examples-linux-11" }, - ${solaris-sparcv9} ${labsjdk8} ${examplesGate} { name: "gate-examples-solaris-8" }, - ${darwin-amd64} ${labsjdk8} ${examplesGate} { name: "gate-examples-darwin-8" }, + ${linux-amd64} ${oraclejdk8} ${examplesGate} ${eclipse} ${jdt} { name: "gate-examples-linux-8" }, + ${linux-amd64} ${oraclejdk11} ${examplesGate} ${eclipse} { name: "gate-examples-linux-11" }, + ${solaris-sparcv9} ${oraclejdk8} ${examplesGate} { name: "gate-examples-solaris-8" }, + ${darwin-amd64} ${oraclejdk8} ${examplesGate} { name: "gate-examples-darwin-8" }, ] diff --git a/regex/README.md b/regex/README.md index 4be7446caf71..34736f7b89d6 100644 --- a/regex/README.md +++ b/regex/README.md @@ -1,6 +1,6 @@ # TRegex -TRegex is an implementation of a subset of ECMAScript regular expressions that uses the Graal compiler and Truffle API to execute regular expressions in an efficient way. +TRegex is an implementation of a subset of ECMAScript regular expressions that uses the GraalVM compiler and Truffle API to execute regular expressions in an efficient way. Its role is to provide support for Truffle languages that need to expose regular expression functionality. In its current iteration, TRegex provides an implementation of ECMAScript regular expressions (ECMAScript regular expressions are based on the widely popular Perl 5 regular expressions). A distinguishing feature of TRegex is that it compiles regular expressions into finite-state automata. @@ -14,7 +14,7 @@ Unlike most regular expression engines which use backtracking, TRegex uses an au The regex is parsed and then translated into a nondeterministic finite-state automaton (NFA). A powerset construction is then used to expand the NFA into a deterministic finite-state automaton (DFA). The resulting DFA is then executed when matching against input strings. -At that point, TRegex exploits the Graal compiler and Truffle to get efficient machine code when interpreting the DFA. +At that point, TRegex exploits the GraalVM compiler and Truffle to get efficient machine code when interpreting the DFA. The benefit of using this approach is that finding out whether a match is found can be done during a single pass over the input string: whenever several alternative ways to match the remaining input are admissible, TRegex considers all of them simultaneously. This is in contrast to backtracking approaches which consider all possible alternatives separately, one after the other. diff --git a/regex/ci.hocon b/regex/ci.hocon index c4cd545c886a..d8755c4860a5 100644 --- a/regex/ci.hocon +++ b/regex/ci.hocon @@ -17,15 +17,15 @@ regexWeekly: ${regex-weekly-notifications} { } builds += [ - ${linux-amd64} ${labsjdk8} ${regexCommon} ${eclipse} ${jdt} {run : [["mx", "--strict-compliance", "gate", "--strict-mode"]], targets : [gate], name: "gate-regex-8"}, + ${linux-amd64} ${oraclejdk8} ${regexCommon} ${eclipse} ${jdt} {run : [["mx", "--strict-compliance", "gate", "--strict-mode"]], targets : [gate], name: "gate-regex-8"}, ${linux-amd64} ${oraclejdk11} ${regexCommon} ${eclipse} {run : [["mx", "--strict-compliance", "gate", "--strict-mode"]], targets : [gate], name: "gate-regex-11"}, - ${solaris-sparcv9} ${labsjdk8} ${gateLite} ${regexWeekly} { + ${solaris-sparcv9} ${oraclejdk8} ${gateLite} ${regexWeekly} { name: "gate-regex-solaris-lite-8" } ${solaris-sparcv9} ${oraclejdk11} ${gateLite} ${regexWeekly} { name: "gate-regex-solaris-lite-11" } - ${darwin-amd64} ${labsjdk8} ${gateLite} ${regexWeekly} { + ${darwin-amd64} ${oraclejdk8} ${gateLite} ${regexWeekly} { name: "gate-regex-mac-lite-8" } ${darwin-amd64} ${oraclejdk11} ${gateLite} ${regexWeekly} { diff --git a/regex/mx.regex/mx_regex.py b/regex/mx.regex/mx_regex.py index d070c1f9e2e0..1a94e8a6e595 100644 --- a/regex/mx.regex/mx_regex.py +++ b/regex/mx.regex/mx_regex.py @@ -39,7 +39,7 @@ def _tregex_tests_gate_runner(args, tasks): unittest(['--enable-timing', '--very-verbose', 'com.oracle.truffle.regex']) -mx_sdk.register_graalvm_component(mx_sdk.GraalVmTool( +mx_sdk.register_graalvm_component(mx_sdk.GraalVmLanguage( suite=_suite, name='TRegex', short_name='rgx', diff --git a/regex/mx.regex/native-image.properties b/regex/mx.regex/native-image.properties index fd109752eadb..247e60d53c99 100644 --- a/regex/mx.regex/native-image.properties +++ b/regex/mx.regex/native-image.properties @@ -1 +1 @@ -Requires = tool:truffle +ExcludeFromAll=true diff --git a/regex/mx.regex/suite.py b/regex/mx.regex/suite.py index e0167ce9f94b..a4aac74a65d8 100644 --- a/regex/mx.regex/suite.py +++ b/regex/mx.regex/suite.py @@ -29,7 +29,7 @@ "name" : "regex", - "version" : "1.0.0-rc18", + "version" : "20.0.0-beta.01", "release" : False, "groupId" : "org.graalvm.regex", "url" : "http://www.graalvm.org/", @@ -108,6 +108,7 @@ }, "TREGEX_UNIT_TESTS" : { + "subDir": "src", "dependencies" : [ "com.oracle.truffle.regex.test", ], diff --git a/regex/src/com.oracle.truffle.regex.test/src/com/oracle/truffle/regex/tregex/test/JsTests.java b/regex/src/com.oracle.truffle.regex.test/src/com/oracle/truffle/regex/tregex/test/JsTests.java new file mode 100644 index 000000000000..e5a48f55efdc --- /dev/null +++ b/regex/src/com.oracle.truffle.regex.test/src/com/oracle/truffle/regex/tregex/test/JsTests.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.regex.tregex.test; + +import org.junit.Test; + +public class JsTests extends RegexTestBase { + + @Override + String getEngineOptions() { + return ""; + } + + @Test + public void lookbehindInLookahead() { + test("\\s*(?=(?<=\\W))", "", "paragraph block*", 1, true, 9, 10); + test("\\s*(?=\\b)", "", "paragraph block*", 1, true, 9, 10); + test("\\s*(?=\\b|\\W|$)", "", "paragraph block*", 1, true, 9, 10); + } +} diff --git a/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/nfa/ASTStepVisitor.java b/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/nfa/ASTStepVisitor.java index 2bfdf791d7bd..27973ead4ac8 100644 --- a/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/nfa/ASTStepVisitor.java +++ b/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/nfa/ASTStepVisitor.java @@ -43,6 +43,7 @@ import java.util.ArrayList; import java.util.Deque; import java.util.List; +import java.util.Set; /** * Regex AST visitor that will find convert all NFA successors of a given {@link Term} to @@ -58,8 +59,7 @@ public final class ASTStepVisitor extends NFATraversalRegexASTVisitor { private ASTStep stepCur; - private final EconomicMap lookAheadMap = EconomicMap.create(); - private final EconomicMap lookAheadMapWithCaret = EconomicMap.create(); + private final EconomicMap lookAheadMap = EconomicMap.create(); private final List curLookAheads = new ArrayList<>(); private final List curLookBehinds = new ArrayList<>(); private final Deque lookAroundExpansionQueue = new ArrayDeque<>(); @@ -213,12 +213,12 @@ protected void visit(ArrayList path) { @Override protected void enterLookAhead(LookAheadAssertion assertion) { - EconomicMap laMap = canTraverseCaret() ? lookAheadMapWithCaret : lookAheadMap; - ASTStep laStep = laMap.get(assertion); + ASTStepCacheKey key = new ASTStepCacheKey(assertion, canTraverseCaret(), getTraversableLookBehindAssertions()); + ASTStep laStep = lookAheadMap.get(key); if (laStep == null) { laStep = new ASTStep(assertion.getGroup()); lookAroundExpansionQueue.push(laStep); - laMap.put(assertion, laStep); + lookAheadMap.put(key, laStep); } curLookAheads.add(laStep); } @@ -228,4 +228,30 @@ protected void leaveLookAhead(LookAheadAssertion assertion) { assert curLookAheads.get(curLookAheads.size() - 1).getRoot().getParent() == assertion; curLookAheads.remove(curLookAheads.size() - 1); } + + private static class ASTStepCacheKey { + private final RegexASTNode root; + private final boolean canTraverseCaret; + private final Set traversableLookBehindAssertions; + + ASTStepCacheKey(RegexASTNode root, boolean canTraverseCaret, Set traversableLookBehindAssertions) { + this.root = root; + this.canTraverseCaret = canTraverseCaret; + this.traversableLookBehindAssertions = traversableLookBehindAssertions; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ASTStepCacheKey)) { + return false; + } + ASTStepCacheKey that = (ASTStepCacheKey) obj; + return this.root.equals(that.root) && this.canTraverseCaret == that.canTraverseCaret && this.traversableLookBehindAssertions.equals(that.traversableLookBehindAssertions); + } + + @Override + public int hashCode() { + return root.hashCode() + 31 * (Boolean.hashCode(canTraverseCaret) + 31 * traversableLookBehindAssertions.hashCode()); + } + } } diff --git a/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/parser/ast/visitors/NFATraversalRegexASTVisitor.java b/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/parser/ast/visitors/NFATraversalRegexASTVisitor.java index ea43284fa5d9..1a24d31707ae 100644 --- a/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/parser/ast/visitors/NFATraversalRegexASTVisitor.java +++ b/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/parser/ast/visitors/NFATraversalRegexASTVisitor.java @@ -184,6 +184,10 @@ protected NFATraversalRegexASTVisitor(RegexAST ast) { this.insideLoops = new ASTNodeSet<>(ast); } + public Set getTraversableLookBehindAssertions() { + return traversableLookBehindAssertions; + } + public void setTraversableLookBehindAssertions(Set traversableLookBehindAssertions) { this.traversableLookBehindAssertions = traversableLookBehindAssertions; } diff --git a/sdk/CHANGELOG.md b/sdk/CHANGELOG.md index 031c150ee2eb..abd09574d48a 100644 --- a/sdk/CHANGELOG.md +++ b/sdk/CHANGELOG.md @@ -2,7 +2,10 @@ This changelog summarizes major changes between GraalVM SDK versions. The main focus is on APIs exported by GraalVM SDK. -## Version 1.0.0 RC17 +## Version 20.0.0 Beta 1 +* Removed deprecated `OptionCategory.DEBUG` (use `OptionCategory.INTERNAL` instead). + +## Version 19.0.0 * `Value.as(Interface.class)` now requires interface classes to be annotated with `HostAccess.Implementable` in `EXPLICIT` host access mode. Added new APIs to configure implementable behavior in HostAccess. ## Version 1.0.0 RC16 diff --git a/sdk/README.md b/sdk/README.md index 77d69a58514a..0a94c96000e0 100644 --- a/sdk/README.md +++ b/sdk/README.md @@ -8,7 +8,7 @@ The GraalVM SDK is a collection of APIs for the components of GraalVM. ## Getting Started -1. Download GraalVM from [Oracle Technology Network](http://www.oracle.com/technetwork/oracle-labs/program-languages/overview/). +1. Download GraalVM from [Oracle Technology Network](https://www.oracle.com/technetwork/graalvm/downloads/index.html). 2. Use any of the Java executables in `./bin` or import GraalVM as JDK in your favorite IDE. 3. Use GraalVM SDK, the jar is put on the class path for you automatically. diff --git a/sdk/ci.hocon b/sdk/ci.hocon index 4a298f38db95..aa3e760cf2cf 100644 --- a/sdk/ci.hocon +++ b/sdk/ci.hocon @@ -13,8 +13,8 @@ sdkGate : ${sdkCommon} { } builds += [ - ${linux-amd64} ${labsjdk8} ${sdkGate} ${eclipse} ${jdt} { name: "gate-sdk-linux-8" }, - ${linux-amd64} ${oraclejdk11} ${sdkGate} ${eclipse} { name: "gate-sdk-linux-11" }, - ${solaris-sparcv9} ${labsjdk8} ${sdkGate} { name: "gate-sdk-solaris-8" }, - ${darwin-amd64} ${labsjdk8} ${sdkGate} { name: "gate-sdk-darwin-8" }, + ${linux-amd64} ${oraclejdk8} ${sdkGate} ${eclipse} ${jdt} { name: "gate-sdk-linux-8" }, + ${linux-amd64} ${oraclejdk11} ${sdkGate} ${eclipse} { name: "gate-sdk-linux-11" }, + ${solaris-sparcv9} ${oraclejdk8} ${sdkGate} { name: "gate-sdk-solaris-8" }, + ${darwin-amd64} ${oraclejdk8} ${sdkGate} { name: "gate-sdk-darwin-8" }, ] diff --git a/sdk/mx.sdk/mx_sdk.py b/sdk/mx.sdk/mx_sdk.py index b6822e061531..67202cd4c96a 100644 --- a/sdk/mx.sdk/mx_sdk.py +++ b/sdk/mx.sdk/mx_sdk.py @@ -95,7 +95,7 @@ def add_graalvm_hostvm_config(name, java_args=None, launcher_args=None, priority class AbstractNativeImageConfig(object): __metaclass__ = ABCMeta - def __init__(self, destination, jar_distributions, build_args, links=None): + def __init__(self, destination, jar_distributions, build_args, links=None, is_polyglot=False): """ :type destination: str :type jar_distributions: list[str] @@ -106,6 +106,7 @@ def __init__(self, destination, jar_distributions, build_args, links=None): self.jar_distributions = jar_distributions self.build_args = build_args self.links = [mx_subst.path_substitutions.substitute(link) for link in links] if links else [] + self.is_polyglot = is_polyglot assert isinstance(self.jar_distributions, list) assert isinstance(self.build_args, list) @@ -119,27 +120,32 @@ def __repr__(self): class LauncherConfig(AbstractNativeImageConfig): def __init__(self, destination, jar_distributions, main_class, build_args, links=None, is_main_launcher=True, - default_symlinks=True): + default_symlinks=True, is_sdk_launcher=False, is_polyglot=False): """ :type main_class: str :type default_symlinks: bool """ - super(LauncherConfig, self).__init__(destination, jar_distributions, build_args, links=links) + super(LauncherConfig, self).__init__(destination, jar_distributions, build_args, links, is_polyglot) self.main_class = main_class self.is_main_launcher = is_main_launcher self.default_symlinks = default_symlinks + self.is_sdk_launcher = is_sdk_launcher class LanguageLauncherConfig(LauncherConfig): - pass + def __init__(self, destination, jar_distributions, main_class, build_args, language, links=None, is_main_launcher=True, + default_symlinks=True, is_sdk_launcher=True): + super(LanguageLauncherConfig, self).__init__(destination, jar_distributions, main_class, build_args, links, + is_main_launcher, default_symlinks, is_sdk_launcher) + self.language = language class LibraryConfig(AbstractNativeImageConfig): - def __init__(self, destination, jar_distributions, build_args, links=None, jvm_library=False): + def __init__(self, destination, jar_distributions, build_args, links=None, jvm_library=False, is_polyglot=False): """ :type jvm_library: bool """ - super(LibraryConfig, self).__init__(destination, jar_distributions, build_args, links=links) + super(LibraryConfig, self).__init__(destination, jar_distributions, build_args, links, is_polyglot) self.jvm_library = jvm_library @@ -149,12 +155,14 @@ def __init__(self, suite, name, short_name, license_files, third_party_license_f dir_name=None, launcher_configs=None, library_configs=None, provided_executables=None, polyglot_lib_build_args=None, polyglot_lib_jar_dependencies=None, polyglot_lib_build_dependencies=None, has_polyglot_lib_entrypoints=False, - boot_jars=None, priority=None, installable=False): + boot_jars=None, priority=None, installable=False, post_install_msg=None, installable_id=None): """ :param suite mx.Suite: the suite this component belongs to :type name: str :param str short_name: a short, unique name for this component :param str | None | False dir_name: the directory name in which this component lives. If `None`, the `short_name` is used. If `False`, files are copied to the root-dir for the component type. + :param installable: Produce a distribution installable via `gu` + :param post_install_msg: Post-installation message to be printed :type license_files: list[str] :type third_party_license_files: list[str] :type provided_executables: list[str] @@ -170,6 +178,8 @@ def __init__(self, suite, name, short_name, license_files, third_party_license_f :type support_distributions: list[str] :type priority: int :type installable: bool + :type installable_id: str + :type post_install_msg: str """ self.suite = suite self.name = name @@ -191,6 +201,8 @@ def __init__(self, suite, name, short_name, license_files, third_party_license_f self.launcher_configs = launcher_configs or [] self.library_configs = library_configs or [] self.installable = installable + self.post_install_msg = post_install_msg + self.installable_id = installable_id or self.dir_name assert isinstance(self.jar_distributions, list) assert isinstance(self.builder_jar_distributions, list) @@ -215,14 +227,12 @@ def __init__(self, suite, name, short_name, license_files, third_party_license_f library_configs=None, provided_executables=None, polyglot_lib_build_args=None, polyglot_lib_jar_dependencies=None, polyglot_lib_build_dependencies=None, has_polyglot_lib_entrypoints=False, boot_jars=None, include_in_polyglot=True, priority=None, - installable=False, post_install_msg=None, standalone_dir_name=None): + installable=False, post_install_msg=None, standalone_dir_name=None, installable_id=None): """ :param truffle_jars: JAR distributions that should be on the classpath for the language implementation. :param include_in_polyglot: whether this component is included in `--language:all` or `--tool:all` and should be part of polyglot images. - :param post_install_msg: Post-installation message to be printed :type truffle_jars: list[str] :type include_in_polyglot: bool - :type post_install_msg: str :type standalone_dir_name: str """ super(GraalVmTruffleComponent, self).__init__(suite, name, short_name, license_files, third_party_license_files, @@ -230,9 +240,8 @@ def __init__(self, suite, name, short_name, license_files, third_party_license_f dir_name, launcher_configs, library_configs, provided_executables, polyglot_lib_build_args, polyglot_lib_jar_dependencies, polyglot_lib_build_dependencies, has_polyglot_lib_entrypoints, - boot_jars, priority, installable) + boot_jars, priority, installable, post_install_msg, installable_id) self.include_in_polyglot = include_in_polyglot - self.post_install_msg = post_install_msg self.standalone_dir_name = standalone_dir_name or '{}---'.format(self.dir_name) assert isinstance(self.include_in_polyglot, bool) @@ -247,7 +256,7 @@ def __init__(self, suite, name, short_name, license_files, third_party_license_f library_configs=None, provided_executables=None, polyglot_lib_build_args=None, polyglot_lib_jar_dependencies=None, polyglot_lib_build_dependencies=None, has_polyglot_lib_entrypoints=False, boot_jars=None, include_in_polyglot=True, include_by_default=False, - priority=None, installable=False): + priority=None, installable=False, post_install_msg=None, installable_id=None): super(GraalVmTool, self).__init__(suite, name, short_name, @@ -267,10 +276,16 @@ def __init__(self, suite, name, short_name, license_files, third_party_license_f boot_jars, include_in_polyglot, priority, - installable) + installable, + post_install_msg, + installable_id) self.include_by_default = include_by_default +class GraalVMSvmMacro(GraalVmComponent): + pass + + class GraalVmJdkComponent(GraalVmComponent): pass @@ -285,7 +300,7 @@ def __init__(self, suite, name, short_name, license_files, third_party_license_f graal_compiler=None, dir_name=None, launcher_configs=None, library_configs=None, provided_executables=None, polyglot_lib_build_args=None, polyglot_lib_jar_dependencies=None, polyglot_lib_build_dependencies=None, has_polyglot_lib_entrypoints=False, boot_jars=None, - priority=None, installable=False): + priority=None, installable=False, post_install_msg=None, installable_id=None): """ :type jvmci_jars: list[str] :type graal_compiler: str @@ -308,7 +323,9 @@ def __init__(self, suite, name, short_name, license_files, third_party_license_f has_polyglot_lib_entrypoints, boot_jars, priority, - installable) + installable, + post_install_msg, + installable_id) self.graal_compiler = graal_compiler self.jvmci_jars = jvmci_jars or [] diff --git a/sdk/mx.sdk/suite.py b/sdk/mx.sdk/suite.py index 44114f8e8fc3..be468069eef5 100644 --- a/sdk/mx.sdk/suite.py +++ b/sdk/mx.sdk/suite.py @@ -41,7 +41,7 @@ suite = { "mxversion" : "5.210.2", "name" : "sdk", - "version" : "1.0.0-rc18", + "version" : "20.0.0-beta.01", "release" : False, "sourceinprojectwhitelist" : [], "url" : "https://github.com/oracle/graal", diff --git a/sdk/src/org.graalvm.launcher/src/org/graalvm/launcher/Launcher.java b/sdk/src/org.graalvm.launcher/src/org/graalvm/launcher/Launcher.java index 944b3422ed79..b4c583a02151 100644 --- a/sdk/src/org.graalvm.launcher/src/org/graalvm/launcher/Launcher.java +++ b/sdk/src/org.graalvm.launcher/src/org/graalvm/launcher/Launcher.java @@ -676,11 +676,8 @@ private static List filterOptions(OptionDescriptors descriptors return options; } - @SuppressWarnings("deprecation") private static boolean sameCategory(OptionDescriptor descriptor, OptionCategory optionCategory) { - return descriptor.getCategory().ordinal() == optionCategory.ordinal() || - (optionCategory.ordinal() == OptionCategory.INTERNAL.ordinal() && - descriptor.getCategory().ordinal() == OptionCategory.DEBUG.ordinal()); + return descriptor.getCategory().ordinal() == optionCategory.ordinal(); } void parsePolyglotOptions(String defaultOptionPrefix, Map polyglotOptions, List unrecognizedArgs) { diff --git a/sdk/src/org.graalvm.launcher/src/org/graalvm/launcher/PolyglotLauncher.java b/sdk/src/org.graalvm.launcher/src/org/graalvm/launcher/PolyglotLauncher.java index 28f413bf8794..1f593e438283 100644 --- a/sdk/src/org.graalvm.launcher/src/org/graalvm/launcher/PolyglotLauncher.java +++ b/sdk/src/org.graalvm.launcher/src/org/graalvm/launcher/PolyglotLauncher.java @@ -42,6 +42,13 @@ import java.io.File; import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; @@ -51,8 +58,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Function; -import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -223,23 +228,90 @@ private void launch(String[] args) { static { if (IS_AOT) { - String launcherClasses = System.getProperty("com.oracle.graalvm.launcher.launcherclasses"); - if (launcherClasses == null || launcherClasses.isEmpty()) { - AOT_LAUNCHER_CLASSES = Collections.emptyMap(); + AOT_LAUNCHER_CLASSES = new HashMap<>(); + Engine engine = Engine.newBuilder().allowExperimentalOptions(true).build(); + Set languages = Collections.unmodifiableSet(engine.getLanguages().keySet()); + engine.close(); + String macrosPathsPorperty = System.getProperty("com.oracle.graalvm.launcher.macrospaths"); + if (macrosPathsPorperty != null && !macrosPathsPorperty.isEmpty()) { + Path macrosDir = Paths.get(macrosPathsPorperty); + if (!Files.isDirectory(macrosDir)) { + throw new RuntimeException("Expected " + macrosDir + " to be a directory"); + } + try { + List classpath = new ArrayList<>(); + List classes = new ArrayList<>(); + Files.list(macrosDir).flatMap(PolyglotLauncher::loadPolyglotConfig).filter(c -> languages.contains(c.language)).forEach(c -> { + c.classpath.stream().map(c.dir::resolve).map(p -> { + if (!Files.exists(p)) { + throw new RuntimeException(p + " does not exist"); + } + try { + return p.normalize().toUri().toURL(); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + }).forEach(classpath::add); + classes.add(c.launcher); + }); + URLClassLoader loader = new URLClassLoader(classpath.toArray(new URL[0]), PolyglotLauncher.class.getClassLoader()); + for (String launcher : classes) { + AOT_LAUNCHER_CLASSES.put(launcher, getLauncherClass(launcher, loader)); + } + } catch (IOException e) { + throw new RuntimeException(e); + } } else { - Stream classNames = Pattern.compile(",").splitAsStream(launcherClasses); - AOT_LAUNCHER_CLASSES = classNames.map(PolyglotLauncher::getLauncherClass).collect(Collectors.toMap(Class::getName, Function.identity())); + System.err.println("ERROR: com.oracle.graalvm.launcher.macrospaths was not provided"); } } else { AOT_LAUNCHER_CLASSES = null; } } - @SuppressWarnings("unchecked") + private static Stream loadPolyglotConfig(Path p) { + Path configPath = p.resolve("polyglot.config"); + if (!Files.exists(configPath)) { + return null; + } + try { + return Files.lines(configPath, StandardCharsets.UTF_8).map(String::trim).filter(s -> !s.isEmpty()).map(l -> PolyglotLauncherConfig.parse(l, configPath)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static final class PolyglotLauncherConfig { + final Path dir; + final String language; + final List classpath; + final String launcher; + + static PolyglotLauncherConfig parse(String spec, Path context) { + String[] parts = spec.split("\\|"); + if (parts.length != 3) { + throw new RuntimeException("Expected 3 `|`-separated parts in polyglot config (" + context + "). Got: " + Arrays.toString(parts)); + } + return new PolyglotLauncherConfig(context.getParent(), parts[0], Arrays.asList(parts[1].split(":")), parts[2]); + } + + PolyglotLauncherConfig(Path dir, String language, List classpath, String launcher) { + this.dir = dir; + this.language = language; + this.classpath = classpath; + this.launcher = launcher; + } + } + private static Class getLauncherClass(String launcherName) { + return getLauncherClass(launcherName, PolyglotLauncher.class.getClassLoader()); + } + + @SuppressWarnings("unchecked") + private static Class getLauncherClass(String launcherName, ClassLoader loader) { try { - Class launcherClass = Class.forName(launcherName); - if (!AbstractLanguageLauncher.class.isAssignableFrom(launcherClass)) { + Class launcherClass = Class.forName(launcherName, false, loader); + if (launcherClass != null && !AbstractLanguageLauncher.class.isAssignableFrom(launcherClass)) { throw new RuntimeException("Launcher class " + launcherName + " does not extend AbstractLanguageLauncher"); } return (Class) launcherClass; @@ -253,18 +325,24 @@ private void switchToLauncher(String launcherName, Map options, if (isAOT()) { launcherClass = AOT_LAUNCHER_CLASSES.get(launcherName); if (launcherClass == null) { - throw abort("Could not find class '" + launcherName + "'.\nYou might need to rebuild the polyglot launcher with 'gu rebuild-images polyglot'."); + throw abort("Could not find class '" + launcherName + + "'.\nYou might need to rebuild the polyglot launcher with 'gu rebuild-images polyglot'.\nThe following launchers are available:\n" + + AOT_LAUNCHER_CLASSES.keySet().stream().sorted().map(s -> " - " + s).collect(Collectors.joining("\n"))); } } else { launcherClass = getLauncherClass(launcherName); + if (launcherClass == null) { + throw abort("Could not find class '" + launcherName + "'."); + } } + AbstractLanguageLauncher launcher; try { - AbstractLanguageLauncher launcher = launcherClass.getDeclaredConstructor().newInstance(); - launcher.setPolyglot(true); - launcher.launch(args, options, false); + launcher = launcherClass.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new RuntimeException("Failed to instantiate launcher class " + launcherName, e); } + launcher.setPolyglot(true); + launcher.launch(args, options, false); } private void checkLanguage(String language, Engine engine) { diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/Platforms.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/Platforms.java index 4d9509574e5b..925b51ce5d2f 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/Platforms.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/Platforms.java @@ -52,7 +52,7 @@ * @since 19.0 */ @Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD}) +@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.PACKAGE}) public @interface Platforms { /** diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/c/function/CLibrary.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/c/function/CLibrary.java index 47ac44aca192..f4860e74fc7b 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/c/function/CLibrary.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/c/function/CLibrary.java @@ -61,4 +61,11 @@ * @since 19.0 */ String value(); + + /** + * Specifies if static linking is required. + * + * @since 20.0 + */ + boolean requireStatic() default false; } diff --git a/sdk/src/org.graalvm.options/snapshot.sigtest b/sdk/src/org.graalvm.options/snapshot.sigtest index d1051fa2b313..6029ea2f1600 100644 --- a/sdk/src/org.graalvm.options/snapshot.sigtest +++ b/sdk/src/org.graalvm.options/snapshot.sigtest @@ -43,8 +43,6 @@ meth public int hashCode() meth public java.lang.String toString() CLSS public final !enum org.graalvm.options.OptionCategory -fld public final static org.graalvm.options.OptionCategory DEBUG - anno 0 java.lang.Deprecated() fld public final static org.graalvm.options.OptionCategory EXPERT fld public final static org.graalvm.options.OptionCategory INTERNAL fld public final static org.graalvm.options.OptionCategory USER diff --git a/sdk/src/org.graalvm.options/src/org/graalvm/options/OptionCategory.java b/sdk/src/org.graalvm.options/src/org/graalvm/options/OptionCategory.java index cd55242491af..416f438cf0a6 100644 --- a/sdk/src/org.graalvm.options/src/org/graalvm/options/OptionCategory.java +++ b/sdk/src/org.graalvm.options/src/org/graalvm/options/OptionCategory.java @@ -61,14 +61,6 @@ public enum OptionCategory { */ EXPERT, - /** - * An option only relevant when debugging language or instrument implementations. - * - * @deprecated Use {@link OptionCategory#INTERNAL} instead. - * @since 19.0 - */ - @Deprecated DEBUG, - /** * An option only relevant when debugging a language implementation or an instrument. * diff --git a/sdk/src/org.graalvm.polyglot.tck/src/org/graalvm/polyglot/tck/IdentityFunctionResultVerifier.java b/sdk/src/org.graalvm.polyglot.tck/src/org/graalvm/polyglot/tck/IdentityFunctionResultVerifier.java new file mode 100644 index 000000000000..4eb13c23a8f2 --- /dev/null +++ b/sdk/src/org.graalvm.polyglot.tck/src/org/graalvm/polyglot/tck/IdentityFunctionResultVerifier.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.polyglot.tck; + +import org.graalvm.polyglot.PolyglotException; +import org.graalvm.polyglot.Value; + +final class IdentityFunctionResultVerifier implements ResultVerifier { + + static ResultVerifier INSTANCE = new IdentityFunctionResultVerifier(); + + private IdentityFunctionResultVerifier() { + } + + public void accept(SnippetRun snippetRun) throws PolyglotException { + final PolyglotException exception = snippetRun.getException(); + if (exception != null) { + throw exception; + } + + Value parameter = snippetRun.getParameters().get(0); + TypeDescriptor parameterType = TypeDescriptor.forValue(parameter); + TypeDescriptor resultType = TypeDescriptor.forValue(snippetRun.getResult()); + if (!parameterType.isAssignable(resultType) || !resultType.isAssignable(resultType)) { + throw new AssertionError(String.format( + "Identity function result type must contain the parameter type. Parameter type: %s Result type: %s.", + parameterType, + resultType)); + } + } +} diff --git a/sdk/src/org.graalvm.polyglot.tck/src/org/graalvm/polyglot/tck/LanguageProvider.java b/sdk/src/org.graalvm.polyglot.tck/src/org/graalvm/polyglot/tck/LanguageProvider.java index 392ff60cceff..3faaafa69073 100644 --- a/sdk/src/org.graalvm.polyglot.tck/src/org/graalvm/polyglot/tck/LanguageProvider.java +++ b/sdk/src/org.graalvm.polyglot.tck/src/org/graalvm/polyglot/tck/LanguageProvider.java @@ -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. * * The Universal Permissive License (UPL), Version 1.0 @@ -85,6 +85,27 @@ public interface LanguageProvider { */ Value createIdentityFunction(Context context); + /** + * Creates a {@link Snippet} for an identity function. The identity function just returns its + * argument. This method allows an implementor to override the default identity function + * verification. In most cases it's not needed to implement this method and it's enough to + * implement {@link #createIdentityFunction}. + *

      + * The implementor can delegate to the default identity function verifier obtained by + * {@link ResultVerifier#getIdentityFunctionDefaultResultVerifier()}. + * + * @param context the context for a guest language code literal evaluation + * @return the {@link Snippet} representing the identity function + * @since 1.0 + */ + default Snippet createIdentityFunctionSnippet(Context context) { + Value value = createIdentityFunction(context); + if (!value.canExecute()) { + throw new AssertionError(String.format("Result of createIdentityFunction for tck provider %s did not return an executable value. Returned value '%s'.", getId(), value)); + } + return (Snippet.newBuilder("identity", value, TypeDescriptor.ANY).parameterTypes(TypeDescriptor.ANY).resultVerifier(ResultVerifier.getIdentityFunctionDefaultResultVerifier()).build()); + } + /** * Creates a collection of functions creating language data types. For each language data type * create a function returning a value of given type and assign a correct {@link TypeDescriptor} diff --git a/sdk/src/org.graalvm.polyglot.tck/src/org/graalvm/polyglot/tck/ResultVerifier.java b/sdk/src/org.graalvm.polyglot.tck/src/org/graalvm/polyglot/tck/ResultVerifier.java index cbff35b45848..a16afd3f49c8 100644 --- a/sdk/src/org.graalvm.polyglot.tck/src/org/graalvm/polyglot/tck/ResultVerifier.java +++ b/sdk/src/org.graalvm.polyglot.tck/src/org/graalvm/polyglot/tck/ResultVerifier.java @@ -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. * * The Universal Permissive License (UPL), Version 1.0 @@ -173,4 +173,15 @@ public static SnippetRun create(final Snippet snippet, final List - option is made available to native-image and also makes the tool available as - tool: in a native-image properties file Requires statement. The tool is - represented in the /tools/ directory. If a - corresponding tools-.properties file exists in mx.substratevm it will get - symlinked as /tools//native-image.properties so that - native-image will use these options whenever the tool is requested. Image_deps and - builder_deps (see below) are also represented as symlinks to JAR files in - /tools/ (/tools//builder). - - :param image_deps: list dependencies that get added to the image-cp (the classpath - of the application you want to compile into an image) when using the tool. - :param builder_deps: list dependencies that get added to the image builder-cp when - using the tool. Builder-cp adds to the classpath that contains the image-generator - itself. This might be necessary, e.g. when custom substitutions are needed to be - able to compile classes on the image-cp. Another possible reason is when the image - builder needs to prepare things prior to image building and doing so needs - additional classes (see junit tool). - :param native_deps: list native dependencies that should be extracted to - /tools/. - """ - self.image_deps = image_deps if image_deps else [] - self.builder_deps = builder_deps if builder_deps else [] - self.native_deps = native_deps if native_deps else [] - -tools_map = { - 'truffle' : ToolDescriptor(), - 'nfi' : ToolDescriptor(image_deps=['truffle:TRUFFLE_NFI']), - 'native-image' : ToolDescriptor(), - 'junit' : ToolDescriptor(builder_deps=['mx:JUNIT_TOOL', 'JUNIT', 'HAMCREST']), - 'regex' : ToolDescriptor(image_deps=['regex:TREGEX']), - 'native-image-agent': ToolDescriptor(image_deps=['substratevm:SVM_AGENT']), - 'native-image-configure' : ToolDescriptor(image_deps=['substratevm:SVM_CONFIGURE']), -} - -def native_image_path(native_image_root): - native_image_name = 'native-image' - native_image_dir = join(native_image_root, platform_name(), 'bin') - return join(native_image_dir, native_image_name) - -def remove_option_prefix(text, prefix): - if text.startswith(prefix): - return True, text[len(prefix):] - return False, text - -def extract_target_name(arg, kind): - target_name, target_value = None, None - is_kind, option_tail = remove_option_prefix(arg, '--' + kind + ':') - if is_kind: - target_name, _, target_value = option_tail.partition('=') - return target_name, target_value - -def build_native_image_image(): - image_path = native_image_path(suite_native_image_root()) - mx.log('Building native-image executable ' + image_path) - image_dir = dirname(image_path) - mkpath(image_dir) - native_image_on_jvm(['--no-fallback', '--tool:native-image', '-H:Path=' + image_dir]) - -svmDistribution = ['substratevm:SVM'] -llvmDistributions = ['compiler:GRAAL_LLVM', 'substratevm:SVM_LLVM', "compiler:LLVM_WRAPPER", "compiler:LLVM_PLATFORM_SPECIFIC", "compiler:JAVACPP"] -graalDistribution = ['compiler:GRAAL'] -librarySupportDistribution = ['substratevm:LIBRARY_SUPPORT'] - -def layout_native_image_root(native_image_root): - - def names_to_dists(dist_names): - deps = [mx.dependency(dist_name, fatalIfMissing=False) for dist_name in dist_names] - return [dep for dep in deps if dep and (not dep.isDistribution() or dep.exists())] - - def native_image_layout_dists(subdir, dist_names): - native_image_layout(names_to_dists(dist_names), subdir, native_image_root) - - def native_image_extract_dists(subdir, dist_names): - native_image_extract(names_to_dists(dist_names), subdir, native_image_root) - - native_image_layout_dists(join('lib', 'graalvm'), ['substratevm:SVM_DRIVER', 'sdk:LAUNCHER_COMMON']) - - # Create native-image layout for sdk parts - graal_sdk_dists = ['sdk:GRAAL_SDK'] - if svm_java80(): - native_image_layout_dists(join('lib', 'boot'), graal_sdk_dists) - jvmci_dists = graalDistribution - else: - jvmci_dists = graalDistribution + graal_sdk_dists - - # Create native-image layout for compiler & jvmci parts - native_image_layout_dists(join('lib', 'jvmci'), jvmci_dists) - jdk_config = mx.get_jdk() - if svm_java80(): - jvmci_path = join(jdk_config.home, 'jre', 'lib', 'jvmci') - if os.path.isdir(jvmci_path): - for symlink_name in os.listdir(jvmci_path): - symlink_or_copy(join(jvmci_path, symlink_name), join(native_image_root, 'lib', 'jvmci', symlink_name)) - - # Create native-image layout for truffle parts - native_image_layout_dists(join('lib', 'truffle'), ['truffle:TRUFFLE_API']) - - # Create native-image layout for tools parts - for tool_name in tools_map: - tool_descriptor = tools_map[tool_name] - native_image_layout_dists(join('tools', tool_name, 'builder'), tool_descriptor.builder_deps) - native_image_layout_dists(join('tools', tool_name), tool_descriptor.image_deps) - native_image_extract_dists(join('tools', tool_name), tool_descriptor.native_deps) - native_image_option_properties('tools', tool_name, native_image_root) - - # Create native-image layout for svm parts - svm_subdir = join('lib', 'svm') - native_image_layout_dists(svm_subdir, librarySupportDistribution) - native_image_layout_dists(join(svm_subdir, 'builder'), svmDistribution + llvmDistributions + ['substratevm:POINTSTO', 'substratevm:OBJECTFILE']) - clibraries_dest = join(native_image_root, join(svm_subdir, 'clibraries')) - for clibrary_path in clibrary_paths(): - copy_tree(clibrary_path, clibraries_dest) - copy_tree(mx._get_dependency_path('TRUFFLE_NFI_NATIVE'), os.path.dirname(native_image_root)) - -def truffle_language_ensure(language_flag, version=None, native_image_root=None, early_exit=False, extract=True): - """ - Ensures that we have a valid suite for the given language_flag, by downloading a binary if necessary - and providing the suite distribution artifacts in the native-image directory hierachy (via symlinks). - :param language_flag: native-image language_flag whose truffle-language we want to use - :param version: if not specified and no TRUFFLE__VERSION set latest binary deployed master revision gets downloaded - :param native_image_root: the native_image_root directory where the the artifacts get installed to - :return: language suite for the given language_flag - """ - if not native_image_root: - native_image_root = suite_native_image_root() +class GraalVMConfig(object): + def __init__(self, dynamicimports=None, disable_libpolyglot=False, force_bash_launchers=None, skip_libraries=None, exclude_components=None): + self.dynamicimports = dynamicimports or [] + self.disable_libpolyglot = disable_libpolyglot + self.force_bash_launchers = force_bash_launchers or [] + self.skip_libraries = skip_libraries or [] + self.exclude_components = exclude_components or [] + if '/substratevm' not in self.dynamicimports: + self.dynamicimports.append('/substratevm') - version_env_var = 'TRUFFLE_' + language_flag.upper() + '_VERSION' - if not version and os.environ.has_key(version_env_var): - version = os.environ[version_env_var] + def mx_args(self): + args = [] + if self.dynamicimports: + args += ['--dynamicimports', ','.join(self.dynamicimports)] + if self.disable_libpolyglot: + args += ['--disable-libpolyglot'] + if self.force_bash_launchers: + if self.force_bash_launchers is True: + args += ['--force-bash-launchers=true'] + else: + args += ['--force-bash-launchers=' + ','.join(self.force_bash_launchers)] + if self.skip_libraries: + if self.skip_libraries is True: + args += ['--skip-libraries=true'] + else: + args += ['--skip-libraries=' + ','.join(self.skip_libraries)] + if self.exclude_components: + args += ['--exclude-components=' + ','.join(self.exclude_components)] + return args - if language_flag not in flag_suitename_map: - mx.abort('No truffle-language uses language_flag \'' + language_flag + '\'') + def _tuple(self): + _force_bash_launchers = tuple(self.force_bash_launchers) if isinstance(self.force_bash_launchers, list) else self.force_bash_launchers + _skip_libraries = tuple(self.skip_libraries) if isinstance(self.skip_libraries, list) else self.skip_libraries + return tuple(self.dynamicimports), self.disable_libpolyglot, _force_bash_launchers, _skip_libraries, tuple(self.exclude_components) - language_dir = join('languages', language_flag) - if early_exit and exists(join(native_image_root, language_dir)): - mx.logv('Early exit mode: Language subdir \'' + language_flag + '\' exists. Skip suite.import_suite.') - return None + def __hash__(self): + return hash(self._tuple()) - language_entry = flag_suitename_map[language_flag] - - language_suite_name = language_entry[0] - language_repo_name = language_entry[3] if len(language_entry) > 3 else None - - urlinfos = [ - mx.SuiteImportURLInfo(mx_urlrewrites.rewriteurl('https://curio.ssw.jku.at/nexus/content/repositories/snapshots'), - 'binary', - mx.vc_system('binary')) - ] - - failure_warning = None - if not version and not mx.suite(language_suite_name, fatalIfMissing=False): - # If no specific version requested use binary import of last recently deployed master version - repo_suite_name = language_repo_name if language_repo_name else language_suite_name - repo_url = mx_urlrewrites.rewriteurl('https://github.com/graalvm/{0}.git'.format(repo_suite_name)) - version = mx.SuiteImport.resolve_git_branchref(repo_url, 'binary', abortOnError=False) - if not version: - failure_warning = 'Resolving \'binary\' against ' + repo_url + ' failed' - - language_suite = suite.import_suite( - language_suite_name, - version=version, - urlinfos=urlinfos, - kind=None, - in_subdir=bool(language_repo_name) - ) + def __eq__(self, other): + if not isinstance(other, GraalVMConfig): + return False + return self._tuple() == self._tuple() + + def __repr__(self): + return "GraalVMConfig[{}]".format(self._tuple()) + + +def _vm_suite_dir(): + return join(dirname(suite.dir), 'vm') + + +def _mx_vm(args, config, nonZeroIsFatal=True, out=None, err=None, timeout=None, env=None, quiet=False): + return mx.run_mx(config.mx_args() + args, suite=_vm_suite_dir(), nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, timeout=timeout, env=env, quiet=quiet) + + +_vm_homes = {} + + +def _vm_home(config): + if config not in _vm_homes: + # get things initialized (e.g., cloning) + _mx_vm(['graalvm-home'], config, out=mx.OutputCapture()) + capture = mx.OutputCapture() + _mx_vm(['graalvm-home'], config, out=capture, quiet=True) + _vm_homes[config] = capture.data.strip() + return _vm_homes[config] + + +_graalvm_exclude_components = ['gu'] if mx.is_windows() else [] # gu does not work on Windows atm +_graalvm_config = GraalVMConfig(disable_libpolyglot=True, + force_bash_launchers=['polyglot', 'native-image-configure'], + skip_libraries=['native-image-agent'], + exclude_components=_graalvm_exclude_components) +_graalvm_jvm_config = GraalVMConfig(disable_libpolyglot=True, + force_bash_launchers=True, + skip_libraries=True, + exclude_components=_graalvm_exclude_components) + +graalvm_configs = [_graalvm_config] +graalvm_jvm_configs = [_graalvm_jvm_config] + + +def graalvm_config(): + return graalvm_configs[-1] + + +def build_native_image_image(config=None): + config = config or graalvm_config() + mx.log('Building GraalVM with native-image in ' + _vm_home(config)) + _mx_vm(['build'], config) - if not language_suite: - if failure_warning: - mx.warn(failure_warning) - mx.abort('Binary suite not found and no local copy of ' + language_suite_name + ' available.') - - if not extract: - if not exists(join(native_image_root, language_dir)): - mx.abort('Language subdir \'' + language_flag + '\' should already exist with extract=False') - return language_suite - - language_suite_depnames = language_entry[1] - language_deps = language_suite.dists + language_suite.libs - language_deps = [dep for dep in language_deps if dep.name in language_suite_depnames] - native_image_layout(language_deps, language_dir, native_image_root) - - language_suite_nativedistnames = language_entry[2] - language_nativedists = [dist for dist in language_suite.dists if dist.name in language_suite_nativedistnames] - native_image_extract(language_nativedists, language_dir, native_image_root) - - option_properties = join(language_suite.mxDir, 'native-image.properties') - target_path = remove_existing_symlink(join(native_image_root, language_dir, 'native-image.properties')) - if exists(option_properties): - if not exists(target_path): - mx.logv('Add symlink to ' + str(option_properties)) - symlink_or_copy(option_properties, target_path) - else: - native_image_option_properties('languages', language_flag, native_image_root) - return language_suite def locale_US_args(): return ['-Duser.country=US', '-Duser.language=en'] @@ -530,29 +315,47 @@ def __getattr__(self, name): 'truffletck' ]) + +def vm_native_image_path(config): + return vm_executable_path('native-image', config) + + +def vm_executable_path(executable, config): + if mx.get_os() == 'windows': + executable += '.cmd' # links are `.cmd` on windows + return join(_vm_home(config), 'bin', executable) + + @contextmanager -def native_image_context(common_args=None, hosted_assertions=True, native_image_cmd=''): +def native_image_context(common_args=None, hosted_assertions=True, native_image_cmd='', config=None, build_if_missing=False): + config = config or graalvm_config() common_args = [] if common_args is None else common_args base_args = ['--no-fallback', '-H:+EnforceMaxRuntimeCompileMethods'] base_args += ['-H:Path=' + svmbuild_dir()] + has_server = mx.get_os() != 'windows' if mx.get_opts().verbose: base_args += ['--verbose'] if mx.get_opts().very_verbose: - base_args += ['--verbose-server'] + if has_server: + base_args += ['--verbose-server'] + else: + base_args += ['--verbose'] if hosted_assertions: base_args += native_image_context.hosted_assertions if native_image_cmd: if not exists(native_image_cmd): mx.abort('Given native_image_cmd does not exist') else: - native_image_cmd = native_image_path(suite_native_image_root()) + native_image_cmd = vm_native_image_path(config) + if build_if_missing and not exists(native_image_cmd): + build_native_image_image(config) if exists(native_image_cmd): mx.log('Use ' + native_image_cmd + ' for remaining image builds') def _native_image(args, **kwargs): - mx.run([native_image_cmd] + args, **kwargs) + mx.run([native_image_cmd, '-H:CLibraryPath=' + clibrary_libpath()] + args, **kwargs) else: - _native_image = native_image_on_jvm + raise mx.abort("GraalVM not built? could not find " + native_image_cmd) def query_native_image(all_args, option): out = mx.LinesOutputCapture() @@ -567,21 +370,22 @@ def native_image_func(args, **kwargs): path = query_native_image(all_args, '-H:Path=') name = query_native_image(all_args, '-H:Name=') image = join(path, name) + if not has_server and '--no-server' in all_args: + all_args = [arg for arg in all_args if arg != '--no-server'] _native_image(all_args, **kwargs) return image try: - if exists(native_image_cmd): + if exists(native_image_cmd) and has_server: _native_image(['--server-wipe']) yield native_image_func finally: - if exists(native_image_cmd): + if exists(native_image_cmd) and has_server: _native_image(['--server-shutdown']) native_image_context.hosted_assertions = ['-J-ea', '-J-esa'] def svm_gate_body(args, tasks): - with Task('Build native-image image', tasks, tags=[GraalTags.build, GraalTags.helloworld]) as t: - if t: build_native_image_image() + build_native_image_image() with native_image_context(IMAGE_ASSERTION_FLAGS) as native_image: with Task('image demos', tasks, tags=[GraalTags.helloworld]) as t: if t: @@ -599,16 +403,10 @@ def svm_gate_body(args, tasks): with Task('Run Truffle NFI unittests with SVM image', tasks, tags=["svmjunit"]) as t: if t: testlib = mx_subst.path_substitutions.substitute('-Dnative.test.lib=/') - native_unittest_args = ['com.oracle.truffle.nfi.test', '--build-args', '--initialize-at-build-time', '--tool:nfi', + native_unittest_args = ['com.oracle.truffle.nfi.test', '--build-args', '--initialize-at-build-time', '--language:nfi', '-H:MaxRuntimeCompileMethods=1500', '--run-args', testlib, '--very-verbose', '--enable-timing'] native_unittest(native_unittest_args) - with Task('JavaScript', tasks, tags=[GraalTags.js]) as t: - if t: - js = build_js(native_image) - test_run([js, '-e', 'print("hello:" + Array.from(new Array(10), (x,i) => i*i ).join("|"))'], 'hello:0|1|4|9|16|25|36|49|64|81\n') - test_js(js, [('octane-richards', 1000, 100, 300)]) - with Task('Truffle TCK', tasks, tags=[GraalTags.truffletck]) as t: if t: junit_native_dir = join(svmbuild_dir(), platform_name(), 'junit') @@ -622,7 +420,7 @@ def svm_gate_body(args, tasks): mx.abort('TCK tests not found.') unittest_deps.append(mx.dependency('truffle:TRUFFLE_SL_TCK')) vm_image_args = mx.get_runtime_jvm_args(unittest_deps, jdk=mx_compiler.jdk) - tests_image = native_image(vm_image_args + ['--tool:truffle', '--initialize-at-build-time', + tests_image = native_image(vm_image_args + ['--macro:truffle', '--initialize-at-build-time', '--features=com.oracle.truffle.tck.tests.TruffleTCKFeature', '-H:Class=org.junit.runner.JUnitCore', '-H:IncludeResources=com/oracle/truffle/sl/tck/resources/.*', '-H:MaxRuntimeCompileMethods=3000']) @@ -632,7 +430,13 @@ def svm_gate_body(args, tasks): finally: remove_tree(junit_tmp_dir) - + build_native_image_image(config=_graalvm_js_config) + with native_image_context(IMAGE_ASSERTION_FLAGS, config=_graalvm_js_config) as native_image: + with Task('JavaScript', tasks, tags=[GraalTags.js]) as t: + if t: + js = build_js(native_image) + test_run([js, '-e', 'print("hello:" + Array.from(new Array(10), (x,i) => i*i ).join("|"))'], 'hello:0|1|4|9|16|25|36|49|64|81\n') + test_js(js, [('octane-richards', 1000, 100, 300)]) with Task('maven plugin checks', tasks, tags=[GraalTags.maven]) as t: if t: @@ -663,7 +467,7 @@ def dummy_harness(test_deps, vm_launcher, vm_args): with open(unittest_file, 'r') as f: mx.log('Building junit image for matching: ' + ' '.join(l.rstrip() for l in f)) extra_image_args = mx.get_runtime_jvm_args(unittest_deps, jdk=mx_compiler.jdk) - unittest_image = native_image(build_args + extra_image_args + ['--tool:junit=' + unittest_file, '-H:Path=' + junit_tmp_dir]) + unittest_image = native_image(build_args + extra_image_args + ['--macro:junit=' + unittest_file, '-H:Path=' + junit_tmp_dir]) if preserve_image: build_dir = join(svmbuild_dir(), 'junit') mkpath(build_dir) @@ -754,9 +558,15 @@ def stderr_collector(x): if not passing: mx.abort('JS benchmark ' + name + ' failed') + +_graalvm_js_config = GraalVMConfig(dynamicimports=['/graal-js'], disable_libpolyglot=True, + force_bash_launchers=['polyglot', 'native-image-configure', 'js'], + skip_libraries=['native-image-agent'], + exclude_components=_graalvm_exclude_components) + + def build_js(native_image): - truffle_language_ensure('js') - return native_image(['--language:js', '--initialize-at-build-time']) + return native_image(['--macro:js-launcher', '--no-server']) def test_js(js, benchmarks, bin_args=None): bench_location = join(suite.dir, '..', '..', 'js-benchmarks') @@ -873,8 +683,8 @@ def _javac_image(native_image, path, args=None): @mx.command(suite.name, 'benchmark') def benchmark(args): - if '--jsvm=substratevm' in args: - truffle_language_ensure('js') + # if '--jsvm=substratevm' in args: + # truffle_language_ensure('js') return orig_command_benchmark(args) def mx_post_parse_cmd_line(opts): @@ -882,9 +692,9 @@ def mx_post_parse_cmd_line(opts): if not dist.isTARDistribution(): dist.set_archiveparticipant(GraalArchiveParticipant(dist, isTest=dist.name.endswith('_TEST'))) -def native_image_context_run(func, func_args=None): +def native_image_context_run(func, func_args=None, config=None, build_if_missing=False): func_args = [] if func_args is None else func_args - with native_image_context() as native_image: + with native_image_context(config=config, build_if_missing=build_if_missing) as native_image: func(native_image, func_args) def pom_from_template(proj_dir, svmVersion): @@ -928,47 +738,33 @@ def deploy_native_image_maven_plugin(svmVersion, repo, gpg, keyid): 'substratevm:POINTSTO', ], support_distributions=['substratevm:SVM_GRAALVM_SUPPORT'], +)) + +mx_sdk.register_graalvm_component(mx_sdk.GraalVmJreComponent( + suite=suite, + name='Native Image', + short_name='ni', + dir_name='svm', + installable_id='native-image', + license_files=[], + third_party_license_files=[], + support_distributions=['substratevm:NATIVE_IMAGE_GRAALVM_SUPPORT'], launcher_configs=[ mx_sdk.LauncherConfig( destination="bin/", jar_distributions=["substratevm:SVM_DRIVER"], main_class="com.oracle.svm.driver.NativeImage", + build_args=[], + ), + mx_sdk.LauncherConfig( + destination="bin/", + jar_distributions=["substratevm:SVM_CONFIGURE"], + main_class="com.oracle.svm.configure.ConfigurationTool", build_args=[ "-H:-ParseRuntimeOptions", ] ) ], - provided_executables=['bin/rebuild-images'], -)) - - -mx_sdk.register_graalvm_component(mx_sdk.GraalVmJreComponent( - suite=suite, - name='SubstrateVM LLVM', - short_name='svml', - dir_name='svm', - license_files=[], - third_party_license_files=[], - builder_jar_distributions=[ - 'substratevm:SVM_LLVM', - 'compiler:GRAAL_LLVM', - 'compiler:LLVM_WRAPPER', - 'compiler:JAVACPP', - 'compiler:LLVM_PLATFORM_SPECIFIC', - ], -)) - - -mx_sdk.register_graalvm_component(mx_sdk.GraalVmJreComponent( - suite=suite, - name='SubstrateVM Agent', - short_name='svmag', - dir_name='.', - license_files=[], - third_party_license_files=[], - jar_distributions=[], - builder_jar_distributions=[], - support_distributions=[], library_configs=[ mx_sdk.LibraryConfig( destination="", @@ -980,19 +776,37 @@ def deploy_native_image_maven_plugin(svmVersion, repo, gpg, keyid): ], ), ], + provided_executables=['bin/rebuild-images'] if not mx.is_windows() else [], + installable=True, )) +mx_sdk.register_graalvm_component(mx_sdk.GraalVmJreComponent( + suite=suite, + name='Native Image licence files', + short_name='nil', + dir_name='svm', + installable_id='native-image', + license_files=['LICENSE_NATIVEIMAGE.txt'], + third_party_license_files=[], + support_distributions=['substratevm:NATIVE_IMAGE_LICENSE_GRAALVM_SUPPORT'], + installable=True, + priority=1, +)) -mx_sdk.register_graalvm_component(mx_sdk.GraalVmTool( +mx_sdk.register_graalvm_component(mx_sdk.GraalVmJreComponent( suite=suite, - name='SubstrateVM Configuration Tool', - short_name='svmcf', - dir_name='native-image-configure', + name='SubstrateVM LLVM', + short_name='svml', + dir_name='svm', license_files=[], third_party_license_files=[], - truffle_jars=['substratevm:SVM_CONFIGURE'], - support_distributions=['substratevm:NATIVE_IMAGE_CONFIGURE_SUPPORT'], - include_in_polyglot=False, + builder_jar_distributions=[ + 'substratevm:SVM_LLVM', + 'compiler:GRAAL_LLVM', + 'compiler:LLVM_WRAPPER', + 'compiler:JAVACPP', + 'compiler:LLVM_PLATFORM_SPECIFIC', + ], )) @@ -1008,9 +822,9 @@ def deploy_native_image_maven_plugin(svmVersion, repo, gpg, keyid): "substratevm:POLYGLOT_NATIVE_API_HEADERS", ], polyglot_lib_build_args=[ - "--tool:truffle", + "--macro:truffle", "-H:Features=org.graalvm.polyglot.nativeapi.PolyglotNativeAPIFeature", - "-Dorg.graalvm.polyglot.nativeapi.libraryPath=", + "-Dorg.graalvm.polyglot.nativeapi.libraryPath=${.}/../../../polyglot/", "-H:CStandard=C11", "-H:+SpawnIsolates", ], @@ -1023,20 +837,16 @@ def deploy_native_image_maven_plugin(svmVersion, repo, gpg, keyid): has_polyglot_lib_entrypoints=True, )) -if os.environ.has_key('NATIVE_IMAGE_TESTING'): - mx_sdk.register_graalvm_component(mx_sdk.GraalVmTool( - suite=suite, - name='Native Image JUnit', - short_name='nju', - dir_name='junit', - license_files=[], - third_party_license_files=[], - truffle_jars=[], - builder_jar_distributions=['mx:JUNIT_TOOL', 'mx:JUNIT', 'mx:HAMCREST'], - support_distributions=['substratevm:NATIVE_IMAGE_JUNIT_SUPPORT'], - include_in_polyglot=False, - )) - +mx_sdk.register_graalvm_component(mx_sdk.GraalVMSvmMacro( + suite=suite, + name='Native Image JUnit', + short_name='nju', + dir_name='junit', + license_files=[], + third_party_license_files=[], + builder_jar_distributions=['mx:JUNIT_TOOL', 'mx:JUNIT', 'mx:HAMCREST'], + support_distributions=['substratevm:NATIVE_IMAGE_JUNIT_SUPPORT'], +)) if os.environ.has_key('LIBGRAAL'): mx_sdk.register_graalvm_component(mx_sdk.GraalVmJreComponent( @@ -1086,7 +896,8 @@ def helloworld(args): output_path = unmask(parsed.output_path)[0] native_image_context_run( lambda native_image, a: - _helloworld(native_image, javac_command, output_path, a), unmask(parsed.image_args) + _helloworld(native_image, javac_command, output_path, a), unmask(parsed.image_args), + build_if_missing=True ) @@ -1095,7 +906,7 @@ def cinterfacetutorial(args): """ runs all tutorials for the C interface. """ - native_image_context_run(_cinterfacetutorial, args) + native_image_context_run(_cinterfacetutorial, args, build_if_missing=True) @mx.command(suite.name, 'clinittest', 'Runs the ') @@ -1132,7 +943,7 @@ def check_class_initialization(classes_file_name, marker): check_class_initialization(delayed_classes, 'MustBeDelayed') check_class_initialization(safe_classes, 'MustBeSafe') - native_image_context_run(build_and_test_clinittest_image, args) + native_image_context_run(build_and_test_clinittest_image, args, build_if_missing=True) @@ -1168,11 +979,17 @@ def update_if_needed(version_tag, graal_compiler_flags): print('Write file ' + flags_path) f.write(flags_contents) + update_if_needed("versions", GRAAL_COMPILER_FLAGS_MAP.keys()) for version_tag in GRAAL_COMPILER_FLAGS_MAP: update_if_needed(version_tag, GRAAL_COMPILER_FLAGS_BASE + GRAAL_COMPILER_FLAGS_MAP[version_tag]) orig_command_build(args, vm) + if 'substratevm' in mx.primary_suite().name: + # build "jvm" config used by native-image and native-image-configure commands + config = graalvm_jvm_configs[-1] + build_native_image_image(config) + @mx.command(suite.name, 'native-image') def native_image_on_jvm(args, **kwargs): @@ -1183,35 +1000,26 @@ def native_image_on_jvm(args, **kwargs): else: save_args.append(arg) - driver_cp = [join(suite_native_image_root(), 'lib', subdir, '*.jar') for subdir in ['boot', 'jvmci', 'graalvm']] - driver_cp += [join(suite_native_image_root(), 'lib', 'svm', tail) for tail in ['*.jar', join('builder', '*.jar')]] - driver_cp = list(itertools.chain.from_iterable(glob.glob(cp) for cp in driver_cp)) - - svm_version = suite.release_version(snapshotSuffix='SNAPSHOT') - run_java([ - '-Dorg.graalvm.version=' + svm_version, - '-Dnative-image.root=' + suite_native_image_root(), - '-cp', os.pathsep.join(driver_cp), - mx.dependency('substratevm:SVM_DRIVER').mainClass] + save_args, **kwargs) + config = graalvm_jvm_configs[-1] + executable = vm_native_image_path(config) + if not exists(executable): + mx.abort("Can not find " + executable + "\nDid you forget to build? Try `mx build`") + mx.run([executable, '-H:CLibraryPath=' + clibrary_libpath()] + save_args, **kwargs) @mx.command(suite.name, 'native-image-configure') def native_image_configure_on_jvm(args, **kwargs): - configure_cp = [join(suite_native_image_root(), 'tools', 'native-image-configure', 'svm-configure.jar')] - configure_cp += [join(suite_native_image_root(), 'lib', 'jvmci', '*.jar')] - configure_cp += [join(suite_native_image_root(), 'lib', 'svm', tail) for tail in ['*.jar', join('builder', '*.jar')]] - configure_cp = list(itertools.chain.from_iterable(glob.glob(cp) for cp in configure_cp)) - svm_version = suite.release_version(snapshotSuffix='SNAPSHOT') - run_java([ - '-Dorg.graalvm.version=' + svm_version, - '-cp', os.pathsep.join(configure_cp), - mx.dependency('substratevm:SVM_CONFIGURE').mainClass] + args, **kwargs) + config = graalvm_jvm_configs[-1] + executable = vm_executable_path('native-image-configure', config) + if not exists(executable): + mx.abort("Can not find " + executable + "\nDid you forget to build? Try `mx build`") + mx.run([executable, '-H:CLibraryPath=' + clibrary_libpath()] + args, **kwargs) @mx.command(suite.name, 'native-unittest') def native_unittest(args): """builds a native image of JUnit tests and runs them.""" - native_image_context_run(_native_unittest, args) + native_image_context_run(_native_unittest, args, build_if_missing=True) @mx.command(suite.name, 'maven-plugin-install') @@ -1308,5 +1116,6 @@ def javac_image(args): output_path = unmask(parsed.output_path)[0] native_image_context_run( lambda native_image, command_args: - _javac_image(native_image, output_path, command_args), unmask(parsed.image_args) + _javac_image(native_image, output_path, command_args), unmask(parsed.image_args), + build_if_missing=True ) diff --git a/substratevm/mx.substratevm/mx_substratevm_benchmark.py b/substratevm/mx.substratevm/mx_substratevm_benchmark.py index 0c181f198b79..ea24573fc358 100644 --- a/substratevm/mx.substratevm/mx_substratevm_benchmark.py +++ b/substratevm/mx.substratevm/mx_substratevm_benchmark.py @@ -224,10 +224,13 @@ def bench_jsimage(bench_conf, out, err, extra_options=None): image_dir, js_image_name, image_path = _bench_image_params(bench_conf) if not exists(image_path): + native_image = mx_substratevm.vm_native_image_path(mx_substratevm._graalvm_js_config) + if not exists(native_image): + mx_substratevm.build_native_image_image(mx_substratevm._graalvm_js_config) with _timedelta('IMAGEBUILD: ', out=out): out('INFO: EXECUTE IMAGEBUILD: svmimage-%s\n' % bench_conf) _, image_building_options = _bench_configs[bench_conf] - command = [mx_substratevm.native_image_path(mx_substratevm.suite_native_image_root()), '--language:js', '-H:Path=' + image_dir, + command = [native_image, '--language:js', '-H:Path=' + image_dir, '-H:Name=' + js_image_name] + image_building_options + extra_options # Print out the command. print(' '.join(command)) @@ -274,7 +277,7 @@ def run_js(vmArgs, jsArgs, nonZeroIsFatal, out, err, cwd): _, _, image_path = _bench_image_params(bench_conf) if should_bench_compile_server and not exists(image_path): for _ in range(_IMAGE_BENCH_REPETITIONS): - with mx_substratevm.native_image_context(): + with mx_substratevm.native_image_context(config=mx_substratevm._graalvm_js_config, build_if_missing=True): _bench_compile_server(bench_conf, out) image_path = bench_jsimage(bench_conf, out=out, err=err) diff --git a/substratevm/mx.substratevm/rebuild-images.sh b/substratevm/mx.substratevm/rebuild-images.sh index b6f00691a55d..cad6d80f8631 100755 --- a/substratevm/mx.substratevm/rebuild-images.sh +++ b/substratevm/mx.substratevm/rebuild-images.sh @@ -28,7 +28,7 @@ # ---------------------------------------------------------------------------------------------------- source="${BASH_SOURCE[0]}" -while [ -h "$source" ] ; do +while [[ -h "$source" ]] ; do prev_source="$source" source="$(readlink "$source")"; if [[ "$source" != /* ]]; then @@ -42,19 +42,6 @@ location="$( cd -P "$( dirname "$source" )" && pwd )" # we assume we are in `jre/lib/svm/bin` graalvm_home="${location}/../../../.." -supported_tools=( - "agent" - "chromeinspector" - "profiler" -) - -supported_languages=( - "js" - "llvm" - "python" - "ruby" -) - function usage_and_exit() { echo "Usage: $0 [--verbose] polyglot|libpolyglot|js|llvm|python|ruby... [custom native-image args]..." exit 1 @@ -99,113 +86,47 @@ function common() { if [[ -f "${graalvm_home}/jre/lib/svm/builder/svm-enterprise.jar" ]]; then cmd_line+=("-g") fi - - for tool in "${supported_tools[@]}"; do - if [[ -d "${graalvm_home}/jre/tools/${tool}" ]]; then - cmd_line+=("--tool:${tool}") - fi - done } function polyglot_common() { - common - - for language in "${supported_languages[@]}"; do - if [[ -d "${graalvm_home}/jre/languages/${language}" ]]; then - cmd_line+=("--language:${language}") - fi - done -} - -function launcher_common() { - cmd_line+=("-H:-ParseRuntimeOptions") -} - -function polyglot() { - polyglot_common - launcher_common - cmd_line+=( - "-H:Features=org.graalvm.launcher.PolyglotLauncherFeature" - "-Dorg.graalvm.launcher.relative.home=jre/bin/polyglot" - "-H:Name=polyglot" - "--tool:truffle" - ) - set_path "${graalvm_home}/jre/bin" - cmd_line+=( - "org.graalvm.launcher.PolyglotLauncher" - ) + cmd_line+=("--language:all") } function libpolyglot() { + common polyglot_common - cp="${graalvm_home}/jre/lib/polyglot/polyglot-native-api.jar" - if [ -f "${graalvm_home}/jre/languages/js/trufflenode.jar" ]; then - cp="${cp}:${graalvm_home}/jre/languages/js/trufflenode.jar" - cmd_line+=( - "-H:JNIConfigurationResources=svmnodejs.jniconfig" - ) - fi - cmd_line+=( - "-cp" - "${cp}" - "--tool:truffle" - "-Dgraalvm.libpolyglot=true" - "-H:Features=org.graalvm.polyglot.nativeapi.PolyglotNativeAPIFeature" - "-Dorg.graalvm.polyglot.nativeapi.libraryPath=${graalvm_home}/jre/lib/polyglot" - "-H:CStandard=C11" - "-H:+IncludeAllTimeZones" - "-H:+SpawnIsolates" - "-H:Name=libpolyglot" - "-H:Kind=SHARED_LIBRARY" - ) - set_path "${graalvm_home}/jre/lib/polyglot" + cmd_line+=("--macro:polyglot-library") } -function language() { +function launcher() { common - launcher_common - local lang="$1" - local relative_path="$2" - local launcher_class="$3" - if [[ "${lang}" = "ruby" || "${lang}" = "python" ]]; then - cmd_line+=("--language:llvm") + local launcher="$1" + cmd_line+=("--macro:${launcher}-launcher") + if [[ "$launcher" == "polyglot" ]]; then + polyglot_common fi - cmd_line+=( - "--language:${lang}" - "-Dorg.graalvm.launcher.relative.language.home=${relative_path}" - "-Dorg.graalvm.launcher.standalone=false" - "-H:Name=$(basename ${relative_path})" - ) - set_path "${graalvm_home}/jre/languages/${lang}/$(dirname ${relative_path})" - cmd_line+=( - "${launcher_class}" - ) -} - -function set_path() { - cmd_line+=("-H:Path=$1") } for binary in "${to_build[@]}"; do cmd_line=() case "${binary}" in polyglot) - polyglot + launcher polyglot ;; libpolyglot) libpolyglot ;; js) - language js "bin/js" "com.oracle.truffle.js.shell.JSLauncher" + launcher js ;; llvm) - language llvm "bin/lli" "com.oracle.truffle.llvm.launcher.LLVMLauncher" + launcher lli ;; python) - language python "bin/graalpython" "com.oracle.graal.python.shell.GraalPythonMain" + launcher graalpython ;; ruby) - language ruby "bin/truffleruby" "org.truffleruby.launcher.RubyLauncher" + launcher truffleruby ;; *) echo "shouldNotReachHere()" diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 15ae36b990af..68659312f0cc 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -1,7 +1,7 @@ suite = { - "mxversion": "5.210.5", + "mxversion": "5.218.0", "name": "substratevm", - "version" : "1.0.0-rc18", + "version" : "20.0.0-beta.01", "release" : False, "url" : "https://github.com/oracle/graal/tree/master/substratevm", @@ -107,7 +107,7 @@ "workingSets": "SVM", }, - "com.oracle.svm.core.jdk9": { + "com.oracle.svm.core.jdk11": { "subDir": "src", "sourceDirs": ["src"], "dependencies": ["com.oracle.svm.core"], @@ -115,25 +115,25 @@ "jdk.internal.misc", "jdk.internal.perf", ], - "javaCompliance": "9+", - "multiReleaseJarVersion": "9", + "javaCompliance": "11+", + "multiReleaseJarVersion": "11", "checkstyle": "com.oracle.svm.core", "workingSets": "SVM", }, - "com.oracle.svm.core.posix.jdk9": { + "com.oracle.svm.core.posix.jdk11": { "subDir": "src", "sourceDirs": ["src"], "dependencies": [ - "com.oracle.svm.core.jdk9", + "com.oracle.svm.core.jdk11", "com.oracle.svm.core.posix" ], "imports" : [ "jdk.internal.misc", "jdk.internal.perf", ], - "javaCompliance": "9+", - "multiReleaseJarVersion": "9", + "javaCompliance": "11+", + "multiReleaseJarVersion": "11", "checkstyle": "com.oracle.svm.core", "workingSets": "SVM", }, @@ -407,8 +407,7 @@ "resources" ], "dependencies": [ - "com.oracle.svm.graal", - "com.oracle.svm.reflect", + "com.oracle.svm.hosted", ], "checkstyle": "com.oracle.svm.driver", "checkstyleVersion" : "8.8", @@ -696,7 +695,7 @@ "resources", ], "dependencies": [ - "com.oracle.svm.hosted", + "com.oracle.svm.core", ], "checkstyle": "com.oracle.svm.driver", "workingSets": "SVM", @@ -747,9 +746,9 @@ "com.oracle.svm.core.graal.amd64", "com.oracle.svm.core.graal.aarch64", "com.oracle.svm.core.jdk8", - "com.oracle.svm.core.jdk9", + "com.oracle.svm.core.jdk11", "com.oracle.svm.core.posix", - "com.oracle.svm.core.posix.jdk9", + "com.oracle.svm.core.posix.jdk11", "com.oracle.svm.core.windows", "com.oracle.svm.core.genscavenge", "com.oracle.svm.jni", @@ -835,6 +834,7 @@ }, "GRAAL_HOTSPOT_LIBRARY": { + "subDir": "src", "description" : "SubstrateVM HotSpot Graal library support", "dependencies": [ "com.oracle.svm.graal.hotspot.libgraal", @@ -891,6 +891,7 @@ }, "SVM_AGENT": { + "subDir": "src", "description" : "SubstrateVM native-image-agent library", "dependencies": [ "com.oracle.svm.agent", @@ -934,6 +935,7 @@ }, "SVM_TESTS" : { + "subDir": "src", "relpath" : True, "dependencies" : [ "com.oracle.svm.test", @@ -946,6 +948,7 @@ }, "POLYGLOT_NATIVE_API" : { + "subDir": "src", "dependencies": [ "org.graalvm.polyglot.nativeapi", ], @@ -972,17 +975,26 @@ "platformDependent" : True, "description" : "SubstrateVM support distribution for the GraalVM", "layout" : { - "bin/rebuild-images" : "file:mx.substratevm/rebuild-images.sh", "clibraries/" : ["extracted-dependency:substratevm:SVM_HOSTED_NATIVE"], "builder/clibraries/" : ["extracted-dependency:substratevm:SVM_HOSTED_NATIVE"], }, }, - "NATIVE_IMAGE_CONFIGURE_SUPPORT" : { + "NATIVE_IMAGE_GRAALVM_SUPPORT" : { "native" : True, - "description" : "SubstrateVM native-image configuration tool", + "platformDependent" : True, + "description" : "Native Image support distribution for the GraalVM", + "layout" : { + "bin/rebuild-images" : "file:mx.substratevm/rebuild-images.sh", + }, + }, + + "NATIVE_IMAGE_LICENSE_GRAALVM_SUPPORT" : { + "native" : True, + "platformDependent" : False, + "description" : "Native Image support distribution for the GraalVM", "layout" : { - "native-image.properties" : "file:mx.substratevm/tools-native-image-configure.properties", + "LICENSE_NATIVEIMAGE.txt" : "file:LICENSE.md", }, }, @@ -990,7 +1002,7 @@ "native" : True, "description" : "Native-image based junit testing support", "layout" : { - "native-image.properties" : "file:mx.substratevm/tools-junit.properties", + "native-image.properties" : "file:mx.substratevm/macro-junit.properties", }, }, diff --git a/substratevm/mx.substratevm/tools-chromeinspector.properties b/substratevm/mx.substratevm/tools-chromeinspector.properties deleted file mode 100644 index b29dc41433ee..000000000000 --- a/substratevm/mx.substratevm/tools-chromeinspector.properties +++ /dev/null @@ -1,3 +0,0 @@ -Requires = tool:profiler -Args = -H:SubstitutionResources=com/oracle/truffle/tools/chromeinspector/aot/substitutions.json \ - -H:MaxRuntimeCompileMethods=300 diff --git a/substratevm/mx.substratevm/tools-native-image-agent.properties b/substratevm/mx.substratevm/tools-native-image-agent.properties deleted file mode 100644 index 7304bf9234e6..000000000000 --- a/substratevm/mx.substratevm/tools-native-image-agent.properties +++ /dev/null @@ -1,4 +0,0 @@ -# Support for building the agent shared object with native-image - -Args = --shared -cp ${.}/svm-agent.jar:${.}/../../lib/graalvm/svm-driver.jar -H:Name=native-image-agent \ - --initialize-at-build-time diff --git a/substratevm/mx.substratevm/tools-native-image-configure.properties b/substratevm/mx.substratevm/tools-native-image-configure.properties deleted file mode 100644 index 1f70ba01086c..000000000000 --- a/substratevm/mx.substratevm/tools-native-image-configure.properties +++ /dev/null @@ -1,6 +0,0 @@ -# Support for building the configuration tool with native-image - -Args = -H:-ParseRuntimeOptions \ - -jar ${.}/svm-configure.jar \ - -H:Name=native-image-configure \ - --initialize-at-build-time diff --git a/substratevm/mx.substratevm/tools-native-image.properties b/substratevm/mx.substratevm/tools-native-image.properties deleted file mode 100644 index 4f65020a81d1..000000000000 --- a/substratevm/mx.substratevm/tools-native-image.properties +++ /dev/null @@ -1,4 +0,0 @@ -# This file contains support for building native-image with native-image - -Args = -jar ${.}/../../lib/graalvm/svm-driver.jar \ - --initialize-at-build-time diff --git a/substratevm/mx.substratevm/tools-profiler.properties b/substratevm/mx.substratevm/tools-profiler.properties deleted file mode 100644 index 2c8acd4a800d..000000000000 --- a/substratevm/mx.substratevm/tools-profiler.properties +++ /dev/null @@ -1,2 +0,0 @@ -Requires = tool:truffle -Args = -H:MaxRuntimeCompileMethods=100 diff --git a/substratevm/mx.substratevm/tools-regex.properties b/substratevm/mx.substratevm/tools-regex.properties deleted file mode 100644 index fd109752eadb..000000000000 --- a/substratevm/mx.substratevm/tools-regex.properties +++ /dev/null @@ -1 +0,0 @@ -Requires = tool:truffle diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java index 92cd880bee6e..f67e6a5a4c9f 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java @@ -173,7 +173,7 @@ public MethodTypeFlowBuilder(BigBang bb, StructuredGraph graph) { @SuppressWarnings("try") private boolean parse() { - OptionValues options = bb.getUniverse().adjustCompilerOptions(bb.getOptions(), method); + OptionValues options = bb.getOptions(); GraalJVMCICompiler compiler = (GraalJVMCICompiler) JVMCI.getRuntime().getCompiler(); SnippetReflectionProvider snippetReflection = compiler.getGraalRuntime().getRequiredCapability(SnippetReflectionProvider.class); // Use the real SnippetReflectionProvider for dumping @@ -210,6 +210,14 @@ private boolean parse() { GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(bb.getProviders().getGraphBuilderPlugins()).withEagerResolving(true) .withUnresolvedIsError(PointstoOptions.UnresolvedIsError.getValue(bb.getOptions())) .withNodeSourcePosition(true).withBytecodeExceptionMode(BytecodeExceptionMode.CheckAll); + + /* + * We want to always disable the liveness analysis, since we want the + * points-to analysis to be as conservative as possible. The analysis + * results can then be used with the liveness analysis enabled or disabled. + */ + config = config.withRetainLocalVariables(true); + bb.getHostVM().createGraphBuilderPhase(bb.getProviders(), config, OptimisticOptimizations.NONE, null).apply(graph); } } catch (PermanentBailoutException ex) { diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/Universe.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/Universe.java index 3f19dca63317..962aca79770a 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/Universe.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/Universe.java @@ -25,7 +25,6 @@ package com.oracle.graal.pointsto.infrastructure; import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; -import org.graalvm.compiler.options.OptionValues; import com.oracle.graal.pointsto.api.HostVM; @@ -65,7 +64,5 @@ public interface Universe { ResolvedJavaMethod resolveSubstitution(ResolvedJavaMethod method); - OptionValues adjustCompilerOptions(OptionValues optionValues, ResolvedJavaMethod method); - ResolvedJavaType objectType(); } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisUniverse.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisUniverse.java index f8392340102b..445fb7225a1c 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisUniverse.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisUniverse.java @@ -40,9 +40,7 @@ import java.util.function.Function; import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; -import org.graalvm.compiler.core.common.GraalOptions; import org.graalvm.compiler.core.common.SuppressFBWarnings; -import org.graalvm.compiler.options.OptionValues; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; import org.graalvm.util.GuardedAnnotationAccess; @@ -52,6 +50,7 @@ import com.oracle.graal.pointsto.BigBang; import com.oracle.graal.pointsto.api.HostVM; import com.oracle.graal.pointsto.constraints.UnsupportedFeatureException; +import com.oracle.graal.pointsto.infrastructure.OriginalClassProvider; import com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor; import com.oracle.graal.pointsto.infrastructure.Universe; import com.oracle.graal.pointsto.infrastructure.WrappedConstantPool; @@ -628,16 +627,6 @@ public ResolvedJavaMethod resolveSubstitution(ResolvedJavaMethod method) { return substitutions.resolve(method); } - @Override - public OptionValues adjustCompilerOptions(OptionValues optionValues, ResolvedJavaMethod method) { - /* - * For the AnalysisUniverse we want to always disable the liveness analysis, since we want - * the points-to analysis to be as conservative as possible. We don't want the optimization - * level to affect the execution of the points-to analysis. - */ - return new OptionValues(optionValues, GraalOptions.OptClearNonLiveLocals, false); - } - @Override public AnalysisType objectType() { return objectClass; @@ -652,6 +641,13 @@ public AnalysisPolicy analysisPolicy() { } public boolean platformSupported(AnnotatedElement element) { + if (element instanceof ResolvedJavaType) { + Package p = OriginalClassProvider.getJavaClass(getOriginalSnippetReflection(), (ResolvedJavaType) element).getPackage(); + if (p != null && !platformSupported(p)) { + return false; + } + } + Platforms platformsAnnotation = GuardedAnnotationAccess.getAnnotation(element, Platforms.class); if (platform == null || platformsAnnotation == null) { return true; diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/HostedProviders.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/HostedProviders.java index b96272be5156..bb9c98eea59a 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/HostedProviders.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/HostedProviders.java @@ -28,6 +28,7 @@ import org.graalvm.compiler.core.common.spi.ConstantFieldProvider; import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; +import org.graalvm.compiler.nodes.spi.GCProvider; import org.graalvm.compiler.nodes.spi.LoweringProvider; import org.graalvm.compiler.nodes.spi.Replacements; import org.graalvm.compiler.nodes.spi.StampProvider; @@ -46,8 +47,8 @@ public class HostedProviders extends Providers { public HostedProviders(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider, ForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, StampProvider stampProvider, SnippetReflectionProvider snippetReflection, - WordTypes wordTypes) { - super(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider); + WordTypes wordTypes, GCProvider gc) { + super(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider, gc); this.snippetReflection = snippetReflection; this.wordTypes = wordTypes; } @@ -71,6 +72,6 @@ public void setGraphBuilderPlugins(GraphBuilderConfiguration.Plugins graphBuilde @Override public Providers copyWith(Replacements substitution) { return new HostedProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), getLowerer(), substitution, getStampProvider(), - getSnippetReflection(), getWordTypes()); + getSnippetReflection(), getWordTypes(), getGC()); } } diff --git a/substratevm/src/com.oracle.svm.agent/src/com/oracle/svm/agent/Agent.java b/substratevm/src/com.oracle.svm.agent/src/com/oracle/svm/agent/Agent.java index 9fd24c7652a9..336c1b358f5c 100644 --- a/substratevm/src/com.oracle.svm.agent/src/com/oracle/svm/agent/Agent.java +++ b/substratevm/src/com.oracle.svm.agent/src/com/oracle/svm/agent/Agent.java @@ -31,7 +31,6 @@ import static com.oracle.svm.agent.jvmti.JvmtiEvent.JVMTI_EVENT_VM_INIT; import static com.oracle.svm.agent.jvmti.JvmtiEvent.JVMTI_EVENT_VM_START; import static com.oracle.svm.agent.jvmti.JvmtiEventMode.JVMTI_ENABLE; -import static com.oracle.svm.hosted.config.ConfigurationDirectories.FileNames; import static com.oracle.svm.jni.JNIObjectHandles.nullHandle; import static org.graalvm.word.WordFactory.nullPointer; @@ -83,20 +82,16 @@ import com.oracle.svm.configure.trace.AccessAdvisor; import com.oracle.svm.configure.trace.TraceProcessor; import com.oracle.svm.core.FallbackExecutor; -import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.c.function.CEntryPointOptions; import com.oracle.svm.core.c.function.CEntryPointSetup; +import com.oracle.svm.core.configure.ConfigurationFiles; import com.oracle.svm.driver.NativeImage; -import com.oracle.svm.hosted.ResourcesFeature; -import com.oracle.svm.hosted.config.ConfigurationDirectories; import com.oracle.svm.jni.nativeapi.JNIEnvironment; import com.oracle.svm.jni.nativeapi.JNIErrors; import com.oracle.svm.jni.nativeapi.JNIJavaVM; import com.oracle.svm.jni.nativeapi.JNIObjectHandle; import com.oracle.svm.jni.nativeapi.JNIVersion; -import com.oracle.svm.reflect.hosted.ReflectionFeature; -import com.oracle.svm.reflect.proxy.hosted.DynamicProxyFeature; public final class Agent { public static final String AGENT_NAME = "native-image-agent"; @@ -107,11 +102,11 @@ private static String oH(OptionKey option) { return NativeImage.oH + option.getName(); } - private static final String oHJNIConfigurationResources = oH(SubstrateOptions.JNIConfigurationResources); - private static final String oHReflectionConfigurationResources = oH(ReflectionFeature.Options.ReflectionConfigurationResources); - private static final String oHDynamicProxyConfigurationResources = oH(DynamicProxyFeature.Options.DynamicProxyConfigurationResources); - private static final String oHResourceConfigurationResources = oH(ResourcesFeature.Options.ResourceConfigurationResources); - private static final String oHConfigurationResourceRoots = oH(ConfigurationDirectories.Options.ConfigurationResourceRoots); + private static final String oHJNIConfigurationResources = oH(ConfigurationFiles.Options.JNIConfigurationResources); + private static final String oHReflectionConfigurationResources = oH(ConfigurationFiles.Options.ReflectionConfigurationResources); + private static final String oHDynamicProxyConfigurationResources = oH(ConfigurationFiles.Options.DynamicProxyConfigurationResources); + private static final String oHResourceConfigurationResources = oH(ConfigurationFiles.Options.ResourceConfigurationResources); + private static final String oHConfigurationResourceRoots = oH(ConfigurationFiles.Options.ConfigurationResourceRoots); private static TraceWriter traceWriter; @@ -342,10 +337,10 @@ private static boolean addRestrictConfigs(JvmtiEnv jvmti, ConfigurationSet restr addURI.add(restrictConfigs.getResourceConfigPaths(), cpEntry, optionParts[1]); } else if (oHConfigurationResourceRoots.equals(argName)) { String resourceLocation = optionParts[1]; - addURI.add(restrictConfigs.getJniConfigPaths(), cpEntry, resourceLocation + "/" + FileNames.JNI_NAME); - addURI.add(restrictConfigs.getReflectConfigPaths(), cpEntry, resourceLocation + "/" + FileNames.REFLECTION_NAME); - addURI.add(restrictConfigs.getProxyConfigPaths(), cpEntry, resourceLocation + "/" + FileNames.DYNAMIC_PROXY_NAME); - addURI.add(restrictConfigs.getResourceConfigPaths(), cpEntry, resourceLocation + "/" + FileNames.RESOURCES_NAME); + addURI.add(restrictConfigs.getJniConfigPaths(), cpEntry, resourceLocation + "/" + ConfigurationFiles.JNI_NAME); + addURI.add(restrictConfigs.getReflectConfigPaths(), cpEntry, resourceLocation + "/" + ConfigurationFiles.REFLECTION_NAME); + addURI.add(restrictConfigs.getProxyConfigPaths(), cpEntry, resourceLocation + "/" + ConfigurationFiles.DYNAMIC_PROXY_NAME); + addURI.add(restrictConfigs.getResourceConfigPaths(), cpEntry, resourceLocation + "/" + ConfigurationFiles.RESOURCES_NAME); } } }); @@ -448,16 +443,16 @@ public static void onUnload(@SuppressWarnings("unused") JNIJavaVM vm) { if (configOutputDirPath != null) { TraceProcessor p = ((TraceProcessorWriterAdapter) traceWriter).getProcessor(); try { - try (JsonWriter writer = new JsonWriter(configOutputDirPath.resolve(FileNames.REFLECTION_NAME))) { + try (JsonWriter writer = new JsonWriter(configOutputDirPath.resolve(ConfigurationFiles.REFLECTION_NAME))) { p.getReflectionConfiguration().printJson(writer); } - try (JsonWriter writer = new JsonWriter(configOutputDirPath.resolve(FileNames.JNI_NAME))) { + try (JsonWriter writer = new JsonWriter(configOutputDirPath.resolve(ConfigurationFiles.JNI_NAME))) { p.getJniConfiguration().printJson(writer); } - try (JsonWriter writer = new JsonWriter(configOutputDirPath.resolve(FileNames.DYNAMIC_PROXY_NAME))) { + try (JsonWriter writer = new JsonWriter(configOutputDirPath.resolve(ConfigurationFiles.DYNAMIC_PROXY_NAME))) { p.getProxyConfiguration().printJson(writer); } - try (JsonWriter writer = new JsonWriter(configOutputDirPath.resolve(FileNames.RESOURCES_NAME))) { + try (JsonWriter writer = new JsonWriter(configOutputDirPath.resolve(ConfigurationFiles.RESOURCES_NAME))) { p.getResourceConfiguration().printJson(writer); } } catch (IOException e) { diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationSet.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationSet.java index 0d3a5d39e77c..4bbe8bc0f276 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationSet.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationSet.java @@ -36,11 +36,11 @@ import java.util.Set; import java.util.function.Function; -import com.oracle.svm.hosted.config.ConfigurationDirectories; -import com.oracle.svm.hosted.config.ConfigurationParser; -import com.oracle.svm.hosted.config.ProxyConfigurationParser; -import com.oracle.svm.hosted.config.ReflectionConfigurationParser; -import com.oracle.svm.hosted.config.ResourceConfigurationParser; +import com.oracle.svm.core.configure.ConfigurationFiles; +import com.oracle.svm.core.configure.ConfigurationParser; +import com.oracle.svm.core.configure.ProxyConfigurationParser; +import com.oracle.svm.core.configure.ReflectionConfigurationParser; +import com.oracle.svm.core.configure.ResourceConfigurationParser; public class ConfigurationSet { public static final Function FAIL_ON_EXCEPTION = e -> e; @@ -51,10 +51,10 @@ public class ConfigurationSet { private final Set resourceConfigPaths = new LinkedHashSet<>(); public void addDirectory(Path path) { - jniConfigPaths.add(path.resolve(ConfigurationDirectories.FileNames.JNI_NAME).toUri()); - reflectConfigPaths.add(path.resolve(ConfigurationDirectories.FileNames.REFLECTION_NAME).toUri()); - proxyConfigPaths.add(path.resolve(ConfigurationDirectories.FileNames.DYNAMIC_PROXY_NAME).toUri()); - resourceConfigPaths.add(path.resolve(ConfigurationDirectories.FileNames.RESOURCES_NAME).toUri()); + jniConfigPaths.add(path.resolve(ConfigurationFiles.JNI_NAME).toUri()); + reflectConfigPaths.add(path.resolve(ConfigurationFiles.REFLECTION_NAME).toUri()); + proxyConfigPaths.add(path.resolve(ConfigurationFiles.DYNAMIC_PROXY_NAME).toUri()); + resourceConfigPaths.add(path.resolve(ConfigurationFiles.RESOURCES_NAME).toUri()); } public boolean isEmpty() { diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java index 812750a974d9..732639b79a56 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java @@ -26,7 +26,7 @@ import java.util.List; -import com.oracle.svm.hosted.config.ReflectionConfigurationParserDelegate; +import com.oracle.svm.core.configure.ReflectionConfigurationParserDelegate; public class ParserConfigurationAdapter implements ReflectionConfigurationParserDelegate { diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ResourceConfiguration.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ResourceConfiguration.java index cd4bab58d762..26a7622843b5 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ResourceConfiguration.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ResourceConfiguration.java @@ -33,11 +33,11 @@ import com.oracle.svm.configure.json.JsonPrintable; import com.oracle.svm.configure.json.JsonPrinter; import com.oracle.svm.configure.json.JsonWriter; -import com.oracle.svm.hosted.ResourcesFeature; +import com.oracle.svm.core.configure.ResourcesRegistry; public class ResourceConfiguration implements JsonPrintable { - public static class ParserAdapter implements ResourcesFeature.ResourcesRegistry { + public static class ParserAdapter implements ResourcesRegistry { private final ResourceConfiguration configuration; public ParserAdapter(ResourceConfiguration configuration) { diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java index 18af50936418..45353472fa53 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java @@ -38,6 +38,9 @@ import javax.management.ObjectName; import org.graalvm.compiler.api.replacements.Fold; +import org.graalvm.compiler.nodes.gc.BarrierSet; +import org.graalvm.compiler.nodes.gc.CardTableBarrierSet; +import org.graalvm.compiler.nodes.spi.GCProvider; import org.graalvm.compiler.word.Word; import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.Platform; @@ -99,6 +102,7 @@ public class HeapImpl extends Heap { final HeapChunkProvider chunkProvider; /** A singleton instance, created during image generation. */ + private final GenScavengeGCProvider gcProvider; private final MemoryMXBean memoryMXBean; /** A list of all the classes, if someone asks for it. */ @@ -124,6 +128,7 @@ public HeapImpl(FeatureAccess access) { chunkProvider = new HeapChunkProvider(); this.pinnedAllocatorListHead = null; this.objectVisitorWalkerOperation = new ObjectVisitorWalkerOperation(); + this.gcProvider = new GenScavengeGCProvider(); this.memoryMXBean = new HeapImplMemoryMXBean(); this.classList = null; SubstrateUtil.DiagnosticThunkRegister.getSingleton().register(() -> { @@ -708,6 +713,24 @@ public UnsignedWord maxMemory() { return HeapPolicy.getMaximumHeapSize(); } + @Override + public GCProvider getGCProvider() { + return gcProvider; + } + + private static class GenScavengeGCProvider implements GCProvider { + private final BarrierSet barrierSet; + + GenScavengeGCProvider() { + this.barrierSet = new CardTableBarrierSet(false); + } + + @Override + public BarrierSet getBarrierSet() { + return barrierSet; + } + } + @Override public void prepareForSafepoint() { // nothing to do diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/BarrierSnippets.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/BarrierSnippets.java index 1c1101be48b7..10fb1e9cd16b 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/BarrierSnippets.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/BarrierSnippets.java @@ -35,6 +35,9 @@ import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.nodes.extended.BranchProbabilityNode; import org.graalvm.compiler.nodes.extended.FixedValueAnchorNode; +import org.graalvm.compiler.nodes.gc.SerialArrayRangeWriteBarrier; +import org.graalvm.compiler.nodes.gc.SerialWriteBarrier; +import org.graalvm.compiler.nodes.gc.WriteBarrier; import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; import org.graalvm.compiler.nodes.spi.LoweringTool; import org.graalvm.compiler.options.Option; @@ -79,7 +82,10 @@ protected static BarrierSnippets factory(OptionValues options, Iterable, NodeLoweringProvider> lowerings) { - lowerings.put(PostWriteBarrierNode.class, new PostWriteBarrierLowering()); + PostWriteBarrierLowering lowering = new PostWriteBarrierLowering(); + lowerings.put(SerialWriteBarrier.class, lowering); + // write barriers are currently always imprecise + lowerings.put(SerialArrayRangeWriteBarrier.class, lowering); } /** @@ -119,19 +125,11 @@ protected BarrierSnippets(OptionValues options, Iterable f super(options, factories, providers, snippetReflection); } - /* - * *Not* a static class: references fields of the containing BarrierSnippet instance. - */ - protected class PostWriteBarrierLowering implements NodeLoweringProvider { - + protected class PostWriteBarrierLowering implements NodeLoweringProvider { private final SnippetInfo postWriteBarrierSnippetInfo = snippet(BarrierSnippets.class, "postWriteBarrierSnippet", CardTable.CARD_REMEMBERED_SET_LOCATION); - /** - * Turn a CardRememberedSetNodes.PostWriteBarrierNode into an instantiation of the body of - * CardRememberedSetSnippets.BarrierSnippets.postWriteBarrierSnippet, with operands. - */ @Override - public void lower(PostWriteBarrierNode barrier, LoweringTool tool) { + public void lower(WriteBarrier barrier, LoweringTool tool) { Arguments args = new Arguments(postWriteBarrierSnippetInfo, barrier.graph().getGuardsStage(), tool.getLoweringStage()); OffsetAddressNode address = (OffsetAddressNode) barrier.getAddress(); args.add("object", address.getBase()); diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/HeapFeature.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/HeapFeature.java index dc87efa06f8c..30fbc2a7e774 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/HeapFeature.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/HeapFeature.java @@ -32,7 +32,6 @@ import org.graalvm.compiler.debug.DebugHandlersFactory; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.options.OptionValues; -import org.graalvm.compiler.phases.tiers.Suites; import org.graalvm.compiler.phases.util.Providers; import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.ImageSingletons; @@ -66,11 +65,6 @@ public void afterRegistration(AfterRegistrationAccess access) { ImageSingletons.add(Heap.class, new HeapImpl(access)); } - @Override - public void registerGraalPhases(Providers providers, SnippetReflectionProvider snippetReflection, Suites suites, boolean hosted) { - suites.getMidTier().appendPhase(InsertWriteBarrierPhase.factory()); - } - @Override public void registerLowerings(RuntimeConfiguration runtimeConfig, OptionValues options, Iterable factories, Providers providers, SnippetReflectionProvider snippetReflection, diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/InsertWriteBarrierPhase.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/InsertWriteBarrierPhase.java deleted file mode 100644 index 994d4454758b..000000000000 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/InsertWriteBarrierPhase.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2014, 2017, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.svm.core.genscavenge.graal; - -import org.graalvm.compiler.graph.Node; -import org.graalvm.compiler.nodes.StructuredGraph; -import org.graalvm.compiler.nodes.ValueNode; -import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode; -import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode; -import org.graalvm.compiler.nodes.memory.FixedAccessNode; -import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType; -import org.graalvm.compiler.nodes.memory.WriteNode; -import org.graalvm.compiler.nodes.memory.address.AddressNode; -import org.graalvm.compiler.nodes.type.StampTool; -import org.graalvm.compiler.phases.BasePhase; -import org.graalvm.compiler.phases.tiers.MidTierContext; - -/** - * Walk the graph and find WriteNodes with barriers and turn them into WriteNodes without barriers - * and separate barrier nodes. - */ -public class InsertWriteBarrierPhase extends BasePhase { - - public static InsertWriteBarrierPhase factory() { - return new InsertWriteBarrierPhase(); - } - - @Override - public boolean checkContract() { - // the size / cost after is highly dynamic and dependent on the graph, thus we do not verify - // costs for this phase - return false; - } - - @Override - protected void run(StructuredGraph graph, MidTierContext context) { - for (Node n : graph.getNodes()) { - if (n instanceof WriteNode) { - rewriteWithBarriers(graph, (WriteNode) n); - } - if (n instanceof AbstractCompareAndSwapNode) { - rewriteWithBarriers(graph, (AbstractCompareAndSwapNode) n); - } - if (n instanceof LoweredAtomicReadAndWriteNode) { - rewriteWithBarriers(graph, (LoweredAtomicReadAndWriteNode) n); - } - } - } - - /** - * WriteNode has - *

        - *
      • The object to which the write is done, in node.object(),
      • - *
      • the value to be written, in node.value(),
      • - *
      • the location within the object for the write, in node.location(),
      • - *
      • whether a precise or imprecise barrier is needed, in node.getBarrierType(),
      • and - *
      • whether the write is an initialization, in node.isInitialization()
      • . - *
      - */ - protected void rewriteWithBarriers(StructuredGraph graph, WriteNode node) { - if (node.getBarrierType() == BarrierType.NONE) { - // No barrier requested. - return; - } - final ValueNode value = node.value(); - if (!value.getStackKind().isObject()) { - // Storing something other than an Object does not require a barrier. - return; - } - if (StampTool.isPointerAlwaysNull(value)) { - // Storing a null does not require a barrier. - return; - } - // TODO: What about initializing writes, which I can check in node.isInitialization()? - addPostWriteBarrier(graph, node, node.getAddress()); - } - - /** - * AbstractCompareAndSwapNode has - *
        - *
      • The object to which the write is done, in node.object(),
      • - *
      • the value to be written, in node.getNewValue(),
      • - *
      • the location within the object for the write, in node.location(),
      • - *
      • whether a precise or imprecise barrier is needed, in node.getBarrierType(),
      • . - *
      - */ - protected void rewriteWithBarriers(StructuredGraph graph, AbstractCompareAndSwapNode node) { - if (node.getBarrierType() == BarrierType.NONE) { - // No barrier requested. - return; - } - final ValueNode value = node.getNewValue(); - if (!value.getStackKind().isObject()) { - // Storing something other than an Object does not require a barrier. - return; - } - if (StampTool.isPointerAlwaysNull(value)) { - // Storing a null does not require a barrier. - return; - } - // TODO: What about initializing writes, which I can check in node.isInitialization()? - addPostWriteBarrier(graph, node, node.getAddress()); - } - - /** - * LoweredAtomicReadAndWriteNode has - *
        - *
      • The object to which the write is done, in node.object(),
      • - *
      • the value to be written, in node.getNewValue(),
      • - *
      • the location within the object for the write, in node.location(),
      • - *
      • whether a precise or imprecise barrier is needed, in node.getBarrierType(),
      • . - *
      - */ - protected void rewriteWithBarriers(StructuredGraph graph, LoweredAtomicReadAndWriteNode node) { - if (node.getBarrierType() == BarrierType.NONE) { - // No barrier requested. - return; - } - final ValueNode value = node.getNewValue(); - if (!value.getStackKind().isObject()) { - // Storing something other than an Object does not require a barrier. - return; - } - if (StampTool.isPointerAlwaysNull(value)) { - // Storing a null does not require a barrier. - return; - } - // TODO: What about initializing writes, which I can check in node.isInitialization()? - addPostWriteBarrier(graph, node, node.getAddress()); - } - - protected void addPostWriteBarrier(StructuredGraph graph, FixedAccessNode node, AddressNode address) { - // TODO: Decide if I want a precise or imprecise barrier. - final PostWriteBarrierNode barrierNode = new PostWriteBarrierNode(address); - graph.addAfterFixed(node, graph.add(barrierNode)); - } - - /** Constructor for sub-classes. */ - protected InsertWriteBarrierPhase() { - super(); - } -} diff --git a/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/meta/SubstrateReplacements.java b/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/meta/SubstrateReplacements.java index 57f5cfc5045b..8c86b6218a26 100644 --- a/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/meta/SubstrateReplacements.java +++ b/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/meta/SubstrateReplacements.java @@ -44,6 +44,7 @@ import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.NodeSourcePosition; +import org.graalvm.compiler.nodes.Cancellable; import org.graalvm.compiler.nodes.EncodedGraph; import org.graalvm.compiler.nodes.GraphEncoder; import org.graalvm.compiler.nodes.StructuredGraph; @@ -309,7 +310,7 @@ public StructuredGraph getSubstitution(ResolvedJavaMethod original, int invokeBc } @Override - public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug) { + public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug, Cancellable cancellable) { // This override keeps graphBuilderPlugins from being reached during image generation. return null; } diff --git a/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java b/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java index 66a8db79e1b9..f04d6bdd4084 100644 --- a/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java +++ b/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java @@ -347,10 +347,14 @@ public static int enterSnippet(IsolateThread thread) { setHeapBase(Isolates.getHeapBase(isolate)); } if (MultiThreaded.getValue()) { - Safepoint.transitionNativeToJava(); if (runtimeAssertionsEnabled()) { + /* + * Verification must happen before the thread state transition. It locks the raw + * THREAD_MUTEX, so the thread must still be invisible to the safepoint manager. + */ runtimeCall(VERIFY_ISOLATE_THREAD, thread); } + Safepoint.transitionNativeToJava(); } return CEntryPointErrors.NO_ERROR; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/DeoptHostedSnippets.java b/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/snippets/DeoptHostedSnippets.java similarity index 98% rename from substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/DeoptHostedSnippets.java rename to substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/snippets/DeoptHostedSnippets.java index 65d234ce89b2..90cf04e9d0f3 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/DeoptHostedSnippets.java +++ b/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/snippets/DeoptHostedSnippets.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.hosted.snippets; +package com.oracle.svm.core.graal.snippets; import static com.oracle.svm.core.graal.snippets.SubstrateIntrinsics.runtimeCall; import static com.oracle.svm.core.util.VMError.shouldNotReachHere; @@ -50,8 +50,6 @@ import com.oracle.svm.core.deopt.DeoptimizationSupport; import com.oracle.svm.core.deopt.Deoptimizer; import com.oracle.svm.core.graal.nodes.UnreachableNode; -import com.oracle.svm.core.graal.snippets.NodeLoweringProvider; -import com.oracle.svm.core.graal.snippets.SubstrateTemplates; import com.oracle.svm.core.heap.RestrictHeapAccessCallees; import com.oracle.svm.core.snippets.ImplicitExceptions; import com.oracle.svm.core.snippets.SnippetRuntime; diff --git a/substratevm/src/com.oracle.svm.core.jdk9/src/com/oracle/svm/core/jdk/AnnotationSupportConfig.java b/substratevm/src/com.oracle.svm.core.jdk11/src/com/oracle/svm/core/jdk/AnnotationSupportConfig.java similarity index 100% rename from substratevm/src/com.oracle.svm.core.jdk9/src/com/oracle/svm/core/jdk/AnnotationSupportConfig.java rename to substratevm/src/com.oracle.svm.core.jdk11/src/com/oracle/svm/core/jdk/AnnotationSupportConfig.java diff --git a/substratevm/src/com.oracle.svm.core.jdk9/src/com/oracle/svm/core/jdk/LocalizationResourceBundles.java b/substratevm/src/com.oracle.svm.core.jdk11/src/com/oracle/svm/core/jdk/LocalizationResourceBundles.java similarity index 90% rename from substratevm/src/com.oracle.svm.core.jdk9/src/com/oracle/svm/core/jdk/LocalizationResourceBundles.java rename to substratevm/src/com.oracle.svm.core.jdk11/src/com/oracle/svm/core/jdk/LocalizationResourceBundles.java index b68d4d8ce456..28eede97837d 100644 --- a/substratevm/src/com.oracle.svm.core.jdk9/src/com/oracle/svm/core/jdk/LocalizationResourceBundles.java +++ b/substratevm/src/com.oracle.svm.core.jdk11/src/com/oracle/svm/core/jdk/LocalizationResourceBundles.java @@ -24,6 +24,8 @@ */ package com.oracle.svm.core.jdk; +//Checkstyle: stop +import java.lang.reflect.Method; import java.util.Locale; import java.util.ResourceBundle; import java.util.TimeZone; @@ -32,15 +34,12 @@ import org.graalvm.nativeimage.Platforms; import com.oracle.svm.core.util.VMError; +import com.oracle.svm.util.ReflectionUtil; -import jdk.internal.misc.JavaUtilResourceBundleAccess; -import jdk.internal.misc.SharedSecrets; -// Checkstyle: stop import sun.util.locale.provider.LocaleProviderAdapter; import sun.util.resources.LocaleData; // Checkstyle: resume -/** JDK-9-or-later localization resource bundle initialization. */ @Platforms(Platform.HOSTED_ONLY.class) public class LocalizationResourceBundles extends LocalizationSupport { @@ -106,6 +105,18 @@ static void initialize(LocalizationSupport localizationSupport) { localizationSupport.addBundleToCache(sunUtilLoggingResourcesLoggingKey, sunUtilLoggingResourcesLoggingBundle); } + private static final Method NEW_RESOURCE_BUNDLE; + + static { + try { + // Checkstyle: stop + NEW_RESOURCE_BUNDLE = ReflectionUtil.lookupMethod(Class.forName("java.util.ResourceBundle$ResourceBundleProviderHelper"), "newResourceBundle", Class.class); + // Checkstyle: resume + } catch (ClassNotFoundException ex) { + throw VMError.shouldNotReachHere(ex); + } + } + private static ResourceBundle getBundleByName(String bundleName) { Class bundleClass = null; try { @@ -118,9 +129,11 @@ private static ResourceBundle getBundleByName(String bundleName) { } catch (ClassCastException cce) { throw VMError.shouldNotReachHere("Class is not a ResourceBundle:", cce); } - final JavaUtilResourceBundleAccess access = SharedSecrets.getJavaUtilResourceBundleAccess(); - final ResourceBundle result = access.newResourceBundle(bundleClass); - return result; + try { + return (ResourceBundle) NEW_RESOURCE_BUNDLE.invoke(null, bundleClass); + } catch (ReflectiveOperationException ex) { + throw VMError.shouldNotReachHere(ex); + } } } diff --git a/substratevm/src/com.oracle.svm.core.jdk9/src/com/oracle/svm/core/jdk/ModuleUtils.java b/substratevm/src/com.oracle.svm.core.jdk11/src/com/oracle/svm/core/jdk/ModuleUtils.java similarity index 100% rename from substratevm/src/com.oracle.svm.core.jdk9/src/com/oracle/svm/core/jdk/ModuleUtils.java rename to substratevm/src/com.oracle.svm.core.jdk11/src/com/oracle/svm/core/jdk/ModuleUtils.java diff --git a/substratevm/src/com.oracle.svm.core.jdk9/src/com/oracle/svm/core/jdk/Target_java_lang_StackWalker.java b/substratevm/src/com.oracle.svm.core.jdk11/src/com/oracle/svm/core/jdk/Target_java_lang_StackWalker.java similarity index 99% rename from substratevm/src/com.oracle.svm.core.jdk9/src/com/oracle/svm/core/jdk/Target_java_lang_StackWalker.java rename to substratevm/src/com.oracle.svm.core.jdk11/src/com/oracle/svm/core/jdk/Target_java_lang_StackWalker.java index dff66c56d614..9a3c96026cc3 100644 --- a/substratevm/src/com.oracle.svm.core.jdk9/src/com/oracle/svm/core/jdk/Target_java_lang_StackWalker.java +++ b/substratevm/src/com.oracle.svm.core.jdk11/src/com/oracle/svm/core/jdk/Target_java_lang_StackWalker.java @@ -51,7 +51,7 @@ import com.oracle.svm.core.stack.JavaStackWalk; import com.oracle.svm.core.stack.JavaStackWalker; -@TargetClass(value = java.lang.StackWalker.class, onlyWith = JDK9OrLater.class) +@TargetClass(value = java.lang.StackWalker.class, onlyWith = JDK11OrLater.class) final class Target_java_lang_StackWalker { @Alias Set