Skip to content

Object Layout

opencode-agent[bot] edited this page May 9, 2026 · 1 revision

Object Layout

The internal memory representation of Java objects in JNode, including the object header, TIB, and instance field layout.

Overview

Every Java object in JNode consists of a fixed-size header followed by instance fields. The header contains metadata the VM needs for type resolution, garbage collection, and method dispatch. Understanding this layout is essential for debugging GC issues, writing native code that manipulates objects, and understanding JIT compiler output.

Object Header Structure

┌─────────────────────────────────────────────────────────────┐
│ OBJECT HEADER │
├─────────────────────┬───────────────────────────────────────┤
│ Flags (1 slot) │ TIB (1 slot) │
│ @ offset -2 │ @ offset -1 │
└─────────────────────┴───────────────────────────────────────┘
│ │
▼ ▼
-2 * SLOT_SIZE -1 * SLOT_SIZE
│ │
▼ ▼
[object start] ──────► Instance Fields Start at Offset 0

The header consists of exactly 2 slots (defined in ObjectLayout.HEADER_SLOTS):

SlotNamePurpose
-2FLAGS_SLOTRuntime flags (interruptibility, finalizeable, etc.)
-1TIB_SLOTReference to the Type Information Block

32-bit vs 64-bit Mode

The slot size depends on the architecture word size:

ModeSLOT_SIZEHeader Size
32-bit4 bytes8 bytes
64-bit8 bytes16 bytes

The offsets are defined as negative indices in ObjectLayout.java because they extend before the object's memory address. The actual object data begins at offset 0.

The TIB (Type Information Block)

The TIB is a reference to an Object[] array that contains type metadata. It is created during class loading in VmType.prepareTIB() and stored in VmClassType.tib.

TIB Structure (defined in TIBLayout)

┌─────────────────────────────────────────────────────────────┐
│ TIB Array │
├─────────┬─────────┬─────────────┬─────────────┬────────────┤
│ Index 0 │ Index 1 │ Index 2 │ Index 3 │ Index 4 │
├─────────┼─────────┼─────────────┼─────────────┼────────────┤
│ VmType │ IMT │ IMT Collisions │ Compiled │ Superclass │
│ │ │ (boolean[]) │ IMT │ array │
└─────────┴─────────┴─────────────┴─────────────┴────────────┘
VMTYPE_INDEX IMT_INDEX IMTCOLLISIONS COMPILED_IMT SUPERCLASSES
INDEX _INDEX _INDEX _INDEX
IndexFieldTypePurpose
0VMTYPE_INDEXVmTypeThe VmType instance for this class
1IMT_INDEXObject[]Interface Method Table for interface method dispatch
2IMTCOLLISIONS_INDEXboolean[]Tracks hash collisions in IMT
3COMPILED_IMT_INDEXObjectArchitecture-specific compiled method table
4SUPERCLASSES_INDEXVmType[]Array of superclasses for method resolution
5+FIRST_METHOD_INDEXVirtual method table (method pointers)

The JIT compilers use the TIB to:

  • Resolve method targets for virtual calls
  • Check object types during type checks
  • Traverse class hierarchy for GC root marking

Instance Field Layout

Instance fields begin immediately after the header at offset 0. Field layout is computed by VmType.layoutInstanceFields() during class loading. Fields are laid out in declaration order, with alignment applied per-field based on type:

  • Reference fields: 4 bytes (32-bit) or 8 bytes (64-bit)
  • Primitive fields: boolean/byte = 1, short/char = 2, int/float = 4, long/double = 8

Object Alignment

All objects are aligned to 8 bytes (ObjectLayout.OBJECT_ALIGN). This is enforced by ObjectLayout.objectAlign():

publicstaticintobjectAlign(intvalue) {
return (value + OBJECT_ALIGN - 1) & ~(OBJECT_ALIGN - 1);
}

This alignment ensures:

  • Efficient access to fields of all sizes
  • Proper handling of long and double fields
  • Better cache line utilization

Key Components

Class / FileRole
core/src/core/org/jnode/vm/classmgr/ObjectLayout.javaDefines header offsets, slot indices, alignment constants
core/src/core/org/jnode/vm/classmgr/TIBLayout.javaTIB array index constants
core/src/core/org/jnode/vm/classmgr/VmType.javaCreates and manages TIB during class loading
core/src/core/org/jnode/vm/classmgr/VmClassType.javaStores the TIB reference (getTIB())
core/src/core/org/jnode/vm/memmgr/def/VmDefaultHeap.javaUses TIB offset for object allocation

How It Works

  1. Class Loading: When a class is loaded, VmType.prepareTIB() creates the TIB array with metadata
  2. Object Allocation: VmDefaultHeap.allocObject() allocates memory and stores the TIB reference at offset -1 * SLOT_SIZE
  3. Method Dispatch: JIT-compiled code loads the TIB from the object header to resolve virtual calls
  4. GC Marking: GCMarkVisitor traverses the TIB as a root during mark phase

Gotchas & Non-Obvious Behavior

  • Negative offsets: The header extends before the object address, so TIB is at objectRef - SLOT_SIZE
  • Interface vs Class: Only class instances have a full TIB. Array types have a minimal TIB. Interface types don't have a TIB at all
  • TIB is shared: All instances of the same class share one TIB object
  • Header size varies: The header is always 2 slots, but slot size differs between 32/64-bit
  • Alignment affects heap: The 8-byte alignment applies to the final object size, not just fields

Related Pages

Clone this wiki locally