org.jikesrvm.classloader
Class DynamicTypeCheck

java.lang.Object
  extended by org.jikesrvm.classloader.DynamicTypeCheck
All Implemented Interfaces:
TIBLayoutConstants

public class DynamicTypeCheck
extends Object
implements TIBLayoutConstants

Data structures and code for fast dynamic type checking.

As a convention, we convert all dynamic type checking operations into the following question: LHS :?= RHS (i.e. can an instance of the RHS class be stored in a variable of the LHS class or interface.) This question arises for four bytecodes: instanceof, checkcast, aastore and invokeinterface and entry into catch blocks. This gives us a uniform terminology, but in some cases (instanceof) can be somewhat counter-intuitive since despite the fact that the Java source code is written as x instanceof C, for the purposes of dynamic type checking x is the RHS and C is the LHS!

The idea of the optimizations presented below is to treat each context in which these queries arises as a special case to be optimised in isolation. Consider the following taxonomy of dynamic type checking conexts:

(1) Is the LHS unknown at compile time? True only for aastore? If so, the following test will be fast in most instances: is the runtime type of the LHS array the same as compile-time type of the variable that contains it? If so, the Java-to-bytecode compiler (and the verifier) guarantees that the test passes. Unfortunately, this test can only be used in two of three cases: when the LHS variable is a field or a parameter. When the LHS is in a local variable the Java-to-bytecode compiler has thrown away the necessary type information.

(2) Otherwise, is the LHS an array? If so, there are three sub-cases (2a) LHS is [^k primitive: If so, the dimensionality of the RHS must be k and the baseclass of the RHS must be the same primitive (2b) LHS is [^k class: If so, the dimensionality of the RHS must be k and the baseclass of the RHS must be assignable with class (see #3) _OR_ the dimensionality of the RHS must be >k and the baseclass of the LHS is java.lang.Cloneable or java.io.Serializable (2c) LHS is [^k Ljava.lang.Object: If so, either the dimensionality of the RHS is greater than k or, this dimensionality is k and the baseclass is NOT primitive

(3) Otherwise, is the LHS unresolved? If so, fall back to calling RuntimeEntrypoints.instanceOf at runtime which will load/resolve the types and then call DynamicTypeCheck.instanceOf.

(4) Otherwise, is the LHS an interface? If so, query the doesImplement array of the RHS's TIB at the entry for the interface ID. If a class does not directly implement any interfaces then it inherits the doesImplement array from its superclass.

(5) Otherwise, is the depth of the LHS greater than MIN_SUPERCLASS_IDS_SIZE? If so, if LHS depth is greater that RHS's superclassIds.length, the test fails. Else, see #6.

(6) Otherwise. If the LHS depth component of the RHS's superclassIds array is the LHS class ID, the test succeeds. Else, it fails.

See Also:
DynamicTypeCheckExpansion, RVMType, RVMClass, RVMArray

Field Summary
private static int[] arrayDoesImplement
           
static int MIN_DOES_IMPLEMENT_SIZE
          Minimum length of the doesImplements array in TIB.
static int MIN_SUPERCLASS_IDS_SIZE
          Minimum length of the superclassIds array in TIB.
 
Fields inherited from interface org.jikesrvm.objectmodel.TIBLayoutConstants
IMT_METHOD_SLOTS, NEEDS_DYNAMIC_LINK, TIB_ARRAY_ELEMENT_TIB_INDEX, TIB_DOES_IMPLEMENT_INDEX, TIB_FIRST_SPECIALIZED_METHOD_INDEX, TIB_FIRST_VIRTUAL_METHOD_INDEX, TIB_INTERFACE_DISPATCH_TABLE_INDEX, TIB_SUPERCLASS_IDS_INDEX, TIB_TYPE_INDEX
 
Constructor Summary
DynamicTypeCheck()
           
 
Method Summary
(package private) static int[] buildDoesImplement(RVMArray t)
          Create the doesImplement vector for a RVMArray.
(package private) static int[] buildDoesImplement(RVMClass t)
          Create the doesImplement vector for a RVMClass.
(package private) static short[] buildSuperclassIds(RVMType t)
          Create the superclass Id vector for a RVMType.
static boolean instanceOfClass(RVMClass LHSclass, TIB rhsTIB)
          LHSclass is a fully loaded class.
static boolean instanceOfInterface(RVMClass LHSclass, TIB rhsTIB)
          LHSclass is a fully loaded interface.
static boolean instanceOfNonArray(RVMClass LHSclass, TIB rhsTIB)
          LHSclass is a fully loaded class or interface.
static boolean instanceOfResolved(RVMType LHSType, RVMType RHSType)
          Can we store an object of type RHSType in a variable of type LHSType?
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

MIN_SUPERCLASS_IDS_SIZE

public static final int MIN_SUPERCLASS_IDS_SIZE
Minimum length of the superclassIds array in TIB. Note: this array is padded to save a index out of bounds test for classes with shallow class depth.

See Also:
Constant Field Values

MIN_DOES_IMPLEMENT_SIZE

public static final int MIN_DOES_IMPLEMENT_SIZE
Minimum length of the doesImplements array in TIB. Note: this array is padded to save a index out of bounds test for the first 32 * MIN_DOES_IMPLEMENT_SIZE interfaces loaded.

See Also:
Constant Field Values

arrayDoesImplement

private static int[] arrayDoesImplement
Constructor Detail

DynamicTypeCheck

public DynamicTypeCheck()
Method Detail

buildSuperclassIds

static short[] buildSuperclassIds(RVMType t)
Create the superclass Id vector for a RVMType.

Parameters:
t - a RVMType to create a superclass Id vector for
Returns:
the superclass Id vector

buildDoesImplement

static int[] buildDoesImplement(RVMArray t)
Create the doesImplement vector for a RVMArray. All arrays implement exactly java.io.Serializable and java.lang.Cloneable.

Parameters:
t - a RVMArray to create a doesImplement vector for
Returns:
the doesImplement vector

buildDoesImplement

static int[] buildDoesImplement(RVMClass t)
Create the doesImplement vector for a RVMClass.

Parameters:
t - a RVMClass to create a doesImplement vector for
Returns:
the doesImplement vector

instanceOfNonArray

public static boolean instanceOfNonArray(RVMClass LHSclass,
                                         TIB rhsTIB)
LHSclass is a fully loaded class or interface. Is rhsTIB the TIB of an instanceof LHSclass?

Parameters:
LHSclass - a fully loaded class or interface class
rhsTIB - the TIB of an object that might be an instance of LHSclass
Returns:
true if the object is an instance of LHSClass or false if it is not

instanceOfClass

public static boolean instanceOfClass(RVMClass LHSclass,
                                      TIB rhsTIB)
LHSclass is a fully loaded class. Is rhsTIB the TIB of a subclass of LHSclass?

Parameters:
LHSclass - a (fully loaded) class
rhsTIB - the TIB of an object that might be an instance of LHSclass
Returns:
true if the object is an instance of LHSClass or false if it is not

instanceOfInterface

public static boolean instanceOfInterface(RVMClass LHSclass,
                                          TIB rhsTIB)
LHSclass is a fully loaded interface. Is rhsTIB the TIB of a class that implements LHSclass?

Parameters:
LHSclass - a class (that is a fully loaded interface)
rhsTIB - the TIB of an object that might be an instance of LHSclass
Returns:
true if the object is an instance of LHSClass or false if it is not

instanceOfResolved

public static boolean instanceOfResolved(RVMType LHSType,
                                         RVMType RHSType)
Can we store an object of type RHSType in a variable of type LHSType? Assumption. LHSType and RHSType are already resolved.

Parameters:
LHSType - the left-hand-side type
RHSType - the right-hand-size type
Returns:
true if we can store an object of RHSType into a variable of type LSType or false if we cannot.