Simple inliner.
The Inlining phase.
A standard phase template
The global environment; overridden by instantiation in Global.
The global environment; overridden by instantiation in Global.
List of phase names, this phase should run after
List of phase names, this phase should run after
Phase name this phase will attach itself to, not allowing any phase to come between it and the phase name declared
Phase name this phase will attach itself to, not allowing any phase to come between it and the phase name declared
Maximum loop iterations.
The maximum size in basic blocks of methods considered for inlining.
Small method size (in blocks)
SubComponent are added to a HashSet and two phases are the same if they have the same name
SubComponent are added to a HashSet and two phases are the same if they have the same name
Internal flag to tell external from internal phases
Internal flag to tell external from internal phases
Is the given class a closure?
Look up implementation of method 'sym in 'clazz'.
Create a new phase
Create a new phase
The phase corresponding to this subcomponent in the current compiler run
The phase corresponding to this subcomponent in the current compiler run
The name of the phase
The name of the phase
New flags defined by the phase which are not valid before
New flags defined by the phase which are not valid before
New flags defined by the phase which are not valid until immediately after it
New flags defined by the phase which are not valid until immediately after it
List of phase names, this phase should run before
List of phase names, this phase should run before
(inliners: StringAdd).self
(inliners: StringFormat).self
(inliners: ArrowAssoc[Inliners]).x
(Since version 2.10.0) Use leftOfArrow
instead
(inliners: Ensuring[Inliners]).x
(Since version 2.10.0) Use resultOfEnsuring
instead
Inliner balances two competing goals: (a) aggressive inlining of: (a.1) the apply methods of anonymous closures, so that their anon-classes can be eliminated; (a.2) higher-order-methods defined in an external library, e.g.
Range.foreach()
among many others. (b) circumventing the barrier to inter-library inlining that private accesses in the callee impose.Summing up the discussion in SI-5442 and SI-5891, the current implementation achieves to a large degree both goals above, and overcomes a problem exhibited by previous versions:
(1) Problem: Attempting to access a private member
p
at runtime resulting in anIllegalAccessError
, wherep
is defined in a library L, and is accessed from a library C (for Client), where C was compiled against L', an optimized version of L where the inliner madep
public at the bytecode level. The only such members are fields, either synthetic or isParamAccessor, and thus having a dollar sign in their name (the accesibility of methods and constructors isn't touched by the inliner).Thus we add one more goal to our list: (c) Compile C (either optimized or not) against any of L or L', so that it runs with either L or L' (in particular, compile against L' and run with L).
The chosen strategy is described in some detail in the comments for
accessRequirements()
andpotentiallyPublicized()
. Documentation at http://lamp.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/2011Q4/Inliner.pdf