From the translator: GraalVM is a new, interesting technology, but on Habré there are not many articles on it that could show examples of the features of Graal. The article below is not just a listing of what GraalVM can do, but also a small workshop similar to the one that Chris Seaton and Oleg Shelayev performed on Oracle CodeOne 2018. Following the author, I urge you - try to make examples from the article, this is really interesting.
GraalVM has a lot of different things, and if you have heard this name before, or even seen reports, there are still a lot of things that you probably don’t know yet, but which GraalVM can do. In this article we will look at the various possibilities that GraalVM provides and show what can be done with their help.
You can do everything that is shown in this article using GraalVM 1.0.0 RC1, which is available at the link from the GraalVM website . I used the Enterprise Edition on MacOS, but the code that is written here will work on Linux and on GraalVM Community Edition.
When you read the article, run the programs that are described in it! The code can be downloaded from GitHub .
After downloading from http://graalvm.org/downloads, I added the path to the GraalVM executables in $PATH
. By default, this adds support for running Java and JavaScript.
$ git clone https://github.com/chrisseaton/graalvm-ten-things.git $ cd foo $ tar -zxf graalvm-ee-1.0.0-rc1-macos-amd64.tar.gz # or graalvm-ee-1.0.0-rc1-linux-amd64.tar.gz on Linux $ export PATH=graalvm-1.0.0-rc1/Contents/Home/bin:$PATH # or PATH=graalvm-1.0.0-rc1/bin:$PATH on Linux
GraalVM comes with built-in support for JavaScript and contains a package manager called gu
, which adds the ability to install support for languages other than Java and JavaScript. I additionally installed Ruby, Python and R, they are downloaded from GitHub.
$ gu install -c org.graalvm.ruby $ gu install -c org.graalvm.python $ gu install -c org.graalvm.R
Now, if you run the java
or js
command, you will see the GraalVM versions of these engines.
$ java -version java version "1.8.0_161" Java(TM) SE Runtime Environment (build 1.8.0_161-b12) GraalVM 1.0.0-rc1 (build 25.71-b01-internal-jvmci-0.42, mixed mode) $ js --version Graal JavaScript 1.0 (GraalVM 1.0.0-rc1)
“Graal” in GraalVM is the name of the compiler. He alone is created to rule by all ! This means that this is a single compiler implementation written in the form of a library that can be used for a large number of different things. For example, we use Graal to compile both ahead-of-time and just-in-time to compile code written in various programming languages, including for different processor architectures.
The first and easiest way to use Graal is to use it as a Java JIT compiler.
As an example, we will use a program that gives out 10 of the most frequently encountered words in a document. The program uses the capabilities of the modern Java language, such as Streams and collections.
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; public class TopTen { public static void main(String[] args) { Arrays.stream(args) .flatMap(TopTen::fileLines) .flatMap(line -> Arrays.stream(line.split("\\b"))) .map(word -> word.replaceAll("[^a-zA-Z]", "")) .filter(word -> word.length() > 0) .map(word -> word.toLowerCase()) .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) .entrySet().stream() .sorted((a, b) -> -a.getValue().compareTo(b.getValue())) .limit(10) .forEach(e -> System.out.format("%s = %d%n", e.getKey(), e.getValue())); } private static Stream<String> fileLines(String path) { try { return Files.lines(Paths.get(path)); } catch (IOException e) { throw new RuntimeException(e); } } }
GraalVM includes the javac
compiler, but for this demo there is no difference, use it or the standard compiler. Therefore, you can use the standard javac
compiler if you want.
$ javac TopTen.java
If we run the java
command, which is included in GraalVM, then the Graal JIT compiler will be used automatically - no need to take any additional steps. I will use the time
command in order to get real data about the time that was spent on executing the program from beginning to end, instead of deploying a complex microbenchmark. There will also be used a large amount of input data so that there are no insinuations about the saved couple of seconds here or there. File large.txt
- 150 MB.
$ make large.txt $ time java TopTen large.txt sed = 502701 ut = 392657 in = 377651 et = 352641 id = 317627 eu = 317627 eget = 302621 vel = 300120 a = 287615 sit = 282613 real 0m17.367s user 0m32.355s sys 0m1.456s
Graal is written in Java, not C ++, like most other JIT compilers for Java. We think that this allows us to improve it faster than existing compilers, complementing new powerful optimizations (such as partial escape analysis, for example) that are not available in the standard JIT compiler for HotSpot.
And it can make your java programs much faster.
For comparison purposes, in order to run programs without the Graal JIT compiler, I will use the -XX:-UseJVMCICompiler
. JVMCI is the interface between Graal and JVM. You can also run an example on a standard JVM and compare the results.
$ time java -XX:-UseJVMCICompiler TopTen large.txt sed = 502701 ut = 392657 in = 377651 et = 352641 id = 317627 eu = 317627 eget = 302621 vel = 300120 a = 287615 sit = 282613 real 0m23.511s user 0m24.293s sys 0m0.579s
This test shows that Graal runs our Java program in about three-quarters of the time it takes to run it with a standard HotSpot compiler. Where we believe that a few percent improvement in productivity is a significant achievement, 25% is a big deal.
Twitter is the only company that currently uses Graal on “combat” servers , and they say that this is justified for them, in terms of saving real money. Twitter uses Graal to execute applications written in Scala - Graal runs at the JVM bytecode level, i.e. applicable to any JVM language.
This is the first use of GraalVM — simply replacing the JIT compiler with a better version for your existing Java applications.
The strengths of the Java platform are particularly evident when dealing with long-running processes and peak loads. In contrast, short-lived processes suffer from a long start-up time and relatively large memory usage.
For example, if we run the application from the previous section, submitting to it a much smaller amount of input data — about 1 KB instead of 150 MB — then it seems to take an unreasonably long time and quite a lot of memory — about 60 MB, in order to process such a small file. . Use the -l
option to print out the amount of memory used in addition to the execution time.
$ make small.txt $ /usr/bin/time -l java TopTen small.txt # -v on Linux instead of -l sed = 6 sit = 6 amet = 6 mauris = 3 volutpat = 3 vitae = 3 dolor = 3 libero = 3 tempor = 2 suscipit = 2 0.32 real 0.49 user 0.05 sys 59846656 maximum resident set size
GraalVM gives us a tool that solves this problem. We said that Graal is a compiler library and it can be used in many different ways. One of them is compiling ahead-of-time into a platform -dependent executable image, instead of just-in-time compiling at runtime. This is similar to how a regular compiler works, such as gcc
.
$ native-image --no-server TopTen classlist: 1,513.82 ms (cap): 2,333.95 ms setup: 3,584.09 ms (typeflow): 4,642.13 ms (objects): 3,073.58 ms (features): 156.34 ms analysis: 8,059.94 ms universe: 353.02 ms (parse): 1,277.02 ms (inline): 1,412.08 ms (compile): 10,337.76 ms compile: 13,776.23 ms image: 2,526.63 ms write: 1,525.03 ms [total]: 31,439.47 ms
This command creates a platform- topten
executable file called topten
. This file does not launch the JVM, it is not linked to the JVM and it generally does not include the JVM in any way. The native-image
command truly compiles your Java code and the Java libraries you use into fully-fledged machine code. For runtime components, such as the garbage collector, we run our own new VM, called SubstrateVM, which, like Graal, is also written in Java.
If you look at the dependencies that topten
uses, you will see that these are only standard system libraries. We can only transfer this one file to a system on which the JVM has never been installed and run it there to verify that it does not use the JVM or any other files. Topten
also quite small - the executable code takes up less than 6 MB.
$ otool -L topten # ldd topten on Linux topten: .../CoreFoundation.framework ... .../libz.1.dylib ... .../libSystem.B.dylib ... $ du -h topten 5.7M topten
If we run this executable file, we will see that it runs about an order of magnitude faster and uses about an order of magnitude less memory than the same program running under the JVM. The launch is so fast that you won't notice how long it took. If you use the command line, you will not feel the pause that is usually present when you run a small, short-lived program under the JVM
$ /usr/bin/time -l ./topten small.txt sed = 6 sit = 6 amet = 6 mauris = 3 volutpat = 3 vitae = 3 dolor = 3 libero = 3 tempor = 2 suscipit = 2 0.02 real 0.00 user 0.00 sys 4702208 maximum resident set size
There are some limitations to the native-image
utility. So, at compile time you should have all the classes, there are also limitations in using the Reflection API. But there are some additional advantages over basic compilation, such as running static initializers at compile time. In this way, the amount of work performed each time an application is loaded is reduced.
This is the second application of GraalVM - the distribution and execution of existing Java programs, with a quick start and less memory consumption. This method eliminates configuration problems such as finding the right jar at runtime, and also allows you to create smaller Docker images.
Along with Java, GraalVM includes new implementations of JavaScript, Ruby, R, and Python engines. They are written using a new framework called Truffle . This framework makes it possible to create interpreters of languages that are both simple and high-performance. When you write an interpreter of a language using Truffle, it will automatically use Graal to provide JIT compilation for your language. Thus, Graal is not only a JIT compiler and an AOT compiler for Java, it can also be a JIT compiler for JavaScript, Ruby, R and Python.
Support for third-party languages in GraalVM aims to be a transparent replacement for existing engines of different languages. For example, we can install the “color” module for Node.js:
$ npm install --global color ... + color@3.0.0 added 6 packages in 14.156s
Then write a program using this module to convert RGB HTML colors to HSL:
var Color = require('color'); process.argv.slice(2).forEach(function (val) { print(Color(val).hsl().string()); });
And run it in the usual way:
$ node color.js '#42aaf4' hsl(204.89999999999998, 89%, 60.8%)
The performance engines of different languages in GraalVM work together - there is an API that allows you to run code from one language in a program written in another language. And it allows you to write multilingual programs - programs written in more than one programming language.
This may be necessary if you write most of your program in one language, but would like to use a library written in another programming language. For example, imagine that we need to write an application to convert the color name from CSS into its numeric representation in Node.js, but we want to use the Ruby color library instead of writing the conversion ourselves.
var express = require('express'); var app = express(); color_rgb = Polyglot.eval('ruby', ` require 'color' Color::RGB `); app.get('/css/:name', function (req, res) { color = color_rgb.by_name(req.params.name).html() res.send('<h1 style="color: ' + color + '" >' + color + '</h1>'); }); app.listen(8080, function () { console.log('serving at http://localhost:8080') });
In this code, we wrote that we had to execute Ruby code as a string, but note that we didn’t do much here - we just connected the libraries and then returned the Ruby object. In Ruby, we would use it like this: Color::RGB.by_name (name).html
. If you look at how color_rgb
used further in JavaScript, you will see that we actually call the same methods from JavaScript, although these are Ruby objects and methods. And we pass them as JavaScript strings and connect the result, which is a Ruby string, with a JavaScript string.
Install both dependencies - Ruby and JavaScript.
$ gem install color Fetching: color-1.8.gem (100%) Successfully installed color-1.8 1 gem installed $ npm install express + express@4.16.2 updated 1 package in 10.393s
Then you need to run node
with a couple of additional options: --polyglot
to say that we need access to other languages and --jvm
, because the executable node
image by default does not include anything other than JavaScript.
$ node --polyglot --jvm color-server.js serving at http://localhost:8080
And then go to the URL http: // localhost: 8080 / css / orange (or some other color), as usual, in your browser.
Let's try to make a more serious example that uses more languages and modules.
JavaScript does not support very large integers. I found several modules like big-integer , but they are all ineffective, because store the components of the number as javascript floating point numbers. The BigInteger
class in Java is more efficient; let's use it to do several arithmetic operations with large integers.
There is also no built-in support for drawing graphs in JavaScript, while R perfectly draws graphics. Let's use the svg
module from R to draw a scatter plot of a trigonometric function in 3D space.
In both cases, we will use the API to support multilingualism from GraalVM (hereinafter referred to as Polyglot API) and we can simply insert the results of executing programs in other languages in JavaScript.
const express = require('express') const app = express() const BigInteger = Java.type('java.math.BigInteger') app.get('/', function (req, res) { var text = 'Hello World from Graal.js!<br> ' // Using Java standard library classes text += BigInteger.valueOf(10).pow(100) .add(BigInteger.valueOf(43)).toString() + '<br>' // Using R interoperability to create graphs text += Polyglot.eval('R', `svg(); require(lattice); x <- 1:100 y <- sin(x/10) z <- cos(x^1.3/(runif(1)*5+10)) print(cloud(x~y*z, main="cloud plot")) grDevices:::svg.off() `); res.send(text) }) app.listen(3000, function () { console.log('Example app listening on port 3000!') })
Open http: // localhost: 3000 / in your browser to see the result:
This is the third thing we can do with GraalVM — run programs written in several languages and use the modules from these languages together in one program. We present this as a way to unify runtime environments and libraries — you can use the programming language that you think is best suited for solving the current problem and any library you want, regardless of what programming language it is written in.
Another language that GraalVM supports is C. GraalVM can execute C code in the same way that it executes programs written in JavaScript and Ruby.
What GraalVM actually supports is the launch of code resulting from the execution of the LLVM utilities, i.e. bitcode, not direct C support. This means that you can use existing tools for C and other languages that support LLVM, such as C ++, Fortran, and potentially more languages in the future. For ease of demonstration, I run a special version of gzip , which is compiled into a single file (this version is supported by Stephen McCamant ). This is just the gzip
source code and autoconf
configuration combined into one file for simplicity. I had to patch a couple of things to make it work on macOS and with clang, but I didn't do anything specifically to support GraalVM.
We compile gzip using the standard clang
(LLVM compiler for C) and want it to make us an LLVM bitcode, not a platform-specific build, because GraalVM will not launch it. I am using clang
4.0.1.
$ clang -c -emit-llvm gzip.c
And then run the result, directly using the lli command (interpreter of the LLVM bitcode) from GraalVM. Let's try to compress the file using my gzip system archiver, and then unzip it using gzip running under GraalVM.
$ cat small.txt Lorem ipsum dolor sit amet... $ gzip small.txt $ lli gzip.bc -d small.txt.gz $ cat small.txt Lorem ipsum dolor sit amet...
Implementations of Ruby and Python in GraalVM use the same technique to run extensions written in C for these languages. This means that you can run these extensions inside a VM and this allows us to maintain high execution speed, even if we use outdated platform-specific extension interfaces.
This is the fourth way to use GraalVM — launch programs written in platform-specific languages, such as C or C ++, as well as launching extensions to languages such as Python or Ruby that the JVM implementations of these languages, such as JRuby, are not able to do.
If you are programming in Java, then you probably use very high-quality tools such as IDE, debuggers, and profilers. Not all languages have such a set of tools, but you can get such a set if you use languages that are supported by GraalVM.
Support for all languages in GraalVM (except Java, currently) is implemented using a common framework - Truffle. This allows us to make functionality, for example, a debugger, once and use it for all languages.
To try this, we will write the simplest program - FizzBuzz , because it is visual (prints something on the screen) and there are clear branches in it that are used only in some iterations. Thus, it will be easier for us to set breakpoints. Let's start with javascript implementation.
function fizzbuzz(n) { if ((n % 3 == 0) && (n % 5 == 0)) { return 'FizzBuzz'; } else if (n % 3 == 0) { return 'Fizz'; } else if (n % 5 == 0) { return 'Buzz'; } else { return n; } } for (var n = 1; n <= 20; n++) { print(fizzbuzz(n)); }
Run the program as usual, using the js
utility, under GraalVM.
$ js fizzbuzz.js 1 2 Fizz 4 Buzz Fizz
We can also run a program with the - --inspect
flag. This will give us a link that you can open in Chrome and stop the program in the debugger.
$ js --inspect fizzbuzz.js Debugger listening on port 9229. To start debugging, open the following URL in Chrome: chrome-devtools://devtools/bundled/inspector.html?ws=127.0.0.1:9229/6c478d4e-1350b196b409
You can put a breakpoint in the FizzBuzz code and then continue execution. When the program interrupts execution, we will see the value of the variable n
in the debugger and we can continue the execution of the program or study the debugger interface.
The Chrome debugger is usually used for JavaScript, but for GraalVM in JavaScript there is nothing different from other languages. The --inspect
flag --inspect
also available and works in the implementation of Python, Ruby and R. I will not show you the source code of each program, but they run the same way and you get the same debugger in Chrome for each of them.
$ graalpython --jvm --inspect fizzbuzz.py
$ ruby --inspect fizzbuzz.rb
$ Rscript --inspect fizzbuzz.r
Another tool that you probably know from Java is VisualVM. It provides a user interface, using which you can join a running JVM on your local machine or via the network to inspect various aspects of program execution, such as memory usage or execution threads.
GraalVM includes VisualVM as a standard jvisualvm
utility.
$ jvisualvm &> /dev/null &
If we run VisualVM while Java is running TopTen
Java, we can observe the memory usage or, for example, take a snapshot of the memory contents and see what types of objects we use memory on the heap.
$ java TopTen large.txt
I wrote this Ruby program to generate some garbage in memory at runtime.
require 'erb' x = 42 template = ERB.new <<-EOF The value of x is: <%= x %> EOF loop do puts template.result(binding) end
If you run the standard Ruby implementation on JVM - JRuby, then you will be disappointed with VisualVM, because you will see only internal Java objects instead of objects of your language.
If you are using the version of Ruby for GraalVM, then VisualVM recognizes Ruby objects. We need to use the - --jvm
option to use VisualVM, since it does not support native versions of Ruby.
$ ruby --jvm render.rb
, , Java , , , Summary, Ruby Heap Ruby .
Truffle — - Nexus . Truffle , , API Truffle' , , Truffle, .
, GraalVM — , . Truffle GraalVM , VisualVM.
, , , Java . API org.graalvm.polyglot
, .
import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Value; public class ExtendJava { public static void main(String[] args) { String language = "js"; try (Context context = Context.newBuilder().allowNativeAccess(true).build()) { for (String arg: args) { if (arg.startsWith("-")) { language = arg.substring(1); } else { Value v = context.eval(language, arg); System.out.println(v); } } } } }
javac
java
GraalVM, org.graalvm.*
classpath
, .. .
$ javac ExtendJava.java $ java ExtendJava '14 + 2' 16 $ java ExtendJava -js 'Math.sqrt(14)' 3.7416573867739413 $ java ExtendJava -python '[2**n for n in range(0, 8)]' [1, 2, 4, 8, 16, 32, 64, 128] $ java ExtendJava -ruby '[4, 2, 3].sort' [2, 3, 4]
, — , node
ruby
, GraalVM.
GraalVM — Java . Polyglot API “” Java , .
GraalVM , , — , , GraalVM, - . , JavaScript , V8, Python — CPython , .. . GraalVM — Polyglot .
GraalVM, , JavaScript. Polyglot , , :
$ graalvm-1.0.0-rc1/Contents/Home/jre/lib/svm/bin/rebuild-images libpolyglot
C, , , GraalVM, . ExtendJava
, , .
#include <stdlib.h> #include <stdio.h> #include <polyglot_api.h> int main(int argc, char **argv) { graal_isolate_t *isolate = NULL; graal_isolatethread_t *thread = NULL; if (graal_create_isolate(NULL, &isolate) != 0 || (thread = graal_current_thread(isolate)) == NULL) { fprintf(stderr, "initialization error\n"); return 1; } poly_context context = NULL; if (poly_create_context(thread, NULL, 0, &context) != poly_ok) { fprintf(stderr, "initialization error\n"); return 1; } char* language = "js"; for (int n = 1; n < argc; n++) { if (argv[n][0] == '-') { language = &argv[n][1]; } else { poly_value result = NULL; if (poly_context_eval(thread, context, language, "unicalc", argv[n], &result) != poly_ok) { fprintf(stderr, "eval error\n"); return 1; } char buffer[1024]; size_t length; if (poly_value_to_string_utf8(thread, result, buffer, sizeof(buffer), &length) != poly_ok) { fprintf(stderr, "to string error\n"); return 1; } buffer[length] = '\0'; printf("%s\n", buffer); poly_destroy_handle(thread, result); } } return 0; }
, polyglot GraalVM. , , JVM.
$ clang -Igraalvm-1.0.0-rc1/Contents/Home/jre/lib/polyglot / -rpath graalvm-1.0.0-rc1/Contents/Home / -Lgraalvm-1.0.0-rc1/Contents/Home/jre/lib/polyglot / -lpolyglot extendc.c -o extendc $ otool -L extendc extendc: .../libpolyglot.dylib ... .../libSystem.B.dylib ...
$ ./extendc '14 + 2' 16 $ ./extendc -js 'Math.sqrt(14)' 3.7416573867739413 $ ./extendc -python '[2**n for n in range(0, 8)]' [1, 2, 4, 8, 16, 32, 64, 128]
, GraalVM — - , , GraalVM.
Java , , , , - , . Java - , JVM , .
GraalVM Java , , - , . , , Java JVM.
, Apache SIS , ( ) . SIS 0.8, http://sis.apache.org/ jar.
import org.apache.sis.distance.DistanceUtils; public class Distance { public static void main(String[] args) { final double aLat = Double.parseDouble(args[0]); final double aLong = Double.parseDouble(args[1]); final double bLat = Double.parseDouble(args[2]); final double bLong = Double.parseDouble(args[3]); System.out.printf("%.2f km%n", DistanceUtils.getHaversineDistance(aLat, aLong, bLat, bLong)); } public static double distance(IsolateThread thread, double aLat, double aLong, double bLat, double bLong) { return DistanceUtils.getHaversineDistance(aLat, aLong, bLat, bLong); } }
, -
$ javac -cp sis.jar -parameters Distance.java $ java -cp sis.jar:. Distance 51.507222 -0.1275 40.7127 -74.0059 5570.25 km
, topten
.
$ native-image --no-server -cp sis.jar:. Distance ... $ ./distance 51.507222 -0.1275 40.7127 -74.0059 5570.25 km
, . , @CEntryPoint
... import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.c.function.CEntryPoint; public class Distance { ... @CEntryPoint(name = "distance") public static double distance(IsolateThread thread, double a_lat, double a_long, double b_lat, double b_long) { return DistanceUtils.getHaversineDistance(a_lat, a_long, b_lat, b_long); } ... }
javac
, GraalVM API classpath
. C .
$ native-image --no-server -cp sis.jar:. -H:Kind=SHARED_LIBRARY \ -H:Name=libdistance $ otool -L libdistance.dylib # .so on Linux libdistance.dylib: .../libdistance.dylib ... .../CoreFoundation.framework ... .../libz.1.dylib ... .../libSystem.B.dylib ... $ du -h libdistance.dylib 4.8M libdistance.dylib
, . , : VM , , .
#include <stdlib.h> #include <stdio.h> #include <libdistance.h> int main(int argc, char **argv) { graal_isolate_t *isolate = NULL; graal_isolatethread_t *thread = NULL; if (graal_create_isolate(NULL, &isolate) != 0 || (thread = graal_current_thread(isolate)) == NULL) { fprintf(stderr, "initialization error\n"); return 1; } double a_lat = strtod(argv[1], NULL); double a_long = strtod(argv[2], NULL); double b_lat = strtod(argv[3], NULL); double b_long = strtod(argv[4], NULL); printf("%.2f km\n", distance(thread, a_lat, a_long, b_lat, b_long)); return 0; }
, ( LD_LIBRARY_PARTH=.
Linux)
$ clang -I. -L. -ldistance distance.c -o distance $ otool -L distance distance: .../libdistance.dylib ... .../libSystem.B.dylib ... $ ./distance 51.507222 -0.1275 40.7127 -74.0059 5570.25 km
GraalVM — java - , JVM
Polyglot — Oracle. Oracle Database Multilingual Engine (MLE), GraalVM SQL.
, front-end, JavaScript email , JavaScript validator
. - , SQL PL/SQL. , .
MLE Docker :
https://oracle.imtqy.com/oracle-db-mle/releases/0.2.7/docker/
Docker Daemon.
$ docker load --input mle-docker-0.2.7.tar.gz
, Docker, , ( ), Bash .
$ docker run mle-docker-0.2.7 $ docker ps $ docker exec -ti <container_id> bash -li
sqlplus
( SQL ), Bash, , , .
$ sqlplus scott/tiger@localhost:1521/ORCLCDB
, sqlplus
. , Bash Docker, dbjs
, . sqlplus
.
$ npm install validator $ npm install @types/validator $ dbjs deploy -u scott -p tiger -c localhost:1521/ORCLCDB validator $ sqlplus scott/tiger@localhost:1521/ORCLCDB
validator
SQL .
SQL> select validator.isEmail('hello.world@oracle.com') from dual; VALIDATOR.ISEMAIL('HELLO.WORLD@ORACLE.COM') ------------------------------------------- 1 SQL> select validator.isEmail('hello.world') from dual; VALIDATOR.ISEMAIL('HELLO.WORLD') -------------------------------- 0
, GraalVM — , GraalVM, Oracle. , front-end back-end, , , .
Oracle Labs JavaScript, R, Ruby, Python C , Truffle, GraalVM.
Truffle — java , (AST). AST — , , , , , . , , Truffle Graal JIT , AST .
Truffle, GraalVM , , DSL. Truffle Graal , , Truffle — GraalVM. , , , , . , , . Oracle labs Ruby , , .
, , , SimpleLanguage — Truffle, JavaScript. , , , , , if .
, Truffle Oracle Labs, SmallTalk , Newspeak Lisp . Lisp , .
GraalVM — , , . , , , , .
GraalVM, http://www.graalvm.org/ . , , .
, , . , GraalVM @ChrisGSeaton @shelajev .
: Oleg Šelajev , Olya Gupalo Doug Simon
Source: https://habr.com/ru/post/433432/
All Articles