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

commits at source.squeak.org commits at source.squeak.org
Thu Dec 3 23:23:46 UTC 2015


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

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

Name: VMMaker.oscog-eem.1545
Author: eem
Time: 3 December 2015, 3:22:11.903 pm
UUID: 4d01d362-c534-495a-979b-c549f7b5541a
Ancestors: VMMaker.oscog-eem.1544, VMMaker.oscog-tpr.1544

Fix setting of expected stack alignment; fp & sp alignments must be mod stack alignment.  This fixes stack alignment checking on x64 when PostBuildStackDelta is incuded.

Fix genPrimitiveClosureValue for 64-bits (use genJumpImmediate: to exclude non-cogged methods).

Add AndRR for x64 and enable multiplication.

Sim: include rump C stack in whereIs: ranges.

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

Item was changed:
  ----- Method: CoInterpreter>>whereIs: (in category 'debug printing') -----
  whereIs: anOop
  	<var: 'somewhere' type: #'char *'>
  	(cogit whereIsMaybeCodeThing: anOop) ifNotNil: [:somewhere| ^somewhere].
+ 	(self isOnRumpCStack: anOop) ifTrue: [^'is on rump C stack'].
  	^super whereIs: anOop!

Item was added:
+ ----- Method: CogX64Compiler>>concretizeAndRR (in category 'generate machine code') -----
+ concretizeAndRR
+ 	"Will get inlined into concretizeAt: switch."
+ 	<inline: true>
+ 	| regLHS regRHS |
+ 	regLHS := self concreteRegister: (operands at: 0).
+ 	regRHS := self concreteRegister: (operands at: 1).
+ 	machineCode
+ 		at: 0 put: (self rexR: regRHS x: 0 b: regLHS);
+ 		at: 1 put: 16r23;
+ 		at: 2 put: (self mod: ModReg RM: regLHS RO: regRHS).
+ 	^machineCodeSize := 2!

Item was changed:
  ----- Method: CogX64CompilerTests>>testMul (in category 'tests') -----
  testMul
  	"CogX64CompilerTests new setUp testMul"
  	| map compiler memory |
  	map := Dictionary new.
  	compiler := self gen: nil.
  	memory := ByteArray new: 1024.
  	self concreteCompilerClass dataRegistersWithAccessorsExcept: #(rbp rsp) do:
  		[:sreg :srget :srset|
  		self concreteCompilerClass dataRegistersWithAccessorsExcept: { #rbp. #rsp. srget } do:
  			[:dreg :drget :drset| | instructions |
  			self resetGen.
  			compiler genMulR: sreg R: dreg.
  			instructions := self generateInstructions.
  			memory atAllPut: 0; replaceFrom: 1 to: instructions size with: instructions startingAt: 1.
  			#(-768 -456 -123 123 456 789)
  				with: #(987 654 321 -321 -654 -987)
  				do: [:a :b|
  					"self processor
  						disassembleFrom: 0 to: instructions size in: memory on: Transcript;
  						printIntegerRegistersOn: Transcript."
  					map
+ 						at: #rax put: (self processor rax: 16rA5A5A5A5);
+ 						at: #rbx put: (self processor rbx: 16rB5B5B5B5);
+ 						at: #rcx put: (self processor rcx: 16rC5C5C5C5);
+ 						at: #rdx put: (self processor rdx: 16rD5D5D5D5);
+ 						at: #rsi put: (self processor rsi: 16r51515151);
+ 						at: #rdi put: (self processor rdi: 16rD1D1D1D1);
- 						at: #eax put: (self processor eax: 16rA5A5A5A5);
- 						at: #ebx put: (self processor ebx: 16rB5B5B5B5);
- 						at: #ecx put: (self processor ecx: 16rC5C5C5C5);
- 						at: #edx put: (self processor edx: 16rD5D5D5D5);
- 						at: #esi put: (self processor esi: 16r51515151);
- 						at: #edi put: (self processor edi: 16rD1D1D1D1);
  								at: srget put: (self processor perform: srset with: (self processor convertIntegerToInternal: b));
  								at: drget put: (self processor perform: drset with: (self processor convertIntegerToInternal: a)).
+ 					self processor rsp: memory size; rip: 0.
- 					self processor esp: memory size; eip: 0.
  					self shouldnt:
  						[[self processor pc < instructions size] whileTrue:
  							[self processor singleStepIn: memory]]
  						raise: Error.
  					map at: drget put: (self processor convertIntegerToInternal: (a * b)).
  					map keysAndValuesDo:
  						[:accessor :value|
  						self assert: value = (self processor perform: accessor)]]]]!

Item was changed:
  ----- Method: Cogit>>setStackAlignment:expectedSPOffset:expectedFPOffset: (in category 'initialization') -----
  setStackAlignment: stackAlignment expectedSPOffset: spOffset expectedFPOffset: fpOffset
+ 	"Spcific platform ABIs mandate specific stack frame alignments.  We capture
+ 	 these constraints in the variables here and test they are adhered to via
+ 	 assertCStackWellAligned whenever transitioning to code that will run in C."
- 	"the processor wants certain stack alignment settings"
  	self assert: stackAlignment isPowerOfTwo.
+ 	expectedSPAlignment := spOffset \\ stackAlignment.
+ 	expectedFPAlignment := fpOffset \\ stackAlignment.
- 	expectedSPAlignment := spOffset. 
- 	expectedFPAlignment := fpOffset. 
  	cStackAlignment := stackAlignment
  !

Item was changed:
  ----- Method: InterpreterPlugin class>>allCodeOlderThan: (in category 'translation') -----
  allCodeOlderThan: modificationTime
+ 	^((self pluginClassesUpToRoot) allSatisfy:
- 	^((self pluginClassesUpTo: self) allSatisfy:
  			[:aPluginClass| aPluginClass timeStamp < modificationTime])
  	  and: [self translatedPrimitives allSatisfy:
  			[:pair| | c m stamp |
  			c := Smalltalk classNamed: pair first.
  			m := c compiledMethodAt: pair last ifAbsent: [c class >> pair last].
  			stamp := (m timeStamp subStrings: {Character space}) last: 2.
  			stamp := TimeStamp date: (Date fromString: stamp first) time: (Time fromString: stamp last).
  			stamp asSeconds < modificationTime]]!

Item was added:
+ ----- Method: InterpreterPlugin class>>buildCodeGenerator (in category 'translation') -----
+ buildCodeGenerator
+ 	"Build a CCodeGenerator for the plugin"
+ 	| cg pluginClasses |
+ 	cg := self codeGeneratorClass new initialize.
+ 	cg pluginClass: self.
+ 	(pluginClasses := self pluginClassesUpToRoot) do:
+ 		[:aClass| cg addClass: aClass].
+ 	(cg structClassesForTranslationClasses: pluginClasses) do:
+ 		[:structClasss| cg addStructClass: structClasss].
+ 	cg addMethodsForTranslatedPrimitives: self translatedPrimitives.
+ 	^cg!

Item was changed:
  ----- Method: InterpreterPlugin class>>buildCodeGeneratorUpTo: (in category 'translation') -----
  buildCodeGeneratorUpTo: aPluginClass
+ 	"Build a CCodeGenerator for the plugin - Deprecated and here only in case old plugin code tries to use it"
+ 	self deprecated.
+ 	^self buildCodeGenerator!
- 	"Build a CCodeGenerator for the plugin"
- 	| cg pluginClasses |
- 	cg := self codeGeneratorClass new initialize.
- 	cg pluginClass: self.
- 	(pluginClasses := self pluginClassesUpTo: aPluginClass) do:
- 		[:aClass| cg addClass: aClass].
- 	(cg structClassesForTranslationClasses: pluginClasses) do:
- 		[:structClasss| cg addStructClass: structClasss].
- 	cg addMethodsForTranslatedPrimitives: self translatedPrimitives.
- 	^cg!

Item was added:
+ ----- Method: InterpreterPlugin class>>moduleFileName (in category 'translation') -----
+ moduleFileName
+ 	"Answer the receiver's module name that is used for the plugin's C code."
+ 
+ 	^ self moduleName, self moduleExtension!

Item was removed:
- ----- Method: InterpreterPlugin class>>pluginClassesUpTo: (in category 'translation') -----
- pluginClassesUpTo: aPluginClass
- 	"Answer the classes to include for translation of aPluginClass, superclasses first, aPluginClass last."
- 	| theClass classes |
- 
- 	classes := OrderedCollection new.
- 	theClass := self.
- 	[theClass == Object
- 	 or: [theClass == VMClass]] whileFalse:
- 		[classes addLast: theClass.
- 		theClass := theClass superclass].
- 	^classes reverse!

Item was added:
+ ----- Method: InterpreterPlugin class>>pluginClassesUpToRoot (in category 'translation') -----
+ pluginClassesUpToRoot
+ 	"Answer the classes to include for translation of aPluginClass, superclasses first, and the root (VMClass in general, possibly Object)  last."
+ 	| theClass classes |
+ 
+ 	classes := OrderedCollection new.
+ 	theClass := self.
+ 	[theClass == Object
+ 	 or: [theClass == VMClass]] whileFalse:
+ 		[classes addLast: theClass.
+ 		theClass := theClass superclass].
+ 	^classes reverse!

Item was changed:
  ----- Method: InterpreterPlugin class>>translateInDirectory:doInlining: (in category 'translation') -----
  translateInDirectory: directory doInlining: inlineFlag
  "This is the default method for writing out sources for a plugin. Several classes need special handling, so look at all implementors of this message"
  	| cg fname |
  	 fname := self moduleName, '.c'.
  
  	"don't translate if the file is newer than my timeStamp"
  	(directory entryAt: fname ifAbsent: nil) ifNotNil:
  		[:fstat| | mTime |
  		mTime := fstat modificationTime.
  		mTime isInteger ifFalse: [mTime := mTime asSeconds].
  		 (self allCodeOlderThan: mTime) ifTrue:
  			[^nil]].
  
  	self initialize.
+ 	cg := self buildCodeGenerator.
- 	cg := self buildCodeGeneratorUpTo: self.
  	cg inferTypesForImplicitlyTypedVariablesAndMethods.
  	self pruneUnusedInterpreterPluginMethodsIn: cg.
  	cg storeCodeOnFile:  (directory fullNameFor: fname) doInlining: inlineFlag.
  	^cg exportedPrimitiveNames asArray!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveClosureValue (in category 'primitive generators') -----
  genPrimitiveClosureValue
  	"Check the argument count.  Fail if wrong.
  	 Get the method from the outerContext and see if it is cogged.  If so, jump to the
  	 block entry or the no-context-switch entry, as appropriate, and we're done.  If not,
  	 invoke the interpreter primitive."
  	| jumpFailNArgs jumpFail1 jumpFail2 jumpFail3 jumpFail4 jumpBCMethod primitiveRoutine result |
  	<var: #jumpFail1 type: #'AbstractInstruction *'>
  	<var: #jumpFail2 type: #'AbstractInstruction *'>
  	<var: #jumpFail3 type: #'AbstractInstruction *'>
  	<var: #jumpFail4 type: #'AbstractInstruction *'>
  	<var: #jumpFailNArgs type: #'AbstractInstruction *'>
  	<var: #jumpBCMethod type: #'AbstractInstruction *'>
  	<var: #primitiveRoutine declareC: 'void (*primitiveRoutine)()'>
  	objectRepresentation genLoadSlot: ClosureNumArgsIndex sourceReg: ReceiverResultReg destReg: TempReg.
  	self CmpCq: (objectMemory integerObjectOf: methodOrBlockNumArgs) R: TempReg.
  	jumpFailNArgs := self JumpNonZero: 0.
  	objectRepresentation genLoadSlot: ClosureOuterContextIndex sourceReg: ReceiverResultReg destReg: ClassReg.
  	jumpFail1 := objectRepresentation genJumpImmediate: ClassReg.
  	objectRepresentation genGetCompactClassIndexNonImmOf: ClassReg into: TempReg.
  	objectRepresentation genCmpClassMethodContextCompactIndexR: TempReg.
  	jumpFail2 := self JumpNonZero: 0.
  	"We defer unforwarding the receiver to the prologue; scanning blocks
  	 for inst var refs and only unforwarding if the block refers to inst vars."
  	(false
  	 and: [objectRepresentation hasSpurMemoryManagerAPI]) ifTrue:
  		[objectRepresentation
  			genLoadSlot: ReceiverIndex sourceReg: ClassReg destReg: SendNumArgsReg;
  			genEnsureOopInRegNotForwarded: SendNumArgsReg
  			scratchReg: TempReg
  			updatingSlot: ReceiverIndex
  			in: ClassReg].
  	objectRepresentation genLoadSlot: MethodIndex sourceReg: ClassReg destReg: SendNumArgsReg.
  	jumpFail3 := objectRepresentation genJumpImmediate: SendNumArgsReg.
  	objectRepresentation genGetFormatOf: SendNumArgsReg into: TempReg.
  	self CmpCq: objectMemory firstCompiledMethodFormat R: TempReg.
  	jumpFail4 := self JumpLess: 0.
  	objectRepresentation genLoadSlot: HeaderIndex sourceReg: SendNumArgsReg destReg: ClassReg.
+ 	jumpBCMethod := objectRepresentation genJumpImmediate: ClassReg.
- 	jumpBCMethod := objectRepresentation genJumpSmallInteger: ClassReg.
  	self MoveM16: (self offset: CogMethod of: #blockEntryOffset) r: ClassReg R: TempReg.
  	self AddR: ClassReg R: TempReg.
  	primitiveRoutine := coInterpreter
  							functionPointerForCompiledMethod: methodObj
  							primitiveIndex: primitiveIndex.
  	primitiveRoutine = #primitiveClosureValueNoContextSwitch ifTrue:
  		[blockNoContextSwitchOffset = nil ifTrue:
  			[^NotFullyInitialized].
  		 self SubCq: blockNoContextSwitchOffset R: TempReg].
  	self JumpR: TempReg.
  	jumpBCMethod jmpTarget: (jumpFail1 jmpTarget: (jumpFail2 jmpTarget: (jumpFail3 jmpTarget: (jumpFail4 jmpTarget: self Label)))).
  	(result := self compileInterpreterPrimitive: primitiveRoutine) < 0 ifTrue:
  		[^result].
  	jumpFailNArgs jmpTarget: self Label.
  	^0!

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 simulatorClasses |
  	self transcript cr; show: 'Looking for module ', pluginString.
  	"Defeat loading of the FloatArrayPlugin & Matrix2x3Plugin since complications with 32-bit
  	 float support prevent simulation.  If you feel up to tackling this start by implementing
  		cCoerce: value to: cType
  			^cType = 'float'
  				ifTrue: [value asIEEE32BitWord]
  				ifFalse: [value]
  	 in FloatArrayPlugin & Matrix2x3Plugin and then address the issues in the BalloonEnginePlugin.
  	 See http://forum.world.st/Simulating-the-BalloonEnginePlugin-FloatArrayPlugin-amp-Matrix2x3Plugin-primitives-td4734673.html"
  	(#('FloatArrayPlugin' 'Matrix2x3Plugin') includes: pluginString) ifTrue:
  		[self transcript show: ' ... defeated'. ^nil].
  	pluginString isEmpty
  		ifTrue:
  			[plugin := self]
  		ifFalse:
  			[plugins := InterpreterPlugin allSubclasses select: [:psc| psc moduleName asString = pluginString asString].
  			simulatorClasses := (plugins
  									select: [:psc| psc simulatorClass notNil]
  									thenCollect: [:psc| psc simulatorClass]) asSet.
  			simulatorClasses isEmpty ifTrue: [self transcript show: ' ... not found'. ^nil].
  			simulatorClasses size > 1 ifTrue: [^self error: 'This won''t work...'].
  			(plugins copyWithoutAll: simulatorClasses) notEmpty ifTrue:
  				[plugins := plugins copyWithoutAll: simulatorClasses].
  			plugins size > 1 ifTrue:
  				[self transcript show: '...multiple plugin classes; choosing ', plugins last name].
  			realPluginClass := plugins last. "hopefully lowest in the hierarchy..."
  			plugin := simulatorClasses anyOne newFor: realPluginClass.
  			plugin setInterpreter: objectMemory. "Ignore return value from setInterpreter"
  			(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]
- 				 cg := realPlugin buildCodeGeneratorUpTo: realPlugin]
  			ifFalse:
  				[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].
  									cg accessorDepthForSelector: fnSymbol}].
  		 self transcript show: '...done'].
  	^pluginString asString -> plugin!

Item was changed:
  ----- Method: SurfacePlugin class>>translateInDirectory:doInlining: (in category 'translation') -----
  translateInDirectory: directory doInlining: inlineFlag
  "handle a special case external file rather than normal generated code."
  	| cg |
  	self initialize.
  
+ 	cg := self buildCodeGenerator.
- 	cg := self buildCodeGeneratorUpTo: self.
  
  	"We rely on the fake entry points implemented on the instance side to allow the export list to be accurate. Please update them if you change the code"
  	^cg exportedPrimitiveNames asArray!



More information about the Vm-dev mailing list