[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