[Vm-dev] VM Maker: VMMaker.oscog-eem.428.mcz

commits at source.squeak.org commits at source.squeak.org
Thu Oct 3 07:59:55 UTC 2013


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

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

Name: VMMaker.oscog-eem.428
Author: eem
Time: 3 October 2013, 12:53:50.91 am
UUID: 480331f4-5272-4a17-8ba8-0abe8035a8b7
Ancestors: VMMaker.oscog-eem.427

Fix method surrogate offsetOf: methods.  These now need to take
baseHeaderSize into account.

Fail genPrimitiveIdentityHash if obj rep says 0 is not a valid hash and
0 is the hash.

Fix genInnerPrimitiveAt: & genGetSizeOf:into:formatReg:scratchReg:abortJumpsInto:.
They were stomping on the numSlots intermediate result.

Implement genInnerPrimitiveStringAt:.  Easy with immediate
characters :-).

Change genGetClassObjectOfClassIndex:into:scratchReg: to open-code
class table indirection and nuke ceClassAtIndexTrampoline.
Change shouldAnnotateObjectReference: to not annotate the
classTableRootPage which will never move, being immediately after
nil, false & true.

Move the register mask c=utilities up to Cogit.  They can be useful
in making run-time calls when caller-saved regs need to be saved.
Add CallRT:registersToBeSavedMask: to do this (not used).

Add BadRegisterSet error to allow routines to ask for a different
combination of registers in certain circumstances.  Use this in
genPrimitiveClass.

Add a cr between successive prints when printing both insts and regs.

Change shortPrint: to print variable bindings as Associations.

More addressCouldBeObj: => addressCouldBeOop: asserts.

More is(Non)IntegerObject: => is(Non)Immediate:.

Bootstrap now way off base, hitting the idle loop before drawing the
screen.

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

Item was changed:
  ----- Method: CoInterpreter>>printFrame:WithSP: (in category 'debug printing') -----
  printFrame: theFP WithSP: theSP
  	<api>
  	| theMethod theMethodEnd numArgs numTemps rcvrAddress topThing |
  	<inline: false>
  	<var: #theFP type: #'char *'>
  	<var: #theSP type: #'char *'>
  	<var: #addr type: #'char *'>
  	<var: #rcvrAddress type: #'char *'>
  	<var: #cogMethod type: #'CogBlockMethod *'>
  	<var: #homeMethod type: #'CogMethod *'>
  	self cCode: '' inSmalltalk: [self transcript ensureCr].
  	(self isMachineCodeFrame: theFP)
  		ifTrue:
  			[| cogMethod homeMethod |
  			 cogMethod := self mframeCogMethod: theFP.
  			 homeMethod := self mframeHomeMethod: theFP.
  			 theMethod := homeMethod asInteger.
  			 theMethodEnd := homeMethod asInteger + homeMethod blockSize.
  			 numArgs := cogMethod cmNumArgs.
  			 numTemps := self temporaryCountOfMethodHeader: homeMethod methodHeader]
  		ifFalse:
  			[theMethod := self frameMethodObject: theFP.
  			 theMethodEnd := theMethod + (objectMemory sizeBitsOfSafe: theMethod).
  			 numArgs := self iframeNumArgs: theFP.
  			 numTemps := self tempCountOf: theMethod].
  	(self frameIsBlockActivation: theFP) ifTrue:
  		[| rcvrOrClosure |
  		 rcvrOrClosure := self pushedReceiverOrClosureOfFrame: theFP.
+ 		 ((objectMemory isNonImmediate: rcvrOrClosure)
- 		 ((objectMemory isNonIntegerObject: rcvrOrClosure)
  		 and: [(objectMemory addressCouldBeObj: rcvrOrClosure)
  		 and: [(objectMemory fetchClassOfNonImm: rcvrOrClosure) = (objectMemory splObj: ClassBlockClosure)]])
  			ifTrue: [numTemps := numArgs + (self stSizeOf: rcvrOrClosure)]
  			ifFalse: [numTemps := 0]].
  	self shortPrintFrame: theFP.
  	(self isBaseFrame: theFP) ifTrue:
  		[self printFrameOop: '(caller ctxt'
  			at: theFP + (self frameStackedReceiverOffset: theFP) + (2 * BytesPerWord).
  		 self printFrameOop: '(saved ctxt'
  			at: theFP + (self frameStackedReceiverOffset: theFP) + (1 * BytesPerWord)].
  	self printFrameOop: 'rcvr/clsr'
  		at: theFP + FoxCallerSavedIP + ((numArgs + 1) * BytesPerWord).
  	numArgs to: 1 by: -1 do:
  		[:i|
  		self printFrameOop: 'arg' index: numArgs - i at: theFP + FoxCallerSavedIP + (i * BytesPerWord)].
  	self printFrameThing: 'caller ip' at: theFP + FoxCallerSavedIP.
  	self printFrameThing: 'saved fp' at: theFP + FoxSavedFP.
  	self printFrameMethodFor: theFP.
  	(self isMachineCodeFrame: theFP) ifFalse:
  		[self printFrameFlagsForFP: theFP].
  	self printFrameOop: 'context' at: theFP + FoxThisContext.
  	(self isMachineCodeFrame: theFP) ifTrue:
  		[self printFrameFlagsForFP: theFP].
  	(self isMachineCodeFrame: theFP)
  		ifTrue: [rcvrAddress := theFP + FoxMFReceiver]
  		ifFalse:
  			[self printFrameThing: 'saved ip'
  				at: theFP + FoxIFSavedIP
  				extra: ((self iframeSavedIP: theFP) = 0
  							ifTrue: [0]
  							ifFalse: [(self iframeSavedIP: theFP) - theMethod + 2 - BaseHeaderSize]).
  			 rcvrAddress := theFP + FoxIFReceiver].
  	self printFrameOop: 'receiver' at: rcvrAddress.
  	topThing := stackPages longAt: theSP.
  	(topThing between: theMethod and: theMethodEnd)
  		ifTrue:
  			[rcvrAddress - BytesPerWord to: theSP + BytesPerWord by: BytesPerWord negated do:
  				[:addr| | index |
  				index := rcvrAddress - addr / BytesPerWord + numArgs.
  				index <= numTemps
  					ifTrue: [self printFrameOop: 'temp' index: index - 1 at: addr]
  					ifFalse: [self printFrameOop: 'stck' at: addr]].
  			self printFrameThing: 'frame ip'
  				at: theSP
  				extra: ((self isMachineCodeFrame: theFP)
  						ifTrue: [topThing - theMethod]
  						ifFalse: [topThing - theMethod + 2 - BaseHeaderSize])]
  		ifFalse:
  			[rcvrAddress - BytesPerWord to: theSP by: BytesPerWord negated do:
  				[:addr| | index |
  				index := rcvrAddress - addr / BytesPerWord + numArgs.
  				index <= numTemps
  					ifTrue: [self printFrameOop: 'temp' index: index - 1 at: addr]
  					ifFalse: [self printFrameOop: 'stck' at: addr]]]!

Item was changed:
  ----- Method: CoInterpreter>>returnToExecutive:postContextSwitch: (in category 'enilopmarts') -----
  returnToExecutive: inInterpreter postContextSwitch: switchedContext
  	"Return to the current frame, either by entering machine code, or longjmp-ing back to the
  	 interpreter or simply returning, depending on where we are. To know whether to return or
  	 enter machine code we have to know from whence we came.  We could have come from
  	 the interpreter, either directly or via a machine code primitive.  We could have come from
  	 machine code.  The instructionPointer tells us where from.  If it is above startOfMemory we're
  	 in the interpreter.  If it is below, then we are in machine-code unless it is ceReturnToInterpreterPC,
  	 in which case we're in a machine-code primitive called from the interpreter."
  	<inline: false>
  	| cogMethod retValue fullyInInterpreter |
  	<var: #cogMethod type: #'CogBlockMethod *'>
  
  	cogit assertCStackWellAligned.
  	(self isMachineCodeFrame: framePointer) ifTrue:
  		[self assertValidExecutionPointe: instructionPointer r: framePointer s: stackPointer imbar: false line: #'__LINE__'.
  		 "If returning after a context switch then a result may have to be popped from the stack.
  		  If the process is suspended at a send then the result of the primitive in which the
  		  process was suspended is still on the stack and must be popped into ReceiverResultReg.
  		  If not, nothing should be popped and ReceiverResultReg gets the receiver."
  		 switchedContext
  			ifTrue:
  				[cogMethod := self mframeCogMethod: framePointer.
  				 (instructionPointer ~= (cogMethod asInteger + cogMethod stackCheckOffset)
  				  and: [cogit isSendReturnPC: instructionPointer])
  					ifTrue:
+ 						[self assert: (objectMemory addressCouldBeOop: self stackTop).
- 						[self assert: ((objectMemory isIntegerObject: self stackTop) or: [objectMemory addressCouldBeObj: self stackTop]).
  						 retValue := self popStack]
  					ifFalse:
  						[retValue := self mframeReceiver: framePointer]]
  			ifFalse: [retValue := self mframeReceiver: framePointer].
  		 self push: instructionPointer.
  		 self push: retValue.
  		 cogit ceEnterCogCodePopReceiverReg
  		 "NOTREACHED"].
  	self setMethod: (self iframeMethod: framePointer).
  	fullyInInterpreter := inInterpreter.
  	instructionPointer = cogit ceReturnToInterpreterPC ifTrue:
  		[instructionPointer := (self iframeSavedIP: framePointer) asUnsignedInteger.
  		 fullyInInterpreter := false].
  	self assertValidExecutionPointe: instructionPointer r: framePointer s: stackPointer imbar: true line: #'__LINE__'.
  	fullyInInterpreter ifFalse:
  		[self siglong: reenterInterpreter jmp: ReturnToInterpreter.
  		 "NOTREACHED"].
  	^nil!

Item was changed:
  SharedPool subclass: #CogCompilationConstants
  	instanceVariableNames: ''
+ 	classVariableNames: 'BadRegisterSet SSBaseOffset SSConstant SSIllegal SSRegister SSSpill'
- 	classVariableNames: 'SSBaseOffset SSConstant SSIllegal SSRegister SSSpill'
  	poolDictionaries: ''
  	category: 'VMMaker-JIT'!

Item was changed:
  ----- Method: CogMethodSurrogate32 class>>offsetOf: (in category 'accessing') -----
+ offsetOf: aByteSymbol
+ 	"These should be generated!!!!"
+ 	self assert: self objectMemoryClass baseHeaderSize = BaseHeaderSize.
- offsetOf: aByteSymbol 
  	^aByteSymbol caseOf:
+ 		{	[#methodObject]		-> [8 + BaseHeaderSize].
+ 			[#selector]				-> [16 + BaseHeaderSize].
+ 			[#blockEntryOffset]	-> [6 + BaseHeaderSize].
- 		{	[#methodObject]	-> [12].
- 			[#selector]			-> [20].
- 			[#blockEntryOffset]	-> [10].
  		}!

Item was changed:
  ----- Method: CogMethodSurrogate64 class>>offsetOf: (in category 'accessing') -----
+ offsetOf: aByteSymbol
+ 	"These should be generated!!!!"
+ 	self assert: self objectMemoryClass baseHeaderSize = BaseHeaderSize.
- offsetOf: aByteSymbol 
  	^aByteSymbol caseOf:
+ 		{	[#methodObject]		-> [8 + BaseHeaderSize].
+ 			[#selector]				-> [24 + BaseHeaderSize].
+ 			[#blockEntryOffset]	-> [6 + BaseHeaderSize].
- 		{	[#methodObject]	-> [16].
- 			[#selector]			-> [32].
- 			[#blockEntryOffset]	-> [14].
  		}!

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 jumpSmallSize
  	  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: #jumpSmallSize type: #'AbstractInstruction *'>
  	<var: #jumpIsContext type: #'AbstractInstruction *'>
  	<var: #jumpArrayDone type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpHasFixedFields type: #'AbstractInstruction *'>
  	<var: #jump32BitLongsDone type: #'AbstractInstruction *'>
  
  	cogit
  		MoveMw: 0 r: sourceReg R: formatReg;				"formatReg := least significant half of self baseHeader: receiver"
  		MoveR: formatReg R: scratchReg;
  		LogicalShiftRightCq: objectMemory formatShift R: formatReg;
  		AndCq: objectMemory formatMask R: formatReg.	"formatReg := self formatOfHeader: destReg"
  
  	"get numSlots into destReg."
+ 	cogit MoveCq: 0 R: destReg. "N.B. MoveMb:r:R: does not zero other bits"
  	cogit MoveMb: 7 r: sourceReg R: destReg. "MSB of header"
  	cogit CmpCq: objectMemory numSlotsMask R: destReg.
  	jumpSmallSize := cogit JumpLess: 0.
  	cogit MoveMw: -8 r: sourceReg R: destReg. "LSW of overflow size header"
  
  	"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
  		10 - 11 32-bit indexable
  		12 - 15 16-bit indexable
  		16 - 23 byte indexable
  		24 - 31 compiled method"
  	jumpSmallSize jmpTarget:
  					(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.
- 	scratchReg ~= TempReg ifTrue:
- 		[cogit MoveR: scratchReg R: TempReg].
- 	self flag: 'sometime soon we could inline the class fetch; it is only two indirections'.
- 	cogit CallRT: ceClassAtIndexTrampoline.
- 	scratchReg ~= TempReg ifTrue:
- 		[cogit MoveR: TempReg R: scratchReg].
- 	self genLoadSlot: InstanceSpecificationIndex sourceReg: scratchReg destReg: formatReg.
  	self genConvertSmallIntegerToIntegerInScratchReg: 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>>genInnerPrimitiveAt: (in category 'primitive generators') -----
  genInnerPrimitiveAt: retNoffset
  	"Implement the guts of primitiveAt; dispatch on size"
  	<returnTypeC: #'AbstractInstruction *'>
  	| formatReg jumpNotIndexable jumpSmallSize jumpImmediate jumpBadIndex
  	  jumpBytesDone jumpShortsDone jumpWordsDone jumpFixedFieldsDone
  	  jumpIsBytes jumpIsShorts jumpIsWords jumpWordTooBig jumpIsArray jumpHasFixedFields jumpIsContext
  	  jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds |
  	<inline: true>
  	"c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  	<var: #jumpIsBytes type: #'AbstractInstruction *'>
  	<var: #jumpIsShorts type: #'AbstractInstruction *'>
  	<var: #jumpBadIndex type: #'AbstractInstruction *'>
  	<var: #jumpSmallSize type: #'AbstractInstruction *'>
  	<var: #jumpIsContext type: #'AbstractInstruction *'>
  	<var: #jumpImmediate type: #'AbstractInstruction *'>
  	<var: #jumpBytesDone type: #'AbstractInstruction *'>
  	<var: #jumpShortsDone type: #'AbstractInstruction *'>
  	<var: #jumpWordsDone type: #'AbstractInstruction *'>
  	<var: #jumpWordTooBig type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpHasFixedFields type: #'AbstractInstruction *'>
  	<var: #jumpFixedFieldsDone type: #'AbstractInstruction *'>
  	<var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpFixedFieldsOutOfBounds type: #'AbstractInstruction *'>
  
  	cogit MoveR: ReceiverResultReg R: TempReg.
  	jumpImmediate := self genJumpImmediateInScratchReg: TempReg.
  	cogit MoveR: Arg0Reg R: TempReg.
  	jumpBadIndex := self genJumpNotSmallIntegerInScratchReg: TempReg.
  	self genConvertSmallIntegerToIntegerInScratchReg: Arg0Reg.
  	cogit SubCq: 1 R: Arg0Reg. "1-rel => 0-rel"
  
  	formatReg := SendNumArgsReg.
  	cogit
  		MoveMw: 0 r: ReceiverResultReg R: formatReg;				"formatReg := least significant half of self baseHeader: receiver"
  		MoveR: formatReg R: TempReg;
  		LogicalShiftRightCq: objectMemory formatShift R: formatReg;
  		AndCq: objectMemory formatMask R: formatReg.	"formatReg := self formatOfHeader: destReg"
  
  	"get numSlots into ClassReg."
+ 	cogit MoveCq: 0 R: ClassReg. "N.B. MoveMb:r:R: does not zero other bits"
  	cogit MoveMb: 7 r: ReceiverResultReg R: ClassReg. "MSB of header"
  	cogit CmpCq: objectMemory numSlotsMask R: ClassReg.
  	jumpSmallSize := cogit JumpLess: 0.
  	cogit MoveMw: -8 r: ReceiverResultReg R: ClassReg. "LSW of overflow size header"
  
  	"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
  		10 - 11 32-bit indexable
  		12 - 15 16-bit indexable
  		16 - 23 byte indexable
  		24 - 31 compiled method"
  	jumpSmallSize jmpTarget:
  					(cogit CmpCq: objectMemory firstByteFormat R: formatReg).
  	jumpIsBytes := cogit JumpGreaterOrEqual: 0.
  					cogit CmpCq: objectMemory arrayFormat R: formatReg.
  	jumpIsArray := 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.
  	jumpIsWords := cogit JumpGreaterOrEqual: 0.
  	"For now ignore 64-bit indexability."
  	jumpNotIndexable jmpTarget: cogit Label.
  	jumpNotIndexable := cogit Jump: 0.
  
  	jumpIsBytes jmpTarget:
  		(cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
  		cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  		cogit SubR: formatReg R: ClassReg;
  		CmpR: Arg0Reg R: ClassReg.
  	jumpBytesOutOfBounds := cogit JumpAboveOrEqual: 0.
  	cogit AddCq: objectMemory baseHeaderSize R: Arg0Reg.
  	cogit MoveXbr: Arg0Reg R: ReceiverResultReg R: ReceiverResultReg.
  	self genConvertIntegerToSmallIntegerInScratchReg: ReceiverResultReg.
  	jumpBytesDone := cogit Jump: 0.
  
  	jumpIsShorts jmpTarget:
  		(cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
  		cogit AndCq: 1 R: formatReg.
  		cogit SubR: formatReg R: ClassReg;
  		CmpR: Arg0Reg R: ClassReg.
  	jumpShortsOutOfBounds := cogit JumpAboveOrEqual: 0.
  	cogit AddR: Arg0Reg R: ReceiverResultReg.
  	cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
  	self genConvertIntegerToSmallIntegerInScratchReg: ReceiverResultReg.
  	jumpShortsDone := cogit Jump: 0.
  
  	jumpIsWords jmpTarget:
  		(cogit CmpR: Arg0Reg R: ClassReg).
  	jumpWordsOutOfBounds := cogit JumpAboveOrEqual: 0.
  	cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg.
  	cogit MoveXwr: Arg0Reg R: ReceiverResultReg R: TempReg.
  	cogit SubCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg.
  	jumpWordTooBig := self jumpNotSmallIntegerUnsignedValueInRegister: TempReg.
  	cogit MoveR: TempReg R: ReceiverResultReg.
  	self genConvertIntegerToSmallIntegerInScratchReg: ReceiverResultReg.
  	jumpWordsDone := cogit Jump: 0.
  
  	jumpHasFixedFields jmpTarget:
  		(cogit AndCq: objectMemory classIndexMask R: TempReg).
  	cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.
+ 	cogit MoveR: TempReg R: formatReg.
+ 	cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.
  	jumpIsContext := cogit JumpZero: 0.
+ 	cogit PushR: ClassReg.
+ 	self genGetClassObjectOfClassIndex: formatReg into: ClassReg scratchReg: TempReg.
+ 	self genLoadSlot: InstanceSpecificationIndex sourceReg: ClassReg destReg: formatReg.
+ 	cogit PopR: ClassReg.
- 	self flag: 'sometime soon we could inline the class fetch; it is only two indirections'.
- 	cogit CallRT: ceClassAtIndexTrampoline.
- 	self genLoadSlot: InstanceSpecificationIndex sourceReg: TempReg destReg: formatReg.
  	self genConvertSmallIntegerToIntegerInScratchReg: formatReg.
  	cogit
  		AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;
  		SubR: formatReg R: ClassReg;
  		CmpR: Arg0Reg R: ClassReg.
  	jumpFixedFieldsOutOfBounds := cogit JumpAboveOrEqual: 0.
  	"index is (formatReg (fixed fields) + Arg0Reg (0-rel index)) * wordSize + baseHeaderSize"
  	cogit AddR: formatReg R: Arg0Reg.
  	cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg.
  	cogit MoveXwr: Arg0Reg R: ReceiverResultReg R: ReceiverResultReg.
  	jumpFixedFieldsDone := cogit Jump: 0.
  
  	jumpIsArray jmpTarget:
  		(cogit CmpR: Arg0Reg R: ClassReg).
  	jumpArrayOutOfBounds := cogit JumpAboveOrEqual: 0.	
  	cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg.
  	cogit MoveXwr: Arg0Reg R: ReceiverResultReg R: ReceiverResultReg.
  
  	jumpFixedFieldsDone jmpTarget:
  	(jumpWordsDone jmpTarget:
  	(jumpShortsDone jmpTarget:
  	(jumpBytesDone jmpTarget:
  		(cogit RetN: retNoffset)))).
  
  	jumpFixedFieldsOutOfBounds jmpTarget:
  	(jumpArrayOutOfBounds jmpTarget:
  	(jumpBytesOutOfBounds jmpTarget:
  	(jumpShortsOutOfBounds jmpTarget:
  	(jumpWordsOutOfBounds jmpTarget:
  	(jumpWordTooBig jmpTarget:
  	(jumpNotIndexable jmpTarget:
  	(jumpIsContext jmpTarget: cogit Label))))))).
  
  	cogit AddCq: 1 R: Arg0Reg. "0-rel => 1-rel"
  	self genConvertIntegerToSmallIntegerInScratchReg: Arg0Reg.
  
  	(jumpBadIndex jmpTarget: (jumpImmediate jmpTarget: cogit Label)).
  
  	^0!

Item was added:
+ ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveStringAt: (in category 'primitive generators') -----
+ genInnerPrimitiveStringAt: retNoffset
+ 	"Implement the guts of primitiveStringAt; dispatch on size"
+ 	<returnTypeC: #'AbstractInstruction *'>
+ 	| formatReg jumpNotIndexable jumpSmallSize jumpBadIndex done
+ 	  jumpIsBytes jumpIsShorts jumpIsWords jumpWordTooBig
+ 	  jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds |
+ 	<inline: true>
+ 	"c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
+ 	<var: #done type: #'AbstractInstruction *'>
+ 	<var: #jumpIsBytes type: #'AbstractInstruction *'>
+ 	<var: #jumpIsShorts type: #'AbstractInstruction *'>
+ 	<var: #jumpIsWords type: #'AbstractInstruction *'>
+ 	<var: #jumpBadIndex type: #'AbstractInstruction *'>
+ 	<var: #jumpSmallSize type: #'AbstractInstruction *'>
+ 	<var: #jumpWordTooBig type: #'AbstractInstruction *'>
+ 	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
+ 	<var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
+ 	<var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
+ 	<var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
+ 
+ 	cogit MoveR: Arg0Reg R: TempReg.
+ 	jumpBadIndex := self genJumpNotSmallIntegerInScratchReg: TempReg.
+ 	self genConvertSmallIntegerToIntegerInScratchReg: Arg0Reg.
+ 	cogit SubCq: 1 R: Arg0Reg. "1-rel => 0-rel"
+ 
+ 	formatReg := SendNumArgsReg.
+ 	cogit
+ 		MoveMw: 0 r: ReceiverResultReg R: formatReg;				"formatReg := least significant half of self baseHeader: receiver"
+ 		MoveR: formatReg R: TempReg;
+ 		LogicalShiftRightCq: objectMemory formatShift R: formatReg;
+ 		AndCq: objectMemory formatMask R: formatReg.	"formatReg := self formatOfHeader: destReg"
+ 
+ 	"get numSlots into ClassReg."
+ 	cogit MoveCq: 0 R: ClassReg. "N.B. MoveMb:r:R: does not zero other bits"
+ 	cogit MoveMb: 7 r: ReceiverResultReg R: ClassReg. "MSB of header"
+ 	cogit CmpCq: objectMemory numSlotsMask R: ClassReg.
+ 	jumpSmallSize := cogit JumpLess: 0.
+ 	cogit MoveMw: -8 r: ReceiverResultReg R: ClassReg. "LSW of overflow size header"
+ 
+ 	"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
+ 		10 - 11 32-bit indexable
+ 		12 - 15 16-bit indexable
+ 		16 - 23 byte indexable
+ 		24 - 31 compiled method"
+ 	jumpSmallSize jmpTarget:
+ 					(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.
+ 	jumpIsWords := cogit JumpGreaterOrEqual: 0.
+ 	jumpNotIndexable := cogit Jump: 0.
+ 
+ 	jumpIsBytes jmpTarget:
+ 		(cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
+ 		cogit AndCq: objectMemory wordSize - 1 R: formatReg.
+ 		cogit SubR: formatReg R: ClassReg;
+ 		CmpR: Arg0Reg R: ClassReg.
+ 	jumpBytesOutOfBounds := cogit JumpAboveOrEqual: 0.
+ 	cogit AddCq: objectMemory baseHeaderSize R: Arg0Reg.
+ 	cogit MoveXbr: Arg0Reg R: ReceiverResultReg R: ReceiverResultReg.
+ 	done := cogit Label.
+ 	self genConvertIntegerToCharacterInScratchReg: ReceiverResultReg.
+ 	cogit RetN: retNoffset.
+ 
+ 	jumpIsShorts jmpTarget:
+ 		(cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
+ 		cogit AndCq: 1 R: formatReg.
+ 		cogit SubR: formatReg R: ClassReg;
+ 		CmpR: Arg0Reg R: ClassReg.
+ 	jumpShortsOutOfBounds := cogit JumpAboveOrEqual: 0.
+ 	cogit AddR: Arg0Reg R: ReceiverResultReg.
+ 	cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
+ 	cogit Jump: done.
+ 
+ 	jumpIsWords jmpTarget:
+ 		(cogit CmpR: Arg0Reg R: ClassReg).
+ 	jumpWordsOutOfBounds := cogit JumpAboveOrEqual: 0.
+ 	cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg.
+ 	cogit MoveXwr: Arg0Reg R: ReceiverResultReg R: TempReg.
+ 	cogit SubCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg.
+ 	jumpWordTooBig := self jumpNotCharacterUnsignedValueInRegister: TempReg.
+ 	cogit MoveR: TempReg R: ReceiverResultReg.
+ 	cogit Jump: done.
+ 
+ 	jumpBytesOutOfBounds jmpTarget:
+ 	(jumpShortsOutOfBounds jmpTarget:
+ 	(jumpWordsOutOfBounds jmpTarget:
+ 	(jumpWordTooBig jmpTarget:
+ 	(jumpNotIndexable jmpTarget: cogit Label)))).
+ 
+ 	cogit AddCq: 1 R: Arg0Reg. "0-rel => 1-rel"
+ 	self genConvertIntegerToSmallIntegerInScratchReg: Arg0Reg.
+ 
+ 	jumpBadIndex jmpTarget: cogit Label.
+ 
+ 	^0!

Item was added:
+ ----- Method: CogObjectRepresentationFor32BitSpur>>genShiftAwaySmallIntegerTagsInScratchReg: (in category 'compile abstract instructions') -----
+ genShiftAwaySmallIntegerTagsInScratchReg: scratchReg
+ 	cogit ArithmeticShiftRightCq: 1 R: scratchReg.
+ 	^0!

Item was changed:
  CogObjectRepresentation subclass: #CogObjectRepresentationForSpur
+ 	instanceVariableNames: ''
- 	instanceVariableNames: 'ceClassAtIndexTrampoline'
  	classVariableNames: ''
+ 	poolDictionaries: 'CogCompilationConstants VMSqueakClassIndices'
- 	poolDictionaries: 'VMSqueakClassIndices'
  	category: 'VMMaker-JIT'!

Item was added:
+ ----- Method: CogObjectRepresentationForSpur>>genConvertIntegerToCharacterInScratchReg: (in category 'compile abstract instructions') -----
+ genConvertIntegerToCharacterInScratchReg: reg
+ 	cogit
+ 		LogicalShiftRightCq: objectMemory numTagBits R: reg;
+ 		AddCq: objectMemory characterTag R: reg.
+ 	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genGetClassObjectOf:into:scratchReg: (in category 'compile abstract instructions') -----
  genGetClassObjectOf: instReg into: destReg scratchReg: scratchReg
  	"Fetch the instance's class into destReg."
  	| jumpIsImm jumpNotForwarded loop |
  	<var: #jumpIsImm type: #'AbstractInstruction *'>
  	<var: #jumpNotForwarded type: #'AbstractInstruction *'>
  	<var: #loop type: #'AbstractInstruction *'>
+ 	instReg = destReg ifTrue:
+ 		[^BadRegisterSet].
  	loop := cogit MoveR: instReg R: scratchReg.
  	cogit AndCq: objectMemory tagMask R: scratchReg.
  	jumpIsImm := cogit JumpNonZero: 0.
  	self flag: #endianness.
  	"Get least significant half of header word in destReg"
  	cogit MoveMw: 0 r: instReg R: scratchReg.
  	"mask off class index"
  	cogit AndCq: objectMemory classIndexMask R: scratchReg.
  	"if it is forwarded..."
  	cogit CmpCq: objectMemory isForwardedObjectClassIndexPun R: scratchReg.
  	jumpNotForwarded := cogit JumpNonZero: 0.
  	"...follow the forwarding pointer and loop to fetch its classIndex"
  	cogit MoveMw: objectMemory baseHeaderSize r: instReg R: instReg.
  	cogit Jump: loop.
  	jumpNotForwarded jmpTarget: (jumpIsImm jmpTarget: cogit Label).
+ 	cogit MoveR: scratchReg R: destReg.
+ 	cogit PushR: instReg.
+ 	self genGetClassObjectOfClassIndex: destReg into: instReg scratchReg: TempReg.
+ 	cogit MoveR: instReg R: destReg.
+ 	cogit PopR: instReg.
+ 	^0!
- 	scratchReg ~= TempReg ifTrue:
- 		[cogit MoveR: scratchReg R: TempReg].
- 	cogit CallRT: ceClassAtIndexTrampoline.
- 	destReg ~= TempReg ifTrue:
- 		[cogit MoveR: TempReg R: destReg]!

Item was added:
+ ----- Method: CogObjectRepresentationForSpur>>genGetClassObjectOfClassIndex:into:scratchReg: (in category 'compile abstract instructions') -----
+ genGetClassObjectOfClassIndex: instReg into: destReg scratchReg: scratchReg
+ 	"Fetch the class object whose index is in instReg into destReg.
+ 	 It is non-obvious, but the Cogit assumes loading a class does not involve
+ 	 a runtime call, so do not call classAtIndex:"
+ 	self assert: instReg ~= destReg.
+ 	self assert: instReg ~= scratchReg.
+ 	self assert: destReg ~= scratchReg.
+ 	cogit
+ 		MoveR: instReg R: scratchReg;
+ 		LogicalShiftRightCq: objectMemory classTableMajorIndexShift R: scratchReg;
+ 		LogicalShiftLeftCq: objectMemory shiftForWord R: scratchReg..
+ 	self assert: (self shouldAnnotateObjectReference: objectMemory classTableRootObj) not.
+ 	cogit
+ 		MoveMw: objectMemory classTableRootObj + objectMemory baseHeaderSize r: scratchReg R: destReg;
+ 		MoveR: instReg R: scratchReg;
+ 		AndCq: objectMemory classTableMinorIndexMask R: scratchReg;
+ 		AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: scratchReg;
+ 		MoveXwr: scratchReg R: destReg R: destReg..
+ 	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveSize: (in category 'primitive generators') -----
  genInnerPrimitiveSize: retNoffset
  	| jumpImm jumpNotIndexable jumpIsContext |
  	"c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: fixedFieldsOf:format:length:"
  	<var: #jumpImm type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpIsContext type: #'AbstractInstruction *'>
  	cogit MoveR: ReceiverResultReg R: TempReg.
  	jumpImm := self genJumpImmediateInScratchReg: TempReg.
  	self
  		genGetSizeOf: ReceiverResultReg
  		into: ClassReg
  		formatReg: SendNumArgsReg
  		scratchReg: TempReg
  		abortJumpsInto: [:jnx :jic| jumpNotIndexable := jnx. jumpIsContext := jic].
  	self genConvertIntegerToSmallIntegerInScratchReg: ClassReg.
  	cogit MoveR: ClassReg R: ReceiverResultReg.
- 	self flag: 'currently caller pushes result'.
  	cogit RetN: retNoffset.
  	jumpImm jmpTarget: (jumpNotIndexable jmpTarget: (jumpIsContext jmpTarget: cogit Label)).
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genStoreSourceReg:slotIndex:destReg:scratchReg: (in category 'compile abstract instructions') -----
  genStoreSourceReg: sourceReg slotIndex: index destReg: destReg scratchReg: scratchReg
  	| jmpImmediate jmpDestYoung jmpSourceOld jmpAlreadyRemembered mask rememberedBitByteOffset |
  	<var: #jmpImmediate type: #'AbstractInstruction *'>
  	<var: #jmpDestYoung type: #'AbstractInstruction *'>
  	<var: #jmpSourceOld type: #'AbstractInstruction *'>
  	<var: #jmpAlreadyRemembered type: #'AbstractInstruction *'>
  	"do the store"
  	cogit MoveR: sourceReg
  		   Mw: index * objectMemory wordSize + objectMemory baseHeaderSize
  		   r: destReg.
  	"now the check.  Is value stored an integer?  If so we're done"
  	cogit MoveR: sourceReg R: scratchReg.
  	cogit AndCq: objectMemory tagMask R: scratchReg.
  	jmpImmediate := cogit JumpNonZero: 0.
  	"Get the old/new boundary in scratchReg"
  	cogit MoveAw: objectMemory newSpaceLimitAddress R: scratchReg.
  	"Is target young?  If so we're done"
  	cogit CmpR: scratchReg R: destReg. "N.B. FLAGS := destReg - scratchReg"
  	jmpDestYoung := cogit JumpBelow: 0.
  	"Is value stored old?  If so we're done."
  	cogit CmpR: scratchReg R: sourceReg. "N.B. FLAGS := sourceReg - scratchReg"
  	jmpSourceOld := cogit JumpAboveOrEqual: 0.
  	"value is young and target is old.
  	 Need to remember this only if the remembered bit is not already set.
  	 Test the remembered bit.  Only need to fetch the byte containing it,
  	 which reduces the size of the mask constant."
  	rememberedBitByteOffset := jmpSourceOld isBigEndian
  									ifTrue: [objectMemory baseHeaderSize - 1 - (objectMemory rememberedBitShift // 8)]
  									ifFalse:[objectMemory rememberedBitShift // 8].
  	mask := 1 << (objectMemory rememberedBitShift \\ 8).
+ 	"N.B. MoveMb:r:R: does not zero other bits"
  	cogit MoveMb: rememberedBitByteOffset r: destReg R: scratchReg.
  	cogit AndCq: mask R: scratchReg.
  	jmpAlreadyRemembered := cogit JumpNonZero: 0.
  	"Remembered bit is not set.  Call store check to insert dest into remembered table."
  	self assert: destReg == ReceiverResultReg.
  	cogit CallRT: ceStoreCheckTrampoline.
  	jmpImmediate jmpTarget:
  	(jmpDestYoung jmpTarget:
  	(jmpSourceOld jmpTarget:
  	(jmpAlreadyRemembered jmpTarget:
  		cogit Label))).
  	^0!

Item was removed:
- ----- Method: CogObjectRepresentationForSpur>>generateObjectRepresentationTrampolines (in category 'initialization') -----
- generateObjectRepresentationTrampolines
- 	super generateObjectRepresentationTrampolines.
- 	ceClassAtIndexTrampoline := cogit
- 									genTrampolineFor: #ceClassAtIndex:
- 									called: 'ceClassAtIndexTrampoline'
- 									arg: TempReg
- 									result: TempReg!

Item was added:
+ ----- Method: CogObjectRepresentationForSpur>>jumpNotCharacterUnsignedValueInRegister: (in category 'compile abstract instructions') -----
+ jumpNotCharacterUnsignedValueInRegister: reg
+ 	cogit CmpCq: 16r3FFFFFFF R: reg.
+ 	^cogit JumpAbove: 0!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>shouldAnnotateObjectReference: (in category 'garbage collection') -----
  shouldAnnotateObjectReference: anOop
+ 	"Objects in newSpace or oldSpace except nil, true, false & classTableRootObj need to be annotated."
- 	"Objects in newSpace or oldSPace except nil, true & false need to be annotated."
  	^(objectMemory isNonImmediate: anOop)
+ 	  and: [(self oop: anOop isGreaterThan: objectMemory classTableRootObj)
- 	  and: [(self oop: anOop isGreaterThan: objectMemory trueObject)
  		or: [self oop: anOop isLessThan: objectMemory nilObject]]!

Item was changed:
  ----- Method: CogObjectRepresentationForSqueakV3>>genInnerPrimitiveSize: (in category 'primitive generators') -----
  genInnerPrimitiveSize: retNoffset
  	| jumpSI jumpNotIndexable jumpIsContext |
  	"c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: fixedFieldsOf:format:length:"
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpIsContext type: #'AbstractInstruction *'>
  	cogit MoveR: ReceiverResultReg R: TempReg.
  	jumpSI := self genJumpSmallIntegerInScratchReg: TempReg.
  	self
  		genGetSizeOf: ReceiverResultReg
  		into: ClassReg
  		formatReg: SendNumArgsReg
  		scratchReg: TempReg
  		abortJumpsInto: [:jnx :jic| jumpNotIndexable := jnx. jumpIsContext := jic].
  	self genConvertIntegerToSmallIntegerInScratchReg: ClassReg.
  	cogit MoveR: ClassReg R: ReceiverResultReg.
- 	self flag: 'currently caller pushes result'.
  	cogit RetN: retNoffset.
  	jumpSI jmpTarget: (jumpNotIndexable jmpTarget: (jumpIsContext jmpTarget: cogit Label)).
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSqueakV3>>genStoreSourceReg:slotIndex:destReg:scratchReg: (in category 'compile abstract instructions') -----
  genStoreSourceReg: sourceReg slotIndex: index destReg: destReg scratchReg: scratchReg
  	| jmpImmediate jmpDestYoung jmpSourceOld jmpAlreadyRoot mask rootBitByteOffset |
  	<var: #jmpImmediate type: #'AbstractInstruction *'>
  	<var: #jmpDestYoung type: #'AbstractInstruction *'>
  	<var: #jmpSourceOld type: #'AbstractInstruction *'>
  	<var: #jmpAlreadyRoot type: #'AbstractInstruction *'>
  	"do the store"
  	cogit MoveR: sourceReg Mw: index * BytesPerWord + BaseHeaderSize r: destReg.
  	"now the check.  Is value stored an integer?  If so we're done"
  	cogit MoveR: sourceReg R: scratchReg.
  	cogit AndCq: 1 R: scratchReg.
  	jmpImmediate := cogit JumpNonZero: 0.
  	"Get the old/new boundary in scratchReg"
  	cogit MoveAw: objectMemory youngStartAddress R: scratchReg.
  	"Is target young?  If so we're done"
  	cogit CmpR: scratchReg R: destReg. "N.B. FLAGS := destReg - scratchReg"
  	jmpDestYoung := cogit JumpAboveOrEqual: 0.
  	"Is value stored old?  If so we're done."
  	cogit CmpR: scratchReg R: sourceReg. "N.B. FLAGS := sourceReg - scratchReg"
  	jmpSourceOld := cogit JumpBelow: 0.
  	"value is young and target is old.
  	 Need to make this a root if the root bit is not already set.
  	 Test the root bit.  Only need to fetch the byte containing it,
  	 which reduces the size of the mask constant."
  	rootBitByteOffset := jmpSourceOld isBigEndian
  							ifTrue: [BytesPerWord - RootBitDigitLength]
  							ifFalse:[RootBitDigitLength - 1].
  	mask := RootBitDigitLength > 1
  				ifTrue: [RootBit >> (RootBitDigitLength - 1 * 8)]
  				ifFalse: [RootBit].
+ 	"N.B. MoveMb:r:R: does not zero other bits"
  	cogit MoveMb: rootBitByteOffset r: destReg R: scratchReg.
  	cogit AndCq: mask R: scratchReg.
  	jmpAlreadyRoot := cogit JumpNonZero: 0.
  	"Root bit is not set.  Call store check to insert dest into root table."
  	self assert: destReg == ReceiverResultReg.
  	cogit CallRT: ceStoreCheckTrampoline.
  	jmpImmediate jmpTarget:
  	(jmpDestYoung jmpTarget:
  	(jmpSourceOld jmpTarget:
  	(jmpAlreadyRoot jmpTarget:
  		cogit Label))).
  	^0!

Item was changed:
  ----- Method: CogSistaMethodSurrogate32 class>>offsetOf: (in category 'accessing') -----
  offsetOf: aByteSymbol
+ 	"These should be generated!!!!"
+ 	self assert: self objectMemoryClass baseHeaderSize = BaseHeaderSize.
  	^aByteSymbol == #numCounters
+ 		ifTrue: [20 + BaseHeaderSize]
- 		ifTrue: [24]
  		ifFalse: [super offsetOf: aByteSymbol]!

Item was changed:
  ----- Method: CogSistaMethodSurrogate64 class>>offsetOf: (in category 'accessing') -----
  offsetOf: aByteSymbol
+ 	"These should be generated!!!!"
+ 	self assert: self objectMemoryClass baseHeaderSize = BaseHeaderSize.
  	^aByteSymbol == #numCounters
+ 		ifTrue: [32 + BaseHeaderSize]
- 		ifTrue: [40]
  		ifFalse: [super offsetOf: aByteSymbol]!

Item was changed:
  ----- Method: CogVMSimulator>>ceSend:super:to:numArgs: (in category 'trampolines') -----
  ceSend: selector super: superNormalBar to: rcvr numArgs: numArgs
  	"self stringOf: selector"
  	"self printOop: rcvr"
+ 	"(superNormalBar ~= 0 and: [(self stringOf: selector) = #bitShift:]) ifTrue:
+ 		[self halt]."
- 	(superNormalBar ~= 0 and: [(self stringOf: selector) = #bitShift:]) ifTrue:
- 		[self halt].
  	self logSend: selector.
  	cogit assertCStackWellAligned.
  	self maybeCheckStackDepth: numArgs + 1 sp: stackPointer pc: (stackPages longAt: stackPointer).
  	^super ceSend: selector super: superNormalBar to: rcvr numArgs: numArgs!

Item was changed:
  ----- Method: CogVMSimulator>>shortPrint: (in category 'debug support') -----
  shortPrint: oop
  	| name classOop |
  	(objectMemory isImmediate: oop) ifTrue:
  		[(objectMemory isImmediateCharacter: oop) ifTrue:
  			[^ '=$' , (objectMemory characterValueOf: oop) printString , 
  			' (' , (String with: (Character value: (objectMemory characterValueOf: oop))) , ')'].
  		(objectMemory isIntegerObject: oop) ifTrue:
  			[^ '=' , (objectMemory integerValueOf: oop) printString , 
  			' (' , (objectMemory integerValueOf: oop) hex , ')'].
  		^'= UNKNOWN IMMEDIATE', ' (' , (objectMemory integerValueOf: oop) hex , ')'].
  	(objectMemory addressCouldBeObj: oop) ifFalse:
  		[^(oop bitAnd: objectMemory allocationUnit - 1) ~= 0
  			ifTrue: [' is misaligned']
  			ifFalse: [' is not on the heap']].
  	(objectMemory isFreeObject: oop) ifTrue:
  		[^' is a free chunk of size ', (objectMemory sizeOfFree: oop) printString].
  	(objectMemory isForwarded: oop) ifTrue:
  		[^' is a forwarded object to ', (objectMemory followForwarded: oop) hex,
  			' of slot size ', (objectMemory numSlotsOfAny: oop) printString].
  	classOop := objectMemory fetchClassOfNonImm: oop.
  	(objectMemory sizeBitsOf: classOop) = metaclassSizeBits ifTrue:
  		[^'class ' , (self nameOfClass: oop)].
  	name := self nameOfClass: classOop.
  	name size = 0 ifTrue: [name := '??'].
  	name = 'String' ifTrue: [^ (self stringOf: oop) printString].
  	name = 'ByteString' ifTrue: [^ (self stringOf: oop) printString].
  	name = 'Symbol' ifTrue: [^ '#' , (self stringOf: oop)].
  	name = 'ByteSymbol' ifTrue: [^ '#' , (self stringOf: oop)].
  	name = 'Character' ifTrue: "SpurMemoryManager has immediate Characters; ObjectMemory does not"
  		[^ '=' , (Character value: (objectMemory integerValueOf: 
  				(objectMemory fetchPointer: 0 ofObject: oop))) printString].
  	name = 'UndefinedObject' ifTrue: [^ 'nil'].
  	name = 'False' ifTrue: [^ 'false'].
  	name = 'True' ifTrue: [^ 'true'].
  	name = 'Float' ifTrue: [^ '=' , (self dbgFloatValueOf: oop) printString].
+ 	(#('Association' 'ReadOnlyVariableBinding' 'VariableBinding') includes: name) ifTrue:
- 	name = 'Association' ifTrue:
  		[^ '(' ,
  		(self shortPrint: (self longAt: oop + BaseHeaderSize)) ,
  		' -> ' ,
  		(self longAt: oop + BaseHeaderSize + BytesPerWord) hex8 , ')'].
+ 	^(('AEIOU' includes: name first) ifTrue: ['an '] ifFalse: ['a ']), name!
- 	^('AEIOU' includes: name first)
- 		ifTrue: ['an ' , name]
- 		ifFalse: ['a ' , name]!

Item was changed:
  CogClass subclass: #Cogit
  	instanceVariableNames: 'coInterpreter objectMemory objectRepresentation processor threadManager methodZone methodZoneBase codeBase minValidCallAddress lastNInstructions simulatedAddresses simulatedTrampolines simulatedVariableGetters simulatedVariableSetters printRegisters printInstructions compilationTrace clickConfirm breakPC breakBlock singleStep guardPageSize traceFlags traceStores breakMethod methodObj initialPC endPC methodOrBlockNumArgs inBlock needsFrame hasYoungReferent primitiveIndex backEnd postCompileHook primInvokeLabel methodLabel stackCheckLabel blockEntryLabel blockEntryNoContextSwitch blockNoContextSwitchOffset stackOverflowCall sendMissCall missOffset entryPointMask checkedEntryAlignment cmEntryOffset entry cmNoCheckEntryOffset noCheckEntry dynSuperEntry dynSuperEntryAlignment cmDynSuperEntryOffset mnuCall interpretCall endCPICCase0 endCPICCase1 numPICCases firstCPICCaseOffset cPICCaseSize cPICEndSize closedPICSize openPICSize fixups abstractOpcodes annotations generatorTable primitiveGeneratorTable byte0 byte1 byte2 byte3 bytecodePC bytecodeSetOffset opcodeIndex numAbstractOpcodes annotationIndex blockStarts blockCount labelCounter cStackAlignment expectedSPAlignment expectedFPAlignment codeModified maxMethodBefore maxLitIndex ceMethodAbortTrampoline cePICAbortTrampoline ceCheckForInterruptTrampoline ceCPICMissTrampoline ceReturnToInterpreterTrampoline ceBaseFrameReturnTrampoline ceSendMustBeBooleanAddTrueTrampoline ceSendMustBeBooleanAddFalseTrampoline ceCannotResumeTrampoline ceClosureCopyTrampoline ceCreateNewArrayTrampoline ceEnterCogCodePopReceiverReg ceEnterCogCodePopReceiverAndClassRegs cePrimReturnEnterCogCode cePrimReturnEnterCogCodeProfiling ceNonLocalReturnTrampoline ceActiveContextTrampoline ceFetchContextInstVarTrampoline ceStoreContextInstVarTrampoline cePositive32BitIntegerTrampoline ceImplicitReceiverTrampoline ceExplicitReceiverTrampoline ceCaptureCStackPointers ceFlushICache ceCheckFeaturesFunction ceTraceLinkedSendTrampoline ceTraceBlockActivationTrampoline ceTraceStoreTrampoline ceGetSP sendTrampolines superSendTrampolines dynamicSuperSendTrampolines firstSend lastSend realCEEnterCogCodePopReceiverReg realCEEnterCogCodePopReceiverAndClassRegs trampolineTableIndex trampolineAddresses objectReferencesInRuntime runtimeObjectRefIndex cFramePointerInUse debugPrimCallStackOffset ceTryLockVMOwner ceUnlockVMOwner cogMethodSurrogateClass cogBlockMethodSurrogateClass extA extB'
  	classVariableNames: 'AltBlockCreationBytecodeSize AltNSSendIsPCAnnotated AnnotationConstantNames AnnotationShift BlockCreationBytecodeSize Debug DisplacementMask DisplacementX2N EagerInstructionDecoration EncounteredUnknownBytecode FirstAnnotation HasBytecodePC InsufficientCodeSpace IsAbsPCReference IsDisplacement IsDisplacementX2N IsNSSendCall IsObjectReference IsRelativeCall IsSendCall MapEnd MaxCompiledPrimitiveIndex MaxNegativeErrorCode MaxStackAllocSize MaxUnitDisplacement MaxX2NDisplacement MethodTooBig NSSendIsPCAnnotated NotFullyInitialized NumObjRefsInRuntime NumSendTrampolines NumTrampolines ProcessorClass YoungSelectorInPIC'
+ 	poolDictionaries: 'CogCompilationConstants CogMethodConstants CogRTLOpcodes VMBasicConstants VMObjectIndices VMStackFrameOffsets'
- 	poolDictionaries: 'CogMethodConstants CogRTLOpcodes VMBasicConstants VMObjectIndices VMStackFrameOffsets'
  	category: 'VMMaker-JIT'!
  Cogit class
  	instanceVariableNames: 'generatorTable primitiveTable'!
  
  !Cogit commentStamp: 'eem 2/13/2013 15:37' prior: 0!
  I am the code generator for the Cog VM.  My job is to produce machine code versions of methods for faster execution and to manage inline caches for faster send performance.  I can be tested in the current image using my class-side in-image compilation facilities.  e.g. try
  
  	StackToRegisterMappingCogit genAndDis: (Integer >> #benchFib)
  
  I have concrete subclasses that implement different levels of optimization:
  	SimpleStackBasedCogit is the simplest code generator.
  
  	StackToRegisterMappingCogit is the current production code generator  It defers pushing operands
  	to the stack until necessary and implements a register-based calling convention for low-arity sends.
  
  	StackToRegisterMappingCogit is an experimental code generator with support for counting
  	conditional branches, intended to support adaptive optimization.
  
  coInterpreter <CoInterpreterSimulator>
  	the VM's interpreter with which I cooperate
  methodZoneManager <CogMethodZoneManager>
  	the manager of the machine code zone
  objectRepresentation <CogObjectRepresentation>
  	the object used to generate object accesses
  processor <BochsIA32Alien|?>
  	the simulator that executes the IA32/x86 machine code I generate when simulating execution in Smalltalk
  simulatedTrampolines <Dictionary of Integer -> MessageSend>
  	the dictionary mapping trap jump addresses to run-time routines used to warp from simulated machine code in to the Smalltalk run-time.
  simulatedVariableGetters <Dictionary of Integer -> MessageSend>
  	the dictionary mapping trap read addresses to variables in run-time objects used to allow simulated machine code to read variables in the Smalltalk run-time.
  simulatedVariableSetters <Dictionary of Integer -> MessageSend>
  	the dictionary mapping trap write addresses to variables in run-time objects used to allow simulated machine code to write variables in the Smalltalk run-time.
  printRegisters printInstructions clickConfirm <Boolean>
  	flags controlling debug printing and code simulation
  breakPC <Integer>
  	machine code pc breakpoint
  cFramePointer cStackPointer <Integer>
  	the variables representing the C stack & frame pointers, which must change on FFI callback and return
  selectorOop <sqInt>
  	the oop of the methodObj being compiled
  methodObj <sqInt>
  	the bytecode method being compiled
  initialPC endPC <Integer>
  	the start and end pcs of the methodObj being compiled
  methodOrBlockNumArgs <Integer>
  	argument count of current method or block being compiled
  needsFrame <Boolean>
  	whether methodObj or block needs a frame to execute
  primitiveIndex <Integer>
  	primitive index of current method being compiled
  methodLabel <CogAbstractOpcode>
  	label for the method header
  blockEntryLabel <CogAbstractOpcode>
  	label for the start of the block dispatch code
  stackOverflowCall <CogAbstractOpcode>
  	label for the call of ceStackOverflow in the method prolog
  sendMissCall <CogAbstractOpcode>
  	label for the call of ceSICMiss in the method prolog
  entryOffset <Integer>
  	offset of method entry code from start (header) of method
  entry <CogAbstractOpcode>
  	label for the first instruction of the method entry code
  noCheckEntryOffset <Integer>
  	offset of the start of a method proper (after the method entry code) from start (header) of method
  noCheckEntry <CogAbstractOpcode>
  	label for the first instruction of start of a method proper
  fixups <Array of <AbstractOpcode Label | nil>>
  	the labels for forward jumps that will be fixed up when reaching the relevant bytecode.  fixup shas one element per byte in methodObj's bytecode
  abstractOpcodes <Array of <AbstractOpcode>>
  	the code generated when compiling methodObj
  byte0 byte1 byte2 byte3 <Integer>
  	individual bytes of current bytecode being compiled in methodObj
  bytecodePointer <Integer>
  	bytecode pc (same as Smalltalk) of the current bytecode being compiled
  opcodeIndex <Integer>
  	the index of the next free entry in abstractOpcodes (this code is translated into C where OrderedCollection et al do not exist)
  numAbstractOpcodes <Integer>
  	the number of elements in abstractOpcocdes
  blockStarts <Array of <BlockStart>>
  	the starts of blocks in the current method
  blockCount
  	the index into blockStarts as they are being noted, and hence eventuakly teh total number of blocks in the current method
  labelCounter <Integer>
  	a nicety for numbering labels not needed in the production system but probably not expensive enough to worry about
  ceStackOverflowTrampoline <Integer>
  ceSend0ArgsTrampoline <Integer>
  ceSend1ArgsTrampoline <Integer>
  ceSend2ArgsTrampoline <Integer>
  ceSendNArgsTrampoline <Integer>
  ceSendSuper0ArgsTrampoline <Integer>
  ceSendSuper1ArgsTrampoline <Integer>
  ceSendSuper2ArgsTrampoline <Integer>
  ceSendSuperNArgsTrampoline <Integer>
  ceSICMissTrampoline <Integer>
  ceCPICMissTrampoline <Integer>
  ceStoreCheckTrampoline <Integer>
  ceReturnToInterpreterTrampoline <Integer>
  ceBaseFrameReturnTrampoline <Integer>
  ceSendMustBeBooleanTrampoline <Integer>
  ceClosureCopyTrampoline <Integer>
  	the various trampolines (system-call-like jumps from machine code to the run-time).
  	See Cogit>>generateTrampolines for the mapping from trampoline to run-time
  	routine and then read the run-time routine for a funcitonal description.
  ceEnterCogCodePopReceiverReg <Integer>
  	the enilopmart (jump from run-time to machine-code)
  methodZoneBase <Integer>
  !
  Cogit class
  	instanceVariableNames: 'generatorTable primitiveTable'!

Item was changed:
  ----- Method: Cogit class>>initializeErrorCodes (in category 'class initialization') -----
  initializeErrorCodes
+ 	"External errors, returned to or from cog:selector:"
  	NotFullyInitialized := -1.
  	InsufficientCodeSpace := -2.
  	MethodTooBig := -4.
  	YoungSelectorInPIC := -5.
  	EncounteredUnknownBytecode := -6.
+ 	MaxNegativeErrorCode := EncounteredUnknownBytecode.
+ 	"Internal errors returned by generator routines to other generator routines"
+ 	BadRegisterSet := 1!
- 	MaxNegativeErrorCode := EncounteredUnknownBytecode!

Item was added:
+ ----- Method: Cogit>>CallRT:registersToBeSavedMask: (in category 'compile abstract instructions') -----
+ CallRT: callTarget registersToBeSavedMask: registersToBeSaved
+ 	<returnTypeC: #'AbstractInstruction *'>
+ 	| callerSavedRegsToBeSaved lastInst |
+ 	<var: 'lastInst' type: #'AbstractInstruction *'>
+ 	callerSavedRegsToBeSaved := backEnd callerSavedRegisterMask bitAnd: registersToBeSaved.
+ 
+ 	GPRegMax to: GPRegMin by: -1 do:
+ 		[:reg|
+ 		(reg ~= TempReg
+ 		 and: [callerSavedRegsToBeSaved anyMask: (self registerMaskFor: reg)]) ifTrue:
+ 			[self PushR: reg]].
+ 	
+ 	lastInst := self CallRT: callTarget.
+ 
+ 	GPRegMin to: GPRegMax do:
+ 		[:reg|
+ 		(reg ~= TempReg
+ 		 and: [callerSavedRegsToBeSaved anyMask: (self registerMaskFor: reg)]) ifTrue:
+ 			[lastInst := self PopR: reg]].
+ 
+ 	^lastInst!

Item was added:
+ ----- Method: Cogit>>registerMaskFor: (in category 'register management') -----
+ registerMaskFor: reg
+ 	"Answer a bit mask identifying the symbolic register.
+ 	 Registers are negative numbers."
+ 	^1 << (1 - reg)!

Item was added:
+ ----- Method: Cogit>>registerMaskFor:and: (in category 'register management') -----
+ registerMaskFor: reg1 and: reg2
+ 	"Answer a bit mask identifying the symbolic registers.
+ 	 Registers are negative numbers."
+ 	^1 << (1 - reg1) bitOr: 1 << (1 - reg2)!

Item was added:
+ ----- Method: Cogit>>registerMaskFor:and:and: (in category 'register management') -----
+ registerMaskFor: reg1 and: reg2 and: reg3
+ 	"Answer a bit mask identifying the symbolic registers.
+ 	 Registers are negative numbers."
+ 	^(1 << (1 - reg1) bitOr: 1 << (1 - reg2)) bitOr: 1 << (1 - reg3)!

Item was added:
+ ----- Method: Cogit>>registerMaskFor:and:and:and: (in category 'register management') -----
+ registerMaskFor: reg1 and: reg2 and: reg3 and: reg4
+ 	"Answer a bit mask identifying the symbolic registers.
+ 	 Registers are negative numbers."
+ 	^((1 << (1 - reg1) bitOr: 1 << (1 - reg2)) bitOr: 1 << (1 - reg3)) bitOr: 1 << (1 - reg4)!

Item was changed:
  ----- Method: Cogit>>simulateCogCodeAt: (in category 'simulation only') -----
  simulateCogCodeAt: address "<Integer>"
  	<doNotGenerate>
  	| stackZoneBase |
  	stackZoneBase := coInterpreter stackZoneBase.
  	processor pc: address.
  	[[[singleStep ifTrue:
  		[[processor sp < stackZoneBase ifTrue: [self halt].
  		  self recordRegisters.
  		  printRegisters ifTrue:
  			[processor printRegistersOn: coInterpreter transcript].
  		  self recordLastInstruction.
  		  printInstructions ifTrue:
+ 			[coInterpreter transcript nextPutAll: lastNInstructions last; cr.
+ 			 printRegisters ifTrue: [coInterpreter transcript cr].
+ 			 coInterpreter transcript flush].
- 			[coInterpreter transcript nextPutAll: lastNInstructions last; cr; flush].
  		  (breakPC isInteger
  			ifTrue:
  				[processor pc = breakPC
  				 and: [breakBlock value: self]]
  			ifFalse:
  				[breakBlock value: self]) ifTrue:
  			["printRegisters := printInstructions := true"
  			 "self reportLastNInstructions"
  			 "coInterpreter printExternalHeadFrame"
  			 "coInterpreter printFrameAndCallers: coInterpreter framePointer SP: coInterpreter stackPointer"
  			 "coInterpreter shortPrintFrameAndCallers: coInterpreter framePointer"
  			 "coInterpreter printFrame: processor fp WithSP: processor sp"
  			 "coInterpreter printFrameAndCallers: processor fp SP: processor sp"
  			 "coInterpreter shortPrintFrameAndCallers: processor fp"
  			"self disassembleMethodFor: processor pc"
  			 coInterpreter changed: #byteCountText.
  			 self halt: 'machine code breakpoint at ',
  						(breakPC isInteger
  							ifTrue: [breakPC hex]
  							ifFalse: [String streamContents: [:s| breakBlock decompile printOn: s indent: 0]])]] value]. "So that the Debugger's Over steps over all this"
  	   singleStep
  		ifTrue: [processor
  					singleStepIn: coInterpreter memory
  					minimumAddress: guardPageSize
  					readOnlyBelow: coInterpreter cogCodeSize]
  		ifFalse: [processor
  					runInMemory: coInterpreter memory
  					minimumAddress: guardPageSize
  					readOnlyBelow: coInterpreter cogCodeSize].
  	   ((printRegisters or: [printInstructions]) and: [clickConfirm]) ifTrue:
  	 	[(self confirm: 'continue?') ifFalse:
  			[self halt]].
  	   true] whileTrue]
  		on: ProcessorSimulationTrap
  		do: [:ex| self handleSimulationTrap: ex].
  	 true] whileTrue!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genFastPrimTraceUsing:and: (in category 'primitive generators') -----
  genFastPrimTraceUsing: r1 and: r2
  	"Suport for compileInterpreterPrimitive.  Generate inline code so as to record the primitive
  	 trace as fast as possible."
  	self MoveCq: 0 R: TempReg.
+ 	self MoveCq: 0 R: r2. "N.B. MoveMb:r:R: does not zero other bits"
- 	self MoveCq: 0 R: r2.
  	self MoveMb: coInterpreter primTraceLogIndexAddress r: TempReg R: r2.
  	self MoveR: r2 R: r1.
  	self AddCq: 1 R: r1.
  	self MoveR: r1 Mb: coInterpreter primTraceLogIndexAddress r: TempReg.
  	methodLabel addDependent:
  		(self annotateAbsolutePCRef:
  			(self MoveCw: methodLabel asInteger R: r1)).
  	self MoveMw: (self offset: CogMethod of: #selector) r: r1 R: TempReg.
  	self MoveCw: coInterpreter primTraceLogAddress asInteger R: r1.
  	self MoveR: TempReg Xwr: r2 R: r1!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveClass (in category 'primitive generators') -----
  genPrimitiveClass
  	"Stack looks like
  		receiver (also in ReceiverResultReg)
  		return address"
+ 	(objectRepresentation
+ 			genGetClassObjectOf: ReceiverResultReg
+ 			into: ReceiverResultReg
+ 			scratchReg: TempReg) = BadRegisterSet ifTrue:
+ 		[objectRepresentation
+ 			genGetClassObjectOf: ReceiverResultReg
+ 			into: ClassReg
+ 			scratchReg: TempReg.
+ 		 self MoveR: ClassReg R: ReceiverResultReg]..
- 	objectRepresentation genGetClassObjectOf: ReceiverResultReg into: ReceiverResultReg scratchReg: TempReg.
  	self flag: 'currently caller pushes result'.
  	self RetN: BytesPerWord.
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveIdentityHash (in category 'primitive generators') -----
  genPrimitiveIdentityHash
+ 	| jumpSI jumpNotSet |
- 	| jumpSI |
  	<var: #jumpSI type: #'AbstractInstruction *'>
+ 	<var: #jumpNotSet type: #'AbstractInstruction *'>
  	self MoveR: ReceiverResultReg R: ClassReg.
  	jumpSI := objectRepresentation genJumpSmallIntegerInScratchReg: ClassReg.
  	objectRepresentation genGetHashFieldNonImmOf: ReceiverResultReg asSmallIntegerInto: TempReg.
+ 	objectRepresentation isHashSetOnInstanceCreation ifFalse:
+ 		[self CmpCq: ConstZero R: TempReg.
+ 		 jumpNotSet := self JumpZero: 0].
  	self MoveR: TempReg R: ReceiverResultReg.
  	self flag: 'currently caller pushes result'.
  	self RetN: BytesPerWord.
  	jumpSI jmpTarget: self Label.
+ 	objectRepresentation isHashSetOnInstanceCreation ifFalse:
+ 		[jumpNotSet jmpTarget: jumpSI getJmpTarget].
  	^0!

Item was removed:
- ----- Method: SimpleStackBasedCogit>>registerMaskFor: (in category 'simulation stack') -----
- registerMaskFor: reg
- 	"Dummy implementation for CogFooCompiler>callerSavedRegisterMask
- 	 which doesn't get pruned due to Slang limitations."
- 	^0!

Item was removed:
- ----- Method: SimpleStackBasedCogit>>registerMaskFor:and: (in category 'simulation stack') -----
- registerMaskFor: reg and: reg2
- 	"Dummy implementation for CogFooCompiler>callerSavedRegisterMask
- 	 which doesn't get pruned due to Slang limitations."
- 	^0!

Item was removed:
- ----- Method: SimpleStackBasedCogit>>registerMaskFor:and:and: (in category 'simulation stack') -----
- registerMaskFor: reg1 and: reg2 and: reg3
- 	"Dummy implementation for CogFooCompiler>callerSavedRegisterMask
- 	 which doesn't get pruned due to Slang limitations."
- 	^0!

Item was added:
+ ----- Method: Spur32BitMMLECoSimulator>>classTableFirstPage (in category 'debug support') -----
+ classTableFirstPage
+ 	^classTableFirstPage!

Item was changed:
  ----- Method: SpurMemoryManager>>isIntegerObject: (in category 'object testing') -----
  isIntegerObject: oop
  	"This list records the valid senders of isIntegerObject: as we replace uses of
  	  isIntegerObject: by isImmediate: where appropriate."
  	| sel |
  	sel := thisContext sender method selector.
  	(#(	DoIt
  		DoItIn:
  		on:do: "from the debugger"
  		makeBaseFrameFor:
  		quickFetchInteger:ofObject:
  		frameOfMarriedContext:
  		objCouldBeClassObj:
  		isMarriedOrWidowedContext:
  		shortPrint:
  		bytecodePrimAt
  		bytecodePrimAtPut
  		commonAt:
  		commonAtPut:
  		loadFloatOrIntFrom:
  		positive32BitValueOf:
  		primitiveExternalCall
  		checkedIntegerValueOf:
  		bytecodePrimAtPut
  		commonAtPut:
  		primitiveVMParameter
  		checkIsStillMarriedContext:currentFP:
  		displayBitsOf:Left:Top:Right:Bottom:
  		fetchStackPointerOf:
  		primitiveContextAt
  		primitiveContextAtPut
  		subscript:with:storing:format:
  		printContext:
  		compare31or32Bits:equal:
  		signed64BitValueOf:
  		primDigitMultiply:negative:
  		digitLength:
  		isNegativeIntegerValueOf:
  		magnitude64BitValueOf:
  		primitiveMakePoint
  		primitiveAsCharacter
  		primitiveInputSemaphore
  		baseFrameReturn
  		primitiveExternalCall
  		primDigitCompare:
  		isLiveContext:
  		numPointerSlotsOf:
  		fileValueOf:
  		loadBitBltDestForm
  		fetchIntOrFloat:ofObject:ifNil:
  		fetchIntOrFloat:ofObject:
  		loadBitBltSourceForm
  		loadPoint:from:
  		primDigitAdd:
  		primDigitSubtract:
  		positive64BitValueOf:
  		digitBitLogic:with:opIndex:
  		signed32BitValueOf:
  		isNormalized:
  		primDigitDiv:negative:
  		bytesOrInt:growTo:
  		primitiveNewMethod
  		isCogMethodReference:
  		functionForPrimitiveExternalCall:
  		genSpecialSelectorArithmetic
  		genSpecialSelectorComparison
  		ensureContextHasBytecodePC:
  		instVar:ofContext:
  		ceBaseFrameReturn:
  		inlineCacheTagForInstance:
  		primitiveObjectAtPut
  		commonVariable:at:put:cacheIndex:
+ 		primDigitBitShiftMagnitude:
+ 		externalInstVar:ofContext:) includes: sel) ifFalse:
- 		primDigitBitShiftMagnitude:) includes: sel) ifFalse:
  		[self halt].
  	^(oop bitAnd: 1) ~= 0!

Item was changed:
  ----- Method: StackInterpreterSimulator>>shortPrint: (in category 'debug support') -----
  shortPrint: oop
  	| name classOop |
  	(objectMemory isImmediate: oop) ifTrue:
  		[(objectMemory isImmediateCharacter: oop) ifTrue:
  			[^ '=$' , (objectMemory characterValueOf: oop) printString , 
  			' (' , (String with: (Character value: (objectMemory characterValueOf: oop))) , ')'].
  		(objectMemory isIntegerObject: oop) ifTrue:
  			[^ '=' , (objectMemory integerValueOf: oop) printString , 
  			' (' , (objectMemory integerValueOf: oop) hex , ')'].
  		^'= UNKNOWN IMMEDIATE', ' (' , (objectMemory integerValueOf: oop) hex , ')'].
  	(objectMemory addressCouldBeObj: oop) ifFalse:
  		[^(oop bitAnd: objectMemory allocationUnit - 1) ~= 0
  			ifTrue: [' is misaligned']
  			ifFalse: [' is not on the heap']].
  	(objectMemory isFreeObject: oop) ifTrue:
  		[^' is a free chunk of size ', (objectMemory sizeOfFree: oop) printString].
  	(objectMemory isForwarded: oop) ifTrue:
  		[^' is a forwarded object to ', (objectMemory followForwarded: oop) hex,
  			' of slot size ', (objectMemory numSlotsOfAny: oop) printString].
  	classOop := objectMemory fetchClassOfNonImm: oop.
  	(objectMemory sizeBitsOf: classOop) = metaclassSizeBits ifTrue:
  		[^'class ' , (self nameOfClass: oop)].
  	name := self nameOfClass: classOop.
  	name size = 0 ifTrue: [name := '??'].
  	name = 'String' ifTrue: [^ (self stringOf: oop) printString].
  	name = 'ByteString' ifTrue: [^ (self stringOf: oop) printString].
  	name = 'Symbol' ifTrue: [^ '#' , (self stringOf: oop)].
  	name = 'ByteSymbol' ifTrue: [^ '#' , (self stringOf: oop)].
  	name = 'Character' ifTrue: "SpurMemoryManager has immediate Characters; ObjectMemory does not"
  		[^ '=' , (Character value: (objectMemory integerValueOf: 
  				(objectMemory fetchPointer: 0 ofObject: oop))) printString].
  	name = 'UndefinedObject' ifTrue: [^ 'nil'].
  	name = 'False' ifTrue: [^ 'false'].
  	name = 'True' ifTrue: [^ 'true'].
  	name = 'Float' ifTrue: [^ '=' , (self dbgFloatValueOf: oop) printString].
+ 	(#('Association' 'ReadOnlyVariableBinding' 'VariableBinding') includes: name) ifTrue:
+ 		[^ '(' ,
+ 		(self shortPrint: (self longAt: oop + BaseHeaderSize)) ,
+ 		' -> ' ,
+ 		(self longAt: oop + BaseHeaderSize + BytesPerWord) hex8 , ')'].
+ 	^(('AEIOU' includes: name first) ifTrue: ['an '] ifFalse: ['a ']), name!
- 	name = 'Association' ifTrue: [^ '(' ,
- 				(self shortPrint: (self longAt: oop + BaseHeaderSize)) ,
- 				' -> ' ,
- 				(self longAt: oop + BaseHeaderSize + BytesPerWord) hex8 , ')'].
- 	('AEIOU' includes: name first)
- 		ifTrue: [^ 'an ' , name]
- 		ifFalse: [^ 'a ' , name]!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genPrimitiveClass (in category 'primitive generators') -----
  genPrimitiveClass
  	"Depending on argument count the argument is either
  		0 args: ReceiverResultReg
  		1 args: Arg0Reg
  		N args: top of stack (assuming 1 reg arg for now)"
  	| reg |
  	methodOrBlockNumArgs = 1
  		ifTrue:
  			[reg := Arg0Reg]
  		ifFalse:
  			[methodOrBlockNumArgs > 0 ifTrue:
  				[self MoveMw: BytesPerWord r: SPReg R: ReceiverResultReg].
  			reg := ReceiverResultReg].
+ 	(objectRepresentation
+ 			genGetClassObjectOf: reg
+ 			into: ReceiverResultReg
+ 			scratchReg: TempReg) = BadRegisterSet ifTrue:
+ 		[objectRepresentation
+ 			genGetClassObjectOf: reg
+ 			into: ClassReg
+ 			scratchReg: TempReg.
+ 		 self MoveR: ClassReg R: ReceiverResultReg].
- 	objectRepresentation
- 		genGetClassObjectOf: reg
- 		into: ReceiverResultReg
- 		scratchReg: TempReg.
  	self RetN: 0.
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genPrimitiveIdentityHash (in category 'primitive generators') -----
  genPrimitiveIdentityHash
  	| jumpSI jumpNotSet |
  	<var: #jumpSI type: #'AbstractInstruction *'>
+ 	<var: #jumpNotSet type: #'AbstractInstruction *'>
  	self MoveR: ReceiverResultReg R: ClassReg.
  	jumpSI := objectRepresentation genJumpSmallIntegerInScratchReg: ClassReg.
  	objectRepresentation genGetHashFieldNonImmOf: ReceiverResultReg asSmallIntegerInto: TempReg.
  	objectRepresentation isHashSetOnInstanceCreation ifFalse:
+ 		[self CmpCq: ConstZero R: TempReg.
- 		[self CmpCq: 0 R: TempReg.
  		 jumpNotSet := self JumpZero: 0].
  	self MoveR: TempReg R: ReceiverResultReg.
  	self RetN: 0.
  	jumpSI jmpTarget: self Label.
  	objectRepresentation isHashSetOnInstanceCreation ifFalse:
  		[jumpNotSet jmpTarget: jumpSI getJmpTarget].
  	^0!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>registerMaskFor: (in category 'simulation stack') -----
- registerMaskFor: reg
- 	"Answer a bit mask identifying the symbolic register.
- 	 Registers are negative numbers."
- 	^1 << (1 - reg)!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>registerMaskFor:and: (in category 'simulation stack') -----
- registerMaskFor: reg1 and: reg2
- 	"Answer a bit mask identifying the symbolic registers.
- 	 Registers are negative numbers."
- 	^1 << (1 - reg1) bitOr: 1 << (1 - reg2)!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>registerMaskFor:and:and: (in category 'simulation stack') -----
- registerMaskFor: reg1 and: reg2 and: reg3
- 	"Answer a bit mask identifying the symbolic registers.
- 	 Registers are negative numbers."
- 	^(1 << (1 - reg1) bitOr: 1 << (1 - reg2)) bitOr: 1 << (1 - reg3)!



More information about the Vm-dev mailing list