Upgrade to Pro — share decks privately, control downloads, hide ads and more …

¿Qué es eso de GraalVM?

¿Qué es eso de GraalVM?

Traspas de la presentación sobre GraalVM para la Commit Conf 2019, impartida por César Sapetti y Daniel Díaz.

Avatar for danidiaz_softtek

danidiaz_softtek

November 22, 2019
Tweet

Other Decks in Programming

Transcript

  1. ¿QUIÉNES SOMOS? ¿QUIÉNES SOMOS? César Sapetti González Daniel Díaz Carrete

    @cesar_sapetti cesar.sapetti@so tek.com @DiazCarrete daniel.diazc@so tek.com
  2. JUST IN TIME COMPILATION (JIT) JUST IN TIME COMPILATION (JIT)

    En los inicios de Java, el rendimiento era lento porque el bytecode resultado de la compilación del código fuente era interpretado por la JVM, instrucción a instrucción. Por ello se decide introducir una compilación a código nativo en tiempo de ejecución.
  3. JUST IN TIME COMPILATION (JIT) JUST IN TIME COMPILATION (JIT)

    Los compiladores JIT aceptan bytecode de la VM y producen código nativo en tiempo de ejecución Código fuente Compilación Bytecode JIT Código nativo Tiempo de ejecución
  4. COMPILACIÓN JIT: PROS COMPILACIÓN JIT: PROS Analiza la ejecución y,

    en base a ello, permite realizar optimizaciones Elimina código inalcanzable Sustituye expresiones constantes por su valor calculado Reemplaza llamadas a métodos por su definición Puede deshacer optimizaciones que no tienen el efecto esperado
  5. AHEAD OF TIME COMPILATION AHEAD OF TIME COMPILATION (AOT) (AOT)

    Como alternativa a JIT, existe la compilación anticipada.
  6. AHEAD OF TIME COMPILATION AHEAD OF TIME COMPILATION (AOT) (AOT)

    Genera código nativo a partir del bytecode mediante un analisis puramente estático, sin depender de una ejecución previa. Código fuente Compilación Bytecode AOT Código nativo
  7. AOT: PROS AOT: PROS Inicio más rápido Menor uso de

    memoria Los ejecutables son autocontenidos
  8. AOT: CONTRAS AOT: CONTRAS No se pueden realizar optimizaciones guiadas

    por el comportamiento dinámico de la aplicación Se necesita compilar para cada arquitectura No soporta fácilmente técnicas de metaprogramación (reflection, anotaciones…)
  9. AOT: USO AOT: USO Programas de “corta” duración donde la

    latencia inicial importa (herramientas de línea de comandos, serverless…)
  10. GRAAL GRAALVM VM ES UNA MÁQUINA VIRTUAL ES UNA MÁQUINA

    VIRTUAL POLÍGLOTA DE ALTO POLÍGLOTA DE ALTO RENDIMIENTO DE ORACLE RENDIMIENTO DE ORACLE
  11. MÁQUINA VIRTUAL MÁQUINA VIRTUAL ES UNA VERSIÓN DE LA JVM

    Y, ES UNA VERSIÓN DE LA JVM Y, COMO TAL, EJECUTA BYTECODE COMO TAL, EJECUTA BYTECODE
  12. POLÍGLOTA POLÍGLOTA PERMITE DEFINIR MÚLTIPLES PERMITE DEFINIR MÚLTIPLES LENGUAJES Y

    COMBINARLOS EN LENGUAJES Y COMBINARLOS EN UN MISMO PROCESO UN MISMO PROCESO
  13. ALTO RENDIMIENTO ALTO RENDIMIENTO INCLUYE OPTIMIZACIONES EN LA INCLUYE OPTIMIZACIONES

    EN LA COMPILACIÓN “JUST IN TIME” COMPILACIÓN “JUST IN TIME”
  14. DE ORACLE DE ORACLE EXISTE UNA VERSIÓN GRATUITA Y EXISTE

    UNA VERSIÓN GRATUITA Y OTRA DE PAGO OTRA DE PAGO
  15. ARQUITECTURA ARQUITECTURA Java, Scala, Kotlin, Clojure JS, Python, Ruby, R

    C, C++ Sulong Truffle framework Graal compiler JVM Compiler Interface (JVMCI) Substrate VM Java HotSpot VM
  16. COMPILADOR GRAAL COMPILADOR GRAAL Java, Scala, Kotlin, Clojure JS, Python,

    Ruby, R C, C++ Sulong Truffle framework Graal compiler JVM Compiler Interface (JVMCI) Substrate VM Java HotSpot VM
  17. COMPILADOR GRAAL COMPILADOR GRAAL No confundir con GraalVM! Graal es

    el compilador JIT Los compiladores JIT anteriores (C1 y C2) estaban escritos en C++ como el resto de la JVM
  18. ESCRITO EN JAVA ESCRITO EN JAVA Más fácil de mantener

    Mejores herramientas para desarrollo y depuración Errores en C++ pueden provocar cuelgues en la JVM e incluso fallos de seguridad (☣ ☣ ) mientras que Java es un lenguaje seguro Mejoras en la generación de código de Graal pueden beneficiar al propio compilador Buffer Overflow
  19. JVM COMPILER INTERFACE JVM COMPILER INTERFACE (JVMCI) (JVMCI) Introducido en

    Java 9 ( ) Interfaz estándar por la cual la JVM se comunica con los compiladores JIT (Graal en nuestro caso) Permite a cualquiera implementar su propio JIT JEP 243 -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler -Djvmci.Compiler=<name of compiler>
  20. “BOOTSTRAPING” GRAAL “BOOTSTRAPING” GRAAL Graal puede repercutir negativamente en el

    tiempo de inicio de la JVM Graal está escrito en Java, eso significa que tiene que compilar su propio bytecode Hasta que no se compile a sí mismo, se estará ejecutando en modo interpretado y funcionará lentamente
  21. “BOOTSTRAPING” GRAAL “BOOTSTRAPING” GRAAL Solución: Una versión de Graal compilada

    AOT a código nativo Las compilaciones JIT serán rápidas desde el principio Se usa por defecto en las últimas versiones de GraalVM LIBGRAAL
  22. SUBSTRATE VM SUBSTRATE VM Java, Scala, Kotlin, Clojure JS, Python,

    Ruby, R C, C++ Sulong Truffle framework Graal compiler JVM Compiler Interface (JVMCI) Substrate VM Java HotSpot VM
  23. SUBSTRATE VM SUBSTRATE VM Máquina Virtual “reducida” pensada para ejecutar

    aplicaciones compiladas AOT Viene incluida en los ejecutables nativos que genera native-image
  24. SUBSTRATE VM SUBSTRATE VM Proporciona funcionalidades como: Recolección de basura

    Gestión de hilos No soporta funcionalidades como: Carga dinámica de clases Security Manager JMX
  25. NATIVE-IMAGE NATIVE-IMAGE Herramienta de línea de comandos para compilar aplicaciones

    AOT Genera ejecutables autocontenidos (“imágenes nativas”) “Hipótesis de mundo cerrado”: todas las clases que existan en tiempo de ejecución tienen que ser accesibles en el momento de la compilación
  26. Main.class Foo.class Bar.class public static void main(String [] argv) {

    Foo foo = new Foo(); URLClassLoader loader = new URLClassLoader(new URL[] { ... }); Class c = loader.loadClass("Bar"); Object bar = c.newInstance(); } $ native-image Main
  27. NATIVE-IMAGE NATIVE-IMAGE Después de un análisis estático que encuentra todas

    las clases existentes, el bytecode es compilado a código nativo usando Graal El ejecutable final incluye Substrate VM como “runtime” No se pueden usar profilers, depuradores… Inicializadores estáticos durante el build, no en tiempo de ejecución Limitaciones
  28. TRUFFLE TRUFFLE Java, Scala, Kotlin, Clojure JS, Python, Ruby, R

    C, C++ Sulong Truffle framework Graal compiler JVM Compiler Interface (JVMCI) Substrate VM Java HotSpot VM
  29. Un framework para la creación de nuevos lenguajes en la

    JVM. Javascript Ruby Python R …o tu propio lenguaje!
  30. Ya existían lenguajes de scripting en la JVM (Jython, JRuby,

    Nashorn…) qué es lo que hace especial a Truffle?
  31. Infraestructura común para construir lenguajes y evitar comenzar siempre desde

    cero. Herramientas compartidas, por ejemplo depuradores y profilers. Intérpretes de alto rendimiento. Fácil interoperación entre lenguajes (poliglotismo).
  32. Los programas en memoria son árboles de sintaxis abstracta (abstract

    syntax trees, ASTs). Cada elemento semántico del lenguaje corresponde a una clase nodo. Para añadir un nuevo lenguaje, definimos los nodos de su AST con la ayuda de la API de Truffle. También tenemos que definir métodos de evaluación para cada tipo de nodo.
  33. + z 5 AddNode ReadVarNode IntLitNode polimórfico! 1 + 2

    = 3 "a"+"b"="ab" Se evalúa al valor de la variable z en el scope actual Se evalúa al literal int 5.
  34. DESAFÍOS PARA LOGRAR UN DESAFÍOS PARA LOGRAR UN INTÉRPRETE RÁPIDO

    INTÉRPRETE RÁPIDO Es difícil generar código eficiente para nodos polimórficos Las cadenas de llamadas entre nodos son costosas
  35. + + ¡Sumo ints! ¡Concateno strings! ¡Solo sumo ints, pero

    lo hago rápido! BYTECODE CÓDIGO NATIVO compila Graal
  36. Truffle necesita la presencia de Graal para que tengan lugar

    las optimizaciones Especialización de nodos polimórficos Evaluación parcial de subárboles + z 5 A los creadores de nuevos lenguajes invitados les basta con conocer la API de Truffle
  37. class Foo def initialize() @val=0 end def go_up() @val+=1 end

    def go_down() @val-=1 end end foos = [Foo.new, Foo.new, Foo.new] loop do foos.each do |x| x.go_up() x.go_down() end end
  38. class Foo def initialize() @val=0 end def go_up() @val+=1 end

    def go_down() @val-=1 end end foos = [Foo.new, Foo.new, Foo.new] loop do foos.each do |x| x.go_up() x.go_down() end end $ ruby --jvm Foo.rb $ polyglot --language ruby --jvm Foo.rb
  39. class Foo def initialize() @val=0 end def go_up() @val+=1 end

    def go_down() @val-=1 end end foos = [Foo.new, Foo.new, Foo.new] loop do foos.each do |x| x.go_up() x.go_down() end end $ ruby --jvm --vm.Dgraal.Dump=:1 --vm.Dgraal.PrintGraph=Network Foo.rb
  40. DEMO POLIGLOTISMO I DEMO POLIGLOTISMO I public class User {

    private String name; public User(String name) { this.name = name; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } }
  41. try (Context context = Context.newBuilder() .allowAllAccess(true) .build()) { User user

    = context.eval( "js", "const User = Java.type('User');" + "const newUser = new User('César');" + "newUser;") .asHostObject(); System.out.println(user.getName()); } bash-4.2# javac PolyglotDemo.java && java PolyglotDemo César
  42. DEMO POLIGLOTISMO II DEMO POLIGLOTISMO II function validateEmail(email) { var

    re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+) return re.test(String(email).toLowerCase()); }
  43. DEMO POLIGLOTISMO II DEMO POLIGLOTISMO II try (Context context =

    Context.create("js")) { File file = new File("path/to/file", "mail-util.js"); Source source = Source.newBuilder("js", file) .build(); context.eval(source); Value jsFunction = context.getBindings(language) .getMember("validateEmail"); System.out.println("isValid: " + jsFunction.execute("cesar@invalid") .asBoolean()); } bash-4.2# javac PolyglotDemo.java && java PolyglotDemo isValid: false
  44. SULONG SULONG Java, Scala, Kotlin, Clojure JS, Python, Ruby, R

    C, C++ Sulong Truffle framework Graal compiler JVM Compiler Interface (JVMCI) Substrate VM Java HotSpot VM
  45. SULONG SULONG Intérprete de bitcode de la LLVM Permite ejecutar

    código de lenguajes como C, C++ o Fortran Implementado con Truffle
  46. LLI LLI #include <stdio.h> int main() { printf("Hola Mundo!\n"); return

    0; } $ clang -c -O1 -emit-llvm HelloWorld.c $ ls HelloWorld.bc HelloWorld.c $ lli HelloWorld.bc Hola Mundo!
  47. DEMO POLIGLOTISMO DEMO POLIGLOTISMO try (Context context = Context.newBuilder() .allowAllAccess(true)

    .build()) { File file = new File("path/to/file", "HelloWorld.bc"); Source source = Source.newBuilder("llvm", file) .build(); Value program = context.eval(source); program.execute(); } $ javac PolyglotDemo.java && java PolyglotDemo Hola Mundo!
  48. ENLACES DE REFERENCIA ENLACES DE REFERENCIA Documentación Oficial Blog So

    tek Announcing GraalVM 19.3 with JDK 11 Support
  49. VÍDEOS VÍDEOS One VM to Rule Them All, One VM

    to Bind Them Everything you need to know about GraalVM Twitter's Quest for a Wholly Graal Runtime GraalVM JIT versus HotSpot JIT C2 Lessons Learned with Truffle and Graal Building a DSL with GraalVM Project Sulong: an LLVM bitcode interpreter Ten Things You Can Do With GraalVM - Oleg Šelajev
  50. STACK OVERFLOW STACK OVERFLOW How does PE take place for

    a Truffle interpreter AOT- compiled with native-image? In Truffle, in which “level of abstraction” do the results of a partial evaluation belong?
  51. PAPERS PAPERS One VM to Rule Them All Practical partial

    evaluation for high-performance dynamic language runtimes Self-Optimizing AST Interpreters Sulong: Memory Safe and Efficient Execution of LLVM-Based Languages