-
Notifications
You must be signed in to change notification settings - Fork 0
Type System Internals
The VM's class representation system, from VmType to TIB construction.
JNode's type system centers on VmType and its subclasses, which provide the runtime representation of Java classes. The type system manages class loading, linking (verification, preparation, compilation), field layout, and the Type Information Block (TIB) construction that enables object method dispatch.
| Class | File | Purpose |
|---|---|---|
VmType |
classmgr/VmType.java |
Abstract base for all type representations |
VmClassType |
classmgr/VmClassType.java |
Base for class and interface types |
VmNormalClass |
classmgr/VmNormalClass.java |
Regular class (non-interface, non-array) |
VmArrayClass |
classmgr/VmArrayClass.java |
Array type |
VmInterfaceClass |
classmgr/VmInterfaceClass.java |
Interface type |
VmPrimitiveClass |
classmgr/VmPrimitiveClass.java |
Primitive type (int, boolean, etc.) |
TIBBuilder |
classmgr/TIBBuilder.java |
Constructs the Type Information Block |
ObjectLayout |
classmgr/ObjectLayout.java |
Calculates field offsets and object size |
VmClassLoader |
classmgr/VmClassLoader.java |
Class loading orchestration |
TIBLayout |
classmgr/TIBLayout.java |
TIB array index constants |
VmType (abstract)
├── VmClassType
│ ├── VmNormalClass
│ └── VmInterfaceClass
├── VmArrayClass
└── VmPrimitiveClass
-
VmTypeprovides common fields (name, classloader, constant pool, state flags, method/field tables) -
VmClassTypeextends VmType for class-like types (has superclass, modifiers) -
VmNormalClassadds object size and reference offset tracking -
VmArrayClasstracks component type and array-specific properties -
VmPrimitiveClassrepresents built-in types (boolean, int, etc.)
The loading pipeline proceeds through defined states (see VmTypeState):
- LOADED — Class bytes parsed, VmType created
- PREPARING — Superclass and interfaces loaded, field layout calculated
- PREPARED — Memory manager type created, TIB allocated
- VERIFYING — Bytecode verification
- VERIFIED — Verification complete
- COMPILING — JIT compilation of methods
- COMPILED — Native code ready
- LINKED — All preparation complete
-
INITIALIZING/INITIALIZED —
<clinit>executed
The entry point is VmClassLoader.loadClass():
public Class<?> loadClass(String name, boolean resolve) {
VmType result = loadClassImpl(name, resolve);
// For reflection, convert to java.lang.Class
return result.asClass();
}The VmType.link() method orchestrates the three-phase linking:
public final VmType link() {
if (!isLinked()) {
prepare(); // Field layout, TIB creation
verify(); // Bytecode verification
compile(); // JIT compile methods
// ...
state |= VmTypeState.ST_LINKED;
}
return this;
}Preparation (doPrepare in VmType):
- Load and prepare superclass
- Resolve implemented interfaces
- Calculate object size via
ObjectLayout - Assign field offsets (including alignment)
- Build
allInterfaceTable(transitive interface closure) - Construct TIB via
TIBBuilder
ObjectLayout calculates instance field offsets:
public static int calculateObjectSize(VmNormalClass<?> clazz) {
int size = OBJECT_HEADER_SIZE; // Flags (4) + TIB reference (4) = 8 bytes
// Walk superclass chain to get inherited field sizes
VmType superClass = clazz.getSuperClass();
if (superClass != null) {
size += ((VmNormalClass)superClass).getObjectSize();
}
// Add this class's fields with 8-byte alignment
for (VmField field : clazz.getDeclaredFields()) {
if (!field.isStatic()) {
size = align(size, field.getTypeSize());
size += field.getTypeSize();
}
}
return size;
}Alignment rules:
- Reference fields aligned to pointer size (4 or 8 bytes)
- long/double fields aligned to 8 bytes
- Object size padded to 8-byte multiple
Reference offsets are collected for GC during preparation.
The Type Information Block (TIB) is a per-class Object array containing:
| Index | Content |
|---|---|
| 0 | VmType reference (class pointer) |
| 1 | IMT (Interface Method Table) |
| 2 | IMT collision flags array |
| 3 | Compiled IMT |
| 4 | Superclasses array |
| 5+ | vtable (virtual method pointers) |
TIBBuilder.buildTIB() creates this structure:
public Object[] buildTIB(VmType type, VmInterfaceClass[] allInterfaces) {
Object[] tib = new Object[calculateTIBSize()];
// Index 0: VmType reference
tib[TIBLayout.VMTYPE_INDEX] = type;
// Index 1-4: IMT, collisions, compiled IMT, superclasses
tib[TIBLayout.IMT_INDEX] = buildIMT(type, allInterfaces);
tib[TIBLayout.IMTCOLLISIONS_INDEX] = new boolean[64];
tib[TIBLayout.COMPILED_IMT_INDEX] = null;
tib[TIBLayout.SUPERCLASSES_INDEX] = buildSuperclassesArray(type);
// Index 5+: vtable methods
int methodIndex = TIBLayout.FIRST_METHOD_INDEX;
for (VmMethod m : type.getVirtualMethods()) {
tib[methodIndex++] = getMethodAddress(m);
}
return tib;
}The TIB is accessed at object header offset -1 (just before the Flags word).
The constant pool (VmCP) contains symbolic references that are resolved on demand:
public Object resolveConstant(int index) {
VmCPEntry entry = getEntry(index);
switch (entry.getType()) {
case CONSTANT_CLASS:
return resolveClass((VmConstClass)entry);
case CONSTANT_FIELD:
return resolveField((VmConstFieldRef)entry);
case CONSTANT_METHOD:
return resolveMethod((VmConstMethodRef)entry);
case CONSTANT_STRING:
return resolveString((VmConstString)entry);
// ...
}
}Resolution lazy-loads referenced classes and verifies method/field existence and accessibility.
-
Recursive preparation: Calling
getSuperClass()during preparation triggers recursive load; the state machine prevents infinite recursion - TIB allocation: TIB is allocated in the boot image for system classes, dynamically for others
- Interface method dispatch: Uses a 64-element hash table (IMT) with collision chains; the compiled IMT provides faster dispatch
- Reference offsets: Collected during preparation for GC; must be recalculated when field layout changes
-
Statics isolation: Classes can have
@SharedStatics(shared across isolates) or isolate-specific statics via separate allocation
- Object-Layout — Object header structure, TIB embedding
- Virtual-Methods — vtable and IMT dispatch mechanisms
- JIT-Compilers — How methods get compiled
- Architecture — Type system in the broader system context