Slide 1

Slide 1 text

scala-miniboxing.org Late Data Layout Late Data Layout or how to boil a frog without it noticing LAMP, 11th of February 2014 Vlad Ureche Cristian Talau Martin Odersky

Slide 2

Slide 2 text

scala-miniboxing.org Late Data Layout Late Data Layout or how to boil a frog without it noticing LAMP, 11th of February 2014 Vlad Ureche Cristian Talau Martin Odersky Frog clipart credits: www.frog-life-cycle.com

Slide 3

Slide 3 text

3 scala-miniboxing.org We all like generics We all like generics

Slide 4

Slide 4 text

4 scala-miniboxing.org We all like generics We all like generics a trivial example a trivial example

Slide 5

Slide 5 text

5 scala-miniboxing.org We all like generics We all like generics def identity[T](t: T): T = t a trivial example a trivial example

Slide 6

Slide 6 text

6 scala-miniboxing.org We all like generics We all like generics def identity[T](t: T): T = t ● will take any type and a trivial example a trivial example

Slide 7

Slide 7 text

7 scala-miniboxing.org We all like generics We all like generics def identity[T](t: T): T = t ● will take any type and ● will return that same type a trivial example a trivial example

Slide 8

Slide 8 text

8 scala-miniboxing.org We all like generics We all like generics def identity[T](t: T): T = t a trivial example a trivial example but under erasure: def identity(t: Any): Any = t

Slide 9

Slide 9 text

9 scala-miniboxing.org We all like generics We all like generics def identity[T](t: T): T = t a trivial example a trivial example but under erasure: def identity(t: Any): Any = t Any indicates a by- reference parameter

Slide 10

Slide 10 text

10 scala-miniboxing.org Specialization Specialization generates too much code generates too much code

Slide 11

Slide 11 text

11 scala-miniboxing.org Specialization Specialization generates too much code generates too much code def identity[T](t: T): T = t

Slide 12

Slide 12 text

12 scala-miniboxing.org Specialization Specialization generates too much code generates too much code def identity[T](t: T): T = t def identity_V(t: Unit): Unit = t def identity_Z(t: Boolean): Boolean = t def identity_B(t: Byte): Byte = t def identity_C(t: Char): Char = t def identity_S(t: Short): Short = t def identity_I(t: Int): Int = t def identity_J(t: Long): Long = t def identity_F(t: Float): Float = t def identity_D(t: Double): Double = t

Slide 13

Slide 13 text

13 scala-miniboxing.org Specialization Specialization generates too much code generates too much code def identity[T](t: T): T = t def identity_V(t: Unit): Unit = t def identity_Z(t: Boolean): Boolean = t def identity_B(t: Byte): Byte = t def identity_C(t: Char): Char = t def identity_S(t: Short): Short = t def identity_I(t: Int): Int = t def identity_J(t: Long): Long = t def identity_F(t: Float): Float = t def identity_D(t: Double): Double = t Generates 10 times the original code

Slide 14

Slide 14 text

14 scala-miniboxing.org Miniboxing Miniboxing

Slide 15

Slide 15 text

15 scala-miniboxing.org Miniboxing Miniboxing reduces the variants reduces the variants

Slide 16

Slide 16 text

16 scala-miniboxing.org Miniboxing Miniboxing reduces the variants reduces the variants by using something like a tagged union TAG DATA (VALUE)

Slide 17

Slide 17 text

17 scala-miniboxing.org Miniboxing Miniboxing reduces the variants reduces the variants by using something like a tagged union TAG DATA (VALUE) Stores the original type

Slide 18

Slide 18 text

18 scala-miniboxing.org Miniboxing Miniboxing reduces the variants reduces the variants by using something like a tagged union TAG DATA (VALUE) Stores the original type Stores the encoded value in a long integer

Slide 19

Slide 19 text

19 scala-miniboxing.org Miniboxing Miniboxing reduces the variants reduces the variants by using something like a tagged union TAG DATA (VALUE)

Slide 20

Slide 20 text

20 scala-miniboxing.org Miniboxing Miniboxing reduces the variants reduces the variants by using something like a tagged union TAG DATA (VALUE) BOOL 0x0 false =

Slide 21

Slide 21 text

21 scala-miniboxing.org Miniboxing Miniboxing reduces the variants reduces the variants by using something like a tagged union TAG DATA (VALUE) BOOL 0x0 false = BOOL 0x1 true =

Slide 22

Slide 22 text

22 scala-miniboxing.org Miniboxing Miniboxing reduces the variants reduces the variants by using something like a tagged union TAG DATA (VALUE) BOOL 0x0 false = BOOL 0x1 true = INT 0x2A 42 =

Slide 23

Slide 23 text

23 scala-miniboxing.org Miniboxing Miniboxing reduces the variants reduces the variants by using something like a tagged union TAG DATA (VALUE)

Slide 24

Slide 24 text

24 scala-miniboxing.org Miniboxing Miniboxing reduces the variants reduces the variants by using something like a tagged union TAG DATA (VALUE) and using the static type information – tags are attached to code, not to values

Slide 25

Slide 25 text

25 scala-miniboxing.org Miniboxing Miniboxing let's revisit `def identity` let's revisit `def identity` def identity[T](t: T): T = t

Slide 26

Slide 26 text

26 scala-miniboxing.org Miniboxing Miniboxing let's revisit `def identity` let's revisit `def identity` def identity[T](t: T): T = t def identity_J(T_tag: Byte, t: Long): Long

Slide 27

Slide 27 text

27 scala-miniboxing.org Miniboxing Miniboxing let's revisit `def identity` let's revisit `def identity` def identity[T](t: T): T = t def identity_J(T_tag: Byte, t: Long): Long TAG

Slide 28

Slide 28 text

28 scala-miniboxing.org Miniboxing Miniboxing let's revisit `def identity` let's revisit `def identity` def identity[T](t: T): T = t def identity_J(T_tag: Byte, t: Long): Long TAG DATA (VALUE)

Slide 29

Slide 29 text

29 scala-miniboxing.org Miniboxing Miniboxing let's revisit `def identity` let's revisit `def identity` def identity[T](t: T): T = t def identity_J(T_tag: Byte, t: Long): Long TAG DATA (VALUE) T_tag corresponds to the type parameter, instead of the values being passed around.

Slide 30

Slide 30 text

30 scala-miniboxing.org Miniboxing Miniboxing let's revisit `def identity` let's revisit `def identity` def identity[T](t: T): T = t def identity_J(T_tag: Byte, t: Long): Long TAG DATA (VALUE) T_tag corresponds to the type parameter, instead of the values being passed around. Tag hoisting

Slide 31

Slide 31 text

31 scala-miniboxing.org WE ARE HERE Transform Boil the frog Advantages Other uses Conclusion

Slide 32

Slide 32 text

32 scala-miniboxing.org Transforming Transforming

Slide 33

Slide 33 text

33 scala-miniboxing.org Transforming Transforming could certainly be easier could certainly be easier

Slide 34

Slide 34 text

34 scala-miniboxing.org Transforming Transforming class C[@miniboxed T] { def foo(t: T): T = if (...) t else ??? } could certainly be easier could certainly be easier

Slide 35

Slide 35 text

35 scala-miniboxing.org Transforming Transforming class C[@miniboxed T] { def foo(t: T): T = if (...) t else ??? } could certainly be easier could certainly be easier How to generate foo_J, the miniboxed version of foo?

Slide 36

Slide 36 text

36 scala-miniboxing.org Transforming Transforming def foo_J(t: T): T = if (...) t else ??? could certainly be easier could certainly be easier

Slide 37

Slide 37 text

37 scala-miniboxing.org Transforming Transforming def foo_J(t: T): T = if (...) t else ??? could certainly be easier could certainly be easier ● change T to Long, one variable at a time

Slide 38

Slide 38 text

38 scala-miniboxing.org Transforming Transforming def foo_J(t: T): T = if (...) t else ??? could certainly be easier could certainly be easier ● change T to Long, one variable at a time ● patch up the tree

Slide 39

Slide 39 text

39 scala-miniboxing.org Transforming Transforming def foo_J(t: Long): T = if (...) t // error: found: Long req'd: T else ??? could certainly be easier could certainly be easier ● change T to Long, one variable at a time ● patch up the tree

Slide 40

Slide 40 text

40 scala-miniboxing.org Transforming Transforming def foo_J(t: Long): T = if (...) minibox2box(T_Tag, t) else ??? could certainly be easier could certainly be easier ● change T to Long, one variable at a time ● patch up the tree

Slide 41

Slide 41 text

41 scala-miniboxing.org Transforming Transforming def foo_J(t: Long): T = if (...) minibox2box(T_Tag, t) else ??? could certainly be easier could certainly be easier ● change T to Long, one variable at a time ● patch up the tree

Slide 42

Slide 42 text

42 scala-miniboxing.org Transforming Transforming def foo_J(t: Long): Long = if (...) minibox2box(T_Tag, t) else ??? // error: found: T req'd: Long could certainly be easier could certainly be easier ● change T to Long, one variable at a time ● patch up the tree

Slide 43

Slide 43 text

43 scala-miniboxing.org Transforming Transforming def foo_J(t: Long): Long = box2minibox(T_Tag, if (...) minibox2box(T_Tag, t) else ???) could certainly be easier could certainly be easier ● change T to Long, one variable at a time ● patch up the tree

Slide 44

Slide 44 text

44 scala-miniboxing.org Transforming Transforming def foo_J(t: Long): Long = box2minibox(T_Tag, if (...) minibox2box(T_Tag, t) else ???) could certainly be easier could certainly be easier

Slide 45

Slide 45 text

45 scala-miniboxing.org Transforming Transforming def foo_J(t: Long): Long = box2minibox(T_Tag, if (...) minibox2box(T_Tag, t) else ???) could certainly be easier could certainly be easier ● performance? – we'd be better off boxing everywhere

Slide 46

Slide 46 text

46 scala-miniboxing.org Peephole optimization Peephole optimization def foo_J(t: Long): Long = box2minibox(T_Tag, if (...) minibox2box(T_Tag, t) else ???) to save the day to save the day

Slide 47

Slide 47 text

47 scala-miniboxing.org Peephole optimization Peephole optimization def foo_J(t: Long): Long = box2minibox(T_Tag, if (...) minibox2box(T_Tag, t) else ???) to save the day to save the day ● special case for if – and blocks, and array operations and and and

Slide 48

Slide 48 text

48 scala-miniboxing.org Peephole optimization Peephole optimization def foo_J(t: Long): Long = if (...) box2minibox(minibox2box(t)) else box2minibox(???) to save the day to save the day

Slide 49

Slide 49 text

49 scala-miniboxing.org Peephole optimization Peephole optimization def foo_J(t: Long): Long = if (...) box2minibox(minibox2box(t)) else box2minibox(???) to save the day to save the day ● special case for nested corecions

Slide 50

Slide 50 text

50 scala-miniboxing.org Peephole optimization Peephole optimization def foo_J(t: Long): Long = if (...) t else box2minibox(???) to save the day to save the day

Slide 51

Slide 51 text

51 scala-miniboxing.org Peephole optimization Peephole optimization def foo_J(t: Long): Long = if (...) t else box2minibox(???) to save the day to save the day ● contains too many special cases

Slide 52

Slide 52 text

52 scala-miniboxing.org Peephole optimization Peephole optimization def foo_J(t: Long): Long = if (...) t else box2minibox(???) to save the day to save the day ● contains too many special cases ● tedious and error-prone to write

Slide 53

Slide 53 text

53 scala-miniboxing.org WE ARE HERE Transform Boil the frog Advantages Other uses Conclusion

Slide 54

Slide 54 text

54 scala-miniboxing.org Transforming Transforming

Slide 55

Slide 55 text

55 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog

Slide 56

Slide 56 text

56 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● if you put it in hot water – it jumps out right away

Slide 57

Slide 57 text

57 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● if you put it in hot water – it jumps out right away error: found: T req'd: Long

Slide 58

Slide 58 text

58 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● if you put it in hot water – it jumps out right away – so you need special precautions ● patching up the tree + peephole optimization error: found: T req'd: Long

Slide 59

Slide 59 text

59 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● if you put it in hot water – it jumps out right away – so you need special precautions ● patching up the tree + peephole optimization ● if you put it in cold water – it will like it there :) error: found: T req'd: Long

Slide 60

Slide 60 text

60 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● if you put it in hot water – it jumps out right away – so you need special precautions ● patching up the tree + peephole optimization ● if you put it in cold water – it will like it there :) – and then you slowly heat up the water :D error: found: T req'd: Long

Slide 61

Slide 61 text

61 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog def foo_J(t: T): T = if (...) t else ???

Slide 62

Slide 62 text

62 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● you put it in cold water def foo_J(t: T): T = if (...) t else ???

Slide 63

Slide 63 text

63 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● you put it in cold water def foo_J(t: @storage T): @storage T = if (...) t else ???

Slide 64

Slide 64 text

64 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● you put it in cold water def foo_J(t: @storage T): @storage T = if (...) t else ??? T =:= @storage T

Slide 65

Slide 65 text

65 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● you can easily do rewiring – foo(t) foo_J(t) → , no coercions needed def foo_J(t: @storage T): @storage T = if (...) t else ???

Slide 66

Slide 66 text

66 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog def foo_J(t: @storage T): @storage T = if (...) t else ???

Slide 67

Slide 67 text

67 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● then you heat up the water def foo_J(t: @storage T): @storage T = if (...) t else ???

Slide 68

Slide 68 text

68 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● then you heat up the water def foo_J(t: @storage T): @storage T = if (...) t else ??? T =/= @storage T

Slide 69

Slide 69 text

69 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● then you heat up the water def foo_J(t: @storage T): @storage T = if (...) t else ??? T =/= @storage T retypecheck expected type: @storage T

Slide 70

Slide 70 text

70 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● then you heat up the water def foo_J(t: @storage T): @storage T = if (...) t else ??? T =/= @storage T retypecheck expected type: @storage T

Slide 71

Slide 71 text

71 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● then you heat up the water def foo_J(t: @storage T): @storage T = if (...) t else ??? T =/= @storage T retypecheck expected type: @storage T OK

Slide 72

Slide 72 text

72 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● then you heat up the water def foo_J(t: @storage T): @storage T = if (...) t else ??? T =/= @storage T retypecheck expected type: @storage T

Slide 73

Slide 73 text

73 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● then you heat up the water def foo_J(t: @storage T): @storage T = if (...) t else ??? T =/= @storage T retypecheck expected type: @storage T NO

Slide 74

Slide 74 text

74 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● then you heat up the water def foo_J(t: @storage T): @storage T = if (...) t else box2minibox(???) T =/= @storage T retypecheck expected type: @storage T

Slide 75

Slide 75 text

75 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● then you heat up the water def foo_J(t: @storage T): @storage T = if (...) t else box2minibox(???) T =/= @storage T retypecheck expected type: @storage T OK

Slide 76

Slide 76 text

76 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● then you boil the frog def foo_J(t: @storage T): @storage T = if (...) t else box2minibox(???)

Slide 77

Slide 77 text

77 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● then you boil the frog def foo_J(t: @storage T): @storage T = if (...) t else box2minibox(???) @storage T Long →

Slide 78

Slide 78 text

78 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● then you boil the frog def foo_J(t: Long): Long = if (...) t else box2minibox(T_Tag, ???) @storage T Long →

Slide 79

Slide 79 text

79 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● the three steps are:

Slide 80

Slide 80 text

80 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● the three steps are: T =:= @storage T

Slide 81

Slide 81 text

81 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● the three steps are: T =/= @storage T T =:= @storage T

Slide 82

Slide 82 text

82 scala-miniboxing.org Transforming Transforming is like boiling a frog is like boiling a frog ● the three steps are: @storage T Long → T =/= @storage T T =:= @storage T

Slide 83

Slide 83 text

83 scala-miniboxing.org WE ARE HERE Transform Boil the frog Advantages Other uses Conclusion

Slide 84

Slide 84 text

84 scala-miniboxing.org Boiling the frog Boiling the frog

Slide 85

Slide 85 text

85 scala-miniboxing.org Boiling the frog Boiling the frog T T Long

Slide 86

Slide 86 text

86 scala-miniboxing.org Boiling the frog Boiling the frog is Late Data Layout is Late Data Layout T T Long

Slide 87

Slide 87 text

87 scala-miniboxing.org Boiling the frog Boiling the frog is Late Data Layout is Late Data Layout

Slide 88

Slide 88 text

88 scala-miniboxing.org Boiling the frog Boiling the frog is Late Data Layout is Late Data Layout ● choice made by injecting annotations ● easy to rewrite the tree ● coercions inserted late and on-demand

Slide 89

Slide 89 text

89 scala-miniboxing.org Boiling the frog Boiling the frog is Late Data Layout is Late Data Layout ● choice made by injecting annotations ● easy to rewrite the tree ● coercions inserted late and on-demand def bar: Unit = { this.foo(...) ... }

Slide 90

Slide 90 text

90 scala-miniboxing.org Boiling the frog Boiling the frog is Late Data Layout is Late Data Layout ● choice made by injecting annotations ● easy to rewrite the tree ● coercions inserted late and on-demand def bar: Unit = { this.foo(...) ... } this.foo_J(...)

Slide 91

Slide 91 text

91 scala-miniboxing.org Boiling the frog Boiling the frog is Late Data Layout is Late Data Layout ● choice made by injecting annotations ● easy to rewrite the tree ● coercions inserted late and on-demand def bar: Unit = { this.foo(...) ... } this.foo_J(...) No coercion necessary @storage T <: WildcardType

Slide 92

Slide 92 text

92 scala-miniboxing.org WE ARE HERE Transform Boil the frog Advantages Other uses Conclusion

Slide 93

Slide 93 text

93 scala-miniboxing.org Late Data Layout Late Data Layout is general is general scala.Int int java.lang.Integer Autoboxing

Slide 94

Slide 94 text

94 scala-miniboxing.org Late Data Layout Late Data Layout is general is general Complex Complex (s.Float, s.Float) Autoboxing Value Classes

Slide 95

Slide 95 text

95 scala-miniboxing.org Late Data Layout Late Data Layout is general is general (s.Int, s.Int) s.Long (s.Int, s.Int) Autoboxing Value Classes Encoding

Slide 96

Slide 96 text

96 scala-miniboxing.org Late Data Layout Late Data Layout is general is general T T Long Autoboxing Value Classes Encoding Miniboxing

Slide 97

Slide 97 text

97 scala-miniboxing.org Transform Boil the frog Advantages Other uses Conclusion WE ARE HERE

Slide 98

Slide 98 text

98 scala-miniboxing.org Conclusion Conclusion Late Data Layout Late Data Layout Autoboxing Value Classes Encoding Miniboxing ● type-driven transformation – heavy-lifting in the type system ● generalization – of existing transformations – not tied to erasure ● formalization – thinking about it now