Deep Dive Into the Scala Native Internals
What is Scala Native?
Part 1
Scala JVM
What is Scala Native?
● Created by Denys Shabelin at EPFL
● Ahead of time compiler
● Dedicated runtime containing subset of Java standard library.
● Since 2020 maintained by Scala Center
● Low-level operations and interop with C
● Instant startup and targeting high peak performance
How its made?
Part 2
Native Intermediate Representation (NIR)
● Definitions
○ Low level: Var, Const, Declare, Define
○ High level Class, Trait, Module
● Types:
○ Primitives,
○ Aggregates - Struct, fixed size Arrays
○ References: Ref, Array, Null, Unit
○ Special types: Function, Var, Varargs, Nothing
● Values:
○ Low-level
■ Local and Global identifiers
■ Primitive value types
■ Structs and Arrays
○ High-level
■ ClassOf, String, Const, Unit
● Instructions
○ Label, Let
○ Control Flow - Jump, Call, If, Try, Throw
● Operands
○ Low-level:
■ Store, Load
■ Call, Stackalloc
■ Add, Comp, Conv
○ High-level:
■ Method, Classalloc,
■ SizeOf, As, Is,
■ Box, Unbox
● Attributes
○ Inlining hints
○ Linking informations: link, stub
○ Extern
Native Intermediate Representation (NIR)
● Single Static Assignment based
● Strongly typed
● Supports high-level oriented structures
● Single top-level scope
● Globally unique mangled names
Name mangling
<mangled-name> ::= _S <defn-name>
<defn-name> ::=
T <name> // top-level name
M <name> <sig-name> // member name
<sig-name> ::=
F <name> <scope> // field name
R <type-name>+ E // constructor
name
D <name> <type-name>+ E <scope> // method name
C <name> // c extern
name
G <name> // generated
name
…
<name> ::= <length number> [-] <chars>
<type-name> ::=
v // c vararg
R _ // c pointer type-name
R <type-name>+ E // c function type-name
S <type-name>+ E // c anonymous struct type-
name
A <type-name> <number> _ // c array type-name
b // scala.Byte
s // scala.Short
i // scala.Int
j // scala.Long
z // scala.Boolean
c // scala.Char
f // scala.Float
d // scala.Double
u // scala.Unit
l // scala.Null
n // scala.Nothing
L <nullable-type-name> // type-name
Native Intermediate Representation (NIR)
module @"T5Test$" : @"T6FooCls", @"T8BarTrait" // Class definition
noinline def @"M5Test$D4mainLAL16java.lang.String_uEO" : (@"T5Test$", array[@"T16java.lang.String"]) => unit { // Function definition
%3(%1 : @"T5Test$", %2 : array[@"T16java.lang.String"]): // Function arguments
%4 = var[int]
%5 = classalloc @"T8Test$Bar"
%6 = call[(@"T8Test$Bar", int) => unit] @"M8Test$BarRiE" : ptr(%5 : !?@"T8Test$Bar", int 42)
%7 = method %5 : !?@"T8Test$Bar", "D3intiEO"
%8 = call[(@"T8Test$Bar") => int] %7 : ptr(%5 : !?@"T8Test$Bar")
%9 = varstore %4 : var[int], %8 : int
%10 = varload %4 : var[int]
%11 = iadd[int] int 42, %10 : int
%12 = imul[int] %11 : int, int 2
%13 = varstore %4 : var[int], %12 : int
ret %13 : unit
}
Pipeline schema
Compiler plugin
● One of last Scala compiler phases
● Traverses ASTs transforming Class, Def and Val definitions to NIR
blocks
● Collects types informations and attributes from annotations
● Collects positions from Trees
● Adapts external function calls
● Creates binary NIR files
Intrinsic functions
● Defined as Scala Native primitives
● Not possible to implement in Scala
● Evaluated in compile-time
● Used for internal low-level operations: stackalloc, pointer load / store,
etc.
Linker
● Loads NIR files based on classpath
● Performs static reachability checks
● Discards all not used definitions
● Collects metadata for classes and members
● Checks for allocations of classes
Optimizer
● Strongly base of type information inferencing
● Functions inlining / polymorphic inlining
● Partial evaluation
● Partial escape analysis
● Method deduplication
Code generation phase
● Creating class virtual tables and memory layouts
● Code injects
○ Main program loop
○ Trait dispatch tables
○ Class / module initializers and accessors
○ Runtime informations and metadata
Lowering phase
● Lowers high-level operations to sequence of low-level instructions
● Static / dynamic method dispatch
● Provides handling of runtime exceptions
● Dead code elimination
NIR translation phase
● Adds LLVM IR headers
● Deconstifies values some of global values
● Generates external dependencies declarations
● Translates NIR into LLVM IR
● Outputs *.ll files
Clang build
● Compiling native sources
● Compiling SN code from LLVM IR
● Linking as one application or shared library
Scala Native Roadmap 2021
Part 3
Goals for Scala Native in 2021
● Support for multithreading
● Scala 3 frontend
● Extending available subset of Java standard library
● Stabilization, bug fixes and performance improvements.
Wojciech_Maz
wmazur@virtuslab.com
scala-native/scala-native

Deep dive into the Scala Native internals.pptx

  • 3.
    Deep Dive Intothe Scala Native Internals
  • 4.
    What is ScalaNative? Part 1
  • 5.
  • 6.
    What is ScalaNative? ● Created by Denys Shabelin at EPFL ● Ahead of time compiler ● Dedicated runtime containing subset of Java standard library. ● Since 2020 maintained by Scala Center ● Low-level operations and interop with C ● Instant startup and targeting high peak performance
  • 7.
  • 8.
    Native Intermediate Representation(NIR) ● Definitions ○ Low level: Var, Const, Declare, Define ○ High level Class, Trait, Module ● Types: ○ Primitives, ○ Aggregates - Struct, fixed size Arrays ○ References: Ref, Array, Null, Unit ○ Special types: Function, Var, Varargs, Nothing ● Values: ○ Low-level ■ Local and Global identifiers ■ Primitive value types ■ Structs and Arrays ○ High-level ■ ClassOf, String, Const, Unit ● Instructions ○ Label, Let ○ Control Flow - Jump, Call, If, Try, Throw ● Operands ○ Low-level: ■ Store, Load ■ Call, Stackalloc ■ Add, Comp, Conv ○ High-level: ■ Method, Classalloc, ■ SizeOf, As, Is, ■ Box, Unbox ● Attributes ○ Inlining hints ○ Linking informations: link, stub ○ Extern
  • 9.
    Native Intermediate Representation(NIR) ● Single Static Assignment based ● Strongly typed ● Supports high-level oriented structures ● Single top-level scope ● Globally unique mangled names
  • 10.
    Name mangling <mangled-name> ::=_S <defn-name> <defn-name> ::= T <name> // top-level name M <name> <sig-name> // member name <sig-name> ::= F <name> <scope> // field name R <type-name>+ E // constructor name D <name> <type-name>+ E <scope> // method name C <name> // c extern name G <name> // generated name … <name> ::= <length number> [-] <chars> <type-name> ::= v // c vararg R _ // c pointer type-name R <type-name>+ E // c function type-name S <type-name>+ E // c anonymous struct type- name A <type-name> <number> _ // c array type-name b // scala.Byte s // scala.Short i // scala.Int j // scala.Long z // scala.Boolean c // scala.Char f // scala.Float d // scala.Double u // scala.Unit l // scala.Null n // scala.Nothing L <nullable-type-name> // type-name
  • 11.
    Native Intermediate Representation(NIR) module @"T5Test$" : @"T6FooCls", @"T8BarTrait" // Class definition noinline def @"M5Test$D4mainLAL16java.lang.String_uEO" : (@"T5Test$", array[@"T16java.lang.String"]) => unit { // Function definition %3(%1 : @"T5Test$", %2 : array[@"T16java.lang.String"]): // Function arguments %4 = var[int] %5 = classalloc @"T8Test$Bar" %6 = call[(@"T8Test$Bar", int) => unit] @"M8Test$BarRiE" : ptr(%5 : !?@"T8Test$Bar", int 42) %7 = method %5 : !?@"T8Test$Bar", "D3intiEO" %8 = call[(@"T8Test$Bar") => int] %7 : ptr(%5 : !?@"T8Test$Bar") %9 = varstore %4 : var[int], %8 : int %10 = varload %4 : var[int] %11 = iadd[int] int 42, %10 : int %12 = imul[int] %11 : int, int 2 %13 = varstore %4 : var[int], %12 : int ret %13 : unit }
  • 12.
  • 13.
    Compiler plugin ● Oneof last Scala compiler phases ● Traverses ASTs transforming Class, Def and Val definitions to NIR blocks ● Collects types informations and attributes from annotations ● Collects positions from Trees ● Adapts external function calls ● Creates binary NIR files
  • 14.
    Intrinsic functions ● Definedas Scala Native primitives ● Not possible to implement in Scala ● Evaluated in compile-time ● Used for internal low-level operations: stackalloc, pointer load / store, etc.
  • 15.
    Linker ● Loads NIRfiles based on classpath ● Performs static reachability checks ● Discards all not used definitions ● Collects metadata for classes and members ● Checks for allocations of classes
  • 16.
    Optimizer ● Strongly baseof type information inferencing ● Functions inlining / polymorphic inlining ● Partial evaluation ● Partial escape analysis ● Method deduplication
  • 17.
    Code generation phase ●Creating class virtual tables and memory layouts ● Code injects ○ Main program loop ○ Trait dispatch tables ○ Class / module initializers and accessors ○ Runtime informations and metadata
  • 18.
    Lowering phase ● Lowershigh-level operations to sequence of low-level instructions ● Static / dynamic method dispatch ● Provides handling of runtime exceptions ● Dead code elimination
  • 19.
    NIR translation phase ●Adds LLVM IR headers ● Deconstifies values some of global values ● Generates external dependencies declarations ● Translates NIR into LLVM IR ● Outputs *.ll files
  • 20.
    Clang build ● Compilingnative sources ● Compiling SN code from LLVM IR ● Linking as one application or shared library
  • 21.
  • 22.
    Goals for ScalaNative in 2021 ● Support for multithreading ● Scala 3 frontend ● Extending available subset of Java standard library ● Stabilization, bug fixes and performance improvements.
  • 23.