[Vm-dev] VM Maker: VMMaker.oscog-eem.2240.mcz
commits at source.squeak.org
commits at source.squeak.org
Sat Jun 10 03:11:39 UTC 2017
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2240.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.2240
Author: eem
Time: 9 June 2017, 8:10:37.386604 pm
UUID: b7a78631-1fbc-42e2-a0e2-0a950a5db06e
Ancestors: VMMaker.oscog-eem.2239
Fix (I think) genGetInstanceOfFixedClass:into:initializingIf: for duff's device instance creation, and restore its use in genUnaryInlinePrimitive:.
Clément, I think I got it right. I tested the generated code worked correctly for the 11 slot case and then did in-image compilation for a set of classes with slot sizes 9 thorugh 32 and the code looks good. I hope you don't mind.
=============== Diff against VMMaker.oscog-eem.2239 ===============
Item was changed:
+ ----- Method: CogObjectRepresentationForSpur>>genGetInstanceOf:into:initializingIf: (in category 'inline primitive support') -----
- ----- Method: CogObjectRepresentationForSpur>>genGetInstanceOf:into:initializingIf: (in category 'bytecode generator support') -----
genGetInstanceOf: classObj into: destReg initializingIf: initializeInstance
"Create an instance of classObj and assign it to destReg, initializing the instance
if initializeInstance is true with nil or 0 as appropriate This is for inline primitives.
Assume there is sufficient space in new space to complete the operation.
Answer zero on success."
| classIndex classFormat header slots |
((objectMemory isNonImmediate: classObj)
and: [(coInterpreter objCouldBeClassObj: classObj)
and: [(classIndex := objectMemory rawHashBitsOf: classObj) ~= 0
and: [(objectMemory isFixedSizePointerFormat: (objectMemory instSpecOfClassFormat: (classFormat := objectMemory formatOfClass: classObj)))
and: [(slots := objectMemory fixedFieldsOfClassFormat: classFormat) < objectMemory numSlotsMask]]]]) ifFalse:
[^UnimplementedOperation].
self deny: destReg = TempReg.
header := objectMemory
headerForSlots: slots
format: (objectMemory instSpecOfClassFormat: classFormat)
classIndex: classIndex.
cogit MoveAw: objectMemory freeStartAddress R: destReg.
self genStoreHeader: header intoNewInstance: destReg using: TempReg.
cogit
LoadEffectiveAddressMw: (objectMemory smallObjectBytesForSlots: slots) r: destReg R: TempReg;
MoveR: TempReg Aw: objectMemory freeStartAddress.
(initializeInstance and: [slots > 0]) ifTrue:
[cogit genMoveConstant: objectMemory nilObject R: TempReg.
0 to: slots - 1 do:
[:i| cogit MoveR: TempReg
Mw: i * objectMemory wordSize + objectMemory baseHeaderSize
r: destReg]].
^0!
Item was changed:
+ ----- Method: CogObjectRepresentationForSpur>>genGetInstanceOfFixedClass:into:initializingIf: (in category 'inline primitive support') -----
- ----- Method: CogObjectRepresentationForSpur>>genGetInstanceOfFixedClass:into:initializingIf: (in category 'bytecode generator support') -----
genGetInstanceOfFixedClass: classObj into: destReg initializingIf: initializeInstance
"Create an instance of classObj and assign it to destReg, initializing the instance
if initializeInstance is true with nil or 0 as appropriate This is for inline primitives.
Assume there is sufficient space in new space to complete the operation.
Answer zero on success."
| classIndex classFormat header slots branch constReg inst loop delta loopCount slotsPerIteration |
((objectMemory isNonImmediate: classObj)
and: [(coInterpreter objCouldBeClassObj: classObj)
and: [(classIndex := objectMemory rawHashBitsOf: classObj) ~= 0
and: [(objectMemory isFixedSizePointerFormat: (objectMemory instSpecOfClassFormat: (classFormat := objectMemory formatOfClass: classObj)))
and: [(slots := objectMemory fixedFieldsOfClassFormat: classFormat) < objectMemory numSlotsMask]]]]) ifFalse:
[^UnimplementedOperation].
header := objectMemory
headerForSlots: slots
format: (objectMemory instSpecOfClassFormat: classFormat)
classIndex: classIndex.
cogit MoveAw: objectMemory freeStartAddress R: destReg.
self genStoreHeader: header intoNewInstance: destReg using: TempReg.
cogit
LoadEffectiveAddressMw: (objectMemory smallObjectBytesForSlots: slots) r: destReg R: TempReg;
MoveR: TempReg Aw: objectMemory freeStartAddress.
(initializeInstance and: [slots > 0]) ifFalse:
[^0].
+ slots <= (slotsPerIteration := 8) ifTrue: "slotsPerIteration must be even; see cogit SubCq: objectMemory bytesPerOop R: TempReg below"
- slots <= (slotsPerIteration := 8) ifTrue: "slotsPerIteration must be a power of two. see bitAnd: below"
[cogit genMoveConstant: objectMemory nilObject R: TempReg.
0 to: slots - 1 do:
[:i| cogit MoveR: TempReg
Mw: i * objectMemory wordSize + objectMemory baseHeaderSize
r: destReg].
^0].
+ "self halt: 'genGetInstanceOfFixedClass:... ', slots asInteger."
constReg := cogit allocateRegNotConflictingWith: destReg.
cogit genMoveConstant: objectMemory nilObject R: constReg.
slots \\ slotsPerIteration ~= 0
+ ifTrue: "delta maps the offset at the loop entryPoint onto destReg + objectMemory baseHeaderSize"
+ [delta := (slotsPerIteration - (slots \\ slotsPerIteration) * objectMemory bytesPerOop) - objectMemory baseHeaderSize.
+ delta > 0 ifTrue: [cogit SubCq: delta R: destReg].
+ delta < 0 ifTrue: [cogit AddCq: delta negated R: destReg].
+ "now delta maps (loopCount * slotsPerIteration * objectMemory bytesPerOop) + objectMemory baseHeaderSize - delta to the start of the object"
+ delta := delta + objectMemory baseHeaderSize.
+ (objectMemory bytesPerOop < objectMemory baseHeaderSize
+ and: [slots \\ 2 = 1]) ifTrue: "if end of loop is not at start of next object, adjust loop limit in TempReg to point to last field filled."
+ [cogit SubCq: objectMemory bytesPerOop R: TempReg].
- ifTrue:
- [delta := objectMemory baseHeaderSize - ((slotsPerIteration - (slots \\ slotsPerIteration) bitAnd: slotsPerIteration - 1) * objectMemory bytesPerOop).
- delta ~= 0 ifTrue:
- [cogit AddCq: delta R: destReg].
branch := cogit Jump: 0]
ifFalse:
+ [delta := 0.
- [delta := objectMemory baseHeaderSize.
cogit AddCq: objectMemory baseHeaderSize R: destReg].
+ "loopCount is number of times through the increment of destReg."
loopCount := slots + slotsPerIteration - 1 // slotsPerIteration.
self assert: loopCount > 1.
loop := cogit Label.
0 to: 7 do:
[:i|
inst := cogit MoveR: constReg Mw: i * objectMemory bytesPerOop r: destReg.
slotsPerIteration - (slots \\ slotsPerIteration) = i ifTrue:
[branch jmpTarget: inst]].
- "N.B. We get away with comparing against TempReg, which points to the start of the next
- object, not necessarily immediately after the last slot, because if the size is a multiple of 8,
- TempReg will point after the last slot, and if the size is not a multiple of 8 then the add of
- slotsPerIteration * objectMemory bytesPerOop will put destReg beyond TempReg any way."
cogit
AddCq: slotsPerIteration * objectMemory bytesPerOop R: destReg;
CmpR: TempReg R: destReg;
JumpBelow: loop;
+ SubCq: (loopCount * slotsPerIteration * objectMemory bytesPerOop) + objectMemory baseHeaderSize - delta R: destReg.
- SubCq: delta + (loopCount * slotsPerIteration * objectMemory bytesPerOop) R: destReg.
^0!
Item was changed:
+ ----- Method: CogObjectRepresentationForSpur>>genSetGCNeeded (in category 'inline primitive support') -----
- ----- Method: CogObjectRepresentationForSpur>>genSetGCNeeded (in category 'bytecode generator support') -----
genSetGCNeeded
<inline: true>
cogit
MoveCq: 1 R: TempReg;
MoveR: TempReg Aw: coInterpreter needGCFlagAddress!
Item was changed:
----- Method: SistaCogit>>genUnaryInlinePrimitive: (in category 'inline primitive generators') -----
genUnaryInlinePrimitive: prim
"Unary inline primitives."
"SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution.
See EncoderForSistaV1's class comment and StackInterpreter>>#unaryInlinePrimitive:"
| rcvrReg resultReg |
rcvrReg := self allocateRegForStackEntryAt: 0.
resultReg := self allocateRegNotConflictingWith: (self registerMaskFor: rcvrReg).
prim
caseOf: {
"00 unchecked class"
[1] -> "01 unchecked pointer numSlots"
[self ssTop popToReg: rcvrReg.
self ssPop: 1.
objectRepresentation
genGetNumSlotsOf: rcvrReg into: resultReg;
genConvertIntegerToSmallIntegerInReg: resultReg].
"02 unchecked pointer basicSize"
[3] -> "03 unchecked byte numBytes"
[self ssTop popToReg: rcvrReg.
self ssPop: 1.
objectRepresentation
genGetNumBytesOf: rcvrReg into: resultReg;
genConvertIntegerToSmallIntegerInReg: resultReg].
"04 unchecked short16Type format numShorts"
"05 unchecked word32Type format numWords"
"06 unchecked doubleWord64Type format numDoubleWords"
[11] -> "11 unchecked fixed pointer basicNew"
[self ssTop type ~= SSConstant ifTrue:
[^EncounteredUnknownBytecode].
(objectRepresentation
+ genGetInstanceOfFixedClass: self ssTop constant
- genGetInstanceOf: self ssTop constant
into: resultReg
+ initializingIf: self extBSpecifiesInitializeInstance) ~= 0 ifTrue:
- initializingIf: self extBSpecifiesInitializeInstance) ~= 0 ifTrue:
[^ShouldNotJIT]. "e.g. bad class"
self ssPop: 1] .
[20] -> "20 identityHash"
[objectRepresentation genGetIdentityHash: rcvrReg resultReg: resultReg.
self ssPop: 1] .
"21 identityHash (SmallInteger)"
"22 identityHash (Character)"
"23 identityHash (SmallFloat64)"
"24 identityHash (Behavior)"
"30 immediateAsInteger (Character)
31 immediateAsInteger (SmallFloat64)
35 immediateAsFloat (SmallInteger) "
[30] ->
[self ssTop popToReg: resultReg.
objectRepresentation genConvertCharacterToSmallIntegerInReg: resultReg.
self ssPop: 1].
[35] ->
[self assert: self processorHasDoublePrecisionFloatingPointSupport.
self MoveR: rcvrReg R: TempReg.
self genConvertSmallIntegerToIntegerInReg: TempReg.
self ConvertR: TempReg Rd: DPFPReg0.
self flag: #TODO. "Should never fail"
self
genAllocFloatValue: DPFPReg0
into: resultReg
scratchReg: TempReg
scratchReg: NoReg. "scratch2 for V3 only"]
}
otherwise:
[^EncounteredUnknownBytecode].
extB := 0.
numExtB := 0.
self ssPushRegister: resultReg.
^0!
More information about the Vm-dev
mailing list