Sample project showing how to control Graal Compiler via Truffle API.
$ git clone https://github.com/jaroslavtulach/talk2compiler
$ cd talk2compiler
$ JAVA_HOME=/jdk-11 mvn package exec:exec -Dexec.appArgs=Truffle
The project stands in its master
state as a platform
ready for your experimentations. Use it to get the
Graal JIT compiler
under your control. Use it to get the best from the dynamic just in time
compiler surrouding your code. Just enclose your code into the
Main.execute
method and you'll be in direct contact with the assembly -
code in Java, but directly influence the native code. That is what
we are aiming at!
Download GraalVM EE and launch
Ideal Graph Visualizer.
It starts listening on port 4445 and is ready to accept graphs showing
progress of Graal compilations. Either run the program with -Pigv
$ JAVA_HOME=/jdk-11 mvn -Pigv process-classes exec:exec -Dexec.appArgs=Truffle
or run the tests to dump the execution graphs
$ JAVA_HOME=/jdk-11 mvn -Pigv test
The igv
profile passes additional arguments to the JVM:
-Dgraal.Dump=:1 -Dgraal.PrintGraph=Network
.
A tree of graphs representing Truffle::Main shall appear in the
IGV.
The most interesting phase is Graal Graphs/Before phase Lowering - it
contains all the Graal optimizations, yet the vertexes still resemble bytecode
instructions and are OS architecture neutral.
Try to add field into Main
class called warmWelcome
. Use different message
format when it is true
and different when it is false
. When you look at
the graph you shall see the load of the field value and if
vertex.
Try to make the field final
. The load and if
disappears. Remove the final
modifier and annotate the field as @CompilationFinal
. The result is the same.
Modify the value of the field (in the Main.execute
method), but don't forget
to call CompilerDirectives.transferToInterpreterAndInvalidate()
to tell the
compiler to recompile.
Rather than using these primitive operations, consider using profiles like
ConditionProfile.createBinaryProfile()
. Profiles are built with the above
primitives, yet they are easier to use.
The BooleanNetwork branch contains
a graph with states representing spreading of tumor in a brain.
Let's search the graph for a state that matches certain pattern - null
s are ignored, true
and false
values
must match. The algorithm counts how many nodes in the graph match.
The algorithm can run in regular HotSpot mode as well as in Truffle one entered via CallTarget. When in Truffle mode,
one can apply additional hints - namely @CompilerDirectives.CompilationFinal(dimensions = 1)
, @ExplodeLoop
and CompilerAsserts.partialEvaluationConstant
-
to speed the execution up by expanding the match loop and eliminating the null
checks.
The @ExplodeLoop
annotation can be used to control the amount of generated code. Use it to build a polymorphic cache a phone book mapping between names and numbers. Control the size of the cache (e.g. generated code) fallback to regular (slow) lookup in a HashMap
.
Create simple AST to process array
of numbers. Send the graph to IGV and see how the partial evaluation reduced
it to three load and two plus instructions. Change the example to use Object[]
.
Rewrite Plus.compute
to support not only int
, but also double
and/or any object.
Observe the gigantic IGV graph. Use compiler directives, profiles & etc. to
optimize the graph again. After realizing that it is too complex, use
the Truffle DSL.
Use DSL specializations to do the hard work for you. Remove even more boilerplate code with Truffle DSL type system. Follow the remaining commits, commit-by-commit, of the Truffle DSL branch to learn more.
In this branch, which can be followed commit-by-commit, we implement simple infrastructure around expressions and statements and few control flow constructs to demonstrate how control flow can be implemented in Truffle based AST interpreters.
In this branch, which can be followed commit-by-commit, we explore common patterns to build internal abstractions in Truffle based languages. One of the patterns with special support from Truffle DSL are Truffle libraries, which are also used for implementing the interoperability protocol between different Truffle languages.
- Radixsort for R interpreter
- Jackpot rule integrated in Truffle API (runs as a part of
mx jackpot
command) that checks for common Truffle API usage issues (e.g.,@Child
field assignment outside of constructor without a call toinsert
). - Pick your favourite Python package, run its test suite on CPython and GraalPython, if there are failures specific to GraalPython, try to fix some of them. If it turns out to be too hard, report your findings in a GitHub issue.