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

commits at source.squeak.org commits at source.squeak.org
Sat Jan 1 03:05:33 UTC 2022


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

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

Name: VMMaker.oscog-eem.3125
Author: eem
Time: 31 December 2021, 7:05:23.768966 pm
UUID: ab22e2df-7dff-4b4c-8a0b-63c148eeeaa9
Ancestors: VMMaker.oscog-eem.3124

A bit of a rag bag:

Fix in image compilation of primitive methods under Spur; the accessor depth was not being computed correctly.  Extract code to compute accessor depths during simulation and in-image compilation to computeAccessorDepthsForInterpreterPrmitives.

Nuke unused zoneEnd:.

Fix formatting bug in longPrintOop:.

Simplify collectCogMethodConstituent: a little.

Comment Spur ensureBehaviorHash: & hashBitsOf: regarding http://lists.squeakfoundation.org/pipermail/squeak-dev/2021-December/217840.html

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

Item was removed:
- ----- Method: CogMethodZone>>zoneEnd: (in category 'simulation only') -----
- zoneEnd: zoneEnd
- 	<doNotGenerate> 
- 	limitAddress := zoneEnd!

Item was removed:
- ----- Method: CogVMSimulator>>codeGeneratorToComputeAccessorDepth (in category 'primitive support') -----
- codeGeneratorToComputeAccessorDepth
- 	^(VMMaker new
- 		buildCodeGeneratorForInterpreter: (COGMTVM ifTrue: [CoInterpreterMT] ifFalse: [CoInterpreterPrimitives])
- 		includeAPIMethods: false
- 		initializeClasses: false)
- 			logger: self transcript;
- 			yourself!

Item was changed:
  ----- Method: CogVMSimulator>>initializePluginEntries (in category 'plugin support') -----
  initializePluginEntries
  	mappedPluginEntries := OrderedCollection new.
  	objectMemory hasSpurMemoryManagerAPI
  		ifTrue:
+ 			[pluginList := {}.
- 			[primitiveAccessorDepthTable := Array new: primitiveTable size.
- 			 pluginList := {}.
  			 self loadNewPlugin: '']
  		ifFalse:
  			[pluginList := {'' -> self }]!

Item was changed:
  ----- Method: Cogit>>collectCogMethodConstituent: (in category 'profiling primitives') -----
  collectCogMethodConstituent: cogMethod
  	"Answer a description of the mapping between machine code pointers and bytecode pointers for the Cog Method.
  	 First value is the address of the cog method.
  	 Following values are pairs of machine code pc and bytecode pc"
  	<var: #cogMethod type: #'CogMethod *'>
  	<var: #cogBlockMethod type: #'CogBlockMethod *'>
+ 	| nSlots errCode cogBlockMethod address data |
- 	| cm nSlots errCode cogBlockMethod address data |
  	(cogMethod cmType = CMMethod) 
  		ifFalse: [^self positiveMachineIntegerFor: cogMethod asUnsignedInteger ].
  	cogBlockMethod := self cCoerceSimple: cogMethod to: #'CogBlockMethod *'.
  	cogBlockMethod stackCheckOffset = 0 "isFrameless ?"
  		ifTrue: [^self positiveMachineIntegerFor: cogMethod asUnsignedInteger].
+ 	nSlots := ((objectMemory byteSizeOf: cogMethod methodObject) - (coInterpreter startPCOfMethodHeader: cogMethod methodHeader)) * 2 + objectMemory minSlotsForShortening + 1."+1 for first address"
- 	cm := cogMethod methodObject.
- 	nSlots := ((objectMemory byteSizeOf: cm) - (coInterpreter startPCOfMethodHeader: cm methodHeader)) * 2 + objectMemory minSlotsForShortening + 1."+1 for first address"
  	data := objectMemory instantiateClass: (objectMemory splObj: ClassArray) indexableSize: nSlots.
  	data ifNil: [^nil].
  	coInterpreter pushRemappableOop: data.
  	"The iteration assumes the object is the top remappable oop"
  	address := (self positiveMachineIntegerFor: cogMethod asUnsignedInteger).
  	address ifNil: [coInterpreter popRemappableOop. ^nil].
  	coInterpreter
  		storePointerUnchecked: 0
  		ofObject: coInterpreter topRemappableOop
  		withValue: address.
  	cogConstituentIndex := 1.
  	errCode := self
  		mapFor: cogBlockMethod
  		bcpc: (coInterpreter startPCOfMethod: cogMethod methodObject)
  		performUntil: #collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method:
  		arg: cogMethod asVoidPointer.
  	errCode ~= 0 ifTrue: [coInterpreter popRemappableOop. ^nil].
  	cogConstituentIndex < nSlots ifTrue:
  		[objectMemory shorten: coInterpreter topRemappableOop toIndexableSize: cogConstituentIndex].
  	^coInterpreter popRemappableOop.!

Item was changed:
  ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation>>accessorDepthForPrimitiveMethod: (in category 'accessing') -----
  accessorDepthForPrimitiveMethod: methodOop
  	
  	| primIndex |
  	primIndex := self primitiveIndexOf: methodOop.
  	^primIndex = PrimNumberExternalCall
  		ifTrue: [self accessorDepthForExternalPrimitiveMethod: methodOop]
  		ifFalse:
+ 			[coInterpreter computeAccessorDepthsForInterpreterPrmitives.
- 			[coInterpreter initializePluginEntries.
  			 coInterpreter accessorDepthForPrimitiveIndex: primIndex]!

Item was changed:
  ----- Method: SpurMemoryManager>>ensureBehaviorHash: (in category 'class table') -----
  ensureBehaviorHash: aBehavior
  	| hash err |
  	<inline: true>
  	self assert: (coInterpreter addressCouldBeClassObj: aBehavior).
+ 	 "eem 12/28/2021 the above asserft is too weak (and only an assert)"
+ 	 self flag: #todo. "See http://lists.squeakfoundation.org/pipermail/squeak-dev/2021-December/217840.html.
+ 					 A solution would be to replace compactClassesArray with #identityHash in the specialObjectsArray
+ 					 and then lookup identityHash in the receiver and use the appropriate hash generator depending
+ 					 on the primitive number of the located method. The lookup could be guarded by objCouldBeClassObj:"
  	^(hash := self rawHashBitsOf: aBehavior) ~= 0
  		ifTrue:
  			[hash]
  		ifFalse:
  			[(coInterpreter objCouldBeClassObj: aBehavior)
  				ifFalse: [PrimErrBadReceiver negated]
  				ifTrue:
  					[(err := self enterIntoClassTable: aBehavior) ~= 0
  						ifTrue: [err negated]
  						ifFalse: [self rawHashBitsOf: aBehavior]]]!

Item was changed:
  ----- Method: SpurMemoryManager>>hashBitsOf: (in category 'header access') -----
  hashBitsOf: objOop
  	| hash |
  	hash := self rawHashBitsOf: objOop.
  	hash = 0 ifTrue:
+ 		["cb 1/19/2017 18:34:
+ 		   would like to assert
- 		["would like to assert
  			self assert: (coInterpreter addressCouldBeClassObj: objOop) not
  		  but instance-specific behaviors that are instances of themselves may
  		  fail this test."
+ 		 "eem 12/28/2021 11:52 I'm not sure this is the issue. The issue is only validating objOop as a behavior."
+ 		 self flag: #todo. "See http://lists.squeakfoundation.org/pipermail/squeak-dev/2021-December/217840.html.
+ 					 A solution would be to replace compactClassesArray with #identityHash in the specialObjectsArray
+ 					 and then lookup identityHash in the receiver and use the appropriate hash generator depending
+ 					 on the primitive number of the located method. The lookup could be guarded by objCouldBeClassObj:"
  		 hash := self newHashBitsOf: objOop].
  	^hash!

Item was added:
+ ----- Method: StackInterpreter>>computeAccessorDepthsForInterpreterPrmitives (in category 'primitive support') -----
+ computeAccessorDepthsForInterpreterPrmitives
+ 	<doNotGenerate>
+ 	| cg |
+ 	cg := self codeGeneratorToComputeAccessorDepth.
+ 	primitiveAccessorDepthTable ifNil:
+ 		[primitiveAccessorDepthTable := Array new: primitiveTable size].		
+ 	primitiveTable withIndexDo:
+ 		[:prim :index| | depth |
+ 		 prim isSymbol ifTrue:
+ 			[depth := cg accessorDepthForSelector: prim.
+ 			 self assert: depth isInteger.
+ 			 primitiveAccessorDepthTable at: index - 1 put: depth]].
+ 	^cg!

Item was changed:
  ----- Method: StackInterpreter>>frameOfMarriedContext: (in category 'frame access') -----
  frameOfMarriedContext: aContext 
+ 	<returnTypeC: #'char *'>
  	| senderOop |
  	<inline: true>
- 	<returnTypeC: 'char *'>
  	senderOop := objectMemory fetchPointer: SenderIndex ofObject: aContext.
  	^self withoutSmallIntegerTags: senderOop!

Item was changed:
  ----- Method: StackInterpreter>>longPrintOop: (in category 'debug printing') -----
  longPrintOop: oop
  	<export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  	| fmt lastIndex startIP column cls |
  
  	(objectMemory isImmediate: oop) ifTrue:
  		[^objectMemory printImmediateObject: oop on: transcript].
  	(objectMemory addressCouldBeObj: oop) ifFalse:
  		[^objectMemory printCantBeObject: oop on: transcript].
  	(objectMemory isFreeObject: oop) ifTrue:
  		[^objectMemory printFreeObject: oop on: transcript].
  	 (objectMemory isForwarded: oop) ifTrue:
  		[^objectMemory printForwarder: oop on: transcript].
  	
  	(cls := objectMemory fetchClassOfNonImm: oop)
  		ifNil: ['%P has a nil class!!!!\n' f: transcript printf: oop asVoidPointer]
  		ifNotNil:
  			[| className length |
  			className := self nameOfClass: cls lengthInto: (self addressOf: length put: [:v| length := v]).
  			'%P: a(n) %.*s' f: transcript printf: {oop asVoidPointer. length. className }.
  			objectMemory hasSpurMemoryManagerAPI ifTrue:
  				['(%lx=>%P)' f: transcript printf: { objectMemory compactClassIndexOf: oop. cls asVoidPointer }]].
  	fmt := objectMemory formatOf: oop.
  	' format %lx' f: transcript printf: fmt.
  	fmt > objectMemory lastPointerFormat
  		ifTrue: [' nbytes %ld' f: transcript printf:  (objectMemory numBytesOf: oop)]
  		ifFalse: [(objectMemory isIndexableFormat: fmt) ifTrue:
  					[| len |
  					len := objectMemory lengthOf: oop.
  					' size %ld' f: transcript printf: len - (objectMemory fixedFieldsOf: oop format: fmt length: len)]].
  	objectMemory printHeaderTypeOf: oop on: transcript.
  	self print: ' hash '; printHex: (objectMemory rawHashBitsOf: oop).
  	self cr.
  	(fmt between: objectMemory firstLongFormat and: objectMemory firstCompiledMethodFormat - 1) ifTrue:
  		["This will answer false if splObj: ClassAlien is nilObject"
  		 (self is: oop KindOfClass: (objectMemory splObj: ClassAlien)) ifTrue:
  			[^' datasize %ld %s @ %p\n' f: transcript printf:
  				{objectMemory sizeFieldOfAlien: oop.
  				  (self isIndirectAlien: oop)
  							ifTrue: ['indirect']
  							ifFalse:
  								[(self isPointerAlien: oop)
  									ifTrue: ['pointer']
  									ifFalse: ['direct']].
  				 self startOfAlienData: oop }].
  		(self is: oop KindOfClass: (self superclassOf: (objectMemory splObj: ClassString))) ifTrue:
  			[^objectMemory printStringDataOf: oop on: transcript].
  		 ^objectMemory printNonPointerDataOf: oop on: transcript].
  	startIP := fmt >= objectMemory firstCompiledMethodFormat
  				ifTrue: [(self startPCOfMethod: oop) / objectMemory wordSize]
  				ifFalse: [objectMemory numSlotsOf: oop].
  	lastIndex := 256 min: startIP.
  	lastIndex > 0 ifTrue:
  		[1 to: lastIndex do:
  			[:i| | fieldOop |
  			fieldOop := objectMemory fetchPointer: i - 1 ofObject: oop.
  			self space; printNum: i - 1; space; printHex: fieldOop; space.
  			(i = 1 and: [objectMemory isCompiledMethod: oop])
  				ifTrue: [self printMethodHeaderOop: fieldOop]
  				ifFalse: [self printOopShortInner: fieldOop].
  			self cr]].
  	(objectMemory isCompiledMethod: oop)
  		ifFalse:
  			[startIP > lastIndex ifTrue: [self print: '...'; cr]]
  		ifTrue:
  			[startIP := (self startPCOfMethod: oop) + 1.
  			 lastIndex := objectMemory lengthOf: oop.
  			 lastIndex - startIP > 256 ifTrue:
  				[lastIndex := startIP + 256].
  			 column := 1.
  			 startIP to: lastIndex do:
  				[:index| | byte |
  				column = 1 ifTrue:
+ 					['%11P ' f: transcript printf: (oop+BaseHeaderSize+index-1) asVoidPointer].
- 					['%11P' f: transcript printf: (oop+BaseHeaderSize+index-1) asVoidPointer].
  				byte := objectMemory fetchByte: index - 1 ofObject: oop.
  				'%02x/%-3d%c'
  					f: transcript
  					printf: { byte. byte. column = 8 ifTrue: [Character cr] ifFalse: [Character space] }.
  				(column := column + 1) > 8 ifTrue: [column := 1]].
  			(objectMemory lengthOf: oop) > lastIndex ifTrue:
  				[self print: '...'].
  			(column between: 2 and: 7) ifTrue:
  				[self cr]]!

Item was changed:
  ----- Method: StackInterpreter>>startPCOfMethodHeader: (in category 'compiled methods') -----
  startPCOfMethodHeader: methodHeader
- 	<api>
  	"Answer the zero-relative index to the initial byte for a method.
  	 Zero-relative version of CompiledMethod>>startpc."
  	^(objectMemory literalCountOfMethodHeader: methodHeader) + LiteralStart * objectMemory bytesPerOop!

Item was changed:
  ----- Method: StackInterpreter>>tryLoadNewPlugin:pluginEntries: (in category 'primitive support') -----
  tryLoadNewPlugin: pluginString pluginEntries: pluginEntries
  	"Load the plugin and if on Spur, populate pluginEntries with the prmitives in the plugin."
  	<doNotGenerate>
  	| plugin realPluginClass plugins |
  	self transcript cr; show: 'Looking for module ', pluginString.
  	pluginString isEmpty
  		ifTrue:
  			[plugin := self]
  		ifFalse:
  			[plugins := InterpreterPlugin allSubclasses select:
  							[:psc|
  							 psc moduleName asString = pluginString asString
  							 and: [psc shouldBeTranslated]].
  			 plugins isEmpty ifTrue: [self transcript show: ' ... not found'. ^nil].
  			 plugins size > 1 ifTrue: [^self error: 'This won''t work...'].
  			 "plugins size > 1 ifTrue:
  				[self transcript show: '...multiple plugin classes; choosing ', plugins last name]."
  			 realPluginClass := plugins anyOne. "hopefully lowest in the hierarchy..."
  			 plugin := realPluginClass simulatorForInterpreterInterface: objectMemory.
  			 plugin ifNil: [self transcript show: ' ... no simulator class; cannot simulate'. ^nil].
  			 (plugin respondsTo: #initialiseModule) ifTrue:
  				[plugin initialiseModule ifFalse:
  					[self transcript show: ' ... initialiser failed'. ^nil]]]. "module initialiser failed"
  	self transcript show: ' ... loaded'.
  	objectMemory hasSpurMemoryManagerAPI ifTrue:
  		[| realPlugin cg |
  		 self transcript show: '...computing accessor depths'.
  		 plugin class isPluginClass
  			ifTrue:
  				[realPlugin := (plugin isSmartSyntaxPluginSimulator
  									ifTrue: [realPluginClass]
  									ifFalse: [plugin class])
  								 withAllSuperclasses detect: [:class| class shouldBeTranslated].
  				 cg := realPlugin buildCodeGenerator]
  			ifFalse:
+ 				[cg := self computeAccessorDepthsForInterpreterPrmitives].
- 				[cg := self codeGeneratorToComputeAccessorDepth.
- 				 primitiveTable withIndexDo:
- 					[:prim :index| | depth |
- 					 prim isSymbol ifTrue:
- 						[depth := cg accessorDepthForSelector: prim.
- 						 self assert: (depth isInteger or: [depth isNil and: [(plugin class whichClassIncludesSelector: prim) isNil]]).
- 						 primitiveAccessorDepthTable at: index - 1 put: depth]]].
  		 cg exportedPrimitiveNames do:
  			[:primName| | fnSymbol |
  			 fnSymbol := primName asSymbol.
  			 pluginEntries addLast: {plugin.
  									fnSymbol.
  									[plugin perform: fnSymbol. self].
  									self metadataFlagsFor: fnSymbol using: cg}].
  		 self transcript show: '...done'].
  	^pluginString asString -> plugin!

Item was changed:
  ----- Method: TAssignmentNode>>emitLiteralArrayDeclarationOn:level:generator: (in category 'C code generation') -----
  emitLiteralArrayDeclarationOn: aStream level: level generator: aCCodeGen
  	| type literalName |
  	type := expression args last value.
  	self assert: type last = $*.
  	literalName := variable name, 'Initializer'.
  	aStream
  		crtab: level;
  		nextPutAll: '{ static ';
  		nextPutAll: (aCCodeGen
  						arrayInitializerCalled: literalName
  						for: expression args first value
  						sizeString: nil
  						type: type allButLast) withBlanksTrimmed;
  		nextPut: $;;
  		crtab: level + 1;
  		nextPutAll: variable name;
  		nextPutAll: ' = ';
  		nextPutAll: literalName;
  		nextPut: $; ;
  		crtab: level;
  		nextPut: $};
+ 		cr
+ 
+ 	"self systemNavigation browseAllSelect:
+ 		[:m|
+ 		(m sendsSelector: #cCoerce:to:)
+ 		and: [| flag |
+ 			flag := false.
+ 			m methodNode nodesDo:
+ 				[:n|
+ 				(n isMessageNode
+ 				and: [n selector key = #cCoerce:to:
+ 				and: [n arguments first isLiteralNode
+ 				and: [n arguments first key isCollection]]]) ifTrue:
+ 					[flag := true]].
+ 			flag]]"!
- 		cr!

Item was changed:
  ----- Method: TSendNode>>isLiteralArrayDeclaration (in category 'testing') -----
  isLiteralArrayDeclaration
  	^selector == #cCoerce:to:
  	  and: [arguments first isConstant
  	  and: [arguments first value isLiteral
+ 	  and: [arguments first value isCollection]]]
+ 
+ 	"self systemNavigation browseAllSelect:
+ 		[:m|
+ 		(m sendsSelector: #cCoerce:to:)
+ 		and: [| flag |
+ 			flag := false.
+ 			m methodNode nodesDo:
+ 				[:n|
+ 				(n isMessageNode
+ 				and: [n selector key = #cCoerce:to:
+ 				and: [n arguments first isLiteralNode
+ 				and: [n arguments first key isCollection]]]) ifTrue:
+ 					[flag := true]].
+ 			flag]]"!
- 	  and: [arguments first value isCollection]]]!



More information about the Vm-dev mailing list