[Vm-dev] VM Maker: VMMaker.oscog-cb.1211.mcz

commits at source.squeak.org commits at source.squeak.org
Sat Apr 18 00:28:11 UTC 2015


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

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

Name: VMMaker.oscog-cb.1211
Author: cb
Time: 17 April 2015, 5:26:30.846 pm
UUID: 5bfea133-65e7-4b14-a105-9d71ebc8266a
Ancestors: VMMaker.oscog-eem.1210

Used register allocation in #== with V3 in order to limit register moves.

Use bytecodeSetOffset constant instead of some bitAnd: computation.

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

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genBinaryInlineComparison:opFalse:destReg: (in category 'inline primitive generators') -----
  genBinaryInlineComparison: opTrue opFalse: opFalse destReg: destReg
  	"Inlined comparison. opTrue = jump for true and opFalse = jump for false"
  	| nextPC branchDescriptor nExts |	
  	nextPC := bytecodePC + 3.
  	nExts := 0.	
+ 	[branchDescriptor := self generatorAt: (objectMemory fetchByte: nextPC ofObject: methodObj) + bytecodeSetOffset.
- 	[branchDescriptor := self generatorAt: (objectMemory fetchByte: nextPC ofObject: methodObj) + (byte0 bitAnd: 256).
  	 branchDescriptor isExtension] whileTrue:
  		[nExts := nExts + 1.
  	 	 nextPC := nextPC + branchDescriptor numBytes].
  	(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse])
  		ifTrue: "This is the path where the inlined comparison is followed immediately by a branch"
  			[| targetBytecodePC postBranchPC |
  			targetBytecodePC := nextPC
  					+ branchDescriptor numBytes
  					+ (self spanFor: branchDescriptor at: nextPC exts: nExts in: methodObj).
  			postBranchPC := nextPC + branchDescriptor numBytes.
  			(self fixupAt: nextPC - initialPC) targetInstruction = 0
  				ifTrue: "The next instruction is dead.  we can skip it."
  					[deadCode := true.
  				 	 self ensureFixupAt: targetBytecodePC - initialPC.
  					 self ensureFixupAt: postBranchPC - initialPC ]
  				ifFalse:
  					[self ssPushConstant: objectMemory trueObject]. "dummy value"
  			self gen: (branchDescriptor isBranchTrue ifTrue: [opTrue] ifFalse: [opFalse])
  				operand: (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger. 
  			deadCode ifFalse: [ self Jump: (self ensureNonMergeFixupAt: postBranchPC - initialPC) ] ]
  		ifFalse: "This is the path where the inlined comparison is *not* followed immediately by a branch"
  			[| condJump jump |
  			condJump := self gen: opTrue operand: 0.
  			self genMoveFalseR: destReg.
  	 		jump := self Jump: 0.
  			condJump jmpTarget: (self genMoveTrueR: destReg).
  			jump jmpTarget: self Label].
  	^ 0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genSpecialSelectorEqualsEqualsWithForwarders (in category 'bytecode generators') -----
  genSpecialSelectorEqualsEqualsWithForwarders
  	| primDescriptor nextPC nExts branchDescriptor unforwardRcvr argReg targetBytecodePC
  	unforwardArg  rcvrReg jumpNotEqual jumpEqual postBranchPC label fixup |
  	<var: #jumpEqual type: #'AbstractInstruction *'>
  	<var: #jumpNotEqual type: #'AbstractInstruction *'>
  	<var: #primDescriptor type: #'BytecodeDescriptor *'>
  	<var: #branchDescriptor type: #'BytecodeDescriptor *'>
  	
  	primDescriptor := self generatorAt: byte0.
  
  	nextPC := bytecodePC + primDescriptor numBytes.
  	nExts := 0.
+ 	[branchDescriptor := self generatorAt: (objectMemory fetchByte: nextPC ofObject: methodObj) + bytecodeSetOffset.
- 	[branchDescriptor := self generatorAt: (objectMemory fetchByte: nextPC ofObject: methodObj) + (byte0 bitAnd: 256).
  	 branchDescriptor isExtension] whileTrue:
  		[nExts := nExts + 1.
  		 nextPC := nextPC + branchDescriptor numBytes].
  	"If branching the stack must be flushed for the merge"
  	(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifTrue:
  		[self ssFlushTo: simStackPtr - 2].
  
  	unforwardRcvr := (objectRepresentation isUnannotatableConstant: (self ssValue: 1)) not.
  	unforwardArg := (objectRepresentation isUnannotatableConstant: self ssTop) not.
  
  	"if the rcvr or the arg is an annotable constant, we need to push it to a register 
  	else the forwarder check can't jump back to the comparison after unforwarding the constant"
  	unforwardArg
  		ifTrue: 
  			[unforwardRcvr
  				ifTrue:
  					[self allocateTwoRegistersInto: [:rTop :rNext| argReg := rTop. rcvrReg := rNext].
  					 self ssTop popToReg: argReg.
  					 (self ssValue:1) popToReg: rcvrReg]
  				ifFalse:
  					[argReg := self allocateOneRegister.
  					 self ssTop popToReg: argReg]]
  		ifFalse:
  			[self assert: unforwardRcvr.
  			 rcvrReg := self allocateOneRegister.
  			 (self ssValue:1) popToReg: rcvrReg].
  
  	label := self Label.
  	
  	"Here we can use Cq because the constant does not need to be annotated"
  	self assert: (unforwardArg not or: [argReg notNil]).
  	self assert: (unforwardRcvr not or: [rcvrReg notNil]).
  	unforwardArg 
  		ifFalse: [ self CmpCq: self ssTop constant R: rcvrReg ]
  		ifTrue: [ unforwardRcvr
  			ifFalse: [ self CmpCq: (self ssValue: 1) constant R: argReg ]
  			ifTrue: [ self CmpR: argReg R: rcvrReg ] ].
  			 
  	self ssPop: 2.
  
  	"If not followed by a branch, resolve to true or false."
  	(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifFalse:
  		[jumpEqual := self JumpZero: 0.
  		 unforwardArg ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: argReg scratchReg: TempReg jumpBackTo: label ].
  		 unforwardRcvr ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: rcvrReg scratchReg: TempReg jumpBackTo: label ].
  		 self genMoveFalseR: rcvrReg.
  		 jumpNotEqual := self Jump: 0.
  		 jumpEqual jmpTarget: (self genMoveTrueR: rcvrReg).
  		 jumpNotEqual jmpTarget: self Label.
  		 self ssPushRegister: rcvrReg.
  		 ^0].
  
  	"Further since there is a following conditional jump bytecode, define
  	 non-merge fixups and leave the cond bytecode to set the mergeness."
  	targetBytecodePC := nextPC
  							+ branchDescriptor numBytes
  							+ (self spanFor: branchDescriptor at: nextPC exts: nExts in: methodObj).
  	postBranchPC := nextPC + branchDescriptor numBytes.
  	(self fixupAt: nextPC - initialPC) targetInstruction = 0
  		ifTrue: "The next instruction is dead.  we can skip it."
  			[deadCode := true.
  		 	 self ensureFixupAt: targetBytecodePC - initialPC.
  			 self ensureFixupAt: postBranchPC - initialPC]
  		ifFalse:
  			[self ssPushConstant: objectMemory trueObject]. "dummy value"
  
  	self assert: (unforwardArg or: [ unforwardRcvr ]).
  	branchDescriptor isBranchTrue ifTrue: 
  		[ deadCode ifFalse: [ fixup := self ensureNonMergeFixupAt: postBranchPC - initialPC ].
  		self JumpZero:  (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
  		unforwardArg ifTrue: [ (deadCode or: [ unforwardRcvr ]) 
  			ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: argReg scratchReg: TempReg jumpBackTo: label ]
  			ifFalse: [ objectRepresentation 
  				genEnsureOopInRegNotForwarded: argReg 
  				scratchReg: TempReg 
  				ifForwarder: label
  				ifNotForwarder: fixup ] ].
  		unforwardRcvr ifTrue: [ deadCode 
  			ifTrue: [objectRepresentation genEnsureOopInRegNotForwarded: rcvrReg scratchReg: TempReg jumpBackTo: label ]
  			ifFalse: [objectRepresentation 
  				genEnsureOopInRegNotForwarded: rcvrReg 
  				scratchReg: TempReg 
  				ifForwarder: label
  				ifNotForwarder: fixup ] ] ].
  	branchDescriptor isBranchFalse ifTrue: 
  		[ fixup := (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
  		self JumpZero: (self ensureNonMergeFixupAt: postBranchPC - initialPC).
  		unforwardArg ifTrue: [ unforwardRcvr 
  			ifFalse: [objectRepresentation 
  				genEnsureOopInRegNotForwarded: argReg 
  				scratchReg: TempReg 
  				ifForwarder: label
  				ifNotForwarder: fixup ]
  			ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: rcvrReg scratchReg: TempReg jumpBackTo: label ] ].
  		unforwardRcvr ifTrue: 
  			[ objectRepresentation 
  				genEnsureOopInRegNotForwarded: rcvrReg 
  				scratchReg: TempReg 
  				ifForwarder: label
  				ifNotForwarder: fixup ].
  		"Not reached"].
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genVanillaSpecialSelectorEqualsEquals (in category 'bytecode generators') -----
  genVanillaSpecialSelectorEqualsEquals
  	| nextPC postBranchPC targetBytecodePC primDescriptor branchDescriptor nExts
  	  jumpEqual jumpNotEqual rcvrReg argReg argIsConstant rcvrIsConstant  |
  	<var: #jumpEqual type: #'AbstractInstruction *'>
  	<var: #jumpNotEqual type: #'AbstractInstruction *'>
  	<var: #primDescriptor type: #'BytecodeDescriptor *'>
  	<var: #branchDescriptor type: #'BytecodeDescriptor *'>
  	primDescriptor := self generatorAt: byte0.
  
  	nextPC := bytecodePC + primDescriptor numBytes.
  	nExts := 0.
  	[branchDescriptor := self generatorAt: (objectMemory fetchByte: nextPC ofObject: methodObj) + bytecodeSetOffset.
  	 branchDescriptor isExtension] whileTrue:
  		[nExts := nExts + 1.
  		 nextPC := nextPC + branchDescriptor numBytes].
  	"If branching the stack must be flushed for the merge"
  	(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifTrue:
  		[self ssFlushTo: simStackPtr - 2].
  
  	"Don't use ReceiverResultReg for receiver to keep ReceiverResultReg live.
  	 Optimize e.g. rcvr == nil, the common case for ifNil: et al."
  	
  	argIsConstant := self ssTop type = SSConstant.
  	rcvrIsConstant := argIsConstant and: [ (self ssValue:1) type = SSConstant ].
  	
+ 	argIsConstant
+ 		ifFalse: 
+ 			[rcvrIsConstant
+ 				ifFalse:
+ 					[self allocateTwoRegistersInto: [:rTop :rNext| argReg := rTop. rcvrReg := rNext].
+ 					 self ssTop popToReg: argReg.
+ 					 (self ssValue:1) popToReg: rcvrReg]
+ 				ifTrue:
+ 					[argReg := self allocateOneRegister.
+ 					 self ssTop popToReg: argReg]]
+ 		ifTrue:
+ 			[self assert: rcvrIsConstant not.
+ 			 rcvrReg := self allocateOneRegister.
+ 			 (self ssValue:1) popToReg: rcvrReg].
- 	needsFrame "If frameless, arg0 and arg1 may be live"
- 		ifTrue: [argReg := Arg0Reg. rcvrReg := Arg1Reg]
- 		ifFalse: [argReg := ClassReg. rcvrReg := SendNumArgsReg].
- 	argIsConstant ifFalse: 
- 		[self ssAllocateRequiredReg: argReg upThrough: simStackPtr - 1.
- 		self ssTop popToReg: argReg].
- 	rcvrIsConstant ifFalse: 
- 		[ self ssAllocateRequiredReg: rcvrReg upThrough: simStackPtr - 2.
- 		(self ssValue:1) popToReg: rcvrReg.].
  	
  	argIsConstant 
  		ifTrue: [ self genCompConstant: self ssTop constant R: rcvrReg ]
  		ifFalse: [ rcvrIsConstant
  			ifTrue: [ self genCompConstant: (self ssValue: 1) constant R: argReg ]
  			ifFalse: [ self CmpR: argReg R: rcvrReg ] ].
  		
  	self ssPop: 2.
  
  	"If not followed by a branch, resolve to true or false."
  	(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifFalse:
  		[jumpNotEqual := self JumpNonZero: 0.
  		 self genMoveTrueR: rcvrReg.
  		 jumpEqual := self Jump: 0.
  		 jumpNotEqual jmpTarget: (self genMoveFalseR: rcvrReg).
  		 jumpEqual jmpTarget: self Label.
  		 self ssPushRegister: rcvrReg.
  		 ^0].
  
  	"Further since there is a following conditional jump bytecode, define
  	 non-merge fixups and leave the cond bytecode to set the mergeness."
  	targetBytecodePC := nextPC
  							+ branchDescriptor numBytes
  							+ (self spanFor: branchDescriptor at: nextPC exts: nExts in: methodObj).
  	postBranchPC := nextPC + branchDescriptor numBytes.
  	(self fixupAt: nextPC - initialPC) targetInstruction = 0
  		ifTrue: "The next instruction is dead.  we can skip it."
  			[deadCode := true.
  		 	 self ensureFixupAt: targetBytecodePC - initialPC.
  			 self ensureFixupAt: postBranchPC - initialPC]
  		ifFalse:
  			[self ssPushConstant: objectMemory trueObject]. "dummy value"
  	self gen: (branchDescriptor isBranchTrue ifTrue: [JumpZero] ifFalse: [JumpNonZero])
  		operand: (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
  		deadCode ifFalse: [self Jump: (self ensureNonMergeFixupAt: postBranchPC - initialPC)].
  	^0!



More information about the Vm-dev mailing list