[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