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

commits at source.squeak.org commits at source.squeak.org
Mon Dec 7 05:53:32 UTC 2015


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

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

Name: VMMaker.oscog-eem.1562
Author: eem
Time: 6 December 2015, 9:51:53.153 pm
UUID: 4928e91f-9353-4858-8b2f-a5d968eec177
Ancestors: VMMaker.oscog-eem.1561

x64 Cogit:
Fix shift right; tags must be zeroed before SI tag can be set.

Fix rewriting of Call/JumpFull

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

Item was added:
+ ----- Method: CogObjectRepresentation>>genClearAndSetSmallIntegerTagsIn: (in category 'compile abstract instructions') -----
+ genClearAndSetSmallIntegerTagsIn: scratchReg
+ 	"Set the SmallInteger tag bits when the tag bits may be filled with garbage."
+ 	self subclassResponsibility!

Item was added:
+ ----- Method: CogObjectRepresentation>>genSetSmallIntegerTagsIn: (in category 'compile abstract instructions') -----
+ genSetSmallIntegerTagsIn: scratchReg
+ 	self subclassResponsibility!

Item was added:
+ ----- Method: CogObjectRepresentationFor32BitSpur>>genClearAndSetSmallIntegerTagsIn: (in category 'compile abstract instructions') -----
+ genClearAndSetSmallIntegerTagsIn: scratchReg
+ 	"Set the SmallInteger tag bits when the tag bits may be filled with garbage."
+ 	^self genSetSmallIntegerTagsIn: scratchReg!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genClearAndSetSmallIntegerTagsIn: (in category 'compile abstract instructions') -----
+ genClearAndSetSmallIntegerTagsIn: scratchReg
+ 	"Set the SmallInteger tag bits when the tag bits may be filled with garbage."
+ 	cogit
+ 		AndCq: -1 - self tagMask R: scratchReg;
+ 		OrCq: 1 R: scratchReg.
+ 	^0!

Item was added:
+ ----- Method: CogObjectRepresentationForSqueakV3>>genClearAndSetSmallIntegerTagsIn: (in category 'compile abstract instructions') -----
+ genClearAndSetSmallIntegerTagsIn: scratchReg
+ 	"Set the SmallInteger tag bits when the tag bits may be filled with garbage."
+ 	^self genSetSmallIntegerTagsIn: scratchReg!

Item was added:
+ ----- Method: CogX64Compiler>>callFullTargetFromReturnAddress: (in category 'full transfer run-time support') -----
+ callFullTargetFromReturnAddress: callSiteReturnAddress
+ 	"Answer the address the full call immediately preceding callSiteReturnAddress will jump to."
+ 	^self sixtyFourBitLiteralBefore: callSiteReturnAddress - 2!

Item was added:
+ ----- Method: CogX64Compiler>>rewriteCallFullAt:target: (in category 'full transfer run-time support') -----
+ rewriteCallFullAt: callSiteReturnAddress target: callTargetAddress
+ 	"Rewrite a CallFull instruction to call a different target.  This variant is used to rewrite cached primitive calls.
+ 	 Answer the extent of the code change which is used to compute the range of the icache to flush.
+ 	 On x64 this is a rewrite of
+ 		movq #64bits, %rax : 48 A1 b0 b1 b2 b3 b4 b5 b6 b7
+ 		jmp %rax : FF E0 "
+ 	self assert: (objectMemory byteAt: callSiteReturnAddress - 12) = 16r48.
+ 	objectMemory
+ 		byteAt: callSiteReturnAddress -   3 put: (callTargetAddress >> 56 bitAnd: 16rFF);
+ 		byteAt: callSiteReturnAddress -   4 put: (callTargetAddress >> 48 bitAnd: 16rFF);
+ 		byteAt: callSiteReturnAddress -   5 put: (callTargetAddress >> 40 bitAnd: 16rFF);
+ 		byteAt: callSiteReturnAddress -   6 put: (callTargetAddress >> 32 bitAnd: 16rFF);
+ 		byteAt: callSiteReturnAddress -   7 put: (callTargetAddress >> 24 bitAnd: 16rFF);
+ 		byteAt: callSiteReturnAddress -   8 put: (callTargetAddress >> 16 bitAnd: 16rFF);
+ 		byteAt: callSiteReturnAddress -   9 put: (callTargetAddress >>   8 bitAnd: 16rFF);
+ 		byteAt: callSiteReturnAddress - 10 put: (callTargetAddress            bitAnd: 16rFF).
+ 	self assert: (self callFullTargetFromReturnAddress: callSiteReturnAddress) signedIntToLong64 = callTargetAddress.
+ 	"self cCode: ''
+ 		inSmalltalk: [cogit disassembleFrom: callSiteReturnAddress - 10 to: callSiteReturnAddress - 1]."
+ 	^12!

Item was added:
+ ----- Method: CogX64Compiler>>rewriteJumpFullAt:target: (in category 'full transfer run-time support') -----
+ rewriteJumpFullAt: callSiteReturnAddress target: callTargetAddress
+ 	"Rewrite a JumpFull instruction to jump to a different target.  This variant is used to rewrite cached primitive calls.
+ 	 Answer the extent of the code change which is used to compute the range of the icache to flush.
+ 	 On x64 this is a rewrite of
+ 		movq #64bits, %rax : 48 A1 b0 b1 b2 b3 b4 b5 b6 b7
+ 		jmp %rax : FF E0 "
+ 	^self rewriteCallFullAt: callSiteReturnAddress target: callTargetAddress!

Item was added:
+ ----- Method: CogX64Compiler>>sixtyFourBitLiteralBefore: (in category 'inline cacheing') -----
+ sixtyFourBitLiteralBefore: followingAddress
+ 	<inline: true>
+ 	^self cCode: [objectMemory unalignedLongAt: followingAddress - 9]
+ 		inSmalltalk: [   ((objectMemory byteAt: followingAddress - 1) << 56)
+ 					+ ((objectMemory byteAt: followingAddress - 2) << 48)
+ 					+ ((objectMemory byteAt: followingAddress - 3) << 40)
+ 					+ ((objectMemory byteAt: followingAddress - 4) << 32)
+ 					+ ((objectMemory byteAt: followingAddress - 5) << 24)
+ 					+ ((objectMemory byteAt: followingAddress - 6) << 16)
+ 					+ ((objectMemory byteAt: followingAddress - 7) << 8)
+ 					+  (objectMemory byteAt: followingAddress - 8)]!

Item was changed:
  ----- Method: CogX64CompilerTests>>testMoveRdM64r (in category 'tests') -----
  testMoveRdM64r
  	"self new testMoveRdM64r"
  	self concreteCompilerClass xmmRegistersWithNamesDo:
  		[:sreg :srname|
  		self concreteCompilerClass registersWithNamesDo:
  			[:dreg :drname|
  			((1 to: 19 by: 3) collect: [:po2| 2 raisedToInteger: po2]) do:
  				[:offset| | inst len |
  				inst := self gen: MoveRdM64r operand: sreg operand: offset operand: dreg.
  				len := inst concretizeAt: 0.
  				self processor
  					disassembleInstructionAt: 0
  					In: inst machineCode object
  					into: [:str :sz| | plainJane herIntended |
  						plainJane := self strip: str.
+ 						herIntended := 'movq ', srname, ', 0x', (offset hex allButFirst: 3), '(', drname, ')'.
- 						herIntended := 'movsd ', srname, ', 0x', (offset hex allButFirst: 3), '(', drname, ')'.
  						self assert: herIntended equals: plainJane.
  						self assert: len = sz]]]]!

Item was changed:
  ----- Method: Cogit>>disassembleMethod:on: (in category 'disassembly') -----
  disassembleMethod: surrogateOrAddress on: aStream
  	<doNotGenerate>
  	| cogMethod mapEntries codeRanges |
  	cogMethod := surrogateOrAddress isInteger
  								ifTrue: [self cogMethodSurrogateAt: surrogateOrAddress]
  								ifFalse: [surrogateOrAddress].
  	cogMethod cmType = CMBlock ifTrue:
  		[^self disassembleMethod: cogMethod cmHomeMethod on: aStream].
  	self printMethodHeader: cogMethod on: aStream.
  
  	(mapEntries := Dictionary new)
  		at: cogMethod asInteger + cmEntryOffset put: 'entry'.
  	
  	cogMethod cmType = CMMethod ifTrue:
  		[mapEntries at: cogMethod asInteger + cmNoCheckEntryOffset put: 'noCheckEntry'].
  
  	cogMethod cmType = CMClosedPIC ifTrue:
  		[mapEntries at: cogMethod asInteger + firstCPICCaseOffset put: 'ClosedPICCase0'.
  		 1 to: maxCPICCases - 1 do:
  			[:i|
  			mapEntries
  				at: cogMethod asInteger + firstCPICCaseOffset + (i * cPICCaseSize)
  				put: 'ClosedPICCase', i printString]].
  
  	self mapFor: cogMethod
  		performUntil: #collectMapEntry:address:into:
  		arg: mapEntries.
  
  	NewspeakVM ifTrue:
  		[objectRepresentation canPinObjects ifFalse:
  			[mapEntries keys do:
  				[:a|
  				(mapEntries at: a) = #IsNSSendCall ifTrue:
  					[mapEntries
  						at: a + backEnd jumpShortByteSize
  							put: {'Class'. #disassembleCachedOop:. (objectMemory wordSize)};
  						at: a + backEnd jumpShortByteSize + objectMemory bytesPerOop
  							put: {'ImplicitReceiver'. #disassembleCachedOop:. (objectMemory wordSize)}]]]].
  
  	"This would all be far more elegant and simple if we used blocks.
  	 But there are no blocks in C and the basic enumerators here need
  	 to be used in the real VM.  Apologies."
  	(codeRanges := self codeRangesFor: cogMethod) do:
  		[:range|
  		(cogMethod cmType = CMMethod) ifTrue:
  			[mapEntries keysAndValuesDo:
+ 				[:mcpc :label| | bcpc selectorOrNone |
- 				[:mcpc :label| | bcpc |
  				((range includes: mcpc)
  				 and: [(AnnotationsWithBytecodePCs includes: label)
  				 and: [range cogMethod stackCheckOffset > 0]]) ifTrue:
  					[bcpc := self bytecodePCFor: mcpc startBcpc: range startpc in: range cogMethod.
  					 bcpc ~= 0 ifTrue:
+ 						[label = #IsSendCall
+ 							ifTrue:
+ 								[selectorOrNone := (self selectorForSendAt: mcpc annotation: IsSendCall in: cogMethod methodObject).
+ 								 (selectorOrNone isInteger and: [objectMemory addressCouldBeOop: selectorOrNone]) ifTrue:
+ 									[selectorOrNone := objectMemory stringOf: selectorOrNone].
+ 								selectorOrNone := ' ', selectorOrNone]
+ 							ifFalse: [selectorOrNone := ''].
+ 						 mapEntries
+ 							at: mcpc
+ 							put: label, selectorOrNone, ' bc ', bcpc printString, '/', (bcpc + 1) printString]]]].
- 						[mapEntries at: mcpc put: label, ' bc ', bcpc printString, '/', (bcpc + 1) printString]]]].
  		(cogMethod blockEntryOffset ~= 0
  		 and: [range first = (cogMethod blockEntryOffset + cogMethod asInteger)])
  			ifTrue:
  				[aStream nextPutAll: 'blockEntry:'; cr.
  				 self blockDispatchFor: cogMethod
  					perform: #disassemble:from:to:arg:
  					arg: aStream]
  			ifFalse:
  				[range first > (cogMethod address + cmNoCheckEntryOffset) ifTrue:
  					[self printMethodHeader: range cogMethod
  						on: aStream].
  				self disassembleFrom: range first to: range last labels: mapEntries on: aStream]].
  	aStream nextPutAll: 'startpc: '; print: codeRanges first startpc; cr.
  	(cogMethod cmType = CMMethod
  	 or: [cogMethod cmType = CMOpenPIC]) ifTrue:
  		[[self mapFor: cogMethod
  			performUntil: #printMapEntry:mcpc:args:
  			arg: { aStream. codeRanges. cogMethod }]
  			on: AssertionFailure
  			do: [:ex|
  				ex primitiveChangeClassTo: ResumableVMError basicNew. ":) :) :)"
  				ex resume: nil]].
  	^cogMethod!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveBitShift (in category 'primitive generators') -----
  genPrimitiveBitShift
  	"Stack looks like
  		receiver (also in ResultReceiverReg)
  		arg
  		return address
  
  	rTemp := ArgOffset(SP)
  	rClass := tTemp
  	rTemp := rTemp & 1
  	jz nonInt
  	rClass >>= 1
  	cmp 0,rClass
  	jge neg
  	cmp 31,rClass // numSmallIntegerBits, jge for sign
  	jge tooBig
  	rTemp := rReceiver
  	rTemp <<= rClass
  	rTemp >>= rClass (arithmetic)
  	cmp rTemp,rReceiver
  	jnz ovfl
  	rReceiver := rReceiver - 1
  	rReceiver := rReceiver <<= rClass
  	rReceiver := rReceiver + 1
  	ret
  neg:
  	rClass := 0 - rClass
  	cmp 31,rClass
  	jge inRange
  	rClass := 31
  inRange
  	rReceiver := rReceiver >>= rClass.
  	rReceiver := rReceiver | 1.
  	ret
  ovfl
  tooBig
  nonInt:
  	fail"
  	| jumpNotSI jumpOvfl jumpNegative jumpTooBig jumpInRange |
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpOvfl type: #'AbstractInstruction *'>
  	<var: #jumpNegative type: #'AbstractInstruction *'>
  	<var: #jumpTooBig type: #'AbstractInstruction *'>
  	<var: #jumpInRange type: #'AbstractInstruction *'>
  	self genLoadArgAtDepth: 0 into: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
  	(self lastOpcode setsConditionCodesFor: JumpNegative) ifFalse:
  		[self CmpCq: 0 R: ClassReg]. "N.B. FLAGS := ClassReg - 0"
  	jumpNegative := self JumpNegative: 0.
  	self CmpCq: objectRepresentation numSmallIntegerBits R: ClassReg. "N.B. FLAGS := ClassReg - 31"
  	jumpTooBig := self JumpGreaterOrEqual: 0.
  	self MoveR: ReceiverResultReg R: TempReg.
  	self LogicalShiftLeftR: ClassReg R: TempReg.
  	self ArithmeticShiftRightR: ClassReg R: TempReg.
  	self CmpR: TempReg R: ReceiverResultReg. "N.B. FLAGS := RRReg - TempReg"
  	jumpOvfl := self JumpNonZero: 0.
  	objectRepresentation genRemoveSmallIntegerTagsInScratchReg: ReceiverResultReg.
  	self LogicalShiftLeftR: ClassReg R: ReceiverResultReg.
  	objectRepresentation genAddSmallIntegerTagsTo: ReceiverResultReg.
  	self RetN: (self primRetNOffsetFor: 1).
  	jumpNegative jmpTarget: (self NegateR: ClassReg).
  	self CmpCq: objectRepresentation numSmallIntegerBits R: ClassReg. "N.B. FLAGS := ClassReg - 31"
  	jumpInRange := self JumpLessOrEqual: 0.
  	self MoveCq: objectRepresentation numSmallIntegerBits R: ClassReg.
  	jumpInRange jmpTarget: (self ArithmeticShiftRightR: ClassReg R: ReceiverResultReg).
+ 	objectRepresentation genClearAndSetSmallIntegerTagsIn: ReceiverResultReg.
- 	objectRepresentation genSetSmallIntegerTagsIn: ReceiverResultReg.
  	self RetN: (self primRetNOffsetFor: 1).
  	jumpNotSI jmpTarget: (jumpTooBig jmpTarget: (jumpOvfl jmpTarget: self Label)).
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genPrimitiveBitShift (in category 'primitive generators') -----
  genPrimitiveBitShift
  	"Receiver and arg in registers.
  	 Stack looks like
  		return address
  
  	rTemp := rArg0
  	rClass := tTemp
  	rTemp := rTemp & 1
  	jz nonInt
  	rClass >>= 1
  	cmp 0,rClass
  	jge neg
  	cmp 31,rClass // numSmallIntegerBits, jge for sign
  	jge tooBig
  	rTemp := rReceiver
  	rTemp <<= rClass
  	rTemp >>= rClass (arithmetic)
  	cmp rTemp,rReceiver
  	jnz ovfl
  	rReceiver := rReceiver - 1
  	rReceiver := rReceiver <<= rClass
  	rReceiver := rReceiver + 1
  	ret
  neg:
  	rClass := 0 - rClass
  	cmp 31,rClass
  	jge inRange
  	rClass := 31
  inRange
  	rReceiver := rReceiver >>= rClass.
  	rReceiver := rReceiver | 1.
  	ret
  ovfl
  tooBig
  nonInt:
  	fail"
  	| jumpNotSI jumpOvfl jumpNegative jumpTooBig jumpInRange |
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpOvfl type: #'AbstractInstruction *'>
  	<var: #jumpNegative type: #'AbstractInstruction *'>
  	<var: #jumpTooBig type: #'AbstractInstruction *'>
  	<var: #jumpInRange type: #'AbstractInstruction *'>
  	self assert: self numRegArgs >= 1.
  	self MoveR: Arg0Reg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.
  	objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
  	(self lastOpcode setsConditionCodesFor: JumpNegative) ifFalse:
  		[self CmpCq: 0 R: ClassReg]. "N.B. FLAGS := ClassReg - 0"
  	jumpNegative := self JumpNegative: 0.
  	self CmpCq: objectRepresentation numSmallIntegerBits R: ClassReg. "N.B. FLAGS := ClassReg - 31"
  	jumpTooBig := self JumpGreaterOrEqual: 0.
  	self MoveR: ReceiverResultReg R: TempReg.
  	self LogicalShiftLeftR: ClassReg R: TempReg.
  	self ArithmeticShiftRightR: ClassReg R: TempReg.
  	self CmpR: TempReg R: ReceiverResultReg. "N.B. FLAGS := RRReg - TempReg"
  	jumpOvfl := self JumpNonZero: 0.
  	objectRepresentation genRemoveSmallIntegerTagsInScratchReg: ReceiverResultReg.
  	self LogicalShiftLeftR: ClassReg R: ReceiverResultReg.
  	objectRepresentation genAddSmallIntegerTagsTo: ReceiverResultReg.
  	self RetN: 0.
  	jumpNegative jmpTarget: (self NegateR: ClassReg).
  	self CmpCq: objectRepresentation numSmallIntegerBits R: ClassReg. "N.B. FLAGS := ClassReg - 31"
  	jumpInRange := self JumpLessOrEqual: 0.
  	self MoveCq: objectRepresentation numSmallIntegerBits R: ClassReg.
  	jumpInRange jmpTarget: (self ArithmeticShiftRightR: ClassReg R: ReceiverResultReg).
+ 	objectRepresentation genClearAndSetSmallIntegerTagsIn: ReceiverResultReg.
- 	objectRepresentation genSetSmallIntegerTagsIn: ReceiverResultReg.
  	self RetN: 0.
  	jumpNotSI jmpTarget: (jumpTooBig jmpTarget: (jumpOvfl jmpTarget: self Label)).
  	^0!



More information about the Vm-dev mailing list