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

commits at source.squeak.org commits at source.squeak.org
Mon Dec 22 21:16:07 UTC 2014


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

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

Name: VMMaker.oscog-eem.997
Author: eem
Time: 22 December 2014, 1:13:29.425 pm
UUID: 91767646-27b5-4e5b-9a0f-fc5fc4bdceb5
Ancestors: VMMaker.oscog-tpr.996

Replace primitiveCharacterValue with
primitiveImmediateAsInteger which provides
SmallFloat64>>identityHash as well as Character>>
asInteger.

Refactor small float manipulations to introduce
smallFloatBitsOf:.

Provide printStackReferencesTo:.

Fix slip in StackToRegisterMappingCogit>>genBinaryConstOpVarInlinePrimitive:

Fix slip in shortPrint:.

Simulator:
Fix simulation of followForwardingPointersInStackZone:.

=============== Diff against VMMaker.oscog-tpr.996 ===============

Item was removed:
- ----- Method: InterpreterPrimitives>>primitiveCharacterValue (in category 'object access primitives') -----
- primitiveCharacterValue
- 	| characterCode characterObject |
- 	characterObject := self stackTop.
- 	characterCode := CharacterTable
- 						ifNil: [objectMemory integerObjectOf: (objectMemory characterValueOf: characterObject)]
- 						ifNotNil: [objectMemory fetchPointer: CharacterValueIndex ofObject: characterObject].
- 	"the Character must be the receiver for safety"
- 	self pop: 1 thenPush: characterCode!

Item was added:
+ ----- Method: InterpreterPrimitives>>primitiveImmediateAsInteger (in category 'arithmetic float primitives') -----
+ primitiveImmediateAsInteger
+ 	"For a Smalnteger, answer itself.
+ 	 For a Character, answer its code as an unsigned integer.
+ 	 For a SmallFloat, answer the signed, but unadjusted bit pattern (so as to keep the result a SmallInteger).
+ 	 This is a good value for an immediate's hash."
+ 	<option: #Spur64BitMemoryManager>
+ 	| oop value |
+ 	oop := self stackTop.
+ 	(objectMemory isIntegerObject: oop) ifTrue:
+ 		[value := objectMemory integerValueOf: oop] ifFalse:
+ 	[(objectMemory isCharacterObject: oop) ifTrue:
+ 		[value := objectMemory characterValueOf: oop] ifFalse:
+ 	[(objectMemory isImmediateFloat: oop) ifTrue:
+ 		[value := objectMemory rotatedFloatBitsOf: oop] ifFalse:
+ 	[^self primitiveFailFor: PrimErrBadReceiver]]].
+ 	self pop: argumentCount thenPushInteger: value!

Item was added:
+ ----- Method: InterpreterPrimitives>>primitiveSmallFloatHash (in category 'arithmetic float primitives') -----
+ primitiveSmallFloatHash
+ 	"Answer the ieee 754 double precision floating point bits of the SmallFloat receiver."
+ 	<option: #Spur64BitMemoryManager>
+ 
+ 	self pop: 1 thenPush: (objectMemory positive64BitIntegerFor: (objectMemory smallFloatBitsOf: self stackTop))!

Item was changed:
  ----- Method: Spur64BitMMLESimulator>>longAt:put: (in category 'memory access') -----
  longAt: byteAddress put: a32BitValue
  	"Store the 64-bit value at byteAddress which must be 0 mod 4."
+ 	"byteAddress = 16r1F5AE8 ifTrue: [self halt]."
- 
  	^self long64At: byteAddress put: a32BitValue!

Item was changed:
  ----- Method: Spur64BitMemoryManager>>fetchLong32:ofFloatObject: (in category 'object access') -----
  fetchLong32: fieldIndex ofFloatObject: oop
  	"index by word size, and return a pointer as long as the word size"
  	
+ 	| bits |
- 	| rot |
  	(self isImmediateFloat: oop) ifFalse:
  		[^self fetchLong32: fieldIndex ofObject: oop].
+ 	bits := self smallFloatBitsOf: oop.
- 	
- 	rot := oop >> self numTagBits.
- 	rot > 1 ifTrue:
- 		[rot := rot + (self smallFloatExponentOffset << (self smallFloatMantissaBits + 1))].
- 	rot := self rotateRight: rot.
  	^self
+ 		cCode: [self longAt: (self cCoerceSimple: (self addressOf: bits) to: #'char *')
- 		cCode: [self longAt: (self cCoerceSimple: (self addressOf: rot) to: #'char *')
  							+ (fieldIndex << self shiftForWord)]
  		inSmalltalk: [self flag: #endian.
  					fieldIndex = 0
+ 						ifTrue: [bits >> 32]
+ 						ifFalse: [bits bitAnd: 16rFFFFFFFF]]!
- 						ifTrue: [rot >> 32]
- 						ifFalse: [rot bitAnd: 16rFFFFFFFF]]!

Item was changed:
  ----- Method: Spur64BitMemoryManager>>mem:mo:ve: (in category 'simulation only') -----
  mem: destAddress mo: sourceAddress ve: bytes
  	<doNotGenerate>
  	| dst src  |
  	dst := destAddress asInteger.
  	src := sourceAddress asInteger.
  	"Emulate the c library memmove function"
+ 	self assert: bytes \\ 4 = 0.
- 	self assert: bytes \\ 8 = 0.
  	destAddress > sourceAddress
  		ifTrue:
+ 			[bytes - 4 to: 0 by: -4 do:
+ 				[:i| self long32At: dst + i put: (self long32At: src + i)]]
- 			[bytes - 8 to: 0 by: -8 do:
- 				[:i| self longAt: dst + i put: (self longAt: src + i)]]
  		ifFalse:
+ 			[0 to: bytes - 4 by: 4 do:
+ 				[:i| self long32At: dst + i put: (self long32At: src + i)]]!
- 			[0 to: bytes - 8 by: 8 do:
- 				[:i| self longAt: dst + i put: (self longAt: src + i)]]!

Item was added:
+ ----- Method: Spur64BitMemoryManager>>rotatedFloatBitsOf: (in category 'interpreter access') -----
+ rotatedFloatBitsOf: oop
+ 	"Answer the signed, but unadjusted value of a SmallFloat64, suitable for use as a hash.
+ 	 Keeping the exponent unadjusted keeps the value in the SmallInteger range.
+ 	 See section 61-bit Immediate Floats in the SpurMemoryManager class comment.
+ 							msb                                             lsb 
+ 	 Decode:				[8expsubset][52mantissa][1s][3tags] 
+ 	 shift away tags & sign:	[   0000   ][8expsubset][52mantissa]
+ 	 add sign:				[    ssss   ][8expsubset][52mantissa]"
+ 	self assert: (self isImmediateFloat: oop).
+ 	^oop asUnsignedInteger >> (self numTagBits + 1)
+ 	 + ((oop anyMask: 1 << self numTagBits)
+ 		ifTrue: [-1 << (64 - self numTagBits - 1)]
+ 		ifFalse: [0])!

Item was added:
+ ----- Method: Spur64BitMemoryManager>>smallFloatBitsOf: (in category 'interpreter access') -----
+ smallFloatBitsOf: oop
+ 	"Answer the ieee 754 double precision floating point bits of the argument, a SmallFloat.
+ 	 See section 61-bit Immediate Floats in the SpurMemoryManager class comment.
+ 							msb                                              lsb 
+ 	 Decode:				[8expsubset][52mantissa][1s][3tags] 
+ 	 shift away tags:		[ 000 ][8expsubset][52mantissa][1s] 
+ 	 add exponent offset:	[     11 exponent     ][52mantissa][1s] 
+ 	 rot sign:				[1s][     11 exponent     ][52mantissa]"
+ 	| rot |
+ 	self assert: (self isImmediateFloat: oop).
+ 	rot := oop asUnsignedInteger >> self numTagBits.
+ 	rot > 1 ifTrue: "a.k.a. ~= +/-0.0"
+ 		[rot := rot + (self smallFloatExponentOffset << (self smallFloatMantissaBits + 1))].
+ 	rot := self rotateRight: rot.
+ 	^rot!

Item was changed:
  ----- Method: Spur64BitMemoryManager>>smallFloatObjectOf: (in category 'interpreter access') -----
  smallFloatObjectOf: aFloat
  	"Encode the argument, aFloat in the SmallFloat range, as a tagged small float.
  	 See section 61-bit Immediate Floats in the SpurMemoryManager class comment.
  
  	 Encode:				[1s][     11 exponent     ][52mantissa] 
  	 rot sign:				[     11 exponent     ][52mantissa][1s] 
  	 sub exponent offset:	[ 000 ][8expsubset][52 mantissa][1s] 
  	 shift:					[8expsubset][52 mantissa][1s][ 000 ] 
  	 or/add tags:			[8expsubset][52mantissa][1s][3tags]"
  	<inline: true>
  	<var: #aFloat type: #double>
  	| rawFloat rot |
  	<var: #rot type: #'unsigned long'>
  	self assert: (self isSmallFloatValue: aFloat).
  	rawFloat := self cCode: [(self cCoerce: (self addressOf: aFloat) to: 'sqLong *') at: 0]
  					inSmalltalk: [(aFloat at: 1) << 32 + (aFloat at: 2)].
  	rot := self rotateLeft: rawFloat.
+ 	rot > 1 ifTrue: "a.k.a. ~= +/-0.0"
- 	rot > 1 ifTrue:
  		[rot := rot - (self smallFloatExponentOffset << (self smallFloatMantissaBits + 1)).
  		 self assert: rot > 0].
  	^self cCode: [rot << self numTagBits + self smallFloatTag]
  		inSmalltalk: [((rot << self numTagBits) bitAnd: 16rFFFFFFFFFFFFFFFF) + self smallFloatTag]!

Item was changed:
  ----- Method: Spur64BitMemoryManager>>smallFloatValueOf: (in category 'interpreter access') -----
  smallFloatValueOf: oop
  	"Answer the C double precision floating point value of the argument, a SmallFloat.
  	 See section 61-bit Immediate Floats in the SpurMemoryManager class comment.
  							msb                                              lsb 
  	 Decode:				[8expsubset][52mantissa][1s][3tags] 
  	 shift away tags:		[ 000 ][8expsubset][52mantissa][1s] 
  	 add exponent offset:	[     11 exponent     ][52mantissa][1s] 
  	 rot sign:				[1s][     11 exponent     ][52mantissa]"
+ 	| bits |
- 	| rot |
  	<returnTypeC: #double>
+ 	bits := self smallFloatBitsOf: oop.
+ 	^self cCode: [(self cCoerce: (self addressOf: bits) to: #'double *') at: 0]
- 	self assert: (oop bitAnd: self tagMask) = self smallFloatTag.
- 	rot := oop asUnsignedInteger >> self numTagBits.
- 	rot > 1 ifTrue:
- 		[rot := rot + (self smallFloatExponentOffset << (self smallFloatMantissaBits + 1))].
- 	rot := self rotateRight: rot.
- 	^self cCode: [(self cCoerce: (self addressOf: rot) to: #'double *') at: 0]
  		inSmalltalk:
  			[(Float new: 2)
+ 				at: 1 put: bits >> 32;
+ 				at: 2 put: (bits bitAnd: 16rFFFFFFFF);
- 				at: 1 put: rot >> 32;
- 				at: 2 put: (rot bitAnd: 16rFFFFFFFF);
  				yourself]!

Item was changed:
  ----- Method: SpurMemoryManager>>become:with:twoWay:copyHash: (in category 'become api') -----
  become: array1 with: array2 twoWay: twoWayFlag copyHash: copyHashFlag
  	"All references to each object in array1 are swapped with all references to the
  	 corresponding object in array2. That is, all pointers to one object are replaced
  	 with with pointers to the other. The arguments must be arrays of the same length. 
  	 Answers PrimNoErr if the primitive succeeds, otherwise a relevant error code."
  	"Implementation: Uses lazy forwarding to defer updating references until message send."
  	| ec |
  	self assert: becomeEffectsFlags = 0.
  	self leakCheckBecome ifTrue:
  		[self runLeakCheckerForFullGC: true].
  	(self isArray: array1) ifFalse:
  		[^PrimErrBadReceiver].
  	((self isArray: array2)
  	 and: [(self numSlotsOf: array1) = (self numSlotsOf: array2)]) ifFalse:
  		[^PrimErrBadArgument].
  	(twoWayFlag or: [copyHashFlag])
  		ifTrue:
  			[ec := self containsOnlyValidBecomeObjects: array1 and: array2]
  		ifFalse:
  			[self followForwardedObjectFields: array2 toDepth: 0.
  			ec := self containsOnlyValidBecomeObjects: array1].
+ 	ec ~= 0 ifTrue:
+ 		[becomeEffectsFlags := 0.
+ 		 ^ec].
- 	ec ~= 0 ifTrue: [^ec].
  
  	coInterpreter preBecomeAction.
  	twoWayFlag
  		ifTrue:
  			[self innerBecomeObjectsIn: array1 and: array2 copyHash: copyHashFlag]
  		ifFalse:
  			[self innerBecomeObjectsIn: array1 to: array2 copyHash: copyHashFlag].
  	self followSpecialObjectsOop.
  	"N.B. perform coInterpreter's postBecomeAction: *before* postBecomeScanClassTable:
  	 to allow the coInterpreter to void method cache entries by spotting classIndices that
  	 refer to forwarded objects. postBecomeScanClassTable: follows forwarders in the table."
  	coInterpreter postBecomeAction: becomeEffectsFlags.
  	self postBecomeScanClassTable: becomeEffectsFlags.
  	becomeEffectsFlags := 0.
  
  	self assert: self validClassTableHashes.
  	self leakCheckBecome ifTrue:
  		[self runLeakCheckerForFullGC: true].
  
  	^PrimNoErr "success"!

Item was changed:
  ----- Method: StackInterpreter class>>initializePrimitiveTable (in category 'initialization') -----
(excessive size, no diff calculated)

Item was changed:
  ----- Method: StackInterpreter>>followForwardingPointersInStackZone: (in category 'object memory support') -----
  followForwardingPointersInStackZone: theBecomeEffectsFlags
  	"Spur's become: is lazy, turning the becommed object into a forwarding object to the other.
  	 The read-barrier is minimised by arranging that forwarding pointers will fail a method cache
  	 probe, since notionally objects' internals are accessed only via sending messages to them,
  	 the exception is primitives that access the internals of the non-receiver argument(s).
  	 To avoid a read barrier on bytecode, literal and inst var fetch we scan the receivers and
  	 methods in the stack zone and follow any forwarded ones.  This is of course way cheaper
  	 than scanning all of memory as in the old become."
  	| theIPPtr |
  	<inline: false>
  	<var: #thePage type: #'StackPage *'>
  	<var: #theSP type: #'char *'>
  	<var: #theFP type: #'char *'>
  	<var: #callerFP type: #'char *'>
  	<var: #theIPPtr type: #usqInt>
  
  	(theBecomeEffectsFlags anyMask: BecameCompiledMethodFlag) ifTrue:
  		[(objectMemory isForwarded: method) ifTrue:
  			[theIPPtr := instructionPointer - method.
  			 method := objectMemory followForwarded: method.
  			 instructionPointer := method + theIPPtr].
  		(objectMemory isForwarded: newMethod) ifTrue:
  			[newMethod := objectMemory followForwarded: newMethod]].
  
  	self assert: stackPage ~= 0.
  	0 to: numStackPages - 1 do:
  		[:i| | thePage theSP theFP callerFP theIP oop |
  		thePage := stackPages stackPageAt: i.
  		thePage isFree ifFalse:
  			[theSP := thePage headSP.
  			 theFP := thePage  headFP.
  			 "Skip the instruction pointer on top of stack of inactive pages."
  			 thePage = stackPage
  				ifTrue: [theIPPtr := 0]
  				ifFalse:
+ 					[theIPPtr := theSP asInteger.
- 					[theIPPtr := theSP asUnsignedInteger.
  					 theSP := theSP + objectMemory wordSize].
  			 [self assert: (thePage addressIsInPage: theFP).
  			  self assert: (theIPPtr = 0 or: [thePage addressIsInPage: theIPPtr asVoidPointer]).
  			  oop := stackPages longAt: theFP + FoxReceiver.
  			  (objectMemory isOopForwarded: oop) ifTrue:
  				[stackPages
  					longAt: theFP + FoxReceiver
  					put: (objectMemory followForwarded: oop)].
  			  theIP := (theFP + (self frameStackedReceiverOffset: theFP)) asInteger. "reuse theIP; its just an offset here"
  			  oop := stackPages longAt: theIP.
  			  (objectMemory isOopForwarded: oop) ifTrue:
  				[stackPages
  					longAt: theIP
  					put: (objectMemory followForwarded: oop)].
  			  ((self frameHasContext: theFP)
  			   and: [(objectMemory isForwarded: (self frameContext: theFP))]) ifTrue:
  				[stackPages
  					longAt: theFP + FoxThisContext
  					put: (objectMemory followForwarded: (self frameContext: theFP))].
  			  oop := self frameMethod: theFP.
  			  (objectMemory isForwarded: oop) ifTrue:
  				[| newOop delta |
  				 newOop := objectMemory followForwarded: oop.
  				 theIPPtr ~= 0 ifTrue:
  					[self assert: (stackPages longAt: theIPPtr) > (self frameMethod: theFP).
  					 delta := newOop - oop.
  					 stackPages
  						longAt: theIPPtr
  						put: (stackPages longAt: theIPPtr) + delta].
  				stackPages
  					longAt: theFP + FoxMethod
  					put: (oop := newOop)].
  			  (callerFP := self frameCallerFP: theFP) ~= 0] whileTrue:
  				[theIPPtr := (theFP + FoxCallerSavedIP) asInteger.
  				 theFP := callerFP]]]!

Item was changed:
  ----- Method: StackInterpreter>>initializeInterpreter: (in category 'initialization') -----
  initializeInterpreter: bytesToShift
  	"Initialize Interpreter state before starting execution of a new image."
  	interpreterProxy := self sqGetInterpreterProxy.
  	self dummyReferToProxy.
  	objectMemory initializeObjectMemory: bytesToShift.
  	self checkAssumedCompactClasses.
  	self initializeExtraClassInstVarIndices.
  	method := newMethod := objectMemory nilObject.
+ 	self cCode: '' inSmalltalk:
+ 		[breakSelectorLength ifNil:
+ 			[breakSelectorLength := objectMemory minSmallInteger]].
- 	self cCode: '' inSmalltalk: [breakSelectorLength := objectMemory minSmallInteger].
  	methodDictLinearSearchLimit := 8.
  	self flushMethodCache.
  	self flushAtCache.
  	self initialCleanup.
  	profileSemaphore := profileProcess := profileMethod := objectMemory nilObject.
  	interruptKeycode := 2094. "cmd-. as used for Mac but no other OS"
  	[globalSessionID = 0] whileTrue:
  		[globalSessionID := self
  								cCode: [(self time: #NULL) + self ioMSecs]
  								inSmalltalk: [(Random new next * SmallInteger maxVal) asInteger]]!

Item was added:
+ ----- Method: StackInterpreter>>printStackReferencesTo: (in category 'object memory support') -----
+ printStackReferencesTo: oop
+ 	<api>
+ 	<var: #thePage type: #'StackPage *'>
+ 	<var: #theSP type: #'char *'>
+ 	<var: #theFP type: #'char *'>
+ 	<var: #callerFP type: #'char *'>
+ 	0 to: numStackPages - 1 do:
+ 		[:i| | thePage theSP theFP callerFP |
+ 		thePage := stackPages stackPageAt: i.
+ 		thePage isFree ifFalse:
+ 			[theSP := thePage headSP.
+ 			 theFP := thePage  headFP.
+ 			 "Skip the instruction pointer on top of stack of inactive pages."
+ 			 thePage = stackPage ifFalse:
+ 				[theSP := theSP + objectMemory wordSize].
+ 			[[theSP <= (theFP + FoxReceiver)] whileTrue:
+ 				[oop = (stackPages longAt: theSP) ifTrue:
+ 					[self print: 'FP: '; printHexnp: theFP; print: ' @ '; printHexnp: theSP; cr].
+ 				 theSP := theSP + objectMemory wordSize].
+ 			 (self frameHasContext: theFP) ifTrue:
+ 				[oop = (self frameContext: theFP) ifTrue:
+ 					[self print: 'FP: '; printHexnp: theFP; print: ' CTXT'; cr]].
+ 			 oop = (self frameMethod: theFP) ifTrue:
+ 				[self print: 'FP: '; printHexnp: theFP; print: ' MTHD'; cr].
+ 			 (callerFP := self frameCallerFP: theFP) ~= 0] whileTrue:
+ 				[theSP := (theFP + FoxCallerSavedIP) + objectMemory wordSize.
+ 				 theFP := callerFP].
+ 			 theSP := theFP + FoxCallerContext. "a.k.a. FoxCallerSavedIP"
+ 			 [theSP <= thePage baseAddress] whileTrue:
+ 				[oop = (stackPages longAt: theSP) ifTrue:
+ 					[self print: 'FP: '; printHexnp: theFP; print: ' @ '; printHexnp: theSP; cr].
+ 				 theSP := theSP + objectMemory wordSize]]]!

Item was changed:
  ----- Method: StackInterpreter>>shortPrint: (in category 'simulation') -----
  shortPrint: oop
  	<doNotGenerate>
  	| name classOop |
  	(objectMemory isImmediate: oop) ifTrue:
  		[(objectMemory isImmediateCharacter: oop) ifTrue:
  			[^(objectMemory characterValueOf: oop) < 256
  				ifTrue:
  					['=$', (objectMemory characterValueOf: oop) printString,
  					' (', (String with: (Character value: (objectMemory characterValueOf: oop))), ')']
  				ifFalse:
  					['=$', (objectMemory characterValueOf: oop) printString, '(???)']].
  		(objectMemory isIntegerObject: oop) ifTrue:
  			[^'=', (objectMemory integerValueOf: oop) printString,
  			' (', (objectMemory integerValueOf: oop) hex, ')'].
  		(objectMemory isImmediateFloat: oop) ifTrue:
  			[^ '=', (objectMemory floatValueOf: oop) printString, ' (', oop hex, ')'].
  		^'= UNKNOWN IMMEDIATE', ' (', (objectMemory integerValueOf: oop) hex, ')'].
  	(objectMemory addressCouldBeObj: oop) ifFalse:
  		[^(oop bitAnd: objectMemory allocationUnit - 1) ~= 0
  			ifTrue: [' is misaligned']
  			ifFalse: [self whereIs: oop]].
  	(objectMemory isFreeObject: oop) ifTrue:
  		[^' is a free chunk of size ', (objectMemory sizeOfFree: oop) printString,
  			(objectMemory hasSpurMemoryManagerAPI
  				ifTrue: [' 0th: ', (objectMemory fetchPointer: 0 ofFreeChunk: oop) hex]
  				ifFalse: [''])].
  	(objectMemory isForwarded: oop) ifTrue:
  		[^' is a forwarded object to ', (objectMemory followForwarded: oop) hex,
  			' of slot size ', (objectMemory numSlotsOfAny: oop) printString].
  	(objectMemory isFloatInstance: oop) ifTrue:
  		[^'=', (objectMemory dbgFloatValueOf: oop) printString].
  	oop = objectMemory nilObject ifTrue:
  		[^'nil'].
  	oop = objectMemory falseObject ifTrue:
  		[^'false'].
  	oop = objectMemory trueObject ifTrue:
  		[^'true'].
  
  	classOop := objectMemory fetchClassOfNonImm: oop.
  	((self objCouldBeClassObj: oop)
  	 and: [(objectMemory numSlotsOf: classOop) = metaclassNumSlots]) ifTrue:
  		[^'class ', (self nameOfClass: oop)].
  	name := self nameOfClass: classOop.
  	name size = 0 ifTrue: [name := '??'].
  	(#('String'  'ByteString') includes: name) ifTrue:
  		[^(self stringOf: oop) printString].
  	(#('Symbol'  'ByteSymbol') includes: name) ifTrue:
  		[^'#', (self stringOf: oop)].
  	name = 'Character' ifTrue: "SpurMemoryManager has immediate Characters (see above); ObjectMemory does not"
  		[^'=', (Character value: (objectMemory integerValueOf: 
  				(objectMemory fetchPointer: 0 ofObject: oop))) printString].
  
  	"Try to spot association-like things; they're all subclasses of LookupKey"
  	((objectMemory isPointersNonImm: oop)
+ 	 and: [classOop ~= objectMemory nilObject
  	 and: [((objectMemory instanceSizeOf: classOop) between: ValueIndex + 1 and: ValueIndex + 2)
+ 	 and: [(objectMemory isBytes: (objectMemory fetchPointer: KeyIndex ofObject: oop))]]]) ifTrue:
- 	 and: [(objectMemory isBytes: (objectMemory fetchPointer: KeyIndex ofObject: oop))]]) ifTrue:
  		[| classLookupKey |
  		 classLookupKey := objectMemory fetchClassOfNonImm: (objectMemory splObj: SchedulerAssociation).
  		 [classLookupKey = objectMemory nilObject ifTrue:
  			[^(('AEIOU' includes: name first) ifTrue: ['an '] ifFalse: ['a ']), name].
  		  (objectMemory instanceSizeOf: classLookupKey) = (KeyIndex + 1)] whileFalse:
  			[classLookupKey := self superclassOf: classLookupKey].
  		 (self includesBehavior: classOop ThatOf: classLookupKey) ifTrue:
  			[^(('AEIOU' includes: name first) ifTrue: ['an '] ifFalse: ['a ']), name,
  				' ', (self shortPrint: (objectMemory fetchPointer: KeyIndex ofObject: oop)),
  				' -> ',
  				(objectMemory fetchPointer: ValueIndex ofObject: oop) hex8]].
  
  	^(('AEIOU' includes: name first) ifTrue: ['an '] ifFalse: ['a ']), name!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genBinaryConstOpVarInlinePrimitive: (in category 'inline primitive generators') -----
  genBinaryConstOpVarInlinePrimitive: prim
  	"Const op var version of binary inline primitives."
  	"SistaV1: 248		11111000 	iiiiiiii		mjjjjjjj		Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution.
  	 See EncoderForSistaV1's class comment and StackInterpreter>>#binaryInlinePrimitive:"
  	| ra val untaggedVal |
  	(ra := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
  		[self ssAllocateRequiredReg:
  			(ra := optStatus isReceiverResultRegLive
  					ifTrue: [Arg0Reg]
  					ifFalse: [ReceiverResultReg])].
  	ra = ReceiverResultReg ifTrue:
  		[optStatus isReceiverResultRegLive: false].
  	self ssTop popToReg: ra.
  	self ssPop: 1.
  	val := self ssTop constant.
  	self ssPop: 1.
  	untaggedVal := val - objectMemory smallIntegerTag.
  	prim caseOf: {
  		"0 through 6, +, -, *, /, //, \\, quo:, SmallInteger op SmallInteger => SmallInteger, no overflow"
  		[0]	->	[self AddCq: untaggedVal R: ra].
+ 		[1]	->	[self MoveCq: val R: TempReg.
+ 				 self SubR: ra R: TempReg.
+ 				 objectRepresentation genAddSmallIntegerTagsTo: TempReg.
+ 				 self MoveR: TempReg R: ra].
- 		[1]	->	[self MoveCq: untaggedVal R: TempReg.
- 				self SubR: ra R: TempReg.
- 				self MoveR: TempReg R: ra ].
  		[2]	->	[objectRepresentation genRemoveSmallIntegerTagsInScratchReg: ra.
  				 self MoveCq: (objectMemory integerValueOf: val) R: TempReg.
  				 self MulR: TempReg R: ra.
  				 objectRepresentation genAddSmallIntegerTagsTo: ra].
  
  		"2016 through 2019, bitAnd:, bitOr:, bitXor, bitShift:, SmallInteger op SmallInteger => SmallInteger, no overflow"
  
  		"2032	through 2037, >, <, >=, <=. =, ~=, SmallInteger op SmallInteger => Boolean (flags?? then in jump bytecodes if ssTop is a flags value, just generate the instruction!!!!)"
  
  		"2064	through 2068, Pointer Object>>at:, Byte Object>>at:, Short16 Word Object>>at: LongWord32 Object>>at: Quad64Word Object>>at:. obj op 0-rel SmallInteger => oop"
  		[64] ->	[self genConvertSmallIntegerToIntegerInReg: ra.
  				 self MoveCq: val R: TempReg.
+ 				 self MoveXwr: ra R: TempReg R: ra].
- 				self MoveXwr: ra R: TempReg R: ra ].
  		[65] ->	[self genConvertSmallIntegerToIntegerInReg: ra.
+ 				 self MoveCq: val R: TempReg.
+ 				 self MoveXbr: ra R: TempReg R: ra]
+ 
- 				self MoveCq: val R: TempReg.
- 				self MoveXbr: ra R: TempReg R: ra ]
  	}
  	otherwise: [^EncounteredUnknownBytecode].
  	self ssPushRegister: ra.
  	^0!



More information about the Vm-dev mailing list