VM Maker: VMMaker.oscog-eem.2081.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

VM Maker: VMMaker.oscog-eem.2081.mcz

commits-2
 
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2081.mcz

==================== Summary ====================

Name: VMMaker.oscog-eem.2081
Author: eem
Time: 10 January 2017, 5:02:06.508527 pm
UUID: 191ab786-20f3-4cab-9b9c-e0c0f21743fb
Ancestors: VMMaker.oscog-eem.2080

Spur:
Fix primitive 105 to work for 64- and 16-bit arrays, and fix the bug there-in that failed for different length mod 4 32-bit arrays on 64-bits.

Split primitive 105 into a Spur and a V3 version.

Fix all the comments that were unsure about the reality of 64-bit word arrays.

=============== Diff against VMMaker.oscog-eem.2080 ===============

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genGetSizeOf:into:formatReg:scratchReg:abortJumpsInto: (in category 'primitive generators') -----
  genGetSizeOf: sourceReg into: destReg formatReg: formatReg scratchReg: scratchReg abortJumpsInto: aBinaryBlock
  "Get the size of the non-immediate object in sourceReg into destReg using formatReg
  and scratchReg as temps.  None of these registers can overlap.  Supply the jumps
  taken if the object in sourceReg is not indexable, or if the object in sourceReg is a
  context.. Hack: If the object has a pointer format other than 2 leave the number of
  fixed fields in formatReg.  Used by primitiveSize, primitiveAt, and primitiveAtPut"
  <returnTypeC: #'AbstractInstruction *'>
  | jumpNotIndexable
   jumpBytesDone jumpShortsDone jumpArrayDone jump32BitLongsDone
   jumpIsBytes jumpHasFixedFields jumpIsShorts jumpIsContext  |
  <inline: true>
  "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  <var: #jumpIsBytes type: #'AbstractInstruction *'>
  <var: #jumpIsShorts type: #'AbstractInstruction *'>
  <var: #jumpIsContext type: #'AbstractInstruction *'>
  <var: #jumpArrayDone type: #'AbstractInstruction *'>
  <var: #jumpNotIndexable type: #'AbstractInstruction *'>
  <var: #jumpHasFixedFields type: #'AbstractInstruction *'>
  <var: #jump32BitLongsDone type: #'AbstractInstruction *'>
 
  "formatReg := self formatOf: sourceReg"
  self genGetFormatOf: sourceReg
  into: formatReg
  leastSignificantHalfOfBaseHeaderIntoScratch: scratchReg.
 
  self genGetNumSlotsOf: sourceReg into: destReg.
 
  "dispatch on format in a combination of highest dynamic frequency order first and convenience.
   0 = 0 sized objects (UndefinedObject True False et al)
   1 = non-indexable objects with inst vars (Point et al)
   2 = indexable objects with no inst vars (Array et al)
   3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
   4 = weak indexable objects with inst vars (WeakArray et al)
   5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
   6 unused, reserved for exotic pointer objects?
   7 Forwarded Object, 1st field is pointer, rest of fields are ignored
   8 unused, reserved for exotic non-pointer objects?
+  9 64-bit indexable
-  9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  jumpIsBytes := cogit JumpGreaterOrEqual: 0.
  cogit CmpCq: objectMemory arrayFormat R: formatReg.
  jumpArrayDone := cogit JumpZero: 0.
  jumpNotIndexable := cogit JumpLess: 0.
  cogit CmpCq: objectMemory weakArrayFormat R: formatReg.
  jumpHasFixedFields := cogit JumpLessOrEqual: 0.
  cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  jumpIsShorts := cogit JumpGreaterOrEqual: 0.
  cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  jump32BitLongsDone := cogit JumpGreaterOrEqual: 0.
  "For now ignore 64-bit indexability."
  jumpNotIndexable jmpTarget: cogit Label.
  jumpNotIndexable := cogit Jump: 0.
 
  jumpIsBytes jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: destReg).
  cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  cogit SubR: formatReg R: destReg.
  jumpBytesDone := cogit Jump: 0.
 
  jumpIsShorts jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: destReg).
  cogit AndCq: 1 R: formatReg.
  cogit SubR: formatReg R: destReg.
  jumpShortsDone := cogit Jump: 0.
 
  "formatReg contains fmt, now up for grabs.
  destReg contains numSlots, precious.
  sourceReg must be preserved"
  jumpHasFixedFields jmpTarget:
  (cogit AndCq: objectMemory classIndexMask R: scratchReg).
  cogit MoveR: scratchReg R: formatReg.
  cogit CmpCq: ClassMethodContextCompactIndex R: scratchReg.
  jumpIsContext := cogit JumpZero: 0.
  cogit PushR: destReg.
  self genGetClassObjectOfClassIndex: formatReg into: destReg scratchReg: scratchReg.
  self genLoadSlot: InstanceSpecificationIndex sourceReg: destReg destReg: formatReg.
  self genConvertSmallIntegerToIntegerInReg: formatReg.
  cogit
  PopR: destReg;
  AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;
  SubR: formatReg R: destReg.
 
  jumpArrayDone jmpTarget:
  (jump32BitLongsDone jmpTarget:
  (jumpShortsDone jmpTarget:
  (jumpBytesDone jmpTarget:
  cogit Label))).
  aBinaryBlock value: jumpNotIndexable value: jumpIsContext!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genPrimitiveAt (in category 'primitive generators') -----
  genPrimitiveAt
  | formatReg nSlotsOrBytesReg convertToIntAndReturn methodInBounds
   jumpNotIndexable jumpImmediate jumpBadIndex
   jumpIsBytes jumpIsShorts jumpIsWords jumpIsMethod
   jumpWordTooBig jumpIsArray jumpHasFixedFields jumpIsContext
   jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds
   jumpMethodOutOfBounds jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds |
  "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  <var: #jumpIsBytes type: #'AbstractInstruction *'>
  <var: #jumpIsShorts type: #'AbstractInstruction *'>
  <var: #jumpIsMethod type: #'AbstractInstruction *'>
  <var: #jumpBadIndex type: #'AbstractInstruction *'>
  <var: #jumpIsContext type: #'AbstractInstruction *'>
  <var: #jumpImmediate type: #'AbstractInstruction *'>
  <var: #methodInBounds type: #'AbstractInstruction *'>
  <var: #jumpWordTooBig type: #'AbstractInstruction *'>
  <var: #jumpNotIndexable type: #'AbstractInstruction *'>
  <var: #jumpHasFixedFields type: #'AbstractInstruction *'>
  <var: #convertToIntAndReturn type: #'AbstractInstruction *'>
  <var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpMethodOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpFixedFieldsOutOfBounds type: #'AbstractInstruction *'>
 
  nSlotsOrBytesReg := ClassReg.
 
  cogit genLoadArgAtDepth: 0 into: Arg0Reg.
  jumpImmediate := self genJumpImmediate: ReceiverResultReg.
  cogit MoveR: Arg0Reg R: Arg1Reg.
  jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
  self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
  cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"
 
  "formatReg := self formatOf: ReceiverResultReg"
  self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.
 
  self genGetNumSlotsOf: ReceiverResultReg into: nSlotsOrBytesReg.
 
  "dispatch on format in a combination of highest dynamic frequency order first and convenience.
   0 = 0 sized objects (UndefinedObject True False et al)
   1 = non-indexable objects with inst vars (Point et al)
   2 = indexable objects with no inst vars (Array et al)
   3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
   4 = weak indexable objects with inst vars (WeakArray et al)
   5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
   6 unused, reserved for exotic pointer objects?
   7 Forwarded Object, 1st field is pointer, rest of fields are ignored
   8 unused, reserved for exotic non-pointer objects?
+  9 64-bit indexable
-  9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  jumpIsBytes := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory arrayFormat R: formatReg.
  jumpIsArray := cogit JumpZero: 0.
  jumpNotIndexable := cogit JumpBelow: 0.
  cogit CmpCq: objectMemory weakArrayFormat R: formatReg.
  jumpHasFixedFields := cogit JumpBelowOrEqual: 0.
  cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  jumpIsShorts := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  jumpIsWords := cogit JumpAboveOrEqual: 0.
  "For now ignore 64-bit indexability."
  jumpNotIndexable jmpTarget: cogit Label.
  jumpNotIndexable := cogit Jump: 0.
 
  jumpIsArray jmpTarget:
  (cogit CmpR: Arg1Reg R: nSlotsOrBytesReg).
  jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsBytes jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: nSlotsOrBytesReg).
  cogit AndCq: objectMemory wordSize - 1 R: formatReg R: TempReg.
  cogit SubR: TempReg R: nSlotsOrBytesReg;
  CmpR: Arg1Reg R: nSlotsOrBytesReg.
  jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit CmpCq: objectMemory firstCompiledMethodFormat R: formatReg.
  jumpIsMethod := cogit JumpAboveOrEqual: 0.
  methodInBounds :=
  (cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg).
  cogit backEnd byteReadsZeroExtend
  ifTrue:
  [cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg]
  ifFalse:
  [cogit "formatReg already contains a value <= 16r1f, so no need to zero it"
  MoveXbr: Arg1Reg R: ReceiverResultReg R: formatReg;
  MoveR: formatReg R: ReceiverResultReg].
  convertToIntAndReturn := cogit Label.
  self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsShorts jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: nSlotsOrBytesReg).
  cogit AndCq: 1 R: formatReg.
  cogit SubR: formatReg R: nSlotsOrBytesReg;
  CmpR: Arg1Reg R: nSlotsOrBytesReg.
  jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddR: Arg1Reg R: ReceiverResultReg.
  cogit AddR: Arg1Reg R: ReceiverResultReg.
  cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
  cogit Jump: convertToIntAndReturn.
 
  jumpIsWords jmpTarget:
  (cogit CmpR: Arg1Reg R: nSlotsOrBytesReg).
  jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: TempReg.
  jumpWordTooBig := self jumpNotSmallIntegerUnsignedValueInRegister: TempReg.
  cogit MoveR: TempReg R: ReceiverResultReg.
  cogit Jump: convertToIntAndReturn.
 
  jumpHasFixedFields jmpTarget:
  (cogit AndCq: objectMemory classIndexMask R: TempReg).
  cogit MoveR: TempReg R: formatReg.
  cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.
  jumpIsContext := cogit JumpZero: 0.
  cogit PushR: nSlotsOrBytesReg.
  self genGetClassObjectOfClassIndex: formatReg into: nSlotsOrBytesReg scratchReg: TempReg.
  self genLoadSlot: InstanceSpecificationIndex sourceReg: nSlotsOrBytesReg destReg: formatReg.
  cogit PopR: nSlotsOrBytesReg.
  self genConvertSmallIntegerToIntegerInReg: formatReg.
  cogit
  AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;
  SubR: formatReg R: nSlotsOrBytesReg;
  CmpR: Arg1Reg R: nSlotsOrBytesReg.
  jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.
  "index is (formatReg (fixed fields) + Arg1Reg (0-rel index)) * wordSize + baseHeaderSize"
  cogit AddR: formatReg R: Arg1Reg.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsMethod jmpTarget: cogit Label.
  "Now check that the index is beyond the method's literals..."
  self getLiteralCountOf: ReceiverResultReg plusOne: true inBytes: true into: nSlotsOrBytesReg scratch: TempReg.
  cogit CmpR: Arg1Reg R: nSlotsOrBytesReg.
  cogit JumpBelow: methodInBounds.
  jumpMethodOutOfBounds := cogit Jump: 0.
 
  jumpWordTooBig jmpTarget:
  (jumpFixedFieldsOutOfBounds jmpTarget:
  (jumpArrayOutOfBounds jmpTarget:
  (jumpBytesOutOfBounds jmpTarget:
  (jumpMethodOutOfBounds jmpTarget:
  (jumpShortsOutOfBounds jmpTarget:
  (jumpWordsOutOfBounds jmpTarget:
  (jumpNotIndexable jmpTarget:
  (jumpIsContext jmpTarget:
  (jumpBadIndex jmpTarget:
  (jumpImmediate jmpTarget: cogit Label)))))))))).
 
  ^0 "Can't be complete because of contexts."!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genPrimitiveAtPut (in category 'primitive generators') -----
  genPrimitiveAtPut
  | formatReg nSlotsOrBytesReg methodInBounds
   jumpImmediate jumpBadIndex jumpImmutable jumpNotIndexablePointers jumpNotIndexableBits
   jumpIsContext jumpIsCompiledMethod jumpIsBytes jumpIsShorts jumpHasFixedFields
   jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds
   jumpWordsOutOfBounds jumpShortsOutOfBounds jumpBytesOutOfBounds
   jumpShortsOutOfRange jumpWordsOutOfRange jumpBytesOutOfRange
   jumpNonSmallIntegerValue jumpNotPointers
   |
  "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  <var: #jumpIsBytes type: #'AbstractInstruction *'>
  <var: #jumpIsShorts type: #'AbstractInstruction *'>
  <var: #jumpBadIndex type: #'AbstractInstruction *'>
  <var: #jumpIsContext type: #'AbstractInstruction *'>
  <var: #jumpImmediate type: #'AbstractInstruction *'>
  <var: #methodInBounds type: #'AbstractInstruction *'>
  <var: #jumpHasFixedFields type: #'AbstractInstruction *'>
  <var: #jumpNotIndexableBits type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfRange type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfRange type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfRange type: #'AbstractInstruction *'>
  <var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpNotIndexablePointers type: #'AbstractInstruction *'>
 
  nSlotsOrBytesReg := ClassReg.
 
  cogit genLoadArgAtDepth: 1 into: Arg0Reg.
  cogit genLoadArgAtDepth: 0 into: Arg1Reg.
  jumpImmediate := self genJumpImmediate: ReceiverResultReg.
  jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
  self genConvertSmallIntegerToIntegerInReg: Arg0Reg.
  cogit SubCq: 1 R: Arg0Reg. "1-rel => 0-rel"
 
  "formatReg := self formatOf: ReceiverResultReg"
  self cppIf: IMMUTABILITY
  ifTrue:
  [ self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.
  jumpImmutable := self genJumpBaseHeaderImmutable: TempReg ]
  ifFalse:
  [ self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: NoReg ].
 
  self genGetNumSlotsOf: ReceiverResultReg into: nSlotsOrBytesReg.
 
  "dispatch on format in a combination of highest dynamic frequency order first and convenience.
   0 = 0 sized objects (UndefinedObject True False et al)
   1 = non-indexable objects with inst vars (Point et al)
   2 = indexable objects with no inst vars (Array et al)
   3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
   4 = weak indexable objects with inst vars (WeakArray et al)
   5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
   6 unused, reserved for exotic pointer objects?
   7 Forwarded Object, 1st field is pointer, rest of fields are ignored
   8 unused, reserved for exotic non-pointer objects?
+  9 64-bit indexable
-  9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  cogit CmpCq: objectMemory weakArrayFormat R: formatReg.
  jumpNotPointers := cogit JumpAbove: 0.
  "optimistic store check; assume index in range (almost always is)."
  self genStoreCheckReceiverReg: ReceiverResultReg
  valueReg: Arg1Reg
  scratchReg: TempReg
  inFrame: false.
 
  cogit CmpCq: objectMemory arrayFormat R: formatReg.
  jumpNotIndexablePointers := cogit JumpBelow: 0.
  jumpHasFixedFields := cogit JumpNonZero: 0.
  cogit CmpR: Arg0Reg R: nSlotsOrBytesReg.
  jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg.
  cogit MoveR: Arg1Reg Xwr: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpHasFixedFields jmpTarget: cogit Label.
  self genGetClassIndexOfNonImm: ReceiverResultReg into: formatReg.
  cogit CmpCq: ClassMethodContextCompactIndex R: formatReg.
  jumpIsContext := cogit JumpZero: 0.
  "get # fixed fields in formatReg"
  cogit PushR: nSlotsOrBytesReg.
  self genGetClassObjectOfClassIndex: formatReg into: nSlotsOrBytesReg scratchReg: TempReg.
  self genLoadSlot: InstanceSpecificationIndex sourceReg: nSlotsOrBytesReg destReg: formatReg.
  cogit PopR: nSlotsOrBytesReg.
  self genConvertSmallIntegerToIntegerInReg: formatReg.
  cogit AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg.
  cogit SubR: formatReg R: nSlotsOrBytesReg.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: formatReg.
  cogit CmpR: Arg0Reg R: nSlotsOrBytesReg.
  jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddR: formatReg R: Arg0Reg.
  cogit MoveR: Arg1Reg Xwr: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpNotPointers jmpTarget: cogit Label.
  jumpNonSmallIntegerValue := self genJumpNotSmallInteger: Arg1Reg scratchReg: TempReg.
  cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  jumpIsBytes := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  jumpIsShorts := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  "For now ignore 64-bit indexability."
  jumpNotIndexableBits := cogit JumpBelow: 0.
 
  "fall through to double words"
  cogit CmpR: Arg0Reg R: nSlotsOrBytesReg.
  jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit MoveR: Arg1Reg R: TempReg.
  self genConvertSmallIntegerToIntegerInReg: TempReg.
  (cogit lastOpcode setsConditionCodesFor: JumpLess) ifFalse:
  [cogit CmpCq: 0 R: TempReg]. "N.B. FLAGS := TempReg - 0"
  jumpWordsOutOfRange := cogit JumpLess: 0.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg.
  cogit MoveR: TempReg Xwr: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsBytes jmpTarget:
  (cogit CmpCq: (objectMemory integerObjectOf: 255) R: Arg1Reg).
  jumpBytesOutOfRange := cogit JumpAbove: 0.
  cogit LogicalShiftLeftCq: objectMemory shiftForWord R: nSlotsOrBytesReg.
  cogit AndCq: objectMemory wordSize - 1 R: formatReg R: TempReg.
  cogit SubR: TempReg R: nSlotsOrBytesReg.
  cogit CmpR: Arg0Reg R: nSlotsOrBytesReg.
  jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit CmpCq: objectMemory firstCompiledMethodFormat R: formatReg.
  jumpIsCompiledMethod := cogit JumpAboveOrEqual: 0.
  methodInBounds :=
  cogit MoveR: Arg1Reg R: TempReg.
  self genConvertSmallIntegerToIntegerInReg: TempReg.
  cogit AddCq: objectMemory baseHeaderSize R: Arg0Reg.
  cogit MoveR: TempReg Xbr: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsShorts jmpTarget:
  (cogit CmpCq: (objectMemory integerObjectOf: 65535) R: Arg1Reg).
  jumpShortsOutOfRange := cogit JumpAbove: 0.
  cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: nSlotsOrBytesReg.
  cogit AndCq: objectMemory wordSize / 2 - 1 R: formatReg.
  cogit SubR: formatReg R: nSlotsOrBytesReg.
  cogit CmpR: Arg0Reg R: nSlotsOrBytesReg.
  jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit MoveR: Arg1Reg R: TempReg.
  self genConvertSmallIntegerToIntegerInReg: TempReg.
  cogit AddR: Arg0Reg R: ReceiverResultReg.
  cogit AddR: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: TempReg M16: objectMemory baseHeaderSize r: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  "Now check that the index is beyond the method's literals..."
  jumpIsCompiledMethod jmpTarget: cogit Label.
  self getLiteralCountOf: ReceiverResultReg plusOne: true inBytes: true into: nSlotsOrBytesReg scratch: TempReg.
  cogit CmpR: Arg0Reg R: nSlotsOrBytesReg.
  cogit JumpBelow: methodInBounds.
 
  jumpIsContext jmpTarget:
  (jumpNotIndexableBits jmpTarget:
  (jumpBytesOutOfRange jmpTarget:
  (jumpWordsOutOfRange jmpTarget:
  (jumpShortsOutOfRange jmpTarget:
  (jumpIsCompiledMethod jmpTarget:
  (jumpArrayOutOfBounds jmpTarget:
  (jumpBytesOutOfBounds jmpTarget:
  (jumpShortsOutOfBounds jmpTarget:
  (jumpWordsOutOfBounds jmpTarget:
  (jumpNotIndexablePointers jmpTarget:
  (jumpNonSmallIntegerValue jmpTarget:
  (jumpFixedFieldsOutOfBounds jmpTarget: cogit Label)))))))))))).
 
  self cppIf: IMMUTABILITY
  ifTrue: [jumpImmutable jmpTarget: jumpIsContext getJmpTarget].
 
  cogit AddCq: 1 R: Arg0Reg. "0-rel => 1-rel"
  self genConvertIntegerToSmallIntegerInReg: Arg0Reg.
 
  jumpBadIndex jmpTarget: (jumpImmediate jmpTarget: cogit Label).
 
  ^0 "Can't be complete because of contexts."!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genPrimitiveStringAt (in category 'primitive generators') -----
  genPrimitiveStringAt
  | formatReg jumpNotIndexable jumpBadIndex done
   jumpIsBytes jumpIsShorts jumpWordTooBig jumpWordsDone
   jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds |
  "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  <var: #done type: #'AbstractInstruction *'>
  <var: #jumpIsBytes type: #'AbstractInstruction *'>
  <var: #jumpIsShorts type: #'AbstractInstruction *'>
  <var: #jumpBadIndex type: #'AbstractInstruction *'>
  <var: #jumpWordsDone type: #'AbstractInstruction *'>
  <var: #jumpWordTooBig type: #'AbstractInstruction *'>
  <var: #jumpNotIndexable type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
 
  cogit genLoadArgAtDepth: 0 into: Arg0Reg.
  cogit MoveR: Arg0Reg R: Arg1Reg.
  jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
  self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
  cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"
 
  self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: NoReg.
 
  self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.
 
  "dispatch on format in a combination of highest dynamic frequency order first and convenience.
   0 = 0 sized objects (UndefinedObject True False et al)
   1 = non-indexable objects with inst vars (Point et al)
   2 = indexable objects with no inst vars (Array et al)
   3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
   4 = weak indexable objects with inst vars (WeakArray et al)
   5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
   6 unused, reserved for exotic pointer objects?
   7 Forwarded Object, 1st field is pointer, rest of fields are ignored
   8 unused, reserved for exotic non-pointer objects?
+  9 64-bit indexable
-  9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  jumpIsBytes := cogit JumpGreaterOrEqual: 0.
  cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  jumpIsShorts := cogit JumpGreaterOrEqual: 0.
  cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  jumpNotIndexable := cogit JumpLess: 0.
 
  "fall through to double words"
  cogit CmpR: Arg1Reg R: ClassReg.
  jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: TempReg.
  jumpWordTooBig := self jumpNotCharacterUnsignedValueInRegister: TempReg.
  cogit MoveR: TempReg R: ReceiverResultReg.
  jumpWordsDone := cogit Jump: 0.
 
  jumpIsBytes jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
  cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg.
  cogit CmpR: Arg1Reg R: ClassReg.
  jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
  cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  cogit backEnd byteReadsZeroExtend ifFalse:
  [cogit AndCq: 255 R: ReceiverResultReg].
  jumpWordsDone jmpTarget: (done := cogit Label).
  self genConvertIntegerToCharacterInReg: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsShorts jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
  cogit AndCq: objectMemory wordSize / 1 - 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg.
  cogit CmpR: Arg1Reg R: ClassReg.
  jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddR: Arg1Reg R: ReceiverResultReg.
  cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
  cogit Jump: done.
 
 
  jumpWordTooBig jmpTarget:
  (jumpBytesOutOfBounds jmpTarget:
  (jumpShortsOutOfBounds jmpTarget:
  (jumpWordsOutOfBounds jmpTarget:
  (jumpNotIndexable jmpTarget:
  (jumpBadIndex jmpTarget: cogit Label))))).
 
  ^CompletePrimitive!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genPrimitiveStringAtPut (in category 'primitive generators') -----
  genPrimitiveStringAtPut
  | formatReg jumpBadIndex jumpBadArg jumpImmutable
   jumpIsBytes jumpIsShorts jumpNotString jumpIsCompiledMethod
   jumpBytesOutOfRange jumpShortsOutOfRange jumpWordsOutOfRange
   jumpBytesOutOfBounds jumpWordsOutOfBounds jumpShortsOutOfBounds |
  "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  <var: #jumpBadArg type: #'AbstractInstruction *'>
  <var: #jumpIsBytes type: #'AbstractInstruction *'>
  <var: #jumpIsShorts type: #'AbstractInstruction *'>
  <var: #jumpBadIndex type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfRange type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfRange type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfRange type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
 
  cogit genLoadArgAtDepth: 1 into: Arg0Reg.
  cogit genLoadArgAtDepth: 0 into: Arg1Reg.
 
  jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg.
  cogit MoveR: Arg1Reg R: TempReg.
  jumpBadArg := self genJumpNotCharacterInScratchReg: TempReg.
  self genConvertSmallIntegerToIntegerInReg: Arg0Reg.
  cogit SubCq: 1 R: Arg0Reg. "1-rel => 0-rel"
 
  "formatReg := self formatOf: ReceiverResultReg"
  self cppIf: IMMUTABILITY
  ifTrue:
  [ self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.
  jumpImmutable := self genJumpBaseHeaderImmutable: TempReg ]
  ifFalse:
  [ self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: NoReg ].
 
  self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.
 
  "dispatch on format; words and/or bytes.
   0 to 8 = pointer objects, forwarders, reserved.
+  9 64-bit indexable
-  9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  jumpNotString := cogit JumpBelow: 0.
  cogit CmpCq: objectMemory firstCompiledMethodFormat R: formatReg.
  jumpIsCompiledMethod := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  jumpIsBytes := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  jumpIsShorts := cogit JumpAboveOrEqual: 0.
 
  "fall through to double words"
  cogit CmpCq: 0 R: Arg1Reg.
  jumpWordsOutOfRange := cogit JumpLess: 0.
  cogit CmpR: Arg0Reg R: ClassReg.
  jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit MoveR: Arg1Reg R: TempReg.
  self genConvertCharacterToCodeInReg: TempReg.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg.
  cogit MoveR: TempReg Xwr: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsShorts jmpTarget:
  (cogit CmpCq: (objectMemory characterObjectOf: 65535) R: Arg1Reg).
  jumpShortsOutOfRange := cogit JumpAbove: 0.
  cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg.
  cogit AndCq: objectMemory wordSize / 2 - 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg.
  cogit CmpR: Arg0Reg R: ClassReg.
  jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit MoveR: Arg1Reg R: TempReg.
  self genConvertCharacterToCodeInReg: TempReg.
  cogit AddR: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: TempReg M16: objectMemory baseHeaderSize r: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsBytes jmpTarget:
  (cogit CmpCq: (objectMemory characterObjectOf: 255) R: Arg1Reg).
  jumpBytesOutOfRange := cogit JumpAbove: 0.
  cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg.
  cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg.
  cogit CmpR: Arg0Reg R: ClassReg.
  jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit MoveR: Arg1Reg R: TempReg.
  self genConvertCharacterToCodeInReg: TempReg.
  cogit AddCq: objectMemory baseHeaderSize R: Arg0Reg.
  cogit MoveR: TempReg Xbr: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpNotString jmpTarget:
  (jumpBytesOutOfRange jmpTarget:
  (jumpShortsOutOfRange jmpTarget:
  (jumpWordsOutOfRange jmpTarget:
  (jumpIsCompiledMethod jmpTarget:
  (jumpBytesOutOfBounds jmpTarget:
  (jumpShortsOutOfBounds jmpTarget:
  (jumpWordsOutOfBounds jmpTarget: cogit Label))))))).
 
  self cppIf: IMMUTABILITY
  ifTrue: [jumpImmutable jmpTarget: jumpNotString getJmpTarget].
 
  cogit AddCq: 1 R: Arg0Reg. "0-rel => 1-rel"
  self genConvertIntegerToSmallIntegerInReg: Arg0Reg.
 
  jumpBadArg jmpTarget:
  (jumpBadIndex jmpTarget: cogit Label).
 
  ^CompletePrimitive!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveAt (in category 'primitive generators') -----
  genPrimitiveAt
  | formatReg nSlotsOrBytesReg convertToIntAndReturn methodInBounds
   jumpNotIndexable jumpImmediate jumpBadIndex
   jumpIsBytes jumpIsShorts jumpIsWords jumpIsMethod jumpIsArray jumpIsContext
   jumpHasFixedFields jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds
   jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds |
  "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  <var: #jumpIsBytes type: #'AbstractInstruction *'>
  <var: #jumpIsShorts type: #'AbstractInstruction *'>
  <var: #jumpBadIndex type: #'AbstractInstruction *'>
  <var: #jumpIsMethod type: #'AbstractInstruction *'>
  <var: #jumpIsContext type: #'AbstractInstruction *'>
  <var: #jumpImmediate type: #'AbstractInstruction *'>
  <var: #methodInBounds type: #'AbstractInstruction *'>
  <var: #jumpNotIndexable type: #'AbstractInstruction *'>
  <var: #jumpHasFixedFields type: #'AbstractInstruction *'>
  <var: #convertToIntAndReturn type: #'AbstractInstruction *'>
  <var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpFixedFieldsOutOfBounds type: #'AbstractInstruction *'>
 
  nSlotsOrBytesReg := ClassReg.
 
  cogit genLoadArgAtDepth: 0 into: Arg0Reg.
  jumpImmediate := self genJumpImmediate: ReceiverResultReg.
  cogit MoveR: Arg0Reg R: Arg1Reg.
  jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
  self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
  cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"
 
  "formatReg := self formatOf: ReceiverResultReg"
  self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.
 
  self genGetNumSlotsOf: ReceiverResultReg into: nSlotsOrBytesReg.
 
  "dispatch on format in a combination of highest dynamic frequency order first and convenience.
   0 = 0 sized objects (UndefinedObject True False et al)
   1 = non-indexable objects with inst vars (Point et al)
   2 = indexable objects with no inst vars (Array et al)
   3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
   4 = weak indexable objects with inst vars (WeakArray et al)
   5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
   6 unused, reserved for exotic pointer objects?
   7 Forwarded Object, 1st field is pointer, rest of fields are ignored
   8 unused, reserved for exotic non-pointer objects?
+  9 64-bit indexable
-  9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  jumpIsBytes := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory arrayFormat R: formatReg.
  jumpIsArray := cogit JumpZero: 0.
  jumpNotIndexable := cogit JumpBelow: 0.
  cogit CmpCq: objectMemory weakArrayFormat R: formatReg.
  jumpHasFixedFields := cogit JumpBelowOrEqual: 0.
  cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  jumpIsShorts := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  jumpIsWords := cogit JumpAboveOrEqual: 0.
  "For now ignore 64-bit indexability."
  jumpNotIndexable jmpTarget: cogit Label.
  jumpNotIndexable := cogit Jump: 0.
 
  jumpIsArray jmpTarget:
  (cogit CmpR: Arg1Reg R: nSlotsOrBytesReg).
  jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsBytes jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: nSlotsOrBytesReg).
  cogit AndCq: objectMemory wordSize - 1 R: formatReg R: TempReg.
  cogit SubR: TempReg R: nSlotsOrBytesReg;
  CmpR: Arg1Reg R: nSlotsOrBytesReg.
  jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit CmpCq: objectMemory firstCompiledMethodFormat R: formatReg.
  jumpIsMethod := cogit JumpAboveOrEqual: 0.
  methodInBounds :=
  (cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg).
  cogit backEnd byteReadsZeroExtend
  ifTrue:
  [cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg]
  ifFalse:
  [cogit "formatReg already contains a value <= 16r1f, so no need to zero it"
  MoveXbr: Arg1Reg R: ReceiverResultReg R: formatReg;
  MoveR: formatReg R: ReceiverResultReg].
  convertToIntAndReturn := cogit Label.
  self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsShorts jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: nSlotsOrBytesReg).
  cogit AndCq: 1 R: formatReg.
  cogit SubR: formatReg R: nSlotsOrBytesReg;
  CmpR: Arg1Reg R: nSlotsOrBytesReg.
  jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddR: Arg1Reg R: ReceiverResultReg.
  cogit AddR: Arg1Reg R: ReceiverResultReg.
  cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
  cogit Jump: convertToIntAndReturn.
 
  jumpIsWords jmpTarget:
  (cogit CmpR: Arg1Reg R: nSlotsOrBytesReg).
  jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize >>  (objectMemory shiftForWord - 1) R: Arg1Reg.
  cogit MoveX32r: Arg1Reg R: ReceiverResultReg R: TempReg.
  cogit MoveR: TempReg R: ReceiverResultReg.
  cogit Jump: convertToIntAndReturn.
 
  jumpHasFixedFields jmpTarget:
  (cogit AndCq: objectMemory classIndexMask R: TempReg).
  cogit MoveR: TempReg R: formatReg.
  cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.
  jumpIsContext := cogit JumpZero: 0.
  self genGetClassObjectOfClassIndex: formatReg into: Extra0Reg scratchReg: TempReg.
  self genLoadSlot: InstanceSpecificationIndex sourceReg: Extra0Reg destReg: formatReg.
  self genConvertSmallIntegerToIntegerInReg: formatReg.
  cogit
  AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;
  SubR: formatReg R: nSlotsOrBytesReg;
  CmpR: Arg1Reg R: nSlotsOrBytesReg.
  jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.
  "index is (formatReg (fixed fields) + Arg1Reg (0-rel index)) * wordSize + baseHeaderSize"
  cogit AddR: formatReg R: Arg1Reg.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsMethod jmpTarget: cogit Label.
  "Now check that the index is beyond the method's literals..."
  self getLiteralCountOf: ReceiverResultReg plusOne: true inBytes: true into: nSlotsOrBytesReg scratch: TempReg.
  cogit CmpR: Arg1Reg R: nSlotsOrBytesReg.
  cogit JumpBelow: methodInBounds.
 
  jumpFixedFieldsOutOfBounds jmpTarget:
  (jumpArrayOutOfBounds jmpTarget:
  (jumpBytesOutOfBounds jmpTarget:
  (jumpShortsOutOfBounds jmpTarget:
  (jumpWordsOutOfBounds jmpTarget:
  (jumpNotIndexable jmpTarget:
  (jumpIsContext jmpTarget:
  (jumpBadIndex jmpTarget:
  (jumpImmediate jmpTarget: cogit Label)))))))).
 
  ^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveAtPut (in category 'primitive generators') -----
  genPrimitiveAtPut
  | formatReg nSlotsOrBytesReg methodInBounds
   jumpImmediate jumpBadIndex jumpImmutable jumpNotIndexablePointers jumpNotIndexableBits
   jumpIsContext jumpIsCompiledMethod jumpIsBytes jumpIsShorts jumpHasFixedFields
   jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds
   jumpWordsOutOfBounds jumpShortsOutOfBounds jumpBytesOutOfBounds
   jumpShortsOutOfRange jumpWordsOutOfRange jumpBytesOutOfRange
   jumpNonSmallIntegerValue jumpNotPointers
   |
  "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  <var: #jumpIsBytes type: #'AbstractInstruction *'>
  <var: #jumpIsShorts type: #'AbstractInstruction *'>
  <var: #jumpBadIndex type: #'AbstractInstruction *'>
  <var: #jumpIsContext type: #'AbstractInstruction *'>
  <var: #jumpImmediate type: #'AbstractInstruction *'>
  <var: #methodInBounds type: #'AbstractInstruction *'>
  <var: #jumpHasFixedFields type: #'AbstractInstruction *'>
  <var: #jumpNotIndexableBits type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfRange type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfRange type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfRange type: #'AbstractInstruction *'>
  <var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpNotIndexablePointers type: #'AbstractInstruction *'>
 
  nSlotsOrBytesReg := ClassReg.
 
  cogit genLoadArgAtDepth: 1 into: Arg0Reg.
  cogit genLoadArgAtDepth: 0 into: Arg1Reg.
  jumpImmediate := self genJumpImmediate: ReceiverResultReg.
  jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
  self genConvertSmallIntegerToIntegerInReg: Arg0Reg.
  cogit SubCq: 1 R: Arg0Reg. "1-rel => 0-rel"
 
  "formatReg := self formatOf: ReceiverResultReg"
  self cppIf: IMMUTABILITY
  ifTrue:
  [ self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.
  jumpImmutable := self genJumpBaseHeaderImmutable: TempReg ]
  ifFalse:
  [ self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: NoReg ].
 
  self genGetNumSlotsOf: ReceiverResultReg into: nSlotsOrBytesReg.
 
  "dispatch on format in a combination of highest dynamic frequency order first and convenience.
   0 = 0 sized objects (UndefinedObject True False et al)
   1 = non-indexable objects with inst vars (Point et al)
   2 = indexable objects with no inst vars (Array et al)
   3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
   4 = weak indexable objects with inst vars (WeakArray et al)
   5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
   6 unused, reserved for exotic pointer objects?
   7 Forwarded Object, 1st field is pointer, rest of fields are ignored
   8 unused, reserved for exotic non-pointer objects?
+  9 64-bit indexable
-  9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  cogit CmpCq: objectMemory weakArrayFormat R: formatReg.
  jumpNotPointers := cogit JumpAbove: 0.
  "optimistic store check; assume index in range (almost always is)."
  self genStoreCheckReceiverReg: ReceiverResultReg
  valueReg: Arg1Reg
  scratchReg: TempReg
  inFrame: false.
 
  cogit CmpCq: objectMemory arrayFormat R: formatReg.
  jumpNotIndexablePointers := cogit JumpBelow: 0.
  jumpHasFixedFields := cogit JumpNonZero: 0.
  cogit CmpR: Arg0Reg R: nSlotsOrBytesReg.
  jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg.
  cogit MoveR: Arg1Reg Xwr: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpHasFixedFields jmpTarget: cogit Label.
  self genGetClassIndexOfNonImm: ReceiverResultReg into: formatReg.
  cogit CmpCq: ClassMethodContextCompactIndex R: formatReg.
  jumpIsContext := cogit JumpZero: 0.
  "get # fixed fields in formatReg"
  self genGetClassObjectOfClassIndex: formatReg into: Extra0Reg scratchReg: TempReg.
  self genLoadSlot: InstanceSpecificationIndex sourceReg: Extra0Reg destReg: formatReg.
  self genConvertSmallIntegerToIntegerInReg: formatReg.
  cogit AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg.
  cogit SubR: formatReg R: nSlotsOrBytesReg.
  cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: formatReg.
  cogit CmpR: Arg0Reg R: nSlotsOrBytesReg.
  jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddR: formatReg R: Arg0Reg.
  cogit MoveR: Arg1Reg Xwr: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpNotPointers jmpTarget: cogit Label.
  jumpNonSmallIntegerValue := self genJumpNotSmallInteger: Arg1Reg scratchReg: TempReg.
  cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  jumpIsBytes := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  jumpIsShorts := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  "For now ignore 64-bit indexability."
  jumpNotIndexableBits := cogit JumpBelow: 0.
 
  "fall through to words"
  cogit CmpCq: (objectMemory integerObjectOf: 16rFFFFFFFF) R: Arg1Reg.
  jumpWordsOutOfRange := cogit JumpAbove: 0.
  cogit LogicalShiftLeftCq: objectMemory shiftForWord - 2 R: nSlotsOrBytesReg.
  cogit AndCq: objectMemory wordSize / 4 - 1 R: formatReg.
  cogit SubR: formatReg R: nSlotsOrBytesReg.
  cogit CmpR: Arg0Reg R: nSlotsOrBytesReg.
  jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit MoveR: Arg1Reg R: TempReg.
  self genConvertSmallIntegerToIntegerInReg: TempReg.
  cogit AddCq: objectMemory baseHeaderSize >> (objectMemory shiftForWord - 1) R: Arg0Reg.
  cogit MoveR: TempReg X32r: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsBytes jmpTarget:
  (cogit CmpCq: (objectMemory integerObjectOf: 255) R: Arg1Reg).
  jumpBytesOutOfRange := cogit JumpAbove: 0.
  cogit LogicalShiftLeftCq: objectMemory shiftForWord R: nSlotsOrBytesReg.
  cogit AndCq: objectMemory wordSize - 1 R: formatReg R: TempReg.
  cogit SubR: TempReg R: nSlotsOrBytesReg.
  cogit CmpR: Arg0Reg R: nSlotsOrBytesReg.
  jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit CmpCq: objectMemory firstCompiledMethodFormat R: formatReg.
  jumpIsCompiledMethod := cogit JumpAboveOrEqual: 0.
  methodInBounds :=
  cogit MoveR: Arg1Reg R: TempReg.
  self genConvertSmallIntegerToIntegerInReg: TempReg.
  cogit AddCq: objectMemory baseHeaderSize R: Arg0Reg.
  cogit MoveR: TempReg Xbr: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsShorts jmpTarget:
  (cogit CmpCq: (objectMemory integerObjectOf: 65535) R: Arg1Reg).
  jumpShortsOutOfRange := cogit JumpAbove: 0.
  cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: nSlotsOrBytesReg.
  cogit AndCq: objectMemory wordSize / 2 - 1 R: formatReg.
  cogit SubR: formatReg R: nSlotsOrBytesReg.
  cogit CmpR: Arg0Reg R: nSlotsOrBytesReg.
  jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit MoveR: Arg1Reg R: TempReg.
  self genConvertSmallIntegerToIntegerInReg: TempReg.
  cogit AddR: Arg0Reg R: ReceiverResultReg.
  cogit AddR: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: TempReg M16: objectMemory baseHeaderSize r: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  "Now check that the index is beyond the method's literals..."
  jumpIsCompiledMethod jmpTarget: cogit Label.
  self getLiteralCountOf: ReceiverResultReg plusOne: true inBytes: true into: nSlotsOrBytesReg scratch: TempReg.
  cogit CmpR: Arg0Reg R: nSlotsOrBytesReg.
  cogit JumpBelow: methodInBounds.
 
  jumpIsContext jmpTarget:
  (jumpNotIndexableBits jmpTarget:
  (jumpBytesOutOfRange jmpTarget:
  (jumpShortsOutOfRange jmpTarget:
  (jumpWordsOutOfRange jmpTarget:
  (jumpIsCompiledMethod jmpTarget:
  (jumpArrayOutOfBounds jmpTarget:
  (jumpBytesOutOfBounds jmpTarget:
  (jumpShortsOutOfBounds jmpTarget:
  (jumpWordsOutOfBounds jmpTarget:
  (jumpNotIndexablePointers jmpTarget:
  (jumpNonSmallIntegerValue jmpTarget:
  (jumpFixedFieldsOutOfBounds jmpTarget: cogit Label)))))))))))).
 
  self cppIf: IMMUTABILITY
  ifTrue: [jumpImmutable jmpTarget: jumpIsContext getJmpTarget].
 
  cogit AddCq: 1 R: Arg0Reg. "0-rel => 1-rel"
  self genConvertIntegerToSmallIntegerInReg: Arg0Reg.
 
  jumpBadIndex jmpTarget: (jumpImmediate jmpTarget: cogit Label).
 
  ^0 "Can't be complete because of contexts."!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveStringAt (in category 'primitive generators') -----
  genPrimitiveStringAt
  | formatReg jumpNotIndexable jumpBadIndex done
   jumpIsBytes jumpIsShorts jumpWordTooBig jumpWordsDone
   jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds |
  "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  <var: #done type: #'AbstractInstruction *'>
  <var: #jumpIsBytes type: #'AbstractInstruction *'>
  <var: #jumpIsShorts type: #'AbstractInstruction *'>
  <var: #jumpBadIndex type: #'AbstractInstruction *'>
  <var: #jumpWordsDone type: #'AbstractInstruction *'>
  <var: #jumpWordTooBig type: #'AbstractInstruction *'>
  <var: #jumpNotIndexable type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
 
  cogit genLoadArgAtDepth: 0 into: Arg0Reg.
  cogit MoveR: Arg0Reg R: Arg1Reg.
  jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
  self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
  cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"
 
  self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: NoReg.
 
  self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.
 
  "dispatch on format in a combination of highest dynamic frequency order first and convenience.
   0 = 0 sized objects (UndefinedObject True False et al)
   1 = non-indexable objects with inst vars (Point et al)
   2 = indexable objects with no inst vars (Array et al)
   3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
   4 = weak indexable objects with inst vars (WeakArray et al)
   5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
   6 unused, reserved for exotic pointer objects?
   7 Forwarded Object, 1st field is pointer, rest of fields are ignored
   8 unused, reserved for exotic non-pointer objects?
+  9 64-bit indexable
-  9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  jumpIsBytes := cogit JumpGreaterOrEqual: 0.
  cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  jumpIsShorts := cogit JumpGreaterOrEqual: 0.
  cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  jumpNotIndexable := cogit JumpLess: 0.
 
  "fall through to double words"
  cogit LogicalShiftLeftCq: objectMemory shiftForWord - 2 R: ClassReg.
  cogit AndCq: objectMemory wordSize / 4 - 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg.
  cogit CmpR: Arg1Reg R: ClassReg.
  jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize >> (objectMemory shiftForWord - 1) R: Arg1Reg.
  cogit MoveX32r: Arg1Reg R: ReceiverResultReg R: TempReg.
  jumpWordTooBig := self jumpNotCharacterUnsignedValueInRegister: TempReg.
  cogit MoveR: TempReg R: ReceiverResultReg.
  jumpWordsDone := cogit Jump: 0.
 
  jumpIsBytes jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
  cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg.
  cogit CmpR: Arg1Reg R: ClassReg.
  jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
  cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  cogit backEnd byteReadsZeroExtend ifFalse:
  [cogit AndCq: 255 R: ReceiverResultReg].
  jumpWordsDone jmpTarget: (done := cogit Label).
  self genConvertIntegerToCharacterInReg: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsShorts jmpTarget:
  (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
  cogit AndCq: objectMemory wordSize / 2 - 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg.
  cogit CmpR: Arg1Reg R: ClassReg.
  jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit AddR: Arg1Reg R: ReceiverResultReg.
  cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
  cogit Jump: done.
 
  jumpWordTooBig jmpTarget:
  (jumpBytesOutOfBounds jmpTarget:
  (jumpShortsOutOfBounds jmpTarget:
  (jumpWordsOutOfBounds jmpTarget:
  (jumpNotIndexable jmpTarget:
  (jumpBadIndex jmpTarget: cogit Label))))).
 
  ^CompletePrimitive!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveStringAtPut (in category 'primitive generators') -----
  genPrimitiveStringAtPut
  | formatReg jumpBadIndex jumpBadArg jumpImmutable
   jumpIsBytes jumpIsShorts jumpNotString jumpIsCompiledMethod
   jumpBytesOutOfRange jumpShortsOutOfRange jumpWordsOutOfRange
   jumpBytesOutOfBounds jumpWordsOutOfBounds jumpShortsOutOfBounds |
  "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  <var: #jumpBadArg type: #'AbstractInstruction *'>
  <var: #jumpIsBytes type: #'AbstractInstruction *'>
  <var: #jumpIsShorts type: #'AbstractInstruction *'>
  <var: #jumpBadIndex type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfRange type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfRange type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfRange type: #'AbstractInstruction *'>
  <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
 
  cogit genLoadArgAtDepth: 1 into: Arg0Reg.
  cogit genLoadArgAtDepth: 0 into: Arg1Reg.
 
  jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg.
  jumpBadArg := self genJumpNotCharacter: Arg1Reg.
  self genConvertSmallIntegerToIntegerInReg: Arg0Reg.
  cogit SubCq: 1 R: Arg0Reg. "1-rel => 0-rel"
 
  "formatReg := self formatOf: ReceiverResultReg"
  self cppIf: IMMUTABILITY
  ifTrue:
  [ self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.
  jumpImmutable := self genJumpBaseHeaderImmutable: TempReg ]
  ifFalse:
  [ self genGetFormatOf: ReceiverResultReg
  into: (formatReg := SendNumArgsReg)
  leastSignificantHalfOfBaseHeaderIntoScratch: NoReg ].
 
  self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.
 
  "dispatch on format; words and/or bytes.
   0 to 8 = pointer objects, forwarders, reserved.
+  9 64-bit indexable
-  9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  jumpNotString := cogit JumpBelow: 0.
  cogit CmpCq: objectMemory firstCompiledMethodFormat R: formatReg.
  jumpIsCompiledMethod := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory firstByteFormat R: formatReg.
  jumpIsBytes := cogit JumpAboveOrEqual: 0.
  cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  jumpIsShorts := cogit JumpAboveOrEqual: 0.
 
  "fall through to double words"
  cogit CmpCq: (objectMemory characterObjectOf: 1 << self numCharacterBits - 1) R: Arg1Reg.
  jumpWordsOutOfRange := cogit JumpAbove: 0.
  cogit LogicalShiftLeftCq: objectMemory shiftForWord - 2 R: ClassReg.
  cogit AndCq: objectMemory wordSize / 4 - 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg.
  cogit CmpR: Arg0Reg R: ClassReg.
  jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit MoveR: Arg1Reg R: TempReg.
  self genConvertCharacterToCodeInReg: TempReg.
  cogit AddCq: objectMemory baseHeaderSize >> (objectMemory shiftForWord - 1) R: Arg0Reg.
  cogit MoveR: TempReg X32r: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsShorts jmpTarget:
  (cogit CmpCq: (objectMemory characterObjectOf: 65535) R: Arg1Reg).
  jumpShortsOutOfRange := cogit JumpAbove: 0.
  cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg.
  cogit AndCq: objectMemory wordSize / 2 - 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg.
  cogit CmpR: Arg0Reg R: ClassReg.
  jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit MoveR: Arg1Reg R: TempReg.
  self genConvertCharacterToCodeInReg: TempReg.
  cogit AddR: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: TempReg M16: objectMemory baseHeaderSize r: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpIsBytes jmpTarget:
  (cogit CmpCq: (objectMemory characterObjectOf: 255) R: Arg1Reg).
  jumpBytesOutOfRange := cogit JumpAbove: 0.
  cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg.
  cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  cogit SubR: formatReg R: ClassReg.
  cogit CmpR: Arg0Reg R: ClassReg.
  jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  cogit MoveR: Arg1Reg R: TempReg.
  self genConvertCharacterToCodeInReg: TempReg.
  cogit AddCq: objectMemory baseHeaderSize R: Arg0Reg.
  cogit MoveR: TempReg Xbr: Arg0Reg R: ReceiverResultReg.
  cogit MoveR: Arg1Reg R: ReceiverResultReg.
  cogit genPrimReturn.
 
  jumpNotString jmpTarget:
  (jumpBytesOutOfRange jmpTarget:
  (jumpShortsOutOfRange jmpTarget:
  (jumpWordsOutOfRange jmpTarget:
  (jumpIsCompiledMethod jmpTarget:
  (jumpBytesOutOfBounds jmpTarget:
  (jumpShortsOutOfBounds jmpTarget:
  (jumpWordsOutOfBounds jmpTarget: cogit Label))))))).
 
  self cppIf: IMMUTABILITY
  ifTrue: [jumpImmutable jmpTarget: jumpNotString getJmpTarget].
 
  cogit AddCq: 1 R: Arg0Reg. "0-rel => 1-rel"
  self genConvertIntegerToSmallIntegerInReg: Arg0Reg.
 
  jumpBadArg jmpTarget:
  (jumpBadIndex jmpTarget: cogit Label).
 
  ^CompletePrimitive!

Item was added:
+ ----- Method: InterpreterPrimitives>>primitiveSpurStringReplace (in category 'indexing primitives') -----
+ primitiveSpurStringReplace
+ "<array> primReplaceFrom: start to: stop with: replacement startingAt: repStart  
+ <primitive: 105>"
+ <inline: true>
+ | array start stop repl replStart arrayFmt arrayLength arrayInstSize replFmt replLength replInstSize srcDelta |
+ array := self stackValue: 4.
+ start := self stackValue: 3.
+ stop := self stackValue: 2.
+ repl := self stackValue: 1.
+ replStart := self stackValue: 0.
+
+ ((objectMemory isNonIntegerObject: start)
+ or: [(objectMemory isNonIntegerObject: stop)
+ or: [(objectMemory isNonIntegerObject: replStart)
+ or: [objectMemory isImmediate: repl]]]) ifTrue: "can happen in LgInt copy"
+ [^self primitiveFailFor: PrimErrBadArgument].
+
+ start := objectMemory integerValueOf: start.
+ stop := objectMemory integerValueOf: stop.
+ replStart := objectMemory integerValueOf: replStart.
+
+ (stop >= start and: [objectMemory isObjImmutable: array]) ifTrue:
+ [^self primitiveFailFor: PrimErrNoModification].
+
+ arrayFmt := objectMemory formatOf: array.
+ arrayLength := objectMemory lengthOf: array format: arrayFmt.
+ arrayFmt := objectMemory classFormatFromInstFormat: arrayFmt.
+ replFmt := objectMemory formatOf: repl.
+ replLength := objectMemory lengthOf: repl format: replFmt.
+ replFmt := objectMemory classFormatFromInstFormat: replFmt.
+
+ "Array formats (without oddFields bits) must be the same"
+ (arrayFmt = replFmt
+ and: [arrayFmt < objectMemory firstCompiledMethodFormat]) ifFalse:
+ [^self primitiveFailFor: PrimErrInappropriate].
+
+ arrayFmt <= objectMemory lastPointerFormat
+ ifTrue:
+ [arrayInstSize := objectMemory fixedFieldsOf: array format: arrayFmt length: arrayLength.
+ replInstSize := objectMemory fixedFieldsOf: repl format: replFmt length: replLength.
+ (start >= 1 and: [start - 1 <= stop and: [stop + arrayInstSize <= arrayLength
+  and: [replStart >= 1 and: [stop - start + replStart + replInstSize <= replLength]]]]) ifFalse:
+ [^self primitiveFailFor: PrimErrBadIndex].
+ srcDelta := (replStart + replInstSize) - (start + arrayInstSize).
+ start + arrayInstSize - 1 to: stop + arrayInstSize - 1 do:
+ [:i |
+ objectMemory storePointer: i ofObject: array withValue: (objectMemory fetchPointer: srcDelta + i ofObject: repl)]]
+ ifFalse:
+ [(start >= 1 and: [start - 1 <= stop and: [stop <= arrayLength
+  and: [replStart >= 1 and: [stop - start + replStart <= replLength]]]]) ifFalse:
+ [^self primitiveFailFor: PrimErrBadIndex].
+ srcDelta := replStart - start.
+ arrayFmt >= objectMemory firstShortFormat
+ ifTrue: "8 & 16-bit word type objects"
+ [arrayFmt >= objectMemory firstByteFormat
+ ifTrue: "byte-type objects"
+ [start - 1 to: stop - 1 do:
+ [:i | objectMemory storeByte: i ofObject: array withValue: (objectMemory fetchByte: srcDelta + i ofObject: repl)]]
+ ifFalse: "short type objects"
+ [start - 1 to: stop - 1 do:
+ [:i | objectMemory storeShort16: i ofObject: array withValue: (objectMemory fetchShort16: srcDelta + i ofObject: repl)]]]
+ ifFalse: "32 & 64-bit word type objects"
+ [arrayFmt >= objectMemory firstLongFormat
+ ifTrue: "word-type objects"
+ [start - 1 to: stop - 1 do:
+ [:i | objectMemory storeLong32: i ofObject: array withValue: (objectMemory fetchLong32: srcDelta + i ofObject: repl)]]
+ ifFalse: "long type objects"
+ [start - 1 to: stop - 1 do:
+ [:i | objectMemory storeLong64: i ofObject: array withValue: (objectMemory fetchLong64: srcDelta + i ofObject: repl)]]]].
+ "We might consider comparing stop - start to some value here and using forceInterruptCheck"
+
+ self pop: argumentCount "leave rcvr on stack"!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveStringReplace (in category 'indexing primitives') -----
  primitiveStringReplace
+ "<array> primReplaceFrom: start to: stop with: replacement startingAt: repStart  
+ <primitive: 105>"
+ objectMemory hasSpurMemoryManagerAPI
+ ifTrue: [self primitiveSpurStringReplace]
+ ifFalse: [self primitiveV3StringReplace]!
- "
- <array> primReplaceFrom: start to: stop with: replacement
- startingAt: repStart  
- <primitive: 105>
- "
- | array start stop repl replStart hdr arrayFmt totalLength arrayInstSize replFmt replInstSize srcIndex |
- array := self stackValue: 4.
- start := self stackIntegerValue: 3.
- stop := self stackIntegerValue: 2.
- repl := self stackValue: 1.
- replStart := self stackIntegerValue: 0.
-
- self successful ifFalse:
- [^self primitiveFailFor: PrimErrBadArgument].
- (objectMemory isImmediate: repl) ifTrue: "can happen in LgInt copy"
- [^self primitiveFailFor: PrimErrBadArgument].
- (stop >= start and: [objectMemory isObjImmutable: array]) ifTrue:
- [^self primitiveFailFor: PrimErrNoModification].
-
- hdr := objectMemory baseHeader: array.
- arrayFmt := objectMemory formatOfHeader: hdr.
- totalLength := objectMemory lengthOf: array baseHeader: hdr format: arrayFmt.
- arrayInstSize := objectMemory fixedFieldsOf: array format: arrayFmt length: totalLength.
- (start >= 1 and: [start - 1 <= stop and: [stop + arrayInstSize <= totalLength]]) ifFalse:
- [^self primitiveFailFor: PrimErrBadIndex].
-
- hdr := objectMemory baseHeader: repl.
- replFmt := objectMemory formatOfHeader: hdr.
- totalLength := objectMemory lengthOf: repl baseHeader: hdr format: replFmt.
- replInstSize := objectMemory fixedFieldsOf: repl format: replFmt length: totalLength.
- (replStart >= 1 and: [stop - start + replStart + replInstSize <= totalLength]) ifFalse:
- [^self primitiveFailFor: PrimErrBadIndex].
-
- "Still to do: rewrite the below to accomodate short & long access"
- (objectMemory hasSpurMemoryManagerAPI
- and: [(arrayFmt between: objectMemory firstShortFormat and: objectMemory firstLongFormat - 1)
- or: [arrayFmt = objectMemory sixtyFourBitIndexableFormat]]) ifTrue:
- [^self primitiveFailFor: PrimErrUnsupported].
-
- "Array formats (without byteSize bits, if bytes array) must be the same"
- arrayFmt < objectMemory firstByteFormat
- ifTrue: [arrayFmt = replFmt ifFalse:
- [^self primitiveFailFor: PrimErrInappropriate]]
- ifFalse: [(arrayFmt bitAnd: objectMemory byteFormatMask) = (replFmt bitAnd: objectMemory byteFormatMask) ifFalse:
- [^self primitiveFailFor: PrimErrInappropriate]].
-
- srcIndex := replStart + replInstSize - 1.
- "- 1 for 0-based access"
-
- arrayFmt <= objectMemory lastPointerFormat
- ifTrue:
- [start + arrayInstSize - 1 to: stop + arrayInstSize - 1 do:
- [:i |
- objectMemory storePointer: i ofObject: array withValue: (objectMemory fetchPointer: srcIndex ofObject: repl).
- srcIndex := srcIndex + 1]]
- ifFalse:
- [arrayFmt < objectMemory firstByteFormat
- ifTrue: "32-bit-word type objects"
- [start + arrayInstSize - 1 to: stop + arrayInstSize - 1 do:
- [:i |
- objectMemory storeLong32: i ofObject: array withValue: (objectMemory fetchLong32: srcIndex ofObject: repl).
- srcIndex := srcIndex + 1]]
- ifFalse: "byte-type objects"
- [start + arrayInstSize - 1 to: stop + arrayInstSize - 1 do:
- [:i |
- objectMemory storeByte: i ofObject: array withValue: (objectMemory fetchByte: srcIndex ofObject: repl).
- srcIndex := srcIndex + 1]]].
- "We might consider comparing stop - start to some value here and using forceInterruptCheck"
-
- self pop: argumentCount "leave rcvr on stack"!

Item was added:
+ ----- Method: InterpreterPrimitives>>primitiveV3StringReplace (in category 'indexing primitives') -----
+ primitiveV3StringReplace
+ "<array> primReplaceFrom: start to: stop with: replacement startingAt: repStart  
+ <primitive: 105>"
+ <inline: true>
+ | array start stop repl replStart hdr arrayFmt totalLength arrayInstSize replFmt replInstSize srcIndex |
+ array := self stackValue: 4.
+ start := self stackIntegerValue: 3.
+ stop := self stackIntegerValue: 2.
+ repl := self stackValue: 1.
+ replStart := self stackIntegerValue: 0.
+
+ self successful ifFalse:
+ [^self primitiveFailFor: PrimErrBadArgument].
+ (objectMemory isImmediate: repl) ifTrue: "can happen in LgInt copy"
+ [^self primitiveFailFor: PrimErrBadArgument].
+ (stop >= start and: [objectMemory isObjImmutable: array]) ifTrue:
+ [^self primitiveFailFor: PrimErrNoModification].
+
+ hdr := objectMemory baseHeader: array.
+ arrayFmt := objectMemory formatOfHeader: hdr.
+ totalLength := objectMemory lengthOf: array baseHeader: hdr format: arrayFmt.
+ arrayInstSize := objectMemory fixedFieldsOf: array format: arrayFmt length: totalLength.
+ (start >= 1 and: [start - 1 <= stop and: [stop + arrayInstSize <= totalLength]]) ifFalse:
+ [^self primitiveFailFor: PrimErrBadIndex].
+
+ hdr := objectMemory baseHeader: repl.
+ replFmt := objectMemory formatOfHeader: hdr.
+ totalLength := objectMemory lengthOf: repl baseHeader: hdr format: replFmt.
+ replInstSize := objectMemory fixedFieldsOf: repl format: replFmt length: totalLength.
+ (replStart >= 1 and: [stop - start + replStart + replInstSize <= totalLength]) ifFalse:
+ [^self primitiveFailFor: PrimErrBadIndex].
+
+ "Array formats (without byteSize bits, if bytes array) must be the same"
+ arrayFmt < objectMemory firstByteFormat
+ ifTrue: [arrayFmt = replFmt ifFalse:
+ [^self primitiveFailFor: PrimErrInappropriate]]
+ ifFalse: [(arrayFmt bitAnd: objectMemory byteFormatMask) = (replFmt bitAnd: objectMemory byteFormatMask) ifFalse:
+ [^self primitiveFailFor: PrimErrInappropriate]].
+
+ srcIndex := replStart + replInstSize - 1.
+ "- 1 for 0-based access"
+
+ arrayFmt <= objectMemory lastPointerFormat
+ ifTrue:
+ [start + arrayInstSize - 1 to: stop + arrayInstSize - 1 do:
+ [:i |
+ objectMemory storePointer: i ofObject: array withValue: (objectMemory fetchPointer: srcIndex ofObject: repl).
+ srcIndex := srcIndex + 1]]
+ ifFalse:
+ [arrayFmt < objectMemory firstByteFormat
+ ifTrue: "32-bit-word type objects"
+ [start + arrayInstSize - 1 to: stop + arrayInstSize - 1 do:
+ [:i |
+ objectMemory storeLong32: i ofObject: array withValue: (objectMemory fetchLong32: srcIndex ofObject: repl).
+ srcIndex := srcIndex + 1]]
+ ifFalse: "byte-type objects"
+ [start + arrayInstSize - 1 to: stop + arrayInstSize - 1 do:
+ [:i |
+ objectMemory storeByte: i ofObject: array withValue: (objectMemory fetchByte: srcIndex ofObject: repl).
+ srcIndex := srcIndex + 1]]].
+ "We might consider comparing stop - start to some value here and using forceInterruptCheck"
+
+ self pop: argumentCount "leave rcvr on stack"!

Item was changed:
  ----- Method: Spur32BitMemoryManager>>set:classIndexTo:formatTo: (in category 'header access') -----
  set: objOop classIndexTo: classIndex formatTo: format
  "0 = 0 sized objects (UndefinedObject True False et al)
  1 = non-indexable objects with inst vars (Point et al)
  2 = indexable objects with no inst vars (Array et al)
  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
  4 = weak indexable objects with inst vars (WeakArray et al)
  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
  6 unused, reserved for exotic pointer objects?
  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
  8 unused, reserved for exotic non-pointer objects?
+ 9 64-bit indexable
- 9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  <inline: true>
  self assert: (classIndex between: 0 and: self classIndexMask).
  self assert: (format between: 0 and: self formatMask).
  self flag: #endianness.
  self longAt: objOop
  put: ((self longAt: objOop) bitAnd: (self formatMask << self formatShift + self classIndexMask) bitInvert32)
  + (classIndex
  +  (format << self formatShift))!

Item was changed:
  ----- Method: Spur32BitMemoryManager>>setFormatOf:to: (in category 'header access') -----
  setFormatOf: objOop to: format
  "0 = 0 sized objects (UndefinedObject True False et al)
  1 = non-indexable objects with inst vars (Point et al)
  2 = indexable objects with no inst vars (Array et al)
  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
  4 = weak indexable objects with inst vars (WeakArray et al)
  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
  6 unused, reserved for exotic pointer objects?
  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
  8 unused, reserved for exotic non-pointer objects?
+ 9 64-bit indexable
- 9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  self assert: (format between: 0 and: self formatMask).
  self flag: #endianness.
  self longAt: objOop
  put: ((self longAt: objOop) bitAnd: (self formatMask << self formatShift) bitInvert32)
  + (format << self formatShift)!

Item was changed:
  ----- Method: Spur64BitMemoryManager>>set:classIndexTo:formatTo: (in category 'header access') -----
  set: objOop classIndexTo: classIndex formatTo: format
  "0 = 0 sized objects (UndefinedObject True False et al)
  1 = non-indexable objects with inst vars (Point et al)
  2 = indexable objects with no inst vars (Array et al)
  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
  4 = weak indexable objects with inst vars (WeakArray et al)
  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
  6 unused, reserved for exotic pointer objects?
  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
  8 unused, reserved for exotic non-pointer objects?
+ 9 64-bit indexable
- 9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  <inline: true>
  self assert: (classIndex between: 0 and: self classIndexMask).
  self assert: (format between: 0 and: self formatMask).
  self longAt: objOop
  put: ((self longAt: objOop) bitAnd: (self formatMask << self formatShift + self classIndexMask) bitInvert64)
  + (classIndex
  +  (format << self formatShift))!

Item was changed:
  ----- Method: Spur64BitMemoryManager>>setFormatOf:to: (in category 'header access') -----
  setFormatOf: objOop to: format
  "0 = 0 sized objects (UndefinedObject True False et al)
  1 = non-indexable objects with inst vars (Point et al)
  2 = indexable objects with no inst vars (Array et al)
  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
  4 = weak indexable objects with inst vars (WeakArray et al)
  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
  6 unused, reserved for exotic pointer objects?
  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
  8 unused, reserved for exotic non-pointer objects?
+ 9 64-bit indexable
- 9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  self assert: (format between: 0 and: self formatMask).
  self longAt: objOop
  put: ((self longAt: objOop) bitAnd: (self formatMask << self formatShift) bitInvert64)
  + (format << self formatShift)!

Item was added:
+ ----- Method: SpurMemoryManager>>classFormatFromInstFormat: (in category 'object access') -----
+ classFormatFromInstFormat: instFormat
+ "0 = 0 sized objects (UndefinedObject True False et al)
+ 1 = non-indexable objects with inst vars (Point et al)
+ 2 = indexable objects with no inst vars (Array et al)
+ 3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
+ 4 = weak indexable objects with inst vars (WeakArray et al)
+ 5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
+ 6 unused, reserved for exotic pointer objects?
+ 7 Forwarded Object, 1st field is pointer, rest of fields are ignored
+ 8 unused, reserved for exotic non-pointer objects?
+ 9 64-bit indexable
+ 10 - 11 32-bit indexable
+ 12 - 15 16-bit indexable
+ 16 - 23 byte indexable
+ 24 - 31 compiled method"
+ <inline: true>
+ instFormat >= self firstByteFormat ifTrue: "this is likely the common case"
+ [^instFormat bitAnd: -8].
+ instFormat <= self sixtyFourBitIndexableFormat ifTrue:
+ [^instFormat].
+ instFormat < self firstShortFormat ifTrue:
+ [^instFormat bitAnd: -2].
+ ^instFormat bitAnd: -4!

Item was changed:
  ----- Method: SpurMemoryManager>>formatMask (in category 'header format') -----
  formatMask
  <api>
  <cmacro>
  "0 = 0 sized objects (UndefinedObject True False et al)
  1 = non-indexable objects with inst vars (Point et al)
  2 = indexable objects with no inst vars (Array et al)
  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
  4 = weak indexable objects with inst vars (WeakArray et al)
  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
  6,7,8 unused
+ 9 64-bit indexable
- 9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  ^16r1f!

Item was changed:
  ----- Method: SpurMemoryManager>>formatOf: (in category 'object access') -----
  formatOf: objOop
  "0 = 0 sized objects (UndefinedObject True False et al)
  1 = non-indexable objects with inst vars (Point et al)
  2 = indexable objects with no inst vars (Array et al)
  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
  4 = weak indexable objects with inst vars (WeakArray et al)
  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
  6 unused, reserved for exotic pointer objects?
  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
  8 unused, reserved for exotic non-pointer objects?
+ 9 64-bit indexable
- 9 (?) 64-bit indexable
  10 - 11 32-bit indexable (11 unused in 32 bits)
  12 - 15 16-bit indexable (14 & 15 unused in 32-bits)
  16 - 23 byte indexable (20-23 unused in 32-bits)
  24 - 31 compiled method (28-31 unused in 32-bits)"
  "A note on performance.  Since the format field is, by design, aligned on a byte boundary
  in the fourth byte of the header we could access it via
  ^(self byteAt: objOop + 3) bitAnd: self formatMask
  but al least on e.g. Core i7 x86-64 using the clang 6 compiler, this makes no difference,
  or at least any change is in the noise."
  ^(self longAt: objOop) >> self formatShift bitAnd: self formatMask!

Item was changed:
  ----- Method: SpurMemoryManager>>formatOfHeader: (in category 'object access') -----
  formatOfHeader: header
  "0 = 0 sized objects (UndefinedObject True False et al)
  1 = non-indexable objects with inst vars (Point et al)
  2 = indexable objects with no inst vars (Array et al)
  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
  4 = weak indexable objects with inst vars (WeakArray et al)
  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
  6 unused, reserved for exotic pointer objects?
  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
  8 unused, reserved for exotic non-pointer objects?
+ 9 64-bit indexable
- 9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  <var: 'header' type: #usqLong>
  ^header >> self formatShift bitAnd: self formatMask!

Item was changed:
  ----- Method: SpurMemoryManager>>set:classIndexTo:formatTo: (in category 'header access') -----
  set: objOop classIndexTo: classIndex formatTo: format
  "0 = 0 sized objects (UndefinedObject True False et al)
  1 = non-indexable objects with inst vars (Point et al)
  2 = indexable objects with no inst vars (Array et al)
  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
  4 = weak indexable objects with inst vars (WeakArray et al)
  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
  6 unused, reserved for exotic pointer objects?
  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
  8 unused, reserved for exotic non-pointer objects?
+ 9 64-bit indexable
- 9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  self subclassResponsibility!

Item was changed:
  ----- Method: SpurMemoryManager>>setFormatOf:to: (in category 'header access') -----
  setFormatOf: objOop to: format
  "0 = 0 sized objects (UndefinedObject True False et al)
  1 = non-indexable objects with inst vars (Point et al)
  2 = indexable objects with no inst vars (Array et al)
  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
  4 = weak indexable objects with inst vars (WeakArray et al)
  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
  6 unused, reserved for exotic pointer objects?
  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
  8 unused, reserved for exotic non-pointer objects?
+ 9 64-bit indexable
- 9 (?) 64-bit indexable
  10 - 11 32-bit indexable
  12 - 15 16-bit indexable
  16 - 23 byte indexable
  24 - 31 compiled method"
  self subclassResponsibility!