public class DynamicTypeCheck extends Object
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
(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.
For details about the expansion of type checks in the optimizing compiler, see the transformation from high level IR to low level IR.
Modifier and Type | Field and Description |
---|---|
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.
|
Constructor and Description |
---|
DynamicTypeCheck() |
Modifier and Type | Method and Description |
---|---|
(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?
|
public static final int MIN_SUPERCLASS_IDS_SIZE
public static final int MIN_DOES_IMPLEMENT_SIZE
private static int[] arrayDoesImplement
public DynamicTypeCheck()
static short[] buildSuperclassIds(RVMType t)
t
- a RVMType to create a superclass Id vector forstatic int[] buildDoesImplement(RVMArray t)
t
- a RVMArray to create a doesImplement vector forstatic int[] buildDoesImplement(RVMClass t)
t
- a RVMClass to create a doesImplement vector forpublic static boolean instanceOfNonArray(RVMClass LHSclass, TIB rhsTIB)
LHSclass
- a fully loaded class or interface classrhsTIB
- the TIB of an object that might be an instance of LHSclasstrue
if the object is an instance of LHSClass
or false
if it is notpublic static boolean instanceOfClass(RVMClass LHSclass, TIB rhsTIB)
LHSclass
- a (fully loaded) classrhsTIB
- the TIB of an object that might be an instance of LHSclasstrue
if the object is an instance of LHSClass
or false
if it is notpublic static boolean instanceOfInterface(RVMClass LHSclass, TIB rhsTIB)
LHSclass
- a class (that is a fully loaded interface)rhsTIB
- the TIB of an object that might be an instance of LHSclasstrue
if the object is an instance of LHSClass
or false
if it is notpublic static boolean instanceOfResolved(RVMType LHSType, RVMType RHSType)
LHSType
- the left-hand-side typeRHSType
- the right-hand-size typetrue
if we can store an object of
RHSType into a variable of type LSType
or false
if we cannot.