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

commits at source.squeak.org commits at source.squeak.org
Fri Oct 4 21:09:02 UTC 2013


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

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

Name: VMMaker.oscog-eem.435
Author: eem
Time: 4 October 2013, 2:06:15.593 pm
UUID: 0c12fb89-e1e8-4428-8d8f-a18236386c12
Ancestors: VMMaker.oscog-eem.434

Avoid forwarding when obtaining classIndex or classObj in
machine code by adding instRegIsReceiver: instRegIsReceiver to
genGetClassObjectOf:into:scratchReg:(instRegIsReceiver:).

Update StackInterpreterSimulator>>writeImageFileIO: to match
CogVMSimulator.  Simplify two putLong:toFile: implementations.

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

Item was removed:
- ----- Method: CogObjectRepresentationForSpur>>genGetClassObjectOf:into:scratchReg: (in category 'compile abstract instructions') -----
- genGetClassObjectOf: instReg into: destReg scratchReg: scratchReg
- 	"Fetch the instance's class into destReg."
- 	| jumpIsImm jumpNotForwarded loop |
- 	<var: #jumpIsImm type: #'AbstractInstruction *'>
- 	<var: #jumpNotForwarded type: #'AbstractInstruction *'>
- 	<var: #loop type: #'AbstractInstruction *'>
- 	instReg = destReg ifTrue:
- 		[^BadRegisterSet].
- 	loop := cogit MoveR: instReg R: scratchReg.
- 	cogit AndCq: objectMemory tagMask R: scratchReg.
- 	jumpIsImm := cogit JumpNonZero: 0.
- 	self flag: #endianness.
- 	"Get least significant half of header word in destReg"
- 	cogit MoveMw: 0 r: instReg R: scratchReg.
- 	"mask off class index"
- 	cogit AndCq: objectMemory classIndexMask R: scratchReg.
- 	"if it is forwarded..."
- 	cogit CmpCq: objectMemory isForwardedObjectClassIndexPun R: scratchReg.
- 	jumpNotForwarded := cogit JumpNonZero: 0.
- 	"...follow the forwarding pointer and loop to fetch its classIndex"
- 	cogit MoveMw: objectMemory baseHeaderSize r: instReg R: instReg.
- 	cogit Jump: loop.
- 	jumpNotForwarded jmpTarget: (jumpIsImm jmpTarget: cogit Label).
- 	cogit MoveR: scratchReg R: destReg.
- 	cogit PushR: instReg.
- 	self genGetClassObjectOfClassIndex: destReg into: instReg scratchReg: TempReg.
- 	cogit MoveR: instReg R: destReg.
- 	cogit PopR: instReg.
- 	^0!

Item was added:
+ ----- Method: CogObjectRepresentationForSpur>>genGetClassObjectOf:into:scratchReg:instRegIsReceiver: (in category 'compile abstract instructions') -----
+ genGetClassObjectOf: instReg into: destReg scratchReg: scratchReg instRegIsReceiver: instRegIsReceiver
+ 	"Fetch the instance's class into destReg."
+ 	| jumpIsImm jumpNotForwarded loop |
+ 	<var: #jumpIsImm type: #'AbstractInstruction *'>
+ 	<var: #jumpNotForwarded type: #'AbstractInstruction *'>
+ 	<var: #loop type: #'AbstractInstruction *'>
+ 	instReg = destReg ifTrue:
+ 		[^BadRegisterSet].
+ 	loop := cogit MoveR: instReg R: scratchReg.
+ 	cogit AndCq: objectMemory tagMask R: scratchReg.
+ 	jumpIsImm := cogit JumpNonZero: 0.
+ 	self flag: #endianness.
+ 	"Get least significant half of header word in destReg"
+ 	cogit MoveMw: 0 r: instReg R: scratchReg.
+ 	"mask off class index"
+ 	cogit AndCq: objectMemory classIndexMask R: scratchReg.
+ 	instRegIsReceiver ifFalse:
+ 		["if it is forwarded..."
+ 		cogit CmpCq: objectMemory isForwardedObjectClassIndexPun R: scratchReg.
+ 		jumpNotForwarded := cogit JumpNonZero: 0.
+ 		"...follow the forwarding pointer and loop to fetch its classIndex"
+ 		cogit MoveMw: objectMemory baseHeaderSize r: instReg R: instReg.
+ 		cogit Jump: loop.
+ 		jumpNotForwarded jmpTarget: cogit Label].
+ 	jumpIsImm jmpTarget:
+ 	(cogit MoveR: scratchReg R: destReg).
+ 	cogit PushR: instReg.
+ 	self genGetClassObjectOfClassIndex: destReg into: instReg scratchReg: TempReg.
+ 	cogit MoveR: instReg R: destReg.
+ 	cogit PopR: instReg.
+ 	^0!

Item was removed:
- ----- Method: CogObjectRepresentationForSqueakV3>>genGetClassObjectOf:into:scratchReg: (in category 'compile abstract instructions') -----
- genGetClassObjectOf: instReg into: destReg scratchReg: scratchReg
- 	"Fetch the instance's class into destReg.  This is almost identical
- 	 to genGetClassFormatOfNonInt:into:scratchReg: but because we
- 	 put the fetch of SmallInteger between the then and the else for 
- 	 compact class/non-compact class we cannot easily share code."
- 	| jumpIsInt jumpCompact jumpGotClass jumpGotClass2 |
- 	<var: #jumpIsInt type: #'AbstractInstruction *'>
- 	<var: #jumpCompact type: #'AbstractInstruction *'>
- 	<var: #jumpGotClass type: #'AbstractInstruction *'>
- 	<var: #jumpGotClass2 type: #'AbstractInstruction *'>
- 	cogit MoveR: instReg R: scratchReg.
- 	cogit AndCq: 1 R: scratchReg.
- 	jumpIsInt := cogit JumpNonZero: 0.
- 	"Get header word in scratchReg"
- 	cogit MoveMw: 0 r: instReg R: scratchReg.
- 	"Form the byte index of the compact class field"
- 	cogit LogicalShiftRightCq: (objectMemory compactClassFieldLSB - ShiftForWord) R: scratchReg.
- 	cogit AndCq: self compactClassFieldMask << ShiftForWord R: scratchReg.
- 	jumpCompact := cogit JumpNonZero: 0.
- 	cogit MoveMw: objectMemory classFieldOffset r: instReg R: destReg.
- 	cogit AndCq: AllButTypeMask signedIntFromLong R: destReg.
- 	jumpGotClass := cogit Jump: 0.
- 	jumpIsInt jmpTarget:
- 		(cogit annotate: (cogit MoveCw: objectMemory classSmallInteger R: destReg)
- 				objRef: objectMemory classSmallInteger).
- 	jumpGotClass2 := cogit Jump: 0.
- 	"Don't have to subtract one from the destReg compactClassArray index because of the header word."
- 	self assert: BaseHeaderSize = BytesPerWord.
- 	jumpCompact jmpTarget:
- 		(cogit annotate: (cogit MoveMw: (objectMemory splObj: CompactClasses) r: scratchReg R: destReg)
- 			objRef: (objectMemory splObj: CompactClasses)).
- 	jumpGotClass jmpTarget:
- 	(jumpGotClass2 jmpTarget: cogit Label).
- 	^0!

Item was added:
+ ----- Method: CogObjectRepresentationForSqueakV3>>genGetClassObjectOf:into:scratchReg:instRegIsReceiver: (in category 'compile abstract instructions') -----
+ genGetClassObjectOf: instReg into: destReg scratchReg: scratchReg instRegIsReceiver: instRegIsReceiver
+ 	"Fetch the instance's class into destReg.  This is almost identical
+ 	 to genGetClassFormatOfNonInt:into:scratchReg: but because we
+ 	 put the fetch of SmallInteger between the then and the else for 
+ 	 compact class/non-compact class we cannot easily share code.
+ 	 instRegIsReceiver is ignored.  It is for Spur compatibility where
+ 	 objects may be forwarded."
+ 	| jumpIsInt jumpCompact jumpGotClass jumpGotClass2 |
+ 	<var: #jumpIsInt type: #'AbstractInstruction *'>
+ 	<var: #jumpCompact type: #'AbstractInstruction *'>
+ 	<var: #jumpGotClass type: #'AbstractInstruction *'>
+ 	<var: #jumpGotClass2 type: #'AbstractInstruction *'>
+ 	cogit MoveR: instReg R: scratchReg.
+ 	cogit AndCq: 1 R: scratchReg.
+ 	jumpIsInt := cogit JumpNonZero: 0.
+ 	"Get header word in scratchReg"
+ 	cogit MoveMw: 0 r: instReg R: scratchReg.
+ 	"Form the byte index of the compact class field"
+ 	cogit LogicalShiftRightCq: (objectMemory compactClassFieldLSB - ShiftForWord) R: scratchReg.
+ 	cogit AndCq: self compactClassFieldMask << ShiftForWord R: scratchReg.
+ 	jumpCompact := cogit JumpNonZero: 0.
+ 	cogit MoveMw: objectMemory classFieldOffset r: instReg R: destReg.
+ 	cogit AndCq: AllButTypeMask signedIntFromLong R: destReg.
+ 	jumpGotClass := cogit Jump: 0.
+ 	jumpIsInt jmpTarget:
+ 		(cogit annotate: (cogit MoveCw: objectMemory classSmallInteger R: destReg)
+ 				objRef: objectMemory classSmallInteger).
+ 	jumpGotClass2 := cogit Jump: 0.
+ 	"Don't have to subtract one from the destReg compactClassArray index because of the header word."
+ 	self assert: BaseHeaderSize = BytesPerWord.
+ 	jumpCompact jmpTarget:
+ 		(cogit annotate: (cogit MoveMw: (objectMemory splObj: CompactClasses) r: scratchReg R: destReg)
+ 			objRef: (objectMemory splObj: CompactClasses)).
+ 	jumpGotClass jmpTarget:
+ 	(jumpGotClass2 jmpTarget: cogit Label).
+ 	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSqueakV3>>genGetClassTagOf:into:scratchReg: (in category 'compile abstract instructions') -----
  genGetClassTagOf: instReg into: destReg scratchReg: scratchReg
  	"Compatibility with SpurObjectRepresentation/SpurMemoryManager."
  	| entryLabel |
  	<var: #entryLabel type: #'AbstractInstruction *'>
  	cogit AlignmentNops: (BytesPerWord max: 8).
  	entryLabel := cogit Label.
+ 	self genGetClassObjectOf: instReg into: destReg scratchReg: scratchReg instRegIsReceiver: nil.
- 	self genGetClassObjectOf: instReg into: destReg scratchReg: scratchReg.
  	^entryLabel!

Item was changed:
  ----- Method: Cogit>>generateNewspeakRuntime (in category 'initialization') -----
  generateNewspeakRuntime
  	<option: #NewspeakVM>
  	| jumpMiss jumpItsTheReceiverStupid |
  	<var: #jumpMiss type: #'AbstractInstruction *'>
  	<var: #jumpItsTheReceiverStupid type: #'AbstractInstruction *'>
  	"Generate the non-send runtime support for Newspeak, explicit outer and implicit receiver.
  	 The dynamic frequency of explicit outer is so low we merely call an interpreter routine."
  	ceExplicitReceiverTrampoline := self genTrampolineFor: #ceExplicitReceiverAt:
  										called: 'ceExplicitReceiverTrampoline'
  										arg: SendNumArgsReg
  										result: ReceiverResultReg.
  	"Cached push implicit receiver implementation.  Caller looks like
  				mov selector, ClassReg
  				call ceImplicitReceiver
  				br continue
  		Lclass:	.word
  		Lmixin::	.word
  		continue:
  	 If class matches class of receiver then mixin contains either 0 or the implicit receiver.
  	 If 0, answer the actual receiver, otherwise the mixin.
  	 Generate the class fetch and cache probe inline for speed. Smashes Arg0Reg and caller-saved regs."
  	opcodeIndex := 0.
  	self MoveMw: FoxMFReceiver r: FPReg R: ReceiverResultReg.
+ 	objectRepresentation
+ 		genGetClassObjectOf: ReceiverResultReg
+ 		into: ClassReg
+ 		scratchReg: TempReg
+ 		instRegIsReceiver: true. "don't follow forwarding pointer here"
- 	objectRepresentation genGetClassObjectOf: ReceiverResultReg into: ClassReg scratchReg: TempReg.
  	self MoveMw: 0 r: SPReg R: TempReg.
  	self MoveMw: backEnd jumpShortByteSize r: TempReg R: Arg1Reg.
  	self CmpR: ClassReg R: Arg1Reg.
  	jumpMiss := self JumpNonZero: 0.
  	self MoveMw: backEnd jumpShortByteSize + BytesPerOop r: TempReg R: ClassReg.
  	self CmpCq: 0 R: ClassReg.
  	jumpItsTheReceiverStupid := self JumpZero: 0.
  	self MoveR: ClassReg R: ReceiverResultReg.
  	jumpItsTheReceiverStupid jmpTarget: (self RetN: 0).
  	jumpMiss jmpTarget: self Label.
  	ceImplicitReceiverTrampoline := self
  										genTrampolineFor: #ceImplicitReceiverFor:receiver:class:
  										called: 'ceImplicitReceiverTrampoline'
  										callJumpBar: true
  										numArgs: 3
  										arg: SendNumArgsReg
  										arg: ReceiverResultReg
  										arg: ClassReg
  										arg: nil
  										saveRegs: false
  										resultReg: ReceiverResultReg
  										appendOpcodes: true!

Item was changed:
  ----- Method: InterpreterSimulatorMSB>>putLong:toFile: (in category 'image save/restore') -----
  putLong: n toFile: f
  	"Append the given 4-byte long word to the given file in my byte order. (Bytes will be swapped, if necessary, when the image is read on a different platform.) Set successFlag to false if the write fails."
  
  	f
  		nextPut: (n bitShift: -24);
+ 		nextPut: ((n bitShift: -16) bitAnd: 16rFF);
+ 		nextPut: ((n bitShift: -8) bitAnd: 16rFF);
- 		nextPut: ((n bitAnd: 16rFF0000) bitShift: -16);
- 		nextPut: ((n bitAnd: 16rFF00) bitShift: -8);
  		nextPut: (n bitAnd: 16rFF).
  
  	self success: true!

Item was changed:
  ----- Method: NewspeakInterpreterSimulatorMSB>>putLong:toFile: (in category 'image save/restore') -----
  putLong: n toFile: f
  	"Append the given 4-byte long word to the given file in my byte order. (Bytes will be swapped, if necessary, when the image is read on a different platform.) Set successFlag to false if the write fails."
  
  	f
  		nextPut: (n bitShift: -24);
+ 		nextPut: ((n bitShift: -16) bitAnd: 16rFF);
+ 		nextPut: ((n bitShift: -8) bitAnd: 16rFF);
- 		nextPut: ((n bitAnd: 16rFF0000) bitShift: -16);
- 		nextPut: ((n bitAnd: 16rFF00) bitShift: -8);
  		nextPut: (n bitAnd: 16rFF).
  
  	self success: true!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveClass (in category 'primitive generators') -----
  genPrimitiveClass
  	"Stack looks like
  		receiver (also in ReceiverResultReg)
  		return address"
  	(objectRepresentation
  			genGetClassObjectOf: ReceiverResultReg
  			into: ReceiverResultReg
+ 			scratchReg: TempReg
+ 			instRegIsReceiver: methodOrBlockNumArgs = 0) = BadRegisterSet ifTrue:
- 			scratchReg: TempReg) = BadRegisterSet ifTrue:
  		[objectRepresentation
  			genGetClassObjectOf: ReceiverResultReg
  			into: ClassReg
+ 			scratchReg: TempReg
+ 			instRegIsReceiver: methodOrBlockNumArgs = 0.
- 			scratchReg: TempReg.
  		 self MoveR: ClassReg R: ReceiverResultReg]..
  	self flag: 'currently caller pushes result'.
  	self RetN: BytesPerWord.
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genSpecialSelectorClass (in category 'bytecode generators') -----
  genSpecialSelectorClass
  	self MoveMw: 0 r: SPReg R: SendNumArgsReg.
+ 	objectRepresentation
+ 		genGetClassObjectOf: SendNumArgsReg
+ 		into: ClassReg
+ 		scratchReg: TempReg
+ 		instRegIsReceiver: false.
- 	objectRepresentation genGetClassObjectOf: SendNumArgsReg into: ClassReg scratchReg: TempReg.
  	self MoveR: ClassReg Mw: 0 r: SPReg.
  	^0!

Item was changed:
  ----- Method: SpurMemoryManager>>lookupAddress: (in category 'simulation only') -----
  lookupAddress: address
  	"If address appears to be that of a Symbol or a few well-known objects (such as classes) answer it, otherwise answer nil.
  	 For code disassembly"
  	<doNotGenerate>
  	| fmt size string class classSize maybeThisClass classNameIndex thisClassIndex |
  	(self addressCouldBeObj: address) ifFalse:
  		[^nil].
+ 	address - self baseHeaderSize = classTableRootObj ifTrue:
+ 		[^'(classTableRoot+baseHeaderSize)'].
  	fmt := self formatOf: address.
  	size := self lengthOf: address baseHeader: (self baseHeader: address) format: fmt.
  	size = 0 ifTrue:
  		[^address caseOf: { [nilObj] -> ['nil']. [trueObj] -> ['true']. [falseObj] -> ['false'] } otherwise: []].
  	((fmt between: self firstByteFormat and: self firstCompiledMethodFormat - 1) "indexable byte fields"
  	and: [(size between: 1 and: 64)
  	and: [Scanner isLiteralSymbol: (string := (0 to: size - 1) collect: [:i| Character value: (self fetchByte: i ofObject: address)])]]) ifTrue:
  		[^'#', (ByteString withAll: string)].
  	class := self fetchClassOfNonImm: address.
  	(class isNil or: [class = nilObj]) ifTrue:
  		[^nil].
  	"address is either a class or a metaclass, or an instance of a class or invalid.  determine which."
  	classNameIndex := coInterpreter classNameIndex.
  	thisClassIndex := coInterpreter thisClassIndex.
  	((classSize := self numSlotsOf: class) <= (classNameIndex max: thisClassIndex)
  	 or: [classSize > 255]) ifTrue:
  		[^nil].
  	"Address could be a class or a metaclass"
  	(fmt = 1 and: [size >= classNameIndex]) ifTrue:
  		["Is address a class? If so class's thisClass is address."
  		 (self lookupAddress: (self fetchPointer: classNameIndex ofObject: address)) ifNotNil:
  			[:maybeClassName|
  			(self fetchPointer: thisClassIndex ofObject: class) = address ifTrue:
  				[^maybeClassName allButFirst]].
  		"Is address a Metaclass?  If so class's name is Metaclass and address's thisClass holds the class name"
  		((self isBytes: (self fetchPointer: classNameIndex ofObject: class))
  		 and: [(self lookupAddress: (self fetchPointer: classNameIndex ofObject: class)) = '#Metaclass'
  		 and: [size >= thisClassIndex]]) ifTrue:
  			[maybeThisClass := self fetchPointer: thisClassIndex ofObject: address.
  			(self lookupAddress: (self fetchPointer: classNameIndex ofObject: maybeThisClass)) ifNotNil:
  				[:maybeThisClassName| ^maybeThisClassName allButFirst, ' class']]].
  	^(self lookupAddress: (self fetchPointer: classNameIndex ofObject: class)) ifNotNil:
  		[:maybeClassName| 'a(n) ', maybeClassName allButFirst]!

Item was changed:
  ----- Method: StackInterpreterSimulator>>writeImageFileIO: (in category 'image save/restore') -----
  writeImageFileIO: numberOfBytesToWrite
  	"Actually emit the first numberOfBytesToWrite object memory bytes onto the snapshot."
  
  	| headerSize file |
  	BytesPerWord = 4 ifFalse: [self error: 'Not rewritten for 64 bits yet'].
  	headerSize := 64.
  
  	[
  		file := FileStream fileNamed: imageName.
  		file == nil ifTrue:
  			[self primitiveFail.
  			 ^nil].
  		file binary.
+ 
- 	
  		{
  			self imageFormatVersion.
  			headerSize.
  			numberOfBytesToWrite.
  			objectMemory startOfMemory.
  			(objectMemory specialObjectsOop).
  			(objectMemory lastHash).
  			self ioScreenSize.
+ 			self getImageHeaderFlags.
- 			fullScreenFlag.
  			extraVMMemory
  		}
  			do: [:long | self putLong: long toFile: file].
  
+ 		{	desiredNumStackPages. self unknownShortOrCodeSizeInKs } do:
- 		{	desiredNumStackPages. 	self unknownShortOrCodeSizeInKs } do:
  			[:short| self putShort: short toFile: file].
  
  		self putLong: desiredEdenBytes toFile: file.
  
  		{	maxExtSemTabSizeSet ifTrue: [self ioGetMaxExtSemTableSize] ifFalse: [0]. 0 } do:
  			[:short| self putShort: short toFile: file].
  
  		"Pad the rest of the header."
  		4 timesRepeat: [self putLong: 0 toFile: file].
  	
  		"Position the file after the header."
  		file position: headerSize.
  	
  		"Write the object memory."
  		objectMemory startOfMemory // 4 + 1
  			to: numberOfBytesToWrite // 4
  			do: [:index |
  				self
  					putLong: (objectMemory memory at: index)
  					toFile: file].
  	
  		self success: true
  	]
  		ensure: [file ifNotNil: [file close]]!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genPrimitiveClass (in category 'primitive generators') -----
  genPrimitiveClass
  	"Depending on argument count the argument is either
  		0 args: ReceiverResultReg
  		1 args: Arg0Reg
  		N args: top of stack (assuming 1 reg arg for now)"
  	| reg |
  	methodOrBlockNumArgs = 1
  		ifTrue:
  			[reg := Arg0Reg]
  		ifFalse:
  			[methodOrBlockNumArgs > 0 ifTrue:
  				[self MoveMw: BytesPerWord r: SPReg R: ReceiverResultReg].
  			reg := ReceiverResultReg].
  	(objectRepresentation
  			genGetClassObjectOf: reg
  			into: ReceiverResultReg
+ 			scratchReg: TempReg
+ 			instRegIsReceiver: methodOrBlockNumArgs = 0) = BadRegisterSet ifTrue:
- 			scratchReg: TempReg) = BadRegisterSet ifTrue:
  		[objectRepresentation
  			genGetClassObjectOf: reg
  			into: ClassReg
+ 			scratchReg: TempReg
+ 			instRegIsReceiver: methodOrBlockNumArgs = 0.
- 			scratchReg: TempReg.
  		 self MoveR: ClassReg R: ReceiverResultReg].
  	self RetN: 0.
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genSpecialSelectorClass (in category 'bytecode generators') -----
  genSpecialSelectorClass
  	| topReg |
  	topReg := self ssTop registerOrNil.
  	self ssPop: 1.
  	(topReg isNil or: [topReg = ClassReg])
  		ifTrue: [self ssAllocateRequiredReg: (topReg := SendNumArgsReg) and: ClassReg]
  		ifFalse: [self ssAllocateRequiredReg: ClassReg].
  	self ssPush: 1.
  	self ssTop popToReg: topReg.
+ 	objectRepresentation
+ 		genGetClassObjectOf: topReg
+ 		into: ClassReg
+ 		scratchReg: TempReg
+ 		instRegIsReceiver: false.
- 	objectRepresentation genGetClassObjectOf: topReg into: ClassReg scratchReg: TempReg.
  	^self ssPop: 1; ssPushRegister: ClassReg!



More information about the Vm-dev mailing list