Last updated at 3:33 pm UTC on 16 August 2020
What is an instSpec? The following explanation by Dave Lewis is for V3 image format. A similar explanation applies for Spur, although the details are different.
In the image:
A Behavior has a format, which is an integer number that encodes the kinds and numbers of variables in a class.
The instSpec for a behavior (and hence for a Class or a Trait) is a 4 bit field in the format number, It describes the type of class. Thinking of the format number as 32-bit twos complement, the instSpec field is 2r00000000000000000000011110000000. This field is sufficient to identify the various types of class. For example, Array instSpec ==> 2 has instance spec 2, indicating a class with a variable number of object pointers (i.e. an array of objects).
In the VM (squeakvm.org portable VM and opensmalltalk-vm Cog):
The instSpec for an object in the object memory corresponds to the instSpec of the class of the object. The representation of an object in memory consists of an object header and data associated with the object. The instSpec for that objects is encoded as a 4 bit field within the first word of the object header (see ObjectMemory class comment for a fuller explanation).
Thinking of the first word of an object header as a 32-bit twos complement, the instSpec field is
2r00000000000000000000111100000000. This matches the field in Behavior, but is shifted left one bit to match the internal representation of integers within the object memory (a short integer is an immediate object encoded as if it was the first word of an object header, with value shifted left one bit, and low order bit set to 1 to identifiy it as an immediate integer). In other words, the instSpec field of a Behavior format matches the instSpec field of an object header in the VM object memory.
How the instSpec information gets from the image to the VM:
New object instances are created from primitive calls to primitiveNew (primitive 70) or primitiveNewWithArg (primitive 71). The VM knows the sender of the primitive (it is on the calling stack) which is a Class (a Behavior), so by knowing the Class it knows the desired class format for the instance to be created. It knows this because the third instance variable of a Class (inherited from Behavior) is the format number described above. When creating the new instance in object memory, the primitive maps the information from the Behavior format number (a SmallInteger) into the newly created object header fields.
How the instSpec is used in the image:
In class Behavior, the methods in 'testing' allow for various tests regarding the nature of a class (or a trait). For example, #isBits answers true if the fields and variables of a class are all "bits" (not object pointers), and #isPointers is true if the fields are all object pointers (actual objects, as opposed to raw data for e.g. strings or arrays of floating point values).
How the instSpec is used in the VM:
In ObjectMemory methods for 'header access', the instSpec field (in an object header) is used to determine how to access and interpret the data portion of an object within the object memory. For example, considering the difference between an Array and a ByteArray, the instSpec information allows indexed access to an element (either an object pointer, or an 8 bit byte) in the data portion of the object. Note, an object pointer is a 32-bit value in a V3 image, or a 64-bit value in the 64-bit V3 image. In general, the data fields in an object (in object memory) are 32-bit fields that are mapped to the appropriate data types (bytes, object pointers, others) based on the instSpec.
What kinds of instSpec are defined?
In the V3 image, we have:
instSpec 0: a simple object, such as Object or Boolean or TextAction
instSpec 1: a simple object with instance variables, such as ColorMap
instSpec 2: an variableSubclass object representing a collection of object pointers, such as Array
instSpec 3: a variableSubclass object, such as BlockContext
instSpec 4: a weakSubclass object, such as WeakArray
instSpec 5: (undefined)
instSpec 6: a variableWordSubclass with 32-bit non-pointer words, such as Bitmap or IntegerArray.
instSpec 7: (undefined, could be variableWordSubclass for 64-bit values)
instSpec 8: a variableByteSubclass bit 8-bit values, such as ByteString
instSpec 12: a specialized variableByteSubclass with both object pointer fields and 8-bit fields, such as CompiledMethod, for execution by the virtual machine
Image format specs in standard V3 images:
instSpec isBytes isBits isFixed isWeak kindOfSubclass
0 (0000) false false true false subclass
1 (0001) false false true false subclass
2 (0010) false false false false variableSubclass
3 (0011) false false false false variableSubclass
4 (0100) false false false true weakSubclass
6 (0110) false true false false variableWordSubclass
8 (1000) true true false false variableByteSubclass
12 (1100) true true false false variableByteSubclass
Proposed image format extension to support isLongs in V3 images (isShorts is unsupported on V3):
instSpec isBytes isBits isFixed isWeak isLongs isShorts kindOfSubclass
0 (0000) false false true false false false subclass
1 (0001) false false true false false false subclass
2 (0010) false false false false false false variableSubclass
3 (0011) false false false false false false variableSubclass
4 (0100) false false false true false false weakSubclass
6 (0110) false true false false false false variableWordSubclass
7 (0111) false true false false true false variableDoubleWordSubclass
8 (1000) true true false false false false variableByteSubclass
12 (1100) true true false false false false variableByteSubclass
Thus future usage should be:
0 no fields
1 fixed fields only (all containing pointers)
2 indexable fields only (all containing pointers)
3 both fixed and indexable fields (all containing pointers)
4 both fixed and indexable weak fields (all containing pointers).
6 indexable word fields only (no pointers)
7 indexable long (64-bit) fields
8-11 indexable byte fields only (no pointers) (low 2 bits are low 2 bits of size)
8 indexable byte (8-bit) fields
9-11 unused (reserved for byte addressability)
12-15 compiled methods:
# of literal oops specified in method header,
followed by indexable bytes (same interpretation of low 2 bits as above)