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

Late Data Layout - Initial Presentation

Vlad Ureche
February 11, 2014

Late Data Layout - Initial Presentation

This presentation shows how the miniboxing plugin transforms complex code structures without invalidating any of the Scala tree invariants.

Project website: http://scala-ldl.org

Vlad Ureche

February 11, 2014
Tweet

More Decks by Vlad Ureche

Other Decks in Technology

Transcript

  1. 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

    View Slide

  2. 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

    View Slide

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

    View Slide

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

    View Slide

  5. 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

    View Slide

  6. 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

    View Slide

  7. 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

    View Slide

  8. 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

    View Slide

  9. 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

    View Slide

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

    View Slide

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

    View Slide

  12. 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

    View Slide

  13. 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

    View Slide

  14. 14
    scala-miniboxing.org
    Miniboxing
    Miniboxing

    View Slide

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

    View Slide

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

    View Slide

  17. 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

    View Slide

  18. 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

    View Slide

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

    View Slide

  20. 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 =

    View Slide

  21. 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 =

    View Slide

  22. 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 =

    View Slide

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

    View Slide

  24. 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

    View Slide

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

    View Slide

  26. 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

    View Slide

  27. 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

    View Slide

  28. 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)

    View Slide

  29. 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.

    View Slide

  30. 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

    View Slide

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

    View Slide

  32. 32
    scala-miniboxing.org
    Transforming
    Transforming

    View Slide

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

    View Slide

  34. 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

    View Slide

  35. 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?

    View Slide

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

    View Slide

  37. 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

    View Slide

  38. 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

    View Slide

  39. 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

    View Slide

  40. 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

    View Slide

  41. 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

    View Slide

  42. 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

    View Slide

  43. 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

    View Slide

  44. 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

    View Slide

  45. 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

    View Slide

  46. 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

    View Slide

  47. 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

    View Slide

  48. 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

    View Slide

  49. 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

    View Slide

  50. 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

    View Slide

  51. 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

    View Slide

  52. 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

    View Slide

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

    View Slide

  54. 54
    scala-miniboxing.org
    Transforming
    Transforming

    View Slide

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

    View Slide

  56. 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

    View Slide

  57. 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

    View Slide

  58. 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

    View Slide

  59. 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

    View Slide

  60. 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

    View Slide

  61. 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
    ???

    View Slide

  62. 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
    ???

    View Slide

  63. 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
    ???

    View Slide

  64. 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

    View Slide

  65. 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
    ???

    View Slide

  66. 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
    ???

    View Slide

  67. 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
    ???

    View Slide

  68. 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

    View Slide

  69. 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

    View Slide

  70. 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

    View Slide

  71. 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

    View Slide

  72. 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

    View Slide

  73. 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

    View Slide

  74. 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

    View Slide

  75. 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

    View Slide

  76. 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(???)

    View Slide

  77. 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

    View Slide

  78. 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

    View Slide

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

    the three steps are:

    View Slide

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

    the three steps are:
    T =:= @storage T

    View Slide

  81. 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

    View Slide

  82. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  88. 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

    View Slide

  89. 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(...)
    ...
    }

    View Slide

  90. 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(...)

    View Slide

  91. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  95. 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

    View Slide

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

    View Slide

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

    View Slide

  98. 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

    View Slide