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

commits at source.squeak.org commits at source.squeak.org
Thu Jul 26 00:45:55 UTC 2018

Eliot Miranda uploaded a new version of VMMaker to project VM Maker:

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

Name: VMMaker.oscog-eem.2422
Author: eem
Time: 25 July 2018, 5:45:27.688681 pm
UUID: c3a5106e-a29f-41cb-9df3-119b03c01fa5
Ancestors: VMMaker.oscog-eem.2421

Revamp pc mapping tests so they can apply to methods in the simulation (used to debug the issue fixed in VMMaker.oscog-eem.2421).

Fix some bogus receivers in bcpcsDescriptorsAndStartpcsFor:bsOffset:do:.
Fix the range check in VMCompiledMethodProxy>>at:, and cache some values (so that pcPreviousTo: doesn't crawl).

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

Item was changed:
  ----- Method: Cogit>>bcpcsDescriptorsAndStartpcsFor:bsOffset:do: (in category 'tests-method map') -----
  bcpcsDescriptorsAndStartpcsFor: aMethod bsOffset: bsOffset do: quinternaryBlock
  	"Evaluate quinternaryBlock with the pc, byte, descriptor and numExtensions for
  	 all the bytecodes in aMethod.  Evaluate with byte, descriptor and numExtensions
  	 nil for the initialPC of the mehtod and any blocks within it."
  	| nExts byte descriptor endpc latestContinuation pc primIdx blockEndPCs startpcs |
  	((primIdx := coInterpreter primitiveIndexOf: aMethod) > 0
  	and: [coInterpreter isQuickPrimitiveIndex: primIdx]) ifTrue:
  	latestContinuation := pc := coInterpreter startPCOfMethod: aMethod.
  	startpcs := OrderedCollection with: pc.
+ 	blockEndPCs := OrderedCollection with: (objectMemory numBytesOf: aMethod).
- 	blockEndPCs := OrderedCollection with: (coInterpreter numBytesOf: aMethod).
  	quinternaryBlock value: pc value: nil value: nil value: 0 value: pc. "stackCheck/entry pc"
  	primIdx > 0 ifTrue:
  		[pc := pc + (self deltaToSkipPrimAndErrorStoreIn: aMethod
+ 							header: (objectMemory methodHeaderOf: aMethod))].
- 							header: (coInterpreter methodHeaderOf: aMethod))].
  	nExts := 0.
  	endpc := objectMemory numBytesOf: aMethod.
  	[pc <= endpc] whileTrue:
  		[byte := objectMemory fetchByte: pc ofObject: aMethod.
  		descriptor := self generatorAt: byte + bsOffset.
  		descriptor isExtension ifFalse:
  			[quinternaryBlock value: pc value: byte value: descriptor value: nExts value: startpcs last].
  		descriptor isReturn ifTrue:
  			[pc >= latestContinuation ifTrue:
  				[endpc := pc]].
  		(descriptor isBranch
  		 or: [descriptor isBlockCreation]) ifTrue:
  			[| targetPC |
  			 targetPC := self latestContinuationPCFor: descriptor at: pc exts: nExts in: aMethod.
  			 descriptor isBlockCreation ifTrue:
  				[quinternaryBlock value: (startpcs addLast: pc + descriptor numBytes) value: nil value: nil value: 0 value: startpcs last.
  				 blockEndPCs addLast: targetPC]. "stackCheck/entry pc"
  			 self assert: targetPC < endpc.
  			 latestContinuation := latestContinuation max: targetPC].
  		descriptor isReturn ifTrue:
  			[pc + descriptor numBytes >= blockEndPCs last ifTrue:
  				[blockEndPCs removeLast.
  				 startpcs removeLast]].
  		pc := pc + descriptor numBytes.
  		nExts := descriptor isExtension ifTrue: [nExts + 1] ifFalse: [0]]!

Item was added:
+ ----- Method: Cogit>>resolveToOopOrNil: (in category 'tests-method map') -----
+ resolveToOopOrNil: proxyOrSpecialSelector
+ 	"Answer the oop of a proxy or a special selector.  When testing pc mapping on simulation
+ 	 methods (as opposed to CurrentImageFacades) selectorForSendBefore:in: answers either
+ 	 VMObjectProxy instances (normal sends) or symbols (special selector sends)."
+ 	<doNotGenerate>
+ 	| index |
+ 	proxyOrSpecialSelector isSymbol ifFalse:
+ 		[^proxyOrSpecialSelector oop].
+ 	index := Smalltalk specialSelectors indexOf: proxyOrSpecialSelector.
+ 	^index > 0 ifTrue:
+ 		[coInterpreter specialSelector: index - 1 // 2]!

Item was changed:
  ----- Method: Cogit>>testMcToBcPcMappingForCompiledMethod:cogMethod: (in category 'tests-method map') -----
  testMcToBcPcMappingForCompiledMethod: aCompiledMethod cogMethod: cogMethod
  	| bcMethod subMethods prevMcpc |
  	"self disassembleMethod: cogMethod"
  	"coInterpreter symbolicMethod: cogMethod methodObject"
  	"coInterpreter printOop: cogMethod methodObject"
  	"self printPCMapPairsFor: cogMethod on: Transcript"
  	cogMethod stackCheckOffset = 0 ifTrue: "frameless"
  	bcMethod := coInterpreter isCurrentImageFacade
  					ifTrue: [coInterpreter objectForOop: cogMethod methodObject]
  					ifFalse: [VMCompiledMethodProxy new
  								for: cogMethod methodObject
  								coInterpreter: coInterpreter
  								objectMemory: objectMemory].
  	subMethods := self subMethodsAsRangesFor: cogMethod.
  	self mapFor: cogMethod do:
  		[:annotation :mcpc| | subMethod subCogMethod bcpc mappedpc |
  		(self isPCMappedAnnotation: annotation) ifTrue:
  			[subMethod := subMethods
  								detect: [:range| range includes: mcpc]
  								ifNone: ["a trailing call ceNonLocalReturnTrampoline's following
  										 pc is the start of a following block or the end of the map"
  										subMethods detect: [:range| range includes: mcpc - 1]].
  			mcpc > subMethod first ifTrue:
  				[bcpc := self
  							bytecodePCFor: mcpc
  							startBcpc: subMethod startpc
  							in: (subCogMethod := subMethod cogMethod).
  				self assert: bcpc ~= 0.
  				mappedpc := self mcPCFor: bcpc startBcpc: subMethod startpc in: subCogMethod.
  				subCogMethod stackCheckOffset = 0
  					ifTrue: [self assert: mappedpc > (subCogMethod address + self noCheckEntryOffset)]
  					ifFalse: [self assert: mappedpc >= (subCogMethod address + subCogMethod stackCheckOffset)].
  				"mcpc = mappedpc is obviously what we want and expect.  prevMcpc = mappedpc hacks
  				 around frame building accessors where the first bytecode is mapped twice, once for the
  				 stack check and once for the context inst var access.  The bytecode pc can only map
  				 back to a single mcpc, the first, so the second map entry will fail without this hack."
  				self assert: (mcpc = mappedpc or: [prevMcpc = mappedpc]).
  				(self isSendAnnotation: annotation) ifTrue:
  					[| mcSelector bcSelector |
  					mcSelector := self selectorForSendAt: mcpc annotation: annotation in: aCompiledMethod.
  					"sends map to the following pc.  need to find the selector for the previous pc"
  					bcSelector := self selectorForSendBefore: bcpc in: bcMethod.
+ 					self assert: (mcSelector = bcSelector
+ 								or: [mcSelector = (self resolveToOopOrNil: bcSelector)])]].
- 					self assert: mcSelector = bcSelector]].
  			 prevMcpc := mcpc].
  		 false "keep scanning"]!

Item was changed:
  ----- Method: Cogit>>testPCMappingForCompiledMethod:cogMethod: (in category 'tests-method map') -----
  testPCMappingForCompiledMethod: aCompiledMethod cogMethod: cm
  	methodObj := methodHeader := nil.
+ 	cm isInteger ifTrue: "If testing in a simulation..."
+ 		[^self testPCMappingForCompiledMethod: aCompiledMethod cogMethod: (self cogMethodSurrogateAt: cm)].
  		testMcToBcPcMappingForCompiledMethod: aCompiledMethod cogMethod: cm;
  		testBcToMcPcMappingForCogMethod: cm!

Item was changed:
  VMObjectProxy subclass: #VMCompiledMethodProxy
+ 	instanceVariableNames: 'size numLiterals'
- 	instanceVariableNames: ''
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'VMMaker-Support'!
  !VMCompiledMethodProxy commentStamp: 'eem 8/6/2014 14:48' prior: 0!
  A VMCompiledMethodProxy is a wrapper for the oop of a CompiledMethod object in the simulator VM's heap that provides accessd to the oop as if it were a CompiledMethod object.!

Item was changed:
  ----- Method: VMCompiledMethodProxy>>at: (in category 'accessing') -----
  at: index
+ 	^(index between: self numLiterals + 1 * objectMemory wordSize + 1 and: self size)
- 	^(index between: 1 and: (objectMemory numBytesOf: oop))
  		ifTrue: [objectMemory fetchByte: index - 1 ofObject: oop]
  		ifFalse: [self errorSubscriptBounds: index]!

Item was changed:
  ----- Method: VMCompiledMethodProxy>>numLiterals (in category 'accessing') -----
  	"Answer the number of literals used by the receiver."
+ 	^numLiterals ifNil: [numLiterals := objectMemory literalCountOf: oop]!
- 	^objectMemory literalCountOf: oop!

Item was added:
+ ----- Method: VMCompiledMethodProxy>>pcPreviousTo: (in category 'scanning') -----
+ pcPreviousTo: thePC
+ 	"Answer the pc of the bytecode before the bytecode at thePC."
+ 	| pc prevPc byte encoderClass |
+ 	thePC > self endPC ifTrue: [^self endPC].
+ 	pc := self initialPC.
+ 	encoderClass := self encoderClass.
+ 	[pc < thePC] whileTrue:
+ 		[byte := self at: (prevPc := pc).
+ 		 [pc := pc + (encoderClass bytecodeSize: byte).
+ 		  encoderClass isExtension: byte] whileTrue:
+ 			[byte := self at: pc]].
+ 	^prevPc!

Item was changed:
  ----- Method: VMCompiledMethodProxy>>size (in category 'accessing') -----
+ 	^size ifNil: [size := objectMemory numBytesOf: oop]!
- 	^objectMemory numBytesOf: oop!

More information about the Vm-dev mailing list