[Vm-dev] VM Maker: VMMaker-dtl.344.mcz

commits at source.squeak.org commits at source.squeak.org
Wed Mar 12 17:09:56 UTC 2014


David T. Lewis uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker-dtl.344.mcz

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

Name: VMMaker-dtl.344
Author: dtl
Time: 12 March 2014, 12:57:02.35 pm
UUID: d27f9db0-776a-4a76-aa71-2fc4aaa4885a
Ancestors: VMMaker-dtl.343

VMMaker 4.13.4

Fix slang inlining regression introduced in VMMaker-dtl.339 caused by TMethod>>tryToInlineMethodsIn: that excluded nodes with selector #cCode:inSmalltalk: which must remain inlineable to support various methods for 32/64 bit image format from common code base, as well as for low level MemoryAccess in slang that must be fully inlined for performance.

Change FloatArrayPlugin>>primitiveDivFloatArray and BitBltSimulation>>primitiveDisplayString to send intAtPointer and byteAtPointer to self rather than to interpreterProxy, because they are not defined in the interpreter proxy and cause compilation errors when slang inlining is turned off. These should be added to the interpreter proxy (or arguably to a hypothetical objects memory proxy) but send to self is a lesser evil for now. 

These changes restore a very small performance gain for the standard VM due to the inlining fix, and also restore inlining of low level MemoryAccess methods when added to the VM build. Inlined MemoryAccess methods are essentially equivalent to the C macros in sqMemoryAccess.h but can be run in simulation, and play nicely with C debuggers and profilers.

=============== Diff against VMMaker-dtl.343 ===============

Item was changed:
  ----- Method: BitBltSimulation>>primitiveDisplayString (in category 'primitives') -----
  primitiveDisplayString
  
  	| kernDelta xTable glyphMap stopIndex startIndex sourceString bbObj maxGlyph ascii glyphIndex sourcePtr left quickBlt |
  	<export: true>
  	<var: #sourcePtr type: 'char *'>
  	interpreterProxy methodArgumentCount = 6 
  		ifFalse:[^interpreterProxy primitiveFail].
  	kernDelta := interpreterProxy stackIntegerValue: 0.
  	xTable := interpreterProxy stackObjectValue: 1.
  	glyphMap := interpreterProxy stackObjectValue: 2.
  	((interpreterProxy fetchClassOf: xTable) = interpreterProxy classArray and:[
  		(interpreterProxy fetchClassOf: glyphMap) = interpreterProxy classArray])
  			ifFalse:[^interpreterProxy primitiveFail].
  	(interpreterProxy slotSizeOf: glyphMap) = 256 ifFalse:[^interpreterProxy primitiveFail].
  	interpreterProxy failed ifTrue:[^nil].
  	maxGlyph := (interpreterProxy slotSizeOf: xTable) - 2.
  
  	stopIndex := interpreterProxy stackIntegerValue: 3.
  	startIndex := interpreterProxy stackIntegerValue: 4.
  	sourceString := interpreterProxy stackObjectValue: 5.
  	(interpreterProxy isBytes: sourceString) ifFalse:[^interpreterProxy primitiveFail].
  	(startIndex > 0 and:[stopIndex > 0 and:[
  		stopIndex <= (interpreterProxy byteSizeOf: sourceString)]])
  			ifFalse:[^interpreterProxy primitiveFail].
  
  	bbObj := interpreterProxy stackObjectValue: 6.
  	(self loadBitBltFrom: bbObj) ifFalse:[^interpreterProxy primitiveFail].
  	(combinationRule = 30 or:[combinationRule = 31]) "needs extra source alpha"
  		ifTrue:[^interpreterProxy primitiveFail].
  	"See if we can go directly into copyLoopPixMap (usually we can)"
  	quickBlt := destBits ~= 0 "no OS surfaces please"
  				and:[sourceBits ~= 0 "and again"
  				and:[noSource = false "needs a source"
  				and:[sourceForm ~= destForm "no blits onto self"
  				and:[(cmFlags ~= 0 
  						or:[sourceMSB ~= destMSB 
  						or:[sourceDepth ~= destDepth]]) "no point using slower version"
  				]]]].
  	left := destX.
  	sourcePtr := interpreterProxy firstIndexableField: sourceString.
  	startIndex to: stopIndex do:[:charIndex|
+ 		ascii := self byteAtPointer: sourcePtr + charIndex - 1.
- 		ascii := interpreterProxy byteAtPointer: sourcePtr + charIndex - 1.
  		glyphIndex := interpreterProxy fetchInteger: ascii ofObject: glyphMap.
  		(glyphIndex < 0 or:[glyphIndex > maxGlyph]) 
  			ifTrue:[^interpreterProxy primitiveFail].
  		sourceX := interpreterProxy fetchInteger: glyphIndex ofObject: xTable.
  		width := (interpreterProxy fetchInteger: glyphIndex+1 ofObject: xTable) - sourceX.
  		interpreterProxy failed ifTrue:[^nil].
  		self clipRange.	"Must clip here"
  		(bbW > 0 and:[bbH > 0]) ifTrue: [
  			quickBlt ifTrue:[
  				self destMaskAndPointerInit.
  				self copyLoopPixMap.
  				"both, hDir and vDir are known to be > 0"
  				affectedL := dx.
  				affectedR := dx + bbW.
  				affectedT := dy.
  				affectedB := dy + bbH.
  			] ifFalse:[self copyBits]].
  		interpreterProxy failed ifTrue:[^nil].
  		destX := destX + width + kernDelta.
  	 ].
  	affectedL := left.
  	self showDisplayBits.
  	"store destX back"	
  	interpreterProxy storeInteger: BBDestXIndex ofObject: bbObj withValue: destX.
  	interpreterProxy pop: 6. "pop args, return rcvr"!

Item was changed:
  ----- Method: FloatArrayPlugin>>primitiveDivFloatArray (in category 'arithmetic primitives') -----
  primitiveDivFloatArray
  	"Primitive. Add the receiver and the argument, both FloatArrays and store the result into the receiver."
  	| rcvr arg rcvrPtr argPtr length |
  	<export: true>
  	<var: #rcvrPtr type:'float *'>
  	<var: #argPtr type:'float *'>
  	arg := interpreterProxy stackObjectValue: 0.
  	rcvr := interpreterProxy stackObjectValue: 1.
  	interpreterProxy failed ifTrue:[^nil].
  	interpreterProxy success: (interpreterProxy isWords: arg).
  	interpreterProxy success: (interpreterProxy isWords: rcvr).
  	interpreterProxy failed ifTrue:[^nil].
  	length := interpreterProxy stSizeOf: arg.
  	interpreterProxy success: (length = (interpreterProxy stSizeOf: rcvr)).
  	interpreterProxy failed ifTrue:[^nil].
  	rcvrPtr := self cCoerce: (interpreterProxy firstIndexableField: rcvr) to: 'float *'.
  	argPtr := self cCoerce: (interpreterProxy firstIndexableField: arg) to: 'float *'.
  	"Check if any of the argument's values is zero"
  	0 to: length-1 do:[:i|
+ 		( self intAtPointer:(self cCoerce: (argPtr + i) to: 'char*')) = 0 ifTrue:[^interpreterProxy primitiveFail]].
- 		( interpreterProxy intAtPointer:(self cCoerce: (argPtr + i) to: 'char*')) = 0 ifTrue:[^interpreterProxy primitiveFail]].
  	0 to: length-1 do:[:i|
  		rcvrPtr at: i put: (self cCoerce: (rcvrPtr at: i) to: 'double') / (self cCoerce: (argPtr at: i) to: 'double').
  	].
  	interpreterProxy pop: 1. "Leave rcvr on stack"!

Item was changed:
+ ----- Method: TMethod>>copy (in category 'copying') -----
- ----- Method: TMethod>>copy (in category 'utilities') -----
  copy
  	"Make a deep copy of this TMethod."
  
  	^ (self class basicNew)
  		setSelector: selector
  		returnType: returnType
  		args: args copy
  		locals: locals copy
  		declarations: declarations copy
  		primitive: primitive
  		parseTree: parseTree copyTree
  		labels: labels copy
  		complete: complete;
  		sharedLabel: sharedLabel;
  		sharedCase: sharedCase;
  		yourself
  !

Item was changed:
  ----- Method: TMethod>>tryToInlineMethodsIn: (in category 'inlining') -----
  tryToInlineMethodsIn: aCodeGen
  	"Expand any (complete) inline methods called by this method. Set the complete bit when all inlining has been done. Return true if something was inlined."
  
  	| stmtLists didSomething newStatements sendsToInline |
  	self definedAsMacro ifTrue:
  		[complete := true.
  		 ^false].
  	didSomething := false.
  	sendsToInline := Dictionary new: 100.
  	parseTree
  		nodesDo:
  			[:node|
  			(self inlineableFunctionCall: node in: aCodeGen) ifTrue:
  				[sendsToInline at: node put: (self inlineFunctionCall: node in: aCodeGen)]]
  		unless: "Don't inline the arguments to asserts to keep the asserts readable"
  			[:node|
+ 				node isSend
+ 					and: [aCodeGen isAssertSelector: node selector]].
- 			node isSend
- 			and: [node selector == #cCode:inSmalltalk:
- 				or: [aCodeGen isAssertSelector: node selector]]].
  
  	sendsToInline isEmpty ifFalse:
  		[didSomething := true.
  		self removeUnreferencedDeclarations.
  		parseTree := parseTree replaceNodesIn: sendsToInline].
  
  	didSomething ifTrue:
  		[writtenToGlobalVarsCache := nil.
  		^didSomething].
  
  	stmtLists := self statementsListsForInliningIn: aCodeGen.
  	stmtLists do:
  		[:stmtList|
  		newStatements := OrderedCollection new: 100.
  		stmtList statements do:
  			[:stmt|
  			(self inlineCodeOrNilForStatement: stmt in: aCodeGen)
  				ifNil: [newStatements addLast: stmt]
  				ifNotNil: [:inlinedStmts|
  					didSomething := true.
  					newStatements addAllLast: inlinedStmts]].
  		stmtList setStatements: newStatements asArray].
  
  	didSomething ifTrue:
  		[writtenToGlobalVarsCache := nil.
  		^didSomething].
  
  	complete ifFalse:
  		[self checkForCompleteness: stmtLists in: aCodeGen.
  		 complete ifTrue: [ didSomething := true ]].  "marking a method complete is progress"
  	^didSomething!

Item was changed:
  ----- Method: VMMaker class>>versionString (in category 'version testing') -----
  versionString
  
  	"VMMaker versionString"
  
+ 	^'4.13.4'!
- 	^'4.13.3'!



More information about the Vm-dev mailing list