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.