-
Notifications
You must be signed in to change notification settings - Fork 17
Details | Miniboxing Transformation Prototyping
Exploring different designs for the miniboxing transformation is the key to ensuring the optimality of the resulting miniboxed code. This page will highlight the Scala compiler features that allowed us to explore many aspects of the miniboxing transformation without the need to code a full language translation form the beginning.
The internal AST representation of the Scala code as it is transformed by each compiler phase, one of which is miniboxing, is actually very close to Scala source code. It becomes harder to read due to the verbose nature of AST nodes after name resolution and typechecking, but in most cases the correspondence between Scala code and the AST can still be followed. To see examples of how to run miniboxing on your own code and check the output of different phases, please have a look at the running the plugin page.
The side-by-side code comparison page gives some examples of code generated from the manual miniboxing transformation and compares them to the code generated by the miniboxing plugin.
Fortunately, the Scala language is very versatile, allowing users to express both high and low-level features at the same time. To give an example of this, we can look at accessors:
class C[T] {
var c: T = ???
}
Will actually be transformed by the Scala compiler to three members:
class C[T] {
// explicit class constructor omitted
private[this] var _c: T = ???
def c: T = _c // getter for the _c field
def c_=(t: T) = _c = t // setter for the _c field
}
Both pieces of Scala source code above can actually be compiled, thus allowing a programmer to express both the higher-level and lower-level. If we look at the Java bytecode translation for both pieces of code, we can observe the fact that they are similar, modulo some name differences.
Curried parameters allow programmers to partially apply a method. For example:
def foo(t: Tag)(p: Parmeter) = ???
But in order to generate valid bytecode for the Java Virtual Machine, the Scala compiler needs to transform such methods into straight-line parameters. Knowing such a transformation phase will take place lets us write all code as straight-line parameters, without fearing performance degradation:
def foo(t: Tag, p: Parmeter) = ???
Many constructs in Scala (for comprehensions, pattern matching) can be seen as smart syntactic sugar, which the compiler decodes into lower-level features which are compatible with the Java Virtual Machine. Knowing how these lowerings work and being able to express the lowered code in Scala allows us to prepare code which is almost identical to the lower-level AST generated by the Scala compiler, without without fearing the performance will change. Of course, the manually translated code usually looks more complex than necessary, but it is important to keep the correct translation semantics. In the end, any simplification we do compared to the translations in Scala can lead to differences between the performance of manually translated code vs automatically translated code, in the plugin.
You can continue with the following resources: