public class EnumOrdinalizer
extends Object
This optimizer replaces enum constants with their ordinal value (a simple
int) when possible. We call this process "ordinalization".
Generally, this can be done for enums that are only ever referred to by
reference, or by their ordinal value. For the specific set of conditions
under which ordinalization can proceed, see the notes for the nested class
EnumOrdinalizer.CannotBeOrdinalAnalyzer
below.
This optimizer modifies enum classes to change their field constants to ints,
and to remove initialization of those constants in the clinit method. An
ordinalized enum class will not be removed from the AST by this optimizer,
but as long as all references to it are replaced, then the enum class itself
will be pruned by subsequent optimizer passes. Some enum classes may not be
completely removed however. Ordinalization can proceed in cases where there
are added static fields or methods in the enum class. In such cases a reduced
version of the original enum class can remain in the AST, containing only
static fields and methods which aren't part of the enum infrastructure (in
which case it will no longer behave as an enum class at all).
Regardless of whether an ordinalized enum class ends up being completely
pruned away, the AST is expected to be in a coherent and usable state after
any pass of this optimizer. Thus, this optimizer should be considered to be
stateless.
The process is broken up into 3 separate passes over the AST, each
implemented as a separate visitor class. The first visitor,
EnumOrdinalizer.CannotBeOrdinalAnalyzer
compiles information about
each enum class in the AST, and looks for reasons not to ordinalize each
enum. Thus, it prepares a "black-list" of enum classes that cannot be
ordinalized (and it follows that all enums that don't get entered in the
black-list, will be allowed to be ordinalized. The set of conditions which
cause an enum to be black-listed are outlined below.
If there are enum classes that didn't get black-listed remaining, the
subsequent passes of the optimizer will be invoked. The first,
EnumOrdinalizer.ReplaceEnumTypesWithInteger
, replaces the type info
for each field or expression involved with a target enum constant with an
integer. The final visitor, descriptively named
EnumOrdinalizer.ReplaceOrdinalFieldAndMethodRefsWithOrdinal
, will do
the job of replacing the value for references to the Enum ordinal field or
method of an enum constant that has been ordinalized.