SOAR¶
This chapter describes SOAR capabilities and optimizations from the Application developer’s point of view. To get more details on its internal structure, please refer to SOAR Build Phases section.
Java Symbols Encoding¶
Java symbols are any of package, type, method, field, or local names.
In .class
files, they are encoded in UTF-8
.
However, SOAR only supports Java symbols composed of characters that can be stored on 8 bits (unsigned byte).
This is typically the case of ISO-8859-X encoding family.
If you try to build an Application that includes an unsupported Java symbol you will get the following error:
Unsupported Java symbol XXX in file YYY. A character cannot be stored on an unsigned byte.
Note
Classpath *.list
files are standard Java properties files that are encoded in ISO-8859-1
(Latin-1).
If you need to refer to a Java Symbol that contains a character out of this charset, you must declare the character using the \uHHHH
notation where HHHH is the hexadecimal index of the character in the Unicode character set.
Class Initialization Code¶
SOAR complies with the deterministic class initialization (<clinit>
)
order specified in [BON] specification. The application is statically analyzed from
its entry points in order to generate a clinit dependency graph. The
computed clinit sequence is the result of the topological sort of the
dependency graph. An error is thrown if the clinit dependency graph
contains cycles.
A clinit map file (ending with extension .clinitmap
) is generated
beside the SOAR object file. It describes for each clinit dependency:
- the types involved
- the kind of dependency
- the stack calls between the two types
In case of complex clinit code with too many runtime dependencies, the statically computed clinit order may be wrong.
It is then possible to help SOAR by manually declaring explicit clinit dependencies.
Such dependencies are declared in XML files with the .clinitdesc
extension in the application classpath.
The file has the following format:
<?xml version='1.0' encoding='UTF-8'?>
<clinit>
<type name="T1" depends="T2"/>
</clinit>
where T1
and T2
are fully qualified names on the form a.b.C
.
This explicitly forces SOAR to create a dependency from T1
to
T2
, and therefore cuts a potentially detected dependency from T2
to T1
.
Method Devirtualization¶
Method devirtualization consists of transforming a virtual method call to a direct method call when possible. A virtual method call is a call to a non-private instance method declared either in an interface or in a class. The Core Engine determines the proper method to call at runtime depending on the actual class of the object. A call to a constructor or a private method is already optimized as a direct method call by the Java compiler.
SOAR automatically optimizes a virtual method call to a direct method call if there is one and only one embedded implementation method.
Note
SOAR generates the list of the embedded methods in the SOAR Information File.
Method Inlining¶
Method inlining consists of replacing a direct method call with the content of the method. This avoids the creation of a new stack frame context, which can be slower than executing the code itself. Method inlining is transitively applied from leaf to root methods.
The following method code patterns are inlined:
- empty code after processing assertions and if code removal.
- call to a constructor with no parameters.
- call to a private method with no parameters.
- call to a static method with no parameters, if and only if the caller is also a static method.
Note
Method inlining is performed after method devirtualization, so a virtual method call will be inlined if there is a unique embedded implementation method that matches one of the inlined method code patterns.