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

commits at source.squeak.org commits at source.squeak.org
Tue Apr 5 02:15:54 UTC 2016


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

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

Name: VMMaker.oscog-cb.1759
Author: cb
Time: 4 April 2016, 7:13:25.535 pm
UUID: 050913c6-bc84-4445-a1b6-fd0380dfb596
Ancestors: VMMaker.oscog-nice.1758

Added support in the JIT for:
- mustbeboolean flag no generating the mustBeBoolean trampoline if the optimizer can prove it does not happen.
- storecheck flag avoiding the storeCheck if the optimizer can prove the value to store is an immediate, nil, true or false.
- remote temporary bytecode allowing remote inst var access in the SistaV1 bytecode set.

=============== Diff against VMMaker.oscog-nice.1758 ===============

Item was changed:
  ----- Method: SimpleStackBasedCogit class>>initializeBytecodeTableForSistaV1 (in category 'class initialization') -----
  initializeBytecodeTableForSistaV1
  	"SimpleStackBasedCogit initializeBytecodeTableForSistaV1"
  
  	BytecodeSetHasDirectedSuperSend := true.
  	FirstSpecialSelector := 96.
  	NumSpecialSelectors := 32.
  	self flag:
  'Special selector send class must be inlined to agree with the interpreter, which
   inlines class.  If class is sent to e.g. a general instance of ProtoObject then unless
   class is inlined there will be an MNU.  It must be that the Cointerpreter and Cogit
   have identical semantics.  We get away with not hardwiring the other special
   selectors either because in the Cointerpreter they are not inlined or because they
   are inlined only to instances of classes for which there will always be a method.'.
  	self generatorTableFrom: #(
  		"1 byte bytecodes"
  		"pushes"
  		(1    0   15 genPushReceiverVariableBytecode isInstVarRef)
  		(1  16   31 genPushLiteralVariable16CasesBytecode	needsFrameNever: 1)
  		(1  32   63 genPushLiteralConstantBytecode			needsFrameNever: 1)
  		(1  64   75 genPushTemporaryVariableBytecode)
  		(1  76   76 genPushReceiverBytecode)
  		(1  77   77 genPushConstantTrueBytecode				needsFrameNever: 1)
  		(1  78   78 genPushConstantFalseBytecode			needsFrameNever: 1)
  		(1  79   79 genPushConstantNilBytecode				needsFrameNever: 1)
  		(1  80   80 genPushConstantZeroBytecode				needsFrameNever: 1)
  		(1  81   81 genPushConstantOneBytecode				needsFrameNever: 1)
  		(1  82   82 genExtPushPseudoVariable)
  		(1  83   83 duplicateTopBytecode						needsFrameNever: 1)
  
  		(1  84   87 unknownBytecode)
  
  		"returns"
  		(1  88   88 genReturnReceiver				return needsFrameIfInBlock: isMappedInBlock 0)
  		(1  89   89 genReturnTrue					return needsFrameIfInBlock: isMappedInBlock 0)
  		(1  90   90 genReturnFalse					return needsFrameIfInBlock: isMappedInBlock 0)
  		(1  91   91 genReturnNil					return needsFrameIfInBlock: isMappedInBlock 0)
  		(1  92   92 genReturnTopFromMethod		return needsFrameIfInBlock: isMappedInBlock -1)
  		(1  93   93 genReturnNilFromBlock			return needsFrameNever: -1)
  		(1  94   94 genReturnTopFromBlock		return needsFrameNever: -1)
  		(1  95   95 genExtNopBytecode			needsFrameNever: 0)
  
  		"sends"
  		(1   96 117 genSpecialSelectorSend isMapped) "#+ #- #< #> #<= #>= #= #~= #* #/ #\\ #@ #bitShift: #// #bitAnd: #bitOr: #at: #at:put: #size #next #nextPut: #atEnd"
  		(1 118 118 genSpecialSelectorEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
  		(1 119 119 genSpecialSelectorClass needsFrameNever: notMapped 0) "not mapped because it is directly inlined (for now)"
  		(1 120 127 genSpecialSelectorSend isMapped) "#blockCopy: #value #value: #do: #new #new: #x #y"
  
  		(1 128 143 genSendLiteralSelector0ArgsBytecode isMapped)
  		(1 144 159 genSendLiteralSelector1ArgBytecode isMapped)
  		(1 160 175 genSendLiteralSelector2ArgsBytecode isMapped)
  
  		"jumps"
  		(1 176 183 genShortUnconditionalJump	branch v3:ShortForward:Branch:Distance:)
  		(1 184 191 genShortJumpIfTrue			branch isBranchTrue isMapped "because of mustBeBoolean"
  													v3:ShortForward:Branch:Distance:)
  		(1 192 199 genShortJumpIfFalse			branch isBranchFalse isMapped "because of mustBeBoolean"
  													v3:ShortForward:Branch:Distance:)
  
  		"stores"
  		(1 200 207 genStoreAndPopReceiverVariableBytecode isInstVarRef isMappedIfImmutability needsFrameIfImmutability: -1)
  		(1 208 215 genStoreAndPopTemporaryVariableBytecode)
  
  		(1 216 216 genPopStackBytecode needsFrameNever: -1)
  
  		(1 217 217 genUnconditionalTrapBytecode isMapped)
  
  		(1 218 223 unknownBytecode)
  
  		"2 byte bytecodes"
  		(2 224 224 extABytecode extension)
  		(2 225 225 extBBytecode extension)
  
  		"pushes"
  		(2 226 226 genExtPushReceiverVariableBytecode isInstVarRef)		"Needs a frame for context inst var access"
  		(2 227 227 genExtPushLiteralVariableBytecode		needsFrameNever: 1)
  		(2 228 228 genExtPushLiteralBytecode					needsFrameNever: 1)
  		(2 229 229 genLongPushTemporaryVariableBytecode)
  		(2 230 230 genPushClosureTempsBytecode)
  		(2 231 231 genPushNewArrayBytecode)
  		(2 232 232 genExtPushIntegerBytecode				needsFrameNever: 1)
  		(2 233 233 genExtPushCharacterBytecode				needsFrameNever: 1)
  
  		"returns"
  		"sends"
  		(2 234 234 genExtSendBytecode isMapped)
  		(2 235 235 genExtSendSuperBytecode isMapped)
  
  		"sista bytecodes"
  		(2 236 236 unknownBytecode)
  
  		"jumps"
  		(2 237 237 genExtUnconditionalJump	branch isMapped "because of interrupt check" v4:Long:Branch:Distance:)
  		(2 238 238 genExtJumpIfTrue			branch isBranchTrue isMapped "because of mustBeBoolean" v4:Long:Branch:Distance:)
  		(2 239 239 genExtJumpIfFalse			branch isBranchFalse isMapped "because of mustBeBoolean" v4:Long:Branch:Distance:)
  
  		"stores"
  		(2 240 240 genExtStoreAndPopReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
  		(2 241 241 genExtStoreAndPopLiteralVariableBytecode isMappedIfImmutability)
  		(2 242 242 genLongStoreAndPopTemporaryVariableBytecode)
  		(2 243 243 genExtStoreReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
  		(2 244 244 genExtStoreLiteralVariableBytecode isMappedIfImmutability)
  		(2 245 245 genLongStoreTemporaryVariableBytecode)
  
  		(2 246 247	unknownBytecode)
  
  		"3 byte bytecodes"
  		(3 248 248 genCallPrimitiveBytecode)
  		(3 249 249 unknownBytecode) "reserved for Push Float"
  		(3 250 250 genExtPushClosureBytecode block v4:Block:Code:Size:)
+ 		(3 251 251 genPushRemoteTempOrRemoteInstVarLongBytecode)
+ 		(3 252 252 genStoreRemoteTempOrRemoteInstVarLongBytecode)
+ 		(3 253 253 genStoreAndPopRemoteTempOrRemoteInstVarLongBytecode)
- 		(3 251 251 genPushRemoteTempLongBytecode)
- 		(3 252 252 genStoreRemoteTempLongBytecode)
- 		(3 253 253 genStoreAndPopRemoteTempLongBytecode)
  
  		(3 254 254	genExtJumpIfNotInstanceOfBehaviorsOrPopBytecode)
  			
  		(3 255 255	unknownBytecode))!

Item was added:
+ ----- Method: SimpleStackBasedCogit>>genPushRemoteInstVarLongBytecode (in category 'bytecode generators') -----
+ genPushRemoteInstVarLongBytecode
+ 	self MoveMw: (self frameOffsetOfTemporary: byte2 - (1 << 7)) r: FPReg R: ClassReg.
+ 	objectRepresentation 
+ 		genEnsureOopInRegNotForwarded: ClassReg 
+ 		scratchReg: TempReg.
+ 	objectRepresentation
+ 		genLoadSlot: byte1
+ 		sourceReg: ClassReg
+ 		destReg: TempReg.
+ 	self PushR: TempReg.
+ 	^0!

Item was added:
+ ----- Method: SimpleStackBasedCogit>>genPushRemoteTempOrRemoteInstVarLongBytecode (in category 'bytecode generators') -----
+ genPushRemoteTempOrRemoteInstVarLongBytecode
+ 	^ (byte2 noMask: 1 << 7)
+ 		ifTrue: [ self genPushRemoteTempLongBytecode ]
+ 		ifFalse: [ self genPushRemoteInstVarLongBytecode ]!

Item was added:
+ ----- Method: SimpleStackBasedCogit>>genStoreAndPopRemoteTempOrRemoteInstVarLongBytecode (in category 'bytecode generators') -----
+ genStoreAndPopRemoteTempOrRemoteInstVarLongBytecode
+ 	^ (byte2 noMask: 1 << 7)
+ 		ifTrue: [ self genStorePop: true RemoteTemp: byte1 At: byte2 ]
+ 		ifFalse: [ self genStorePop: true RemoteInstVar: byte1 At: byte2 - (1 << 7) ]!

Item was added:
+ ----- Method: SimpleStackBasedCogit>>genStorePop:RemoteInstVar:At: (in category 'bytecode generator support') -----
+ genStorePop: popBoolean RemoteInstVar: slotIndex At: objectIndex 
+ 	<inline: false>
+ 	"The only reason we assert needsFrame here is that in a frameless method
+ 	 ReceiverResultReg must and does contain only self, but the ceStoreCheck
+ 	 trampoline expects the target of the store to be in ReceiverResultReg.  So
+ 	 in a frameless method we would have a conflict between the receiver and
+ 	 the temote temp store, unless we we smart enough to realise that
+ 	 ReceiverResultReg was unused after the literal variable store, unlikely given
+ 	 that methods return self by default."
+ 	self assert: needsFrame.
+ 	popBoolean
+ 		ifTrue: [self PopR: ClassReg]
+ 		ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].
+ 	self MoveMw: (self frameOffsetOfTemporary: objectIndex) r: FPReg R: ReceiverResultReg.
+ 	objectRepresentation 
+ 		genEnsureOopInRegNotForwarded: ReceiverResultReg 
+ 		scratchReg: TempReg.
+ 	^objectRepresentation
+ 		genStoreSourceReg: ClassReg
+ 		slotIndex: slotIndex
+ 		destReg: ReceiverResultReg
+ 		scratchReg: TempReg
+ 		inFrame: needsFrame!

Item was added:
+ ----- Method: SimpleStackBasedCogit>>genStoreRemoteTempOrRemoteInstVarLongBytecode (in category 'bytecode generators') -----
+ genStoreRemoteTempOrRemoteInstVarLongBytecode
+ 	^ (byte2 noMask: 1 << 7)
+ 		ifTrue: [ self genStorePop: false RemoteTemp: byte1 At: byte2 ]
+ 		ifFalse: [ self genStorePop: false RemoteInstVar: byte1 At: byte2 - (1 << 7) ]!

Item was changed:
  ----- Method: StackToRegisterMappingCogit class>>initializeBytecodeTableForSistaV1 (in category 'class initialization') -----
  initializeBytecodeTableForSistaV1
  	"StackToRegisterMappingCogit initializeBytecodeTableForSistaV1"
  
  	numPushNilsFunction := #sistaV1:Num:Push:Nils:.
  	pushNilSizeFunction := #sistaV1PushNilSize:numInitialNils:.
  	BytecodeSetHasDirectedSuperSend := true.
  	FirstSpecialSelector := 96.
  	NumSpecialSelectors := 32.
  	self flag:
  'Special selector send class must be inlined to agree with the interpreter, which
   inlines class.  If class is sent to e.g. a general instance of ProtoObject then unless
   class is inlined there will be an MNU.  It must be that the Cointerpreter and Cogit
   have identical semantics.  We get away with not hardwiring the other special
   selectors either because in the Cointerpreter they are not inlined or because they
   are inlined only to instances of classes for which there will always be a method.'.
  	self generatorTableFrom: #(
  		"1 byte bytecodes"
  		"pushes"
  		(1    0   15 genPushReceiverVariableBytecode isInstVarRef		needsFrameNever: 1)
  		(1  16   31 genPushLitVarDirSup16CasesBytecode				needsFrameNever: 1)
  		(1  32   63 genPushLiteralConstantBytecode					needsFrameNever: 1)
  		(1  64   75 genPushTemporaryVariableBytecode				needsFrameIfMod16GENumArgs: 1)
  		(1  76   76 genPushReceiverBytecode							needsFrameNever: 1)
  		(1  77   77 genPushConstantTrueBytecode						needsFrameNever: 1)
  		(1  78   78 genPushConstantFalseBytecode					needsFrameNever: 1)
  		(1  79   79 genPushConstantNilBytecode						needsFrameNever: 1)
  		(1  80   80 genPushConstantZeroBytecode						needsFrameNever: 1)
  		(1  81   81 genPushConstantOneBytecode						needsFrameNever: 1)
  		(1  82   82 genExtPushPseudoVariable)
  		(1  83   83 duplicateTopBytecode								needsFrameNever: 1)
  
  		(1  84   87 unknownBytecode)
  
  		"returns"
  		(1  88   88 genReturnReceiver				return needsFrameIfInBlock: isMappedInBlock 0)
  		(1  89   89 genReturnTrue					return needsFrameIfInBlock: isMappedInBlock 0)
  		(1  90   90 genReturnFalse					return needsFrameIfInBlock: isMappedInBlock 0)
  		(1  91   91 genReturnNil					return needsFrameIfInBlock: isMappedInBlock 0)
  		(1  92   92 genReturnTopFromMethod		return needsFrameIfInBlock: isMappedInBlock -1)
  		(1  93   93 genReturnNilFromBlock			return needsFrameNever: -1)
  		(1  94   94 genReturnTopFromBlock		return needsFrameNever: -1)
  		(1  95   95 genExtNopBytecode			needsFrameNever: 0)
  
  		"sends"
  		(1  96   96 genSpecialSelectorArithmetic isMapped AddRR)
  		(1  97   97 genSpecialSelectorArithmetic isMapped SubRR)
  		(1  98   98 genSpecialSelectorComparison isMapped JumpLess)
  		(1  99   99 genSpecialSelectorComparison isMapped JumpGreater)
  		(1 100 100 genSpecialSelectorComparison isMapped JumpLessOrEqual)
  		(1 101 101 genSpecialSelectorComparison isMapped JumpGreaterOrEqual)
  		(1 102 102 genSpecialSelectorComparison isMapped JumpZero)
  		(1 103 103 genSpecialSelectorComparison isMapped JumpNonZero)
  		(1 104 109 genSpecialSelectorSend isMapped)	 " #* #/ #\\ #@ #bitShift: //"
  		(1 110 110 genSpecialSelectorArithmetic isMapped AndRR)
  		(1 111 111 genSpecialSelectorArithmetic isMapped OrRR)
  		(1 112 117 genSpecialSelectorSend isMapped) "#at: #at:put: #size #next #nextPut: #atEnd"
  		(1 118 118 genSpecialSelectorEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
  		(1 119 119 genSpecialSelectorClass needsFrameIfStackGreaterThanOne: notMapped 0) "not mapped because it is directly inlined (for now)"
  		(1 120 127 genSpecialSelectorSend isMapped) "#blockCopy: #value #value: #do: #new #new: #x #y"
  
  		(1 128 143 genSendLiteralSelector0ArgsBytecode isMapped)
  		(1 144 159 genSendLiteralSelector1ArgBytecode isMapped)
  		(1 160 175 genSendLiteralSelector2ArgsBytecode isMapped)
  
  		"jumps"
  		(1 176 183 genShortUnconditionalJump	branch v3:ShortForward:Branch:Distance:)
  		(1 184 191 genShortJumpIfTrue			branch isBranchTrue isMapped "because of mustBeBoolean"
  													v3:ShortForward:Branch:Distance:)
  		(1 192 199 genShortJumpIfFalse			branch isBranchFalse isMapped "because of mustBeBoolean"
  													v3:ShortForward:Branch:Distance:)
  		(1 200 207 genStoreAndPopReceiverVariableBytecode isInstVarRef isMappedIfImmutability needsFrameIfImmutability: -1)
  		
  		(1 208 215 genStoreAndPopTemporaryVariableBytecode)
  
  		(1 216 216 genPopStackBytecode needsFrameNever: -1)
  
  		(1 217 217 genUnconditionalTrapBytecode isMapped)
  
  		(1 218 223 unknownBytecode)
  
  		"2 byte bytecodes"
  		(2 224 224 extABytecode extension)
  		(2 225 225 extBBytecode extension)
  
  		"pushes"
  		(2 226 226 genExtPushReceiverVariableBytecode isInstVarRef)		"Needs a frame for context inst var access"
  		(2 227 227 genExtPushLitVarDirSupBytecode			needsFrameNever: 1)
  		(2 228 228 genExtPushLiteralBytecode					needsFrameNever: 1)
  		(2 229 229 genLongPushTemporaryVariableBytecode)
  		(2 230 230 genPushClosureTempsBytecode)
  		(2 231 231 genPushNewArrayBytecode)
  		(2 232 232 genExtPushIntegerBytecode				needsFrameNever: 1)
  		(2 233 233 genExtPushCharacterBytecode				needsFrameNever: 1)
  
  		"returns"
  		"sends"
  		(2 234 234 genExtSendBytecode isMapped)
  		(2 235 235 genExtSendSuperBytecode isMapped)
  
  		"sista bytecodes"
  		(2 236 236 unknownBytecode)
  
  		"jumps"
  		(2 237 237 genExtUnconditionalJump	branch isMapped "because of interrupt check" v4:Long:Branch:Distance:)
  		(2 238 238 genExtJumpIfTrue			branch isBranchTrue isMapped "because of mustBeBoolean" v4:Long:Branch:Distance:)
  		(2 239 239 genExtJumpIfFalse			branch isBranchFalse isMapped "because of mustBeBoolean" v4:Long:Branch:Distance:)
  
  		"stores"
  		(2 240 240 genExtStoreAndPopReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
  		(2 241 241 genExtStoreAndPopLiteralVariableBytecode isMappedIfImmutability)
  		(2 242 242 genLongStoreAndPopTemporaryVariableBytecode)
  		(2 243 243 genExtStoreReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
  		(2 244 244 genExtStoreLiteralVariableBytecode isMappedIfImmutability)
  		(2 245 245 genLongStoreTemporaryVariableBytecode)
  
  		(2 246 247	unknownBytecode)
  
  		"3 byte bytecodes"
  		(3 248 248 genCallPrimitiveBytecode)
  		(3 249 249 unknownBytecode) "reserved for Push Float"
  		(3 250 250 genExtPushClosureBytecode block v4:Block:Code:Size:)
+ 		(3 251 251 genPushRemoteTempOrRemoteInstVarLongBytecode)
+ 		(3 252 252 genStoreRemoteTempOrRemoteInstVarLongBytecode)
+ 		(3 253 253 genStoreAndPopRemoteTempOrRemoteInstVarLongBytecode)
- 		(3 251 251 genPushRemoteTempLongBytecode)
- 		(3 252 252 genStoreRemoteTempLongBytecode)
- 		(3 253 253 genStoreAndPopRemoteTempLongBytecode)
  
  		(3 254 254	genExtJumpIfNotInstanceOfBehaviorsOrPopBytecode branch v4:Long:BranchIfNotInstanceOf:Distance:)
  		
  		(3 255 255	unknownBytecode))!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genImmutabilityCheckStorePop:LiteralVariable: (in category 'bytecode generator support') -----
  genImmutabilityCheckStorePop: popBoolean LiteralVariable: litVarIndex
  	<inline: true>
  	| association needStoreCheck |
  	"The only reason we assert needsFrame here is that in a frameless method
  	 ReceiverResultReg must and does contain only self, but the ceStoreCheck
  	 trampoline expects the target of the store to be in ReceiverResultReg.  So
  	 in a frameless method we would have a conflict between the receiver and
  	 the literal store, unless we we smart enough to realise that ReceiverResultReg
  	 was unused after the literal variable store, unlikely given that methods
  	 return self by default."
  	self assert: needsFrame.
  	"N.B.  No need to check the stack for references because we generate code for
  	 literal variable loads that stores the result in a register, deferring only the register push."
+ 	needStoreCheck := self ssTopNeedsStoreCheck.
- 	needStoreCheck := (objectRepresentation isUnannotatableConstant: self ssTop) not.
  	association := self getLiteral: litVarIndex.
  	optStatus isReceiverResultRegLive: false.
  	self ssAllocateRequiredReg: ReceiverResultReg. "for store trampoline call in genStoreSourceReg: has to be ReceiverResultReg"
  	self genMoveConstant: association R: ReceiverResultReg.
  	objectRepresentation genEnsureObjInRegNotForwarded: ReceiverResultReg scratchReg: TempReg.
  	self ssAllocateRequiredReg: ClassReg.
  	self ssStoreAndReplacePop: popBoolean toReg: ClassReg.
  	self ssFlushTo: simStackPtr.
  	objectRepresentation 
  		genStoreWithImmutabilityCheckSourceReg: ClassReg 
  		slotIndex: ValueIndex 
  		destReg: ReceiverResultReg 
  		scratchReg: TempReg 
  		needsStoreCheck: needStoreCheck 
  		needRestoreRcvr: false.
  	^ 0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genImmutabilityCheckStorePop:MaybeContextReceiverVariable: (in category 'bytecode generator support') -----
  genImmutabilityCheckStorePop: popBoolean MaybeContextReceiverVariable: slotIndex
  	<inline: true>
  	| jmpSingle jmpDone needStoreCheck |
  	<var: #jmpSingle type: #'AbstractInstruction *'>
  	<var: #jmpDone type: #'AbstractInstruction *'>
  	"The reason we need a frame here is that assigning to an inst var of a context may
  	 involve wholesale reorganization of stack pages, and the only way to preserve the
  	 execution state of an activation in that case is if it has a frame."
  	self assert: needsFrame.
+ 	needStoreCheck := self ssTopNeedsStoreCheck.
- 	needStoreCheck := (objectRepresentation isUnannotatableConstant: self ssTop) not.
  	"Note that ReceiverResultReg remains live after both
  	 ceStoreContextInstVarTrampoline and ceStoreCheckTrampoline."
  	self ensureReceiverResultRegContainsSelf.
  	self ssPop: 1.
  	self ssAllocateCallReg: ClassReg and: SendNumArgsReg. "for ceStoreContextInstVarTrampoline"
  	self ssPush: 1.
  	objectRepresentation
  		genLoadSlot: SenderIndex
  		sourceReg: ReceiverResultReg
  		destReg: TempReg.
  	self ssStoreAndReplacePop: popBoolean toReg: ClassReg.
  	"stack is flushed except maybe ssTop if popBoolean is false.
  	  ssTop is a SSregister in this case due to #ssStoreAndReplacePop:
  	  to avoid a second indirect read / annotation in case of SSConstant
  	  or SSBaseRegister"
  	self ssFlushTo: simStackPtr.
  	jmpSingle := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	self MoveCq: slotIndex R: SendNumArgsReg.
  	self CallRT: ceStoreContextInstVarTrampoline.
  	jmpDone := self Jump: 0.
  	jmpSingle jmpTarget: self Label.
  	objectRepresentation 
  		genStoreWithImmutabilityCheckSourceReg: ClassReg 
  		slotIndex: slotIndex 
  		destReg: ReceiverResultReg 
  		scratchReg: TempReg 
  		needsStoreCheck: needStoreCheck 
  		needRestoreRcvr: true.
  	jmpDone jmpTarget: self Label.
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genImmutabilityCheckStorePop:ReceiverVariable: (in category 'bytecode generator support') -----
  genImmutabilityCheckStorePop: popBoolean ReceiverVariable: slotIndex
  	<inline: true>
  	| needStoreCheck |
  	self assert: needsFrame. 
+ 	needStoreCheck := self ssTopNeedsStoreCheck.
- 	needStoreCheck := (objectRepresentation isUnannotatableConstant: self ssTop) not.
  	"Note that ReceiverResultReg remains live after the trampoline."
  	self ensureReceiverResultRegContainsSelf.
  	self ssAllocateRequiredReg: ClassReg.
  	self ssStoreAndReplacePop: popBoolean toReg: ClassReg.
  	self ssFlushTo: simStackPtr.
  	objectRepresentation 
  		genStoreWithImmutabilityCheckSourceReg: ClassReg 
  		slotIndex: slotIndex 
  		destReg: ReceiverResultReg 
  		scratchReg: TempReg 
  		needsStoreCheck: needStoreCheck 
  		needRestoreRcvr: true.
  		
  	^ 0!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genImmutabilityCheckStorePop:RemoteInstVar:At: (in category 'bytecode generator support') -----
+ genImmutabilityCheckStorePop: popBoolean RemoteInstVar: slotIndex At: objectIndex 
+ 	<inline: true>
+ 	| needStoreCheck |
+ 	self assert: needsFrame. 
+ 	needStoreCheck := self ssTopNeedsStoreCheck.
+ 	
+ 	self ssAllocateRequiredReg: ReceiverResultReg. 
+ 	optStatus isReceiverResultRegLive: false.
+ 	self MoveMw: (self frameOffsetOfTemporary: objectIndex) r: FPReg R: ReceiverResultReg.
+ 	
+ 	self ssAllocateRequiredReg: ClassReg.
+ 	self ssStoreAndReplacePop: popBoolean toReg: ClassReg.
+ 	self ssFlushTo: simStackPtr.
+ 	
+ 	objectRepresentation 
+ 		genEnsureOopInRegNotForwarded: ReceiverResultReg 
+ 		scratchReg: TempReg.
+ 	
+ 	objectRepresentation 
+ 		genStoreWithImmutabilityCheckSourceReg: ClassReg 
+ 		slotIndex: slotIndex 
+ 		destReg: ReceiverResultReg 
+ 		scratchReg: TempReg 
+ 		needsStoreCheck: needStoreCheck 
+ 		needRestoreRcvr: false.
+ 	^ 0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genJumpIf:to: (in category 'bytecode generator support') -----
  genJumpIf: boolean to: targetBytecodePC
  	<inline: false>
  	| desc fixup ok |
  	<var: #desc type: #'CogSimStackEntry *'>
  	<var: #fixup type: #'BytecodeFixup *'>
  	<var: #ok type: #'AbstractInstruction *'>
  	self ssFlushTo: simStackPtr - 1.
  	desc := self ssTop.
  	self ssPop: 1.
  	(desc type == SSConstant
  	 and: [desc constant = objectMemory trueObject or: [desc constant = objectMemory falseObject]]) ifTrue:
  		["Must arrange there's a fixup at the target whether it is jumped to or
  		  not so that the simStackPtr can be kept correct."
  		 fixup := self ensureFixupAt: targetBytecodePC - initialPC.
  		 "Must enter any annotatedConstants into the map"
  		 desc annotateUse ifTrue:
  			[self annotateBytecode: (self prevInstIsPCAnnotated
  											ifTrue: [self Nop]
  											ifFalse: [self Label])].
  		 "Must annotate the bytecode for correct pc mapping."
  		 self annotateBytecode: (desc constant = boolean
  									ifTrue: [self Jump: fixup]
  									ifFalse: [self prevInstIsPCAnnotated
  												ifTrue: [self Nop]
  												ifFalse: [self Label]]).
  		 ^0].
  	desc popToReg: TempReg.
+ 	
  	"Cunning trick by LPD.  If true and false are contiguous subtract the smaller.
  	 Correct result is either 0 or the distance between them.  If result is not 0 or
  	 their distance send mustBeBoolean."
  	self assert: (objectMemory objectAfter: objectMemory falseObject) = objectMemory trueObject.
  	self annotate: (self SubCw: boolean R: TempReg) objRef: boolean.
  	self JumpZero: (self ensureFixupAt: targetBytecodePC - initialPC).
+ 	
+ 	extA = 1 ifTrue: [ extA := 0. ^ 0 ].
+ 	extA := 0.
+ 	
  	self CmpCq: (boolean == objectMemory falseObject
  					ifTrue: [objectMemory trueObject - objectMemory falseObject]
  					ifFalse: [objectMemory falseObject - objectMemory trueObject])
  		R: TempReg.
  	ok := self JumpZero: 0.
  	self CallRT: (boolean == objectMemory falseObject
  					ifTrue: [ceSendMustBeBooleanAddFalseTrampoline]
  					ifFalse: [ceSendMustBeBooleanAddTrueTrampoline]).
  	ok jmpTarget: (self annotateBytecode: self Label).
  	^0!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genPushRemoteInstVarLongBytecode (in category 'bytecode generators') -----
+ genPushRemoteInstVarLongBytecode
+ 	| tempVectReg remoteTempReg |	
+ 	tempVectReg := self allocateRegNotConflictingWith: 0.
+ 	self MoveMw: (self frameOffsetOfTemporary: byte2 - (1 << 7)) r: FPReg R: tempVectReg.
+ 	objectRepresentation 
+ 		genEnsureOopInRegNotForwarded: tempVectReg 
+ 		scratchReg: TempReg.
+ 	remoteTempReg := self availableRegOrNoneNotConflictingWith: (self registerMaskFor: tempVectReg). 
+ 	remoteTempReg = NoReg ifTrue: [remoteTempReg := tempVectReg].
+ 	objectRepresentation
+ 		genLoadSlot: byte1
+ 		sourceReg: tempVectReg
+ 		destReg: remoteTempReg.
+ 	^self ssPushRegister: remoteTempReg!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genStorePop:RemoteInstVar:At: (in category 'bytecode generator support') -----
+ genStorePop: popBoolean RemoteInstVar: slotIndex At: objectIndex 
+ 	<inline: false>
+ 	self 
+ 		cppIf: IMMUTABILITY
+ 		ifTrue: [ ^ self genImmutabilityCheckStorePop: popBoolean RemoteInstVar: slotIndex At: objectIndex  ]
+ 		ifFalse: [ ^ self genVanillaStorePop: popBoolean RemoteInstVar: slotIndex At: objectIndex  ]
+ 		!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genVanillaStorePop:LiteralVariable: (in category 'bytecode generator support') -----
  genVanillaStorePop: popBoolean LiteralVariable: litVarIndex 
  	<inline: true>
  	| topReg association needStoreCheck |
  	"The only reason we assert needsFrame here is that in a frameless method
  	 ReceiverResultReg must and does contain only self, but the ceStoreCheck
  	 trampoline expects the target of the store to be in ReceiverResultReg.  So
  	 in a frameless method we would have a conflict between the receiver and
  	 the literal store, unless we we smart enough to realise that ReceiverResultReg
  	 was unused after the literal variable store, unlikely given that methods
  	 return self by default."
  	self assert: needsFrame.
  	"N.B.  No need to check the stack for references because we generate code for
  	 literal variable loads that stores the result in a register, deferring only the register push."
+ 	needStoreCheck := self ssTopNeedsStoreCheck.
- 	needStoreCheck := (objectRepresentation isUnannotatableConstant: self ssTop) not.
  	association := self getLiteral: litVarIndex.
  	optStatus isReceiverResultRegLive: false.
  	self ssAllocateRequiredReg: ReceiverResultReg. "for ceStoreCheck call in genStoreSourceReg: has to be ReceiverResultReg"
  	self genMoveConstant: association R: ReceiverResultReg.
  	objectRepresentation genEnsureObjInRegNotForwarded: ReceiverResultReg scratchReg: TempReg.
  	topReg := self allocateRegForStackEntryAt: 0 notConflictingWith: (self registerMaskFor: ReceiverResultReg).
  	self ssStorePop: popBoolean toReg: topReg.
  	objectRepresentation
  		genStoreSourceReg: topReg
  		slotIndex: ValueIndex
  		destReg: ReceiverResultReg
  		scratchReg: TempReg
  		inFrame: needsFrame
  		needsStoreCheck: needStoreCheck.
  	^ 0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genVanillaStorePop:MaybeContextReceiverVariable: (in category 'bytecode generator support') -----
  genVanillaStorePop: popBoolean MaybeContextReceiverVariable: slotIndex
  	<inline: true>
  	| jmpSingle jmpDone needStoreCheck |
  	<var: #jmpSingle type: #'AbstractInstruction *'>
  	<var: #jmpDone type: #'AbstractInstruction *'>
  	"The reason we need a frame here is that assigning to an inst var of a context may
  	 involve wholesale reorganization of stack pages, and the only way to preserve the
  	 execution state of an activation in that case is if it has a frame."
  	self assert: needsFrame.
  	self ssFlushUpThroughReceiverVariable: slotIndex.
+ 	needStoreCheck := self ssTopNeedsStoreCheck.
- 	needStoreCheck := (objectRepresentation isUnannotatableConstant: self ssTop) not.
  	"Note that ReceiverResultReg remains live after both
  	 ceStoreContextInstVarTrampoline and ceStoreCheckTrampoline."
  	self ensureReceiverResultRegContainsSelf.
  	self ssPop: 1.
  	self ssAllocateCallReg: ClassReg and: SendNumArgsReg. "for ceStoreContextInstVarTrampoline"
  	self ssPush: 1.
  	objectRepresentation
  		genLoadSlot: SenderIndex
  		sourceReg: ReceiverResultReg
  		destReg: TempReg.
  	self ssStorePop: popBoolean toReg: ClassReg.
  	jmpSingle := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	self MoveCq: slotIndex R: SendNumArgsReg.
  	self CallRT: ceStoreContextInstVarTrampoline.
  	jmpDone := self Jump: 0.
  	jmpSingle jmpTarget: self Label.
  	objectRepresentation
  		genStoreSourceReg: ClassReg
  		slotIndex: slotIndex
  		destReg: ReceiverResultReg
  		scratchReg: TempReg
  		inFrame: true
  		needsStoreCheck: needStoreCheck.
  	jmpDone jmpTarget: self Label.
  	
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genVanillaStorePop:ReceiverVariable: (in category 'bytecode generator support') -----
  genVanillaStorePop: popBoolean ReceiverVariable: slotIndex 
  	<inline: true>
  	| topReg needStoreCheck |
  	self ssFlushUpThroughReceiverVariable: slotIndex.
+ 	needStoreCheck := self ssTopNeedsStoreCheck.
- 	needStoreCheck := (objectRepresentation isUnannotatableConstant: self ssTop) not.
  	"Note that ReceiverResultReg remains live after ceStoreCheckTrampoline."
  	self ensureReceiverResultRegContainsSelf.
  	topReg := self allocateRegForStackEntryAt: 0 notConflictingWith: (self registerMaskFor: ReceiverResultReg). 
  	self ssStorePop: popBoolean toReg: topReg.
  	objectRepresentation
  		genStoreSourceReg: topReg
  		slotIndex: slotIndex
  		destReg: ReceiverResultReg
  		scratchReg: TempReg
  		inFrame: needsFrame
  		needsStoreCheck: needStoreCheck.
  	^ 0!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genVanillaStorePop:RemoteInstVar:At: (in category 'bytecode generator support') -----
+ genVanillaStorePop: popBoolean RemoteInstVar: slotIndex At: objectIndex
+ 	<inline: false>
+ 	| topReg needStoreCheck |
+ 	"The only reason we assert needsFrame here is that in a frameless method
+ 	 ReceiverResultReg must and does contain only self, but the ceStoreCheck
+ 	 trampoline expects the target of the store to be in ReceiverResultReg.  So
+ 	 in a frameless method we would have a conflict between the receiver and
+ 	 the temote temp store, unless we we smart enough to realise that
+ 	 ReceiverResultReg was unused after the literal variable store, unlikely given
+ 	 that methods return self by default."
+ 	self assert: needsFrame.
+ 	"N.B.  No need to check the stack for references because we generate code for
+ 	 remote temp loads that stores the result in a register, deferring only the register push."
+ 	needStoreCheck := (objectRepresentation isUnannotatableConstant: self ssTop) not.
+ 	topReg := self allocateRegForStackEntryAt: 0 notConflictingWith: (self registerMaskFor: ReceiverResultReg).
+ 	self ssAllocateRequiredReg: ReceiverResultReg. 
+ 	optStatus isReceiverResultRegLive: false.
+ 	self ssStorePop: popBoolean toReg: topReg.
+ 	self MoveMw: (self frameOffsetOfTemporary: objectIndex) r: FPReg R: ReceiverResultReg.
+ 	objectRepresentation 
+ 		genEnsureOopInRegNotForwarded: ReceiverResultReg 
+ 		scratchReg: TempReg.
+ 	^objectRepresentation
+ 		genStoreSourceReg: topReg
+ 		slotIndex: slotIndex
+ 		destReg: ReceiverResultReg
+ 		scratchReg: TempReg
+ 		inFrame: needsFrame
+ 		needsStoreCheck: needStoreCheck!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>ssTopNeedsStoreCheck (in category 'bytecode generator support') -----
+ ssTopNeedsStoreCheck
+ 	<inline: true>
+ 	| needsStoreCheck |
+ 	needsStoreCheck := (extB noMask: 1) and: [ (objectRepresentation isUnannotatableConstant: self ssTop) not ].
+ 	extB := 0.
+ 	^ needsStoreCheck!



More information about the Vm-dev mailing list