Slide 1

Slide 1 text

scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations 11th of September 2014 Virtual Machine Meetup ETH Zürich, Switzerland

Slide 2

Slide 2 text

scala-miniboxing.org/ldl Vlad URECHE PhD student in the Scala Team @ EPFL Miniboxing guy. Also worked on specialization, the backend and scaladoc. @ @VladUreche @VladUreche [email protected]

Slide 3

Slide 3 text

scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations

Slide 4

Slide 4 text

4 scala-miniboxing.org/ldl

Slide 5

Slide 5 text

5 scala-miniboxing.org/ldl OOPSLA 2014, Portland, OR

Slide 6

Slide 6 text

scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations

Slide 7

Slide 7 text

scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations ● compiler transformations ● separate compilation ● global scope

Slide 8

Slide 8 text

scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations ● unboxing, value classes ● how data is represented

Slide 9

Slide 9 text

scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations ● what is there to unify? ● why bother?

Slide 10

Slide 10 text

scala-miniboxing.org/ldl Motivation Transformation Conclusion

Slide 11

Slide 11 text

scala-miniboxing.org/ldl Representation Transformations

Slide 12

Slide 12 text

scala-miniboxing.org/ldl Unboxing Primitive Types Representation Transformations

Slide 13

Slide 13 text

scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Representation Transformations

Slide 14

Slide 14 text

scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations

Slide 15

Slide 15 text

scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations motivated by erased generics

Slide 16

Slide 16 text

scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations Staging (Multi-Stage Programming) motivated by erased generics

Slide 17

Slide 17 text

scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations Staging (Multi-Stage Programming) Function Representation motivated by erased generics

Slide 18

Slide 18 text

scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations Staging (Multi-Stage Programming) Function Representation motivated by erased generics

Slide 19

Slide 19 text

19 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types def identity[T](t: T): T = t

Slide 20

Slide 20 text

20 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types def identity[T](t: T): T = t scalac / javac

Slide 21

Slide 21 text

21 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types def identity[T](t: T): T = t def identity(t: Object): Object = t scalac / javac

Slide 22

Slide 22 text

22 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types identity(5)

Slide 23

Slide 23 text

23 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types identity(5) scalac / javac

Slide 24

Slide 24 text

24 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types identity(5) identity(j.l.Integer.valueOf(5)).intValue scalac / javac

Slide 25

Slide 25 text

25 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types identity(5) identity(j.l.Integer.valueOf(5)).intValue scalac / javac Object representation

Slide 26

Slide 26 text

26 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types identity(5) identity(j.l.Integer.valueOf(5)).intValue scalac / javac produces garbage breaks locality guarantees inflates heap requirements indirect (slow) access to the value Object representation

Slide 27

Slide 27 text

27 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five: Int = 5

Slide 28

Slide 28 text

28 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five: Int = 5 scala.Int behaves like an object (has methods, can be used with generics)

Slide 29

Slide 29 text

29 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five: Int = 5 scalac scala.Int behaves like an object (has methods, can be used with generics)

Slide 30

Slide 30 text

30 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five: Int = 5 val five: int = 5 scalac scala.Int behaves like an object (has methods, can be used with generics)

Slide 31

Slide 31 text

31 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five: Int = 5 val five: int = 5 scalac Unboxed integer scala.Int behaves like an object (has methods, can be used with generics)

Slide 32

Slide 32 text

32 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five: Int = identity(5)

Slide 33

Slide 33 text

33 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five: Int = identity(5) scalac

Slide 34

Slide 34 text

34 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five: Int = identity(5) val five: int = scalac

Slide 35

Slide 35 text

35 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five: Int = identity(5) val five: int = identity(I.valueOf(5)).intValue scalac

Slide 36

Slide 36 text

36 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five: Int = identity(5) val five: int = identity(I.valueOf(5)).intValue scalac Boxing coercion

Slide 37

Slide 37 text

37 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five: Int = identity(5) val five: int = identity(I.valueOf(5)).intValue scalac Boxing coercion Unboxing coercion

Slide 38

Slide 38 text

38 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int

Slide 39

Slide 39 text

39 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int

Slide 40

Slide 40 text

40 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int int ● fast access ● no garbage collection ● locality

Slide 41

Slide 41 text

41 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int int ● fast access ● no garbage collection ● locality ● indirect access ● object allocation ● and thus garbage collection ● no locality guarantees ● compatible with erased generics java.lang.Integer

Slide 42

Slide 42 text

42 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int int ● fast access ● no garbage collection ● locality ● indirect access ● object allocation ● and thus garbage collection ● no locality guarantees ● compatible with erased generics java.lang.Integer incompatible → coercions

Slide 43

Slide 43 text

scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations Staging (Multi-Stage Programming) Function Representation

Slide 44

Slide 44 text

44 scala-miniboxing.org/ldl Specialization Specialization def identity[T](t: T): T = t

Slide 45

Slide 45 text

45 scala-miniboxing.org/ldl Specialization Specialization def identity[T](t: T): T = t specialization

Slide 46

Slide 46 text

46 scala-miniboxing.org/ldl Specialization Specialization def identity[T](t: T): T = t def identity(t: Object): Object = t specialization

Slide 47

Slide 47 text

47 scala-miniboxing.org/ldl Specialization Specialization def identity[T](t: T): T = t def identity(t: Object): Object = t specialization def identity_Z(t: bool): bool = t

Slide 48

Slide 48 text

48 scala-miniboxing.org/ldl Specialization Specialization def identity[T](t: T): T = t def identity(t: Object): Object = t specialization def identity_Z(t: bool): bool = t def identity_C(t: char): char = t

Slide 49

Slide 49 text

49 scala-miniboxing.org/ldl Specialization Specialization def identity[T](t: T): T = t def identity(t: Object): Object = t specialization def identity_Z(t: bool): bool = t def identity_C(t: char): char = t … (7 other variants)

Slide 50

Slide 50 text

50 scala-miniboxing.org/ldl Specialization Specialization identity(5)

Slide 51

Slide 51 text

51 scala-miniboxing.org/ldl Specialization Specialization identity(5) specialization

Slide 52

Slide 52 text

52 scala-miniboxing.org/ldl Specialization Specialization identity(5) identity_I(5) specialization

Slide 53

Slide 53 text

53 scala-miniboxing.org/ldl Specialization Specialization identity(5) identity_I(5) specialization The variant of identity specialized for int

Slide 54

Slide 54 text

54 scala-miniboxing.org/ldl Specialization Specialization identity(5) identity_I(5) specialization The variant of identity specialized for int // no boxing!

Slide 55

Slide 55 text

55 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2) ...

Slide 56

Slide 56 text

56 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2) ... specialization

Slide 57

Slide 57 text

57 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2) ... // 100 methods (102) specialization

Slide 58

Slide 58 text

58 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2) ... // 100 methods (102) specialization

Slide 59

Slide 59 text

59 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2) ... // 100 methods (102) specialization Can we do better?

Slide 60

Slide 60 text

60 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2) ... // 100 methods (102) specialization Can we do better?

Slide 61

Slide 61 text

61 scala-miniboxing.org/ldl Miniboxing Miniboxing def identity[T](t: T): T = t

Slide 62

Slide 62 text

62 scala-miniboxing.org/ldl Miniboxing Miniboxing def identity[T](t: T): T = t miniboxing

Slide 63

Slide 63 text

63 scala-miniboxing.org/ldl Miniboxing Miniboxing def identity[T](t: T): T = t def identity(t: Object): Object = t miniboxing

Slide 64

Slide 64 text

64 scala-miniboxing.org/ldl Miniboxing Miniboxing def identity[T](t: T): T = t def identity(t: Object): Object = t miniboxing def identity_M(..., t: long): long = t

Slide 65

Slide 65 text

65 scala-miniboxing.org/ldl Miniboxing Miniboxing def identity[T](t: T): T = t def identity(t: Object): Object = t miniboxing def identity_M(..., t: long): long = t long encodes all primitive types

Slide 66

Slide 66 text

66 scala-miniboxing.org/ldl Miniboxing Miniboxing def identity[T](t: T): T = t def identity(t: Object): Object = t miniboxing def identity_M(..., t: long): long = t Only 2n variants long encodes all primitive types

Slide 67

Slide 67 text

67 scala-miniboxing.org/ldl Miniboxing Miniboxing identity(3)

Slide 68

Slide 68 text

68 scala-miniboxing.org/ldl Miniboxing Miniboxing identity(3) miniboxing

Slide 69

Slide 69 text

69 scala-miniboxing.org/ldl Miniboxing Miniboxing identity(3) identity_M(..., int2minibox(3)) miniboxing

Slide 70

Slide 70 text

70 scala-miniboxing.org/ldl Miniboxing Miniboxing identity(3) identity_M(..., int2minibox(3)) miniboxing The miniboxed variant of identity

Slide 71

Slide 71 text

71 scala-miniboxing.org/ldl Miniboxing Miniboxing identity(3) identity_M(..., int2minibox(3)) miniboxing Coercion The miniboxed variant of identity

Slide 72

Slide 72 text

72 scala-miniboxing.org/ldl Miniboxing Miniboxing T

Slide 73

Slide 73 text

73 scala-miniboxing.org/ldl Miniboxing Miniboxing T

Slide 74

Slide 74 text

74 scala-miniboxing.org/ldl Miniboxing Miniboxing T long ● preferred encoding

Slide 75

Slide 75 text

75 scala-miniboxing.org/ldl Miniboxing Miniboxing T long ● preferred encoding ● fallback encoding ● compatible with ● virtual dispatch ● subtyping ● erased generics T (erased to Object)

Slide 76

Slide 76 text

76 scala-miniboxing.org/ldl Miniboxing Miniboxing T long ● preferred encoding ● fallback encoding ● compatible with ● virtual dispatch ● subtyping ● erased generics T (erased to Object) incompatible → coercions

Slide 77

Slide 77 text

scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations Staging (Multi-Stage Programming) Function Representation

Slide 78

Slide 78 text

78 scala-miniboxing.org/ldl Value Classes Value Classes def abs(c: Complex): Double = ...

Slide 79

Slide 79 text

79 scala-miniboxing.org/ldl Value Classes Value Classes def abs(c: Complex): Double = ... value class transformation

Slide 80

Slide 80 text

80 scala-miniboxing.org/ldl Value Classes Value Classes def abs(c: Complex): Double = ... def abs(c_re: Double, c_im: Double): Double = ... value class transformation

Slide 81

Slide 81 text

81 scala-miniboxing.org/ldl Value Classes Value Classes def abs(c: Complex): Double = ... def abs(c_re: Double, c_im: Double): Double = ... value class transformation No object created!

Slide 82

Slide 82 text

82 scala-miniboxing.org/ldl Value Classes Value Classes val c: Complex = Complex(2,1)

Slide 83

Slide 83 text

83 scala-miniboxing.org/ldl Value Classes Value Classes val c: Complex = Complex(2,1) value class transformation

Slide 84

Slide 84 text

84 scala-miniboxing.org/ldl Value Classes Value Classes val c: Complex = Complex(2,1) val c_re: Double = 2 val c_im: Double = 1 value class transformation

Slide 85

Slide 85 text

85 scala-miniboxing.org/ldl Value Classes Value Classes val c: Complex = Complex(2,1) val c_re: Double = 2 val c_im: Double = 1 value class transformation No object created!

Slide 86

Slide 86 text

86 scala-miniboxing.org/ldl Value Classes Value Classes val a: Any = c

Slide 87

Slide 87 text

87 scala-miniboxing.org/ldl Value Classes Value Classes val a: Any = c value class transformation

Slide 88

Slide 88 text

88 scala-miniboxing.org/ldl Value Classes Value Classes val a: Any = c val a: Any = new Complex(c_re, c_im) value class transformation

Slide 89

Slide 89 text

89 scala-miniboxing.org/ldl Value Classes Value Classes val a: Any = c val a: Any = new Complex(c_re, c_im) value class transformation Coercion!

Slide 90

Slide 90 text

90 scala-miniboxing.org/ldl Value Classes Value Classes value class

Slide 91

Slide 91 text

91 scala-miniboxing.org/ldl Value Classes Value Classes value class

Slide 92

Slide 92 text

92 scala-miniboxing.org/ldl Value Classes Value Classes value class structure (by-val) ● preferred encoding

Slide 93

Slide 93 text

93 scala-miniboxing.org/ldl Value Classes Value Classes value class structure (by-val) ● preferred encoding ● fallback encoding ● compatible with ● subtyping ● erased generics class (by-ref)

Slide 94

Slide 94 text

94 scala-miniboxing.org/ldl Value Classes Value Classes value class structure (by-val) ● preferred encoding ● fallback encoding ● compatible with ● subtyping ● erased generics class (by-ref) incompatible → coercions

Slide 95

Slide 95 text

scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations Staging (Multi-Stage Programming) Function Representation

Slide 96

Slide 96 text

96 scala-miniboxing.org/ldl Staging Staging T

Slide 97

Slide 97 text

97 scala-miniboxing.org/ldl Staging Staging T

Slide 98

Slide 98 text

98 scala-miniboxing.org/ldl Staging Staging T T (direct) ● executed in this stage ● stores a value

Slide 99

Slide 99 text

99 scala-miniboxing.org/ldl Staging Staging T T (direct) ● executed in this stage ● stores a value ● executed in the next stage ● stores the expression that produces the value Rep[T] (lifted)

Slide 100

Slide 100 text

100 scala-miniboxing.org/ldl Staging Staging T T (direct) ● executed in this stage ● stores a value ● executed in the next stage ● stores the expression that produces the value Rep[T] (lifted) incompatible → coercions

Slide 101

Slide 101 text

scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations Staging (Multi-Stage Programming) Function Representation

Slide 102

Slide 102 text

102 scala-miniboxing.org/ldl Function Representation Function Representation scala.FunctionX

Slide 103

Slide 103 text

103 scala-miniboxing.org/ldl Function Representation Function Representation scala.FunctionX

Slide 104

Slide 104 text

104 scala-miniboxing.org/ldl Function Representation Function Representation scala.FunctionX FunctionX ● compatible with the library ● does not have all specializations ● slow when used by miniboxed code

Slide 105

Slide 105 text

105 scala-miniboxing.org/ldl Function Representation Function Representation scala.FunctionX FunctionX ● compatible with the library ● does not have all specializations ● slow when used by miniboxed code ● fast calling from miniboxed code ● all specializations are there MbFunctionX

Slide 106

Slide 106 text

106 scala-miniboxing.org/ldl Function Representation Function Representation scala.FunctionX FunctionX ● compatible with the library ● does not have all specializations ● slow when used by miniboxed code ● fast calling from miniboxed code ● all specializations are there MbFunctionX incompatible → coercions

Slide 107

Slide 107 text

scala-miniboxing.org/ldl Motivation Transformation Conclusion

Slide 108

Slide 108 text

scala-miniboxing.org/ldl Motivation Transformation Conclusion

Slide 109

Slide 109 text

109 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL)

Slide 110

Slide 110 text

110 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL) concept

Slide 111

Slide 111 text

111 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL) concept

Slide 112

Slide 112 text

112 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL) concept repr. 1

Slide 113

Slide 113 text

113 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL) concept repr. 1 repr. 2

Slide 114

Slide 114 text

114 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL) concept repr. 1 … repr. n repr. 2

Slide 115

Slide 115 text

115 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL) concept repr. 1 … repr. n repr. 2 Constraints from the interaction with other language features: ● generics ● subtyping ● virtual dispatch ● DSL semantics (staging)

Slide 116

Slide 116 text

116 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL) concept repr. 1 … repr. n repr. 2 Constraints from the interaction with other language features: ● generics ● subtyping ● virtual dispatch ● DSL semantics (staging) incompatible → coercions

Slide 117

Slide 117 text

scala-miniboxing.org/ldl How to transform a program?

Slide 118

Slide 118 text

scala-miniboxing.org/ldl How to transform a program? We'll use primitive unboxing as the running example, to keep things simple

Slide 119

Slide 119 text

119 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int int ● fast access ● no garbage collection ● locality ● indirect access ● object allocation ● and thus garbage collection ● no locality guarantees ● compatible with erased generics java.lang.Integer

Slide 120

Slide 120 text

120 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int int ● fast access ● no garbage collection ● locality ● indirect access ● object allocation ● and thus garbage collection ● no locality guarantees ● compatible with erased generics java.lang.Integer incompatible → coercions

Slide 121

Slide 121 text

scala-miniboxing.org/ldl Naive transformation Syntax-based transformation Type-based LDL transformation

Slide 122

Slide 122 text

122 scala-miniboxing.org/ldl Naive transformation Naive transformation val x: Int = List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) naive unboxing

Slide 123

Slide 123 text

123 scala-miniboxing.org/ldl Naive transformation Naive transformation val x: Int = List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) val x: int = List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) naive unboxing

Slide 124

Slide 124 text

124 scala-miniboxing.org/ldl Naive transformation Naive transformation val x: Int = List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) val x: int = List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) naive unboxing representation mismatch: expected: int (unboxed) found: Int (boxed)

Slide 125

Slide 125 text

125 scala-miniboxing.org/ldl Naive transformation Naive transformation val x: Int = List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) val x: int = List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) naive unboxing representation mismatch: expected: int (unboxed) found: Int (boxed) representation mismatch: expected: Int (boxed) found: int (unboxed)

Slide 126

Slide 126 text

126 scala-miniboxing.org/ldl Naive transformation Naive transformation ● naively replacing representations – leads to mismatches – which are hard to recover (impossible for value classes and miniboxing) ● we need coercions between representations

Slide 127

Slide 127 text

scala-miniboxing.org/ldl Naive transformation Syntax-based transformation Type-based LDL transformation

Slide 128

Slide 128 text

128 scala-miniboxing.org/ldl Syntax-based Syntax-based ● when transforming a value – coerce the definition right-hand side – coerce all references to it

Slide 129

Slide 129 text

129 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2, 3).head

Slide 130

Slide 130 text

130 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2, 3).head syntax-based unboxing

Slide 131

Slide 131 text

131 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2, 3).head val x: int = syntax-based unboxing

Slide 132

Slide 132 text

132 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2, 3).head val x: int = unbox(List[Int](1, 2, 3).head) syntax-based unboxing

Slide 133

Slide 133 text

133 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2, 3).head val x: int = unbox(List[Int](1, 2, 3).head) syntax-based unboxing There are no references to x, so there's nothing else to do.

Slide 134

Slide 134 text

134 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2, 3).head val x: int = unbox(List[Int](1, 2, 3).head) syntax-based unboxing There are no references to x, so there's nothing else to do.

Slide 135

Slide 135 text

135 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2, 3).head val z: Int = x

Slide 136

Slide 136 text

136 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2, 3).head val z: Int = x Transform one by one

Slide 137

Slide 137 text

137 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2, 3).head val z: Int = x syntax-based unboxing Transform one by one

Slide 138

Slide 138 text

138 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2, 3).head val z: Int = x val x: int = unbox(List[Int](1, 2, 3).head) syntax-based unboxing Transform one by one

Slide 139

Slide 139 text

139 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2, 3).head val z: Int = x val x: int = unbox(List[Int](1, 2, 3).head) val z: Int = box(x) syntax-based unboxing Transform one by one

Slide 140

Slide 140 text

140 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: int = unbox(List[Int](1, 2, 3).head) val z: Int = box(x)

Slide 141

Slide 141 text

141 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: int = unbox(List[Int](1, 2, 3).head) val z: Int = box(x) syntax-based unboxing

Slide 142

Slide 142 text

142 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: int = unbox(List[Int](1, 2, 3).head) val z: Int = box(x) val x: int = unbox(List[Int](1, 2, 3).head) val z: int = syntax-based unboxing

Slide 143

Slide 143 text

143 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: int = unbox(List[Int](1, 2, 3).head) val z: Int = box(x) val x: int = unbox(List[Int](1, 2, 3).head) val z: int = unbox(box(x)) syntax-based unboxing

Slide 144

Slide 144 text

144 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: int = unbox(List[Int](1, 2, 3).head) val z: Int = box(x) val x: int = unbox(List[Int](1, 2, 3).head) val z: int = unbox(box(x)) syntax-based unboxing suboptimal

Slide 145

Slide 145 text

145 scala-miniboxing.org/ldl Peephole Optimization Peephole Optimization val z: int = unbox(box(x))

Slide 146

Slide 146 text

146 scala-miniboxing.org/ldl Peephole Optimization Peephole Optimization val z: int = unbox(box(x)) peephole

Slide 147

Slide 147 text

147 scala-miniboxing.org/ldl Peephole Optimization Peephole Optimization val z: int = unbox(box(x)) val z: int = x peephole

Slide 148

Slide 148 text

148 scala-miniboxing.org/ldl Peephole Optimization Peephole Optimization val z: int = unbox(box(x)) val z: int = x peephole

Slide 149

Slide 149 text

149 scala-miniboxing.org/ldl Peephole Optimization Peephole Optimization val z: int = unbox(box(x)) val z: int = x peephole Okay, let's add the peephole transformation in the pipeline.

Slide 150

Slide 150 text

150 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: Int, t2: Int): Int = if (Random.nextBoolean()) t1 else t2

Slide 151

Slide 151 text

151 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: Int, t2: Int): Int = if (Random.nextBoolean()) t1 else t2 Transform one by one

Slide 152

Slide 152 text

152 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: Int): Int = if (Random.nextBoolean()) box(t1) else t2

Slide 153

Slide 153 text

153 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): Int = if (Random.nextBoolean()) box(t1) else box(t2)

Slide 154

Slide 154 text

154 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): Int = if (Random.nextBoolean()) box(t1) else box(t2) Anything missing?

Slide 155

Slide 155 text

155 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int = unbox(if (Random.nextBoolean()) box(t1) else box(t2))

Slide 156

Slide 156 text

156 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int = unbox(if (Random.nextBoolean()) box(t1) else box(t2))

Slide 157

Slide 157 text

157 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int = unbox(if (Random.nextBoolean()) box(t1) else box(t2)) new peephole rule

Slide 158

Slide 158 text

158 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int = unbox(if (Random.nextBoolean()) box(t1) else box(t2)) new peephole rule sink outside coercions into the if branches

Slide 159

Slide 159 text

159 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int = if (Random.nextBoolean()) unbox(box(t1)) else unbox(box(t2))

Slide 160

Slide 160 text

160 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int = if (Random.nextBoolean()) unbox(box(t1)) else unbox(box(t2))

Slide 161

Slide 161 text

161 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int = if (Random.nextBoolean()) t1 else t2

Slide 162

Slide 162 text

162 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int = if (Random.nextBoolean()) t1 else t2 complicated

Slide 163

Slide 163 text

163 scala-miniboxing.org/ldl Syntax-based Syntax-based ● peephole transformation does not scale – needs multiple rules for each node – needs stateful rewrites – leads to an explosion of rules x states Details in the paper

Slide 164

Slide 164 text

scala-miniboxing.org/ldl Naive transformation Syntax-based transformation Type-based LDL transformation

Slide 165

Slide 165 text

165 scala-miniboxing.org/ldl LDL Transformation LDL Transformation ● propagate representation information – into the type system (based on annotated types) – allows selective marking of values to be unboxed

Slide 166

Slide 166 text

166 scala-miniboxing.org/ldl LDL Transformation LDL Transformation ● re-typecheck the tree – exposes inconsistencies in the representation ● based on backward type propagation ● from local type inference – so we introduce coercions ● optimally, only when representations don't match

Slide 167

Slide 167 text

167 scala-miniboxing.org/ldl LDL Transformation LDL Transformation ● three-stage mechanism – inject annotate the values to be unboxed → – coerce introduce coercion markers → – commit commit to the alternative representations →

Slide 168

Slide 168 text

168 scala-miniboxing.org/ldl LDL Transformation LDL Transformation Warning! Throughout the presentation we'll be writing annotations written before types (e.g. “@unboxed Int”), although in the Scala syntax they are written after the type (e.g.“Int @unboxed”). This makes it easier to read the types aloud.

Slide 169

Slide 169 text

169 scala-miniboxing.org/ldl LDL Transformation LDL Transformation inject coerce commit

Slide 170

Slide 170 text

170 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: Int, t2: Int): Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit

Slide 171

Slide 171 text

171 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: Int, t2: Int): Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit

Slide 172

Slide 172 text

172 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit configurable introduction of annotations based on external constraints

Slide 173

Slide 173 text

173 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit

Slide 174

Slide 174 text

174 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit

Slide 175

Slide 175 text

175 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit the return type of choice is @unboxed Int

Slide 176

Slide 176 text

176 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit the return type of choice is @unboxed Int

Slide 177

Slide 177 text

177 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int the return type of choice is @unboxed Int

Slide 178

Slide 178 text

178 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int expected type (part of local type inference) the return type of choice is @unboxed Int

Slide 179

Slide 179 text

179 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int

Slide 180

Slide 180 text

180 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : Boolean

Slide 181

Slide 181 text

181 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : Boolean matches: expected: Boolean found: Boolean

Slide 182

Slide 182 text

182 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int

Slide 183

Slide 183 text

183 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int matches: expected: @unboxed Int found: @unboxed Int

Slide 184

Slide 184 text

184 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int

Slide 185

Slide 185 text

185 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit matches: ... : @unboxed Int

Slide 186

Slide 186 text

186 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit

Slide 187

Slide 187 text

187 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit all okay, next phase

Slide 188

Slide 188 text

188 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit

Slide 189

Slide 189 text

189 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit Replace: @unboxed Int → int (not showing Int → j.l.Integer)

Slide 190

Slide 190 text

190 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: int, t2: int): int = if (Random.nextBoolean()) t1 else t2 inject coerce commit

Slide 191

Slide 191 text

191 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: int, t2: int): int = if (Random.nextBoolean()) t1 else t2 inject coerce commit that's it!

Slide 192

Slide 192 text

192 scala-miniboxing.org/ldl LDL Transformation LDL Transformation ● three-stage mechanism – inject: add annotations – coerce: add coercions (based on the annotations) – commit: final representation semantics

Slide 193

Slide 193 text

193 scala-miniboxing.org/ldl LDL Transformation LDL Transformation ● Scalac's erasure – similar transformation – less flexible (no annotations) – entangled with other transformations ● we took what's good – and allowed the transformation to work on other use cases as well

Slide 194

Slide 194 text

scala-miniboxing.org/ldl Consistency Selectivity Optimality (not formally proven yet) Properties Type-based LDL transformation

Slide 195

Slide 195 text

195 scala-miniboxing.org/ldl Consistency Consistency inject coerce commit ● representations become explicit in types – representation mismatches ● become type mismatches ● are exposed by the type system – mismatches lead to coercions ● explicit bridges between representations ● are introduced automatically – regardless of the representations ● at a meta-level

Slide 196

Slide 196 text

scala-miniboxing.org/ldl Consistency Selectivity Optimality (not formally proven yet) Properties Type-based LDL transformation

Slide 197

Slide 197 text

197 scala-miniboxing.org/ldl Selectivity Selectivity inject coerce commit ● annotations allow selectively picking the values to be transformed – value classes ● cannot unbox multi-param values in return position (not supported by the JVM platform) ● bridge methods – staging ● annotations signal domain-specific knowledge – can occur inside generics (List[@staged Int])

Slide 198

Slide 198 text

198 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: Int): Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit

Slide 199

Slide 199 text

199 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: Int): Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit what if we did not annotate t1?

Slide 200

Slide 200 text

200 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit what if we did not annotate t1?

Slide 201

Slide 201 text

201 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int

Slide 202

Slide 202 text

202 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int

Slide 203

Slide 203 text

203 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int mismatch: expected: @unboxed Int found: Int

Slide 204

Slide 204 text

204 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int mismatch: expected: @unboxed Int found: Int coercion

Slide 205

Slide 205 text

205 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) unbox(t1) else t2 inject coerce commit

Slide 206

Slide 206 text

206 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) unbox(t1) else t2 inject coerce commit

Slide 207

Slide 207 text

207 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: int): int = if (Random.nextBoolean()) t1.intValue else t2 inject coerce commit

Slide 208

Slide 208 text

scala-miniboxing.org/ldl Consistency Selectivity Optimality (not formally proven yet) Properties Type-based LDL transformation

Slide 209

Slide 209 text

209 scala-miniboxing.org/ldl Optimality Optimality def choice(t1: Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) unbox(t1) else t2 inject coerce commit

Slide 210

Slide 210 text

210 scala-miniboxing.org/ldl Optimality Optimality def choice(t1: Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) unbox(t1) else t2 inject coerce commit

Slide 211

Slide 211 text

211 scala-miniboxing.org/ldl Optimality Optimality def choice(t1: Int, t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) unbox(t1) else t2 inject coerce commit Coercions are sunk in the tree → excute only if necessary

Slide 212

Slide 212 text

scala-miniboxing.org/ldl Motivation Transformation Conclusion

Slide 213

Slide 213 text

scala-miniboxing.org/ldl Motivation Transformation Conclusion

Slide 214

Slide 214 text

214 scala-miniboxing.org/ldl Conclusion Conclusion LDL is a LDL is a ● compile-time transformation – compatible with separate compilation – compatible with partial transformation

Slide 215

Slide 215 text

215 scala-miniboxing.org/ldl Conclusion Conclusion LDL is a LDL is a ● compile-time transformation – compatible with separate compilation – compatible with partial transformation – global scope (Graal/Truffle: local scope) ● optimizes all data in a program

Slide 216

Slide 216 text

216 scala-miniboxing.org/ldl Conclusion Conclusion LDL is a LDL is a ● compile-time transformation – compatible with separate compilation – compatible with partial transformation – global scope (Graal/Truffle: local scope) ● optimizes all data in a program / containers – conservative (Graal/Truffle: speculative)

Slide 217

Slide 217 text

217 scala-miniboxing.org/ldl Conclusion Conclusion LDL is a LDL is a ● compile-time transformation – compatible with separate compilation – compatible with partial transformation – global scope (Graal/Truffle: local scope) ● optimizes all data in a program / containers – conservative (Graal/Truffle: speculative) Complementary optimizations

Slide 218

Slide 218 text

218 scala-miniboxing.org/ldl Conclusion Conclusion LDL allows LDL allows ● splitting a high-level concept – into multiple representations – in a consistent way (through coercions) – in a selective way (through annotations) – in an optimal way (coerce only if necessary)

Slide 219

Slide 219 text

219 scala-miniboxing.org/ldl Conclusion Conclusion LDL is used in LDL is used in ● the miniboxing plugin – for specialization – for function representation ● other prototypes – value classes – staging

Slide 220

Slide 220 text

220 scala-miniboxing.org/ldl Conclusion Conclusion LDL is used in LDL is used in ● the miniboxing plugin – for specialization – for function representation ● other prototypes – value classes – staging Don't take my word for it

Slide 221

Slide 221 text

221 scala-miniboxing.org/ldl Conclusion Conclusion LDL is used in LDL is used in ● the miniboxing plugin – for specialization – for function representation ● other prototypes – value classes – staging Don't take my word for it Sources on github, artifact online.

Slide 222

Slide 222 text

222 scala-miniboxing.org/ldl

Slide 223

Slide 223 text

223 scala-miniboxing.org/ldl Conclusion Conclusion What's your use-case? What's your use-case? concept repr. 1 … repr. n repr. 2

Slide 224

Slide 224 text

scala-miniboxing.org/ldl Credits and Thank you-s ● Cristian Talau - developed the initial prototype, as a semester project ● Eugene Burmako - the value class plugin based on the LDL transformation ● Aymeric Genet - developing collection-like benchmarks for the miniboxing plugin ● Martin Odersky, for his patient guidance ● Eugene Burmako, for trusting the idea enough to develop the value-plugin based on the LDL transformation ● Iulian Dragos, for his work on specialization and many explanations ● Miguel Garcia, for his original insights that spawned the miniboxing idea ● Michel Schinz, for his wonderful comments and enlightening ACC course ● Andrew Myers and Roland Ducournau for the discussions we had and the feedback provided ● Heather Miller for the eye-opening discussions we had ● Vojin Jovanovic, Sandro Stucki, Manohar Jonalagedda and the whole LAMP laboratory in EPFL for the extraordinary atmosphere ● Adriaan Moors, for the miniboxing name which stuck :)) ● Thierry Coppey, Vera Salvisberg and George Nithin, who patiently listened to many presentations and provided valuable feedback ● Grzegorz Kossakowski, for the many brainstorming sessions on specialization ● Erik Osheim, Tom Switzer and Rex Kerr for their guidance on the Scala community side ● OOPSLA paper and artifact reviewers, who reshaped the paper with their feedback ● Sandro, Vojin, Nada, Heather, Manohar - reviews and discussions on the LDL paper ● Hubert Plociniczak for the type notation in the LDL paper ● Denys Shabalin, Dmitry Petrashko for their patient reviews of the LDL paper Special thanks to the Scala Community for their support! (@StuHood, @vpatryshev and everyone else!)

Slide 225

Slide 225 text

scala-miniboxing.org/ldl Thank you! concept repr. 1 … repr. n repr. 2