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

commits at source.squeak.org commits at source.squeak.org
Tue Aug 31 23:19:27 UTC 2021


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

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

Name: VMMaker.oscog-eem.3050
Author: eem
Time: 31 August 2021, 4:19:17.748712 pm
UUID: 735b9bfc-cf40-4a45-b98e-7f9a2b979b5e
Ancestors: VMMaker.oscog-mt.3049

Cogit: avoid using the Context store check for the Spur extended push/spop/store receiver var bytecodes by extending receiverTags with a bit for "maybe Context class".  This is good for a 35% speedup in ReadStream>>#next et al, e.g.

	| string stream |
	string := (SourceFiles at: 2) contentsOfEntireFile.
	string := string first: (string size roundDownTo: 10000).
	stream := ReadStream on: string.
	[[stream next isNil] whileFalse] timeToRun

=============== Diff against VMMaker.oscog-mt.3049 ===============

Item was added:
+ ----- Method: CogObjectRepresentationForSpur>>storeTrampolines (in category 'accessing') -----
+ storeTrampolines
+ 	<doNotGenerate>
+ 	^ceStoreTrampolines!

Item was changed:
  ----- Method: Cogit>>cog:selector: (in category 'jit - api') -----
  cog: aMethodObj selector: aSelectorOop
  	"Attempt to produce a machine code method for the bytecode method
  	 object aMethodObj.  N.B. If there is no code memory available do *NOT*
  	 attempt to reclaim the method zone.  Certain clients (e.g. ceSICMiss:)
  	 depend on the zone remaining constant across method generation."
  	<api>
  	<returnTypeC: #'CogMethod *'>
  	| selector cogMethod |
  	<var: #cogMethod type: #'CogMethod *'>
  	(self exclude: aMethodObj selector: aSelectorOop) ifTrue:
  		[^nil].
  	"In Newspeak we support anonymous accessors and hence tolerate the same
  	 method being cogged multiple times.  But only if the method class association is nil."
  	NewspeakVM
  		ifTrue:
  			[(coInterpreter methodHasCogMethod: aMethodObj) ifTrue:
  				[cogMethod := coInterpreter cogMethodOf: aMethodObj.
  				 self deny: cogMethod selector = aSelectorOop.
  				 cogMethod selector = aSelectorOop ifTrue:
  					[^cogMethod].
  				 (coInterpreter methodClassAssociationOf: aMethodObj) ~= objectMemory nilObject ifTrue:
  					[self cCode: 'extern void *firstIndexableField(sqInt)'. "Slang, au natural"
  					 self warnMultiple: cogMethod selectors: aSelectorOop.
  					^nil]]]
  		ifFalse: [self deny: (coInterpreter methodHasCogMethod: aMethodObj)].
  	self deny: (objectMemory isOopCompiledMethod: (coInterpreter ultimateLiteralOf: aMethodObj)).
  	selector := aSelectorOop = objectMemory nilObject
  					ifTrue: [coInterpreter maybeSelectorOfMethod: aMethodObj]
  					ifFalse: [aSelectorOop].
  	"coInterpreter stringOf: selector"
  	selector ifNotNil:
  		[coInterpreter compilationBreakpoint: selector isMNUCase: false].
  	aMethodObj = breakMethod ifTrue: [self halt: 'Compilation of breakMethod'].
  	NewspeakVM ifTrue:
  		[cogMethod := methodZone findPreviouslyCompiledVersionOf: aMethodObj with: aSelectorOop.
  		 cogMethod ifNotNil:
  			[(coInterpreter methodHasCogMethod: aMethodObj) not ifTrue:
  				[self assert: (coInterpreter rawHeaderOf: aMethodObj) = cogMethod methodHeader.
  				 cogMethod methodObject: aMethodObj.
  				 coInterpreter rawHeaderOf: aMethodObj put: cogMethod asInteger].
  			^cogMethod]].
  	"If the generators for the alternate bytecode set are missing then interpret."
  	(coInterpreter methodUsesAlternateBytecodeSet: aMethodObj)
  		ifTrue:
  			[(self numElementsIn: generatorTable) <= 256 ifTrue:
  				[^nil].
  			 bytecodeSetOffset := 256]
  		ifFalse:
  			[bytecodeSetOffset := 0].
  	objectRepresentation ensureNoForwardedLiteralsIn: aMethodObj.
  	methodObj := aMethodObj.
  	methodHeader := objectMemory methodHeaderOf: aMethodObj.
+ 	receiverTags := -1. "lazy initialization"
- 	receiverTags := objectMemory receiverTagBitsForMethod: methodObj.
  	cogMethod := self compileCogMethod: aSelectorOop.
  	(cogMethod asInteger between: MaxNegativeErrorCode and: -1) ifTrue:
  		[cogMethod asInteger = InsufficientCodeSpace ifTrue:
  			[coInterpreter callForCogCompiledCodeCompaction].
  		 self maybeFreeCounters.
  		 "Right now no errors should be reported, so nothing more to do."
  		 "self reportError: (self cCoerceSimple: cogMethod to: #sqInt)."
  		 ^nil].
  	"self cCode: ''
  		inSmalltalk:
  			[coInterpreter printCogMethod: cogMethod.
  			 ""coInterpreter symbolicMethod: aMethodObj.""
  			 self assertValidMethodMap: cogMethod."
  			 "self disassembleMethod: cogMethod."
  			 "printInstructions := clickConfirm := true""]."
  	^cogMethod!

Item was changed:
  ----- Method: Cogit>>cogFullBlockMethod:numCopied: (in category 'jit - api') -----
  cogFullBlockMethod: aMethodObj numCopied: numCopied
  	"Attempt to produce a machine code method for the bytecode method
  	 object aMethodObj.  N.B. If there is no code memory available do *NOT*
  	 attempt to reclaim the method zone.  Certain clients (e.g. ceSICMiss:)
  	 depend on the zone remaining constant across method generation."
  	<api>
  	<option: #SistaV1BytecodeSet>
  	<returnTypeC: #'CogMethod *'>
  	| cogMethod |
  	<var: #cogMethod type: #'CogMethod *'>
  	(self exclude: aMethodObj) ifTrue:
  		[^nil].
  	self deny: (coInterpreter methodHasCogMethod: aMethodObj).
  	self assert: (objectMemory isOopCompiledMethod: (coInterpreter ultimateLiteralOf: aMethodObj)).
  	aMethodObj = breakMethod ifTrue: [self halt: 'Compilation of breakMethod'].
  	"If the generators for the alternate bytecode set are missing then interpret."
  	(coInterpreter methodUsesAlternateBytecodeSet: aMethodObj)
  		ifTrue:
  			[(self numElementsIn: generatorTable) <= 256 ifTrue:
  				[^nil].
  			 bytecodeSetOffset := 256]
  		ifFalse:
  			[bytecodeSetOffset := 0].
  	objectRepresentation ensureNoForwardedLiteralsIn: aMethodObj.
  	methodObj := aMethodObj.
  	methodHeader := objectMemory methodHeaderOf: aMethodObj.
+ 	receiverTags := -1. "lazy initialization"
- 	receiverTags := objectMemory receiverTagBitsForMethod: methodObj.
  	cogMethod := self compileCogFullBlockMethod: numCopied.
  	(cogMethod asInteger between: MaxNegativeErrorCode and: -1) ifTrue:
  		[cogMethod asInteger = InsufficientCodeSpace ifTrue:
  			[coInterpreter callForCogCompiledCodeCompaction].
  		 self maybeFreeCounters.
  		 "Right now no errors should be reported, so nothing more to do."
  		 "self reportError: (self cCoerceSimple: cogMethod to: #sqInt)."
  		 ^nil].
  	"self cCode: ''
  		inSmalltalk:
  			[coInterpreter printCogMethod: cogMethod.
  			 ""coInterpreter symbolicMethod: aMethodObj.""
  			 self assertValidMethodMap: cogMethod."
  			 "self disassembleMethod: cogMethod."
  			 "printInstructions := clickConfirm := true""]."
  	^cogMethod!

Item was added:
+ ----- Method: Cogit>>mclassCouldBeContext (in category 'initialization') -----
+ mclassCouldBeContext
+ 	receiverTags < 0 ifTrue:
+ 		[receiverTags := objectMemory receiverTagBitsForMethod: methodObj].
+ 	^receiverTags anyMask: (1 bitShift: objectMemory numTagBits)!

Item was changed:
  ----- Method: Cogit>>mclassIsSmallInteger (in category 'initialization') -----
  mclassIsSmallInteger
+ 	receiverTags < 0 ifTrue:
+ 		[receiverTags := objectMemory receiverTagBitsForMethod: methodObj].
  	^objectMemory isIntegerObject: receiverTags!

Item was added:
+ ----- Method: CurrentImageCoInterpreterFacade>>ifTestProfilingAdvanceNextProfileTick (in category 'accessing') -----
+ ifTestProfilingAdvanceNextProfileTick
+ 	^self!

Item was changed:
  ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation>>receiverTagBitsForMethod: (in category 'accessing') -----
  receiverTagBitsForMethod: methodOop
+ 	| mclass |
+ 	^(mclass := (self objectForOop: methodOop) methodClass)
- 	^(self objectForOop: methodOop) methodClass
  		caseOf: {
+ 			[SmallInteger]			-> [objectMemory smallIntegerTag].
+ 			[Character]				-> [objectMemory characterTag].
+ 			[SmallFloat64]			-> [objectMemory smallFloatTag].
+ 			[Context]				-> [1 bitShift: objectMemory numTagBits] }
+ 		otherwise:
+ 			[(Context includesBehavior: mclass)
+ 				ifTrue: [1 bitShift: objectMemory numTagBits]
+ 				ifFalse: [0]]!
- 			[SmallInteger]	-> [objectMemory smallIntegerTag].
- 			[Character]		-> [objectMemory characterTag].
- 			[SmallFloat64]	-> [objectMemory smallFloatTag] }
- 		otherwise: [0]!

Item was changed:
  ----- Method: CurrentImageCoInterpreterFacadeForSqueakV3ObjectRepresentation>>receiverTagBitsForMethod: (in category 'accessing') -----
  receiverTagBitsForMethod: methodOop
+ 	^(self objectForOop: methodOop) methodClass = SmallInteger
- 	^(self objectForOop: methodOop) methodClass =SmallInteger
  		ifTrue: [1]
  		ifFalse: [0]!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genExtPushReceiverVariableBytecode (in category 'bytecode generators') -----
  genExtPushReceiverVariableBytecode
  	"226		11100010	i i i i i i i i	Push Receiver Variable #iiiiiiii (+ Extend A * 256)"
  	| index |
  	index := byte1 + (extA << 8).
  	extA := 0.
+ 	^(self mclassCouldBeContext
+ 	  and: [coInterpreter isReadMediatedContextInstVarIndex: index])
- 	^(coInterpreter isReadMediatedContextInstVarIndex: index)
  		ifTrue: [self genPushMaybeContextReceiverVariable: index]
  		ifFalse: [self genPushReceiverVariable: index]!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genExtStoreAndPopReceiverVariableBytecode (in category 'bytecode generators') -----
  genExtStoreAndPopReceiverVariableBytecode
  	"235		11101011	i i i i i i i i	Pop and Store Receiver Variable #iiiiiii (+ Extend A * 256)"
  	| index |
  	index := byte1 + (extA << 8).
  	extA := 0.
+ 	^(self mclassCouldBeContext
+ 	   and: [coInterpreter isWriteMediatedContextInstVarIndex: index])
- 	^(coInterpreter isWriteMediatedContextInstVarIndex: index)
  		ifTrue: [self genStorePop: true MaybeContextReceiverVariable: index]
  		ifFalse: [self genStorePop: true ReceiverVariable: index]!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genExtStoreReceiverVariableBytecode (in category 'bytecode generators') -----
  genExtStoreReceiverVariableBytecode
  	"232		11101000	i i i i i i i i	Store Receiver Variable #iiiiiii (+ Extend A * 256)"
  	| index |
  	index := byte1 + (extA << 8).
  	extA := 0.
+ 	^(self mclassCouldBeContext
+ 	   and: [coInterpreter isWriteMediatedContextInstVarIndex: index])
- 	^(coInterpreter isWriteMediatedContextInstVarIndex: index)
  		ifTrue: [self genStorePop: false MaybeContextReceiverVariable: index]
  		ifFalse: [self genStorePop: false ReceiverVariable: index]!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genSistaExtStoreAndPopReceiverVariableBytecodePopBoolean: (in category 'bytecode generators') -----
  genSistaExtStoreAndPopReceiverVariableBytecodePopBoolean: boolean
  	| index |
  	extB := 0. "Simple cogit don't use the extra flags"
  	numExtB := 0.
  	index := byte1 + (extA << 8).
  	extA := 0.
+ 	^(self mclassCouldBeContext
+ 	   and: [coInterpreter isWriteMediatedContextInstVarIndex: index])
- 	^(coInterpreter isWriteMediatedContextInstVarIndex: index)
  		ifTrue: [self genStorePop: boolean MaybeContextReceiverVariable: index ]
  		ifFalse: [self genStorePop: boolean ReceiverVariable: index ]!

Item was added:
+ ----- Method: Spur32BitCoMemoryManager>>receiverTagBitsForImmediateMethodClass: (in category 'cog jit support') -----
+ receiverTagBitsForImmediateMethodClass: methodClassOrNil
+ 	<inline: #always>
+ 	^methodClassOrNil = (self fetchPointer: self smallIntegerTag ofObject: classTableFirstPage)
+ 		ifTrue: [self smallIntegerTag]
+ 		ifFalse: [self assert: methodClassOrNil = (self fetchPointer: self characterTag ofObject: classTableFirstPage).
+ 				self characterTag]!

Item was removed:
- ----- Method: Spur32BitCoMemoryManager>>receiverTagBitsForMethod: (in category 'cog jit support') -----
- receiverTagBitsForMethod: aMethodObj
- 	"Answer the tag bits for the receiver based on the method's methodClass, if any."
- 	<api>
- 	| methodClassOrNil |
- 	methodClassOrNil := coInterpreter methodClassOf: aMethodObj.
- 	NewspeakVM "Mixins don't necessarily have a format inst var; filter out non-integer format."
- 		ifTrue:
- 			[| instSpec |
- 			(methodClassOrNil = nilObj
- 			 or: [(self isNonIntegerObject: (instSpec := self fetchPointer: InstanceSpecificationIndex ofObject: methodClassOrNil))
- 			 or: [(self instSpecOfClassFormat: (self integerValueOf: instSpec)) ~= self forwardedFormat]]) ifTrue:
- 				[^0]]
- 		ifFalse:
- 			[(methodClassOrNil = nilObj
- 			 or: [(self instSpecOfClass: methodClassOrNil) ~= self forwardedFormat]) ifTrue:
- 				[^0]].
- 	^methodClassOrNil = (self fetchPointer: self smallIntegerTag ofObject: classTableFirstPage)
- 		ifTrue: [self smallIntegerTag]
- 		ifFalse: [self assert: methodClassOrNil = (self fetchPointer: self characterTag ofObject: classTableFirstPage).
- 				self characterTag]!

Item was added:
+ ----- Method: Spur64BitCoMemoryManager>>receiverTagBitsForImmediateMethodClass: (in category 'cog jit support') -----
+ receiverTagBitsForImmediateMethodClass: methodClassOrNil
+ 	<inline: #always>
+ 	methodClassOrNil = (self fetchPointer: self smallIntegerTag ofObject: classTableFirstPage) ifTrue:
+ 		[^self smallIntegerTag].
+ 	methodClassOrNil = (self fetchPointer: self characterTag ofObject: classTableFirstPage) ifTrue:
+ 		[^self characterTag].
+ 	self assert: methodClassOrNil = (self fetchPointer: self smallFloatTag ofObject: classTableFirstPage).
+ 	^self smallFloatTag!

Item was removed:
- ----- Method: Spur64BitCoMemoryManager>>receiverTagBitsForMethod: (in category 'cog jit support') -----
- receiverTagBitsForMethod: aMethodObj
- 	"Answer the tag bits for the receiver based on the method's methodClass, if any."
- 	<api>
- 	| methodClassOrNil |
- 	methodClassOrNil := coInterpreter methodClassOf: aMethodObj.
- 	NewspeakVM "Mixins don't necessarily have a format inst var; filter out non-integer format."
- 		ifTrue:
- 			[| instSpec |
- 			(methodClassOrNil = nilObj
- 			 or: [(self isNonIntegerObject: (instSpec := self fetchPointer: InstanceSpecificationIndex ofObject: methodClassOrNil))
- 			 or: [(self instSpecOfClassFormat: (self integerValueOf: instSpec)) ~= self forwardedFormat]]) ifTrue:
- 				[^0]]
- 		ifFalse:
- 			[(methodClassOrNil = nilObj
- 			 or: [(self instSpecOfClass: methodClassOrNil) ~= self forwardedFormat]) ifTrue:
- 				[^0]].
- 	methodClassOrNil = (self fetchPointer: self smallIntegerTag ofObject: classTableFirstPage) ifTrue:
- 		[^self smallIntegerTag].
- 	methodClassOrNil = (self fetchPointer: self characterTag ofObject: classTableFirstPage) ifTrue:
- 		[^self characterTag].
- 	self assert: methodClassOrNil = (self fetchPointer: self smallFloatTag ofObject: classTableFirstPage).
- 	^self smallFloatTag!

Item was added:
+ ----- Method: SpurMemoryManager>>maybeContextMClassTagBits (in category 'cog jit support') -----
+ maybeContextMClassTagBits
+ 	<inline: #always>
+ 	^1 bitShift: self numTagBits!

Item was added:
+ ----- Method: SpurMemoryManager>>receiverTagBitsForMethod: (in category 'cog jit support') -----
+ receiverTagBitsForMethod: aMethodObj
+ 	"Answer the tag bits for the receiver based on the method's methodClass, if any.
+ 	 These bits are extended with a bit that says that the method may have a Context receiver, i.e.
+ 	 mclass is Context or its superclasses.  The absence of this bit is used to avoid expensive store checks, etc."
+ 	<api>
+ 	| methodClassOrNil classContextOrSuperclass |
+ 	methodClassOrNil := coInterpreter methodClassOf: aMethodObj.
+ 	methodClassOrNil = nilObj ifTrue: "If we don't know the methodClass be pessimal"
+ 		[^self maybeContextMClassTagBits].
+ 	NewspeakVM "Mixins don't necessarily have a format inst var; filter out non-integer format."
+ 		ifTrue:
+ 			[| instSpec |
+ 			((self isIntegerObject: (instSpec := self fetchPointer: InstanceSpecificationIndex ofObject: methodClassOrNil))
+ 			 and: [(self instSpecOfClassFormat: (self integerValueOf: instSpec)) = self forwardedFormat]) ifTrue:
+ 				[^self receiverTagBitsForImmediateMethodClass: methodClassOrNil]]
+ 		ifFalse:
+ 			[(self instSpecOfClass: methodClassOrNil) = self forwardedFormat ifTrue:
+ 				[^self receiverTagBitsForImmediateMethodClass: methodClassOrNil]].
+ 	"Now check if mclass is one of Context's superclasses..."
+ 	classContextOrSuperclass := self knownClassAtIndex: ClassMethodContextCompactIndex.
+ 	[classContextOrSuperclass = methodClassOrNil ifTrue:
+ 		[^self maybeContextMClassTagBits].
+ 	 classContextOrSuperclass := self fetchPointer: SuperclassIndex ofObject: classContextOrSuperclass.
+ 	 classContextOrSuperclass ~= nilObj]
+ 		whileTrue.
+ 	^0!



More information about the Vm-dev mailing list