GraalVM is a universal virtual machine for running applications written in JVM-based languages (Java, Scala, Clojure, Kotlin), JavaScript, Python, Ruby, R, and LLVM-based languages such as C and C++.
Quite often research projects look like something out of the world, something you won’t probably use in real life. Graal changes the picture: it took the stage out of the blue, and not as a newbie, but as a mature competitor. In this talk, we’ll look at what Graal consists of and what practical use you can get from it right now.
We’ll talk about GraalVM components:
Graal Compiler – an optimizing compiler that supports both dynamic and static compilation and can integrate with the Java HotSpot VM or run standalone. We’ll see how to run existing applications, and what benefit (in numbers) it can bring.
Substrate VM — a framework for ahead-of-time (AOT) compilation into executable images or shared objects. It sounds like a most radical and cheating optimization because it works the way no one else can (under closed-world assumption).
Truffle – language implementation framework for creating languages and instrumentations for GraalVM. Language design is a very complex field, so here we’ll focus on existing languages from GraalVM distribution.
Graal, Truffle, SubstrateVM and other perks: what are those and why do you need them
1. One GraalVM to rule them all
One VM to find them,
One VM to bring them all and in darkness bind
them
In the land of Java where shadows lie.
2. The following is intended to outline our supposed general direction of growth and
development as Java programmers. It is intended for information purposes only, and may not
be incorporated into any contract. It is not a commitment to deliver any material, code, or
functionality, and should not be relied upon in making purchasing decisions. The
development, release and timing of any features or functionality described for products or
services remains at the sole discretion of corresponding companies. Opinions expressed are
solely my own and do not express the views or opinions of my employer.
Информация предназначается чтобы обозначить наше общее направление роста и
развития как Java-программистов. Она предоставляется только в целях ознакомления, и
не может быть использована в контрактах или договорах любого вида. Эта информация
не является попыткой предоставления какого-то материала, кода, или
функциональности, и не должна быть использована в принятии коммерческих решений.
Разработка, выпуск, календарные сроки любых объектов или функциональности,
описанных в контексте продуктов или услуг различных компаний, остается на
усмотрение соответствующих компаний. Описанные в докладе мнения не отражают
позиции работодателя.
Safe Harbor
6. Нужно ли это нам?
НЕТ
ДА!
Обычная бизнес-логика, код в стиле Java 6
• Код в современном стиле (лямбды, стримы, Spring, …)
• Дикое количество мелких объектов (которые не убегают)
• Числодробилки
• Scala
• Смешивание языков в одном проекте
7. ЭТО В ПРОДЕ!
• Twitter
• Несколько финансовых организаций
(пожелавших остаться неизвестными)
• Oracle Labs (GraalVM Enterprise Edition)
25. ДЕНЬ СУРКА
1. Дизайн языка
2. Парсер, интерпретатор AST
3. Люди начинают этим пользоваться
26. ДЕНЬ СУРКА
1. Дизайн языка
2. Парсер, интерпретатор AST
3. Люди начинают этим пользоваться
4. Все тормозит
27. ДЕНЬ СУРКА
1. Дизайн языка
2. Парсер, интерпретатор AST
3. Люди начинают этим пользоваться
4. Все тормозит → разработчик — криворукая тварь
28. ДЕНЬ СУРКА
1. Дизайн языка
2. Парсер, интерпретатор AST
3. Люди начинают этим пользоваться
4. Все тормозит → разработчик — криворукая тварь
5. Мучительная оптимизация
30. ДЕНЬ СУРКА
1. Дизайн языка
2. Парсер, интерпретатор AST
3. Люди начинают этим пользоваться
4. Все тормозит → разработчик — криворукая тварь
5. Мучительная оптимизация
• Может, переписать на C++? (нет, нельзя)
• Байткод, интерпретатор байткода
• Работа с немусором (кэширование)
• Работа с мусором (сборщик)
• … (стандартные оптимизации)
31. МЕЧТЫ
1. Придумал язык
2. Записал на фреймворке
3. Все счастливы
• Быстро работает
• Включая границу языков
• Есть инструменты
• Кишки понятны
33. НЕУЛОВИМЫЙ ДЖО
1.Очень академический
2.Сложный и не очень понятный
3.Частично закрытые исходники
4.Недостаточное освещение в СМИ
• Куча научных работ
• Документации днем с огнем не найдешь
• Очень специальные люди
69. 1. Partial Escape Analysis
2. Более хороший инлайнинг
GraalVM CE vs C2
70. 1. Более лучший инлайнинг (+10 — +150%)
• Java Streams
• BigData (Apache Spark)
2. Автоматическая векторизация SIMD
3. Вынос условий из циклов
4. Дублирование/инлайнинг на merge points
5. cmov вместо бранча, если предикшен плох
GraalVM EE vs CE
74. JEP 243: Java-Level JVM Compiler Interface
http://openjdk.java.net/jeps/243
JEP 317: Experimental Java-Based JIT Compiler
http://openjdk.java.net/jeps/317
75. public interface JVMCICompiler {
int INVOCATION_ENTRY_BCI = -1;
/**
* Services a compilation request. This object should compile the method
to machine code and
* install it in the code cache if the compilation is successful.
*/
CompilationRequestResult compileMethod(CompilationRequest request);
}
76. public class CompilationRequest {
private final ResolvedJavaMethod method;
/**
* Gets the method to be compiled.
*/
public ResolvedJavaMethod getMethod() {
return method;
}
}
78. src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java
/**
* Installs the result of a compilation into the code cache.
*
* @param target the target where this code should be installed
* @param compiledCode the result of a compilation
* @param code the details of the installed CodeBlob are written to this object
* @return the outcome of the installation which will be one of
native int installCode(TargetDescription target,
HotSpotCompiledCode compiledCode,
InstalledCode code,
HotSpotSpeculationLog speculationLog);
final class CompilerToVM {
79. Context-sensitive trace inlining for Java
• Одна из самых старых оптимизаций (исследование)
• Позволяет понять, какие оптимизации можно делать
• Сейчас не используется
(мешает высоко полиморфный код)
https://www.sciencedirect.com/science/article/pii/S1477842413000146
99. public int ArrayList.indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
100. public class LineBuilder {
private final Appendable buffer;
public LineBuilder(Appendable buffer) {
this.buffer = buffer;
}
public void appendLine(CharSequence sequence)
throws Exception {
buffer.append(sequence);
buffer.append("n");
}
}
105. public int ArrayList.indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
113. abstract class Node {
// Запускаем операцию, возвращаем результат
public abstract Object execute(Frame f);
// Родительский узел в AST
private Node parent;
// Заменить этот узел другим
protected void replace(Node newNode);
}
114.
115. abstract class Node {
public abstract Object execute(Frame f);
public abstract int executeInt(Frame f)
throws UnexpectedResultException;
public abstract double executeDouble(Frame f)
throws UnexpectedResultException;
}
119. class IntegerAddNode extends BinaryNode {
public Object execute(Frame frame) {
Object a = left.execute(frame);
if (!(a instanceof Integer)) {
// Перезаписать ноду, запустить перезаписанное
// подав на вход уже вычисленное left
}
Object b = right.execute(frame);
if (!(b instanceof Integer)) {
// Перезаписать ноду, запустить перезаписанное
// подав на вход уже вычисленное right
}
// Здесь могла бы быть ваша реклама проверка на переполнение.
return (Integer) a + (Integer) b;
}
}
120. class IntegerAddNode extends BinaryNode {
public int executeInt(Frame frame)
throws UnexpectedResultException {
int a;
try {
a = left.executeInt(frame);
} catch (UnexpectedResultException ex) {
// Перезаписать ноду и запустить с left
}
int b;
try {
b = right.executeInt(frame);
} catch (UnexpectedResultException ex) {
// Перезаписать и запустить с left и right
}
// Здесь могла бы быть ваша реклама проверка на переполнение.
return a + b;
}
121. function foo(a, b, c, d) {
return add(a, b) + add(c, d);
}
function add(a, b) {
return a + b;
}
foo(1, 2, "Маша", "Петя");
132. function foo(a, b, c, d) {
var x; var i;
for (i = 0; i < n; i++) {
x += add (a, b);
}
var y; var i2;
for (i2 = 0; i2 < n; i2++) {
y += add (a, b);
}
return x + y;
}
144. Основные проблемы
• Использование наиболее подходящего языка
(можно смешивать произвольные языки)
• Миграция между языками, поддержка легаси
(взять две существующие кодовые базы и развивать их параллельно)
(без написания костыльных переходников и врапперов)
• Избежать потерь при пересечении границы языка
145. Доступные языки в GraalVM
• Java
• JavaScript
• Ruby
• R
Доступные языки вообще
• С, C++, Fortran (Sulong – LLVM bitcode)
• Python (ZipPy)
• Можно написать свой
https://gist.github.com/smarr/d1f8f2101b5cc8e14e12
One VM to Rule Them All by Thomas Wuerthinger
151. Node.JS
var fs = require('fs');
var vm = require('vm');
var includeInThisContext = function(path) {
var code = fs.readFileSync(path);
vm.runInThisContext(code, path);
}.bind(this);
includeInThisContext(__dirname+"/shared.js");
validate(1);
156. Зачем нужна Java для генерации фронта?
• Генерация стабов и прокси-классов для общения по HTTP
• Состав поставки приложения (набор фич)
• Статическая генерация по Java-источникам (Hibernate)
• Перенос данных об окружении (номер версии из Maven)
• Причины возникают по ходу дела
164. loaders/preload.js
module.exports = function main(source) {
this.cacheable();
var MyString = Java.type("java.lang.String");
var buttonCaption = new MyString("Сказать ещё дичи!");
return `window.buttonCaption="${buttonCaption}";` + `${source}`;
};
204. JDK 11 - не всё адаптировано
JDK 8 - устарел
mx igv
Error occurred during initialization of boot layer
java.lang.module.FindException: Module java.xml.bind not found