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

commits at source.squeak.org commits at source.squeak.org
Thu Nov 24 12:44:57 UTC 2016


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

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

Name: VMMaker.oscog-cb.2003
Author: cb
Time: 24 November 2016, 1:44:37.073343 pm
UUID: 9951550e-3f78-457d-a373-2485d63d5abd
Ancestors: VMMaker.oscog-eem.2002

Made #~~ a special selector instead of #blockCopy:.

If the bytecode compiler compiles #~~ using the special selector bytecode, then the pointer comparison with #~~ is inlined as it is with #==.

This leads #~~ to have the same performance as #==. It also means #~~ is not a primitive call, as #==. 

I believe this is important for system consistency. 

To integrate that in the Squeak / Pharo image, one needs to add #~~ instead of #blockCopy: in the special selector array and add Object>>#~~ as primitive 169 if not already the case.

I compiled both Sista and non Sista VMs with Spur and ensure everything is correct. I "guess" the V3 and Newspeak VMs are correct too.

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

Item was added:
+ ----- Method: CogObjectRepresentationForSpur>>genInlinedIdenticalOrNotIfGuts: (in category 'compile abstract instructions') -----
+ genInlinedIdenticalOrNotIfGuts: orNot
+ 	<inline: true>
+ 	^ cogit genForwardersInlinedIdenticalOrNotIf: orNot!

Item was removed:
- ----- Method: CogObjectRepresentationForSpur>>genSpecialSelectorEqualsEqualsGuts (in category 'compile abstract instructions') -----
- genSpecialSelectorEqualsEqualsGuts
- 	< inline: true >
- 	^ cogit genSpecialSelectorEqualsEqualsWithForwarders!

Item was added:
+ ----- Method: CogObjectRepresentationForSqueakV3>>genInlinedIdenticalOrNotIf: (in category 'compile abstract instructions') -----
+ genInlinedIdenticalOrNotIf: orNot
+ 	<inline: true>
+ 	^ cogit genVanillaInlinedIdenticalOrNotIf: orNot!

Item was removed:
- ----- Method: CogObjectRepresentationForSqueakV3>>genSpecialSelectorEqualsEqualsGuts (in category 'compile abstract instructions') -----
- genSpecialSelectorEqualsEqualsGuts
- 	< inline: true >
- 	^ cogit genVanillaSpecialSelectorEqualsEquals!

Item was changed:
  ----- Method: SimpleStackBasedCogit class>>initializeBytecodeTableForNewspeakV4 (in category 'class initialization') -----
  initializeBytecodeTableForNewspeakV4
  	"SimpleStackBasedCogit initializeBytecodeTableForNewspeakV4"
  
  	NSSendIsPCAnnotated := false. "IsNSSendCall used by SendAbsentImplicit"
  	FirstSpecialSelector := 80.
  	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"
  		(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 genExtPushPseudoVariableOrOuterBytecode)
  		(1  78   78 genPushConstantZeroBytecode)
  		(1  79   79 genPushConstantOneBytecode)
  
  		(1   80 101 genSpecialSelectorSend isMapped) "#+ #- #< #> #<= #>= #= #~= #* #/ #\\ #@ #bitShift: #// #bitAnd: #bitOr: #at: #at:put: #size #next #nextPut: #atEnd"
  		(1 102 102 genSpecialSelectorEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
  		(1 103 103 genSpecialSelectorClass needsFrameNever: notMapped 0) "not mapped because it is directly inlined (for now)"
+ 		(1 104 104 genSpecialSelectorNotEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
+ 		(1 105 111 genSpecialSelectorSend isMapped) "#value #value: #do: #new #new: #x #y"
- 		(1 104 111 genSpecialSelectorSend isMapped) "#blockCopy: #value #value: #do: #new #new: #x #y"
  
  		(1 112 127 genSendLiteralSelector0ArgsBytecode isMapped)
  		(1 128 143 genSendLiteralSelector1ArgBytecode isMapped)
  		(1 144 159 genSendLiteralSelector2ArgsBytecode isMapped)
  		(1 160 175	genSendAbsentImplicit0ArgsBytecode isMapped hasIRC)
  
  		(1 176 183 genStoreAndPopReceiverVariableBytecode isInstVarRef isMappedIfImmutability needsFrameIfImmutability: -1)
  
  		(1 184 191 genStoreAndPopTemporaryVariableBytecode)
  
  		(1 192 199 genShortUnconditionalJump	branch v3:ShortForward:Branch:Distance:)
  		(1 200 207 genShortJumpIfTrue			branch isBranchTrue isMapped "because of mustBeBoolean"
  													v3:ShortForward:Branch:Distance:)
  		(1 208 215 genShortJumpIfFalse			branch isBranchFalse isMapped "because of mustBeBoolean"
  													v3:ShortForward:Branch:Distance:)
  
  		(1 216 216 genReturnReceiver				return needsFrameIfInBlock: isMappedInBlock 0)
  		(1 217 217 genReturnTopFromMethod		return needsFrameIfInBlock: isMappedInBlock -1)
  		(1 218 218 genExtReturnTopFromBlock	return needsFrameNever: -1)
  
  		(1 219 219 duplicateTopBytecode			needsFrameNever: 1)
  		(1 220 220 genPopStackBytecode			needsFrameNever: -1)
  		(1 221 221 genExtNopBytecode			needsFrameNever: 0)
  		(1 222 223	unknownBytecode)
  
  		"2 byte bytecodes"
  		(2 224 224 extABytecode extension)
  		(2 225 225 extBBytecode extension)
  		(2 226 226 genExtPushReceiverVariableBytecode isInstVarRef)
  		(2 227 227 genExtPushLiteralVariableBytecode		needsFrameNever: 1)
  		(2 228 228 genExtPushLiteralBytecode					needsFrameNever: 1)
  		(2 229 229 genExtPushIntegerBytecode				needsFrameNever: 1)
  		(2 230 230 genLongPushTemporaryVariableBytecode)
  		(2 231 231 genPushNewArrayBytecode)
  		(2 232 232 genExtStoreReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
  		(2 233 233 genExtStoreLiteralVariableBytecode isMappedIfImmutability)
  		(2 234 234 genLongStoreTemporaryVariableBytecode)
  		(2 235 235 genExtStoreAndPopReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
  		(2 236 236 genExtStoreAndPopLiteralVariableBytecode isMappedIfImmutability)
  		(2 237 237 genLongStoreAndPopTemporaryVariableBytecode)
  
  		(2 238 238 genExtSendBytecode isMapped)
  		(2 239 239 genExtSendSuperBytecode isMapped)
  		(2 240 240 genExtSendAbsentImplicitBytecode isMapped hasIRC)
  		(2 241 241 genExtSendAbsentDynamicSuperBytecode isMapped hasIRC)
  
  		(2 242 242 genExtUnconditionalJump	branch isMapped "because of interrupt check" v4:Long:Branch:Distance:)
  		(2 243 243 genExtJumpIfTrue			branch isBranchTrue isMapped "because of mustBeBoolean" v4:Long:Branch:Distance:)
  		(2 244 244 genExtJumpIfFalse			branch isBranchFalse isMapped "because of mustBeBoolean" v4:Long:Branch:Distance:)
  
  		(2 245 245 genExtSendAbsentSelfBytecode isMapped hasIRC)
  
  		(2 246 248	unknownBytecode)
  
  		"3 byte bytecodes"
  		(3 249 249 genCallPrimitiveBytecode)
  		(3 250 250 genPushRemoteTempLongBytecode)
  		(3 251 251 genStoreRemoteTempLongBytecode)
  		(3 252 252 genStoreAndPopRemoteTempLongBytecode)
  		(3 253 253 genExtPushClosureBytecode block v4:Block:Code:Size:)
  		(3 254 254 genExtSendAbsentOuterBytecode isMapped hasIRC)
  
  		(3 255 255	unknownBytecode))!

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 120 genSpecialSelectorNotEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
+ 		(1 121 127 genSpecialSelectorSend isMapped) "#value #value: #do: #new #new: #x #y"
- 		(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 unknownBytecode)
  		(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 genSistaExtStoreAndPopReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
  		(2 241 241 genSistaExtStoreAndPopLiteralVariableBytecode isMappedIfImmutability)
  		(2 242 242 genLongStoreAndPopTemporaryVariableBytecode)
  		(2 243 243 genSistaExtStoreReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
  		(2 244 244 genSistaExtStoreLiteralVariableBytecode isMappedIfImmutability)
  		(2 245 245 genLongStoreTemporaryVariableBytecode)
  
  		(2 246 247	unknownBytecode)
  
  		"3 byte bytecodes"
  		(3 248 248 genCallPrimitiveBytecode)
  		(3 249 249 genExtPushFullClosureBytecode) 
  		(3 250 250 genExtPushClosureBytecode block v4:Block:Code:Size:)
  		(3 251 251 genExtPushRemoteTempOrInstVarLongBytecode)
  		(3 252 252 genExtStoreRemoteTempOrInstVarLongBytecode isMappedIfImmutability)
  		(3 253 253 genExtStoreAndPopRemoteTempOrInstVarLongBytecode isMappedIfImmutability)
  
  		(3 254 254	genExtJumpIfNotInstanceOfBehaviorsBytecode)
  			
  		(3 255 255	unknownBytecode))!

Item was changed:
  ----- Method: SimpleStackBasedCogit class>>initializeBytecodeTableForSqueakV3PlusClosures (in category 'class initialization') -----
  initializeBytecodeTableForSqueakV3PlusClosures
  	"SimpleStackBasedCogit initializeBytecodeTableForSqueakV3PlusClosures"
  
  	FirstSpecialSelector := 176.
  	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    0   15 genPushReceiverVariableBytecode isInstVarRef)
  		(1  16   31 genPushTemporaryVariableBytecode)
  		(1  32   63 genPushLiteralConstantBytecode needsFrameNever: 1)
  		(1  64   95 genPushLiteralVariableBytecode needsFrameNever: 1)
  		(1  96 103 genStoreAndPopReceiverVariableBytecode isInstVarRef isMappedIfImmutability needsFrameIfImmutability: -1)
  		(1 104 111 genStoreAndPopTemporaryVariableBytecode)
  		(1 112 112 genPushReceiverBytecode)
  		(1 113 113 genPushConstantTrueBytecode needsFrameNever: 1)
  		(1 114 114 genPushConstantFalseBytecode needsFrameNever: 1)
  		(1 115 115 genPushConstantNilBytecode needsFrameNever: 1)
  		(1 116 119 genPushQuickIntegerConstantBytecode needsFrameNever: 1)
  		"method returns in blocks need a frame because of nonlocalReturn:through:"
  		(1 120 120 genReturnReceiver				return needsFrameIfInBlock: isMappedInBlock 0)
  		(1 121 121 genReturnTrue					return needsFrameIfInBlock: isMappedInBlock 0)
  		(1 122 122 genReturnFalse					return needsFrameIfInBlock: isMappedInBlock 0)
  		(1 123 123 genReturnNil					return needsFrameIfInBlock: isMappedInBlock 0)
  		(1 124 124 genReturnTopFromMethod		return needsFrameIfInBlock: isMappedInBlock -1)
  		(1 125 125 genReturnTopFromBlock		return needsFrameNever: -1)
  
  		(1 126 127 unknownBytecode)
  
  		(2 128 128 extendedPushBytecode isInstVarRef) "well, maybe inst var ref"
  		(2 129 129 extendedStoreBytecode isInstVarRef isMappedIfImmutability) "well, maybe inst var ref"
  		(2 130 130 extendedStoreAndPopBytecode isInstVarRef isMappedIfImmutability) "well, maybe inst var ref"
  		(2 131 131 genExtendedSendBytecode isMapped)
  		(3 132 132 doubleExtendedDoAnythingBytecode isInstVarRef isMapped) "well, maybe inst var ref"
  		(2 133 133 genExtendedSuperBytecode isMapped)
  		(2 134 134 genSecondExtendedSendBytecode isMapped)
  		(1 135 135 genPopStackBytecode needsFrameNever: -1)
  		(1 136 136 duplicateTopBytecode needsFrameNever: 1)
  
  		(1 137 137 genPushActiveContextBytecode)
  		(2 138 138 genPushNewArrayBytecode)),
  
  		((initializationOptions at: #SpurObjectMemory ifAbsent: [false])
  			ifTrue: [#((3 139 139 genCallPrimitiveBytecode))]
  			ifFalse: [#((1 139 139 unknownBytecode))]),
  
  	  #(
  		(3 140 140 genPushRemoteTempLongBytecode)
  		(3 141 141 genStoreRemoteTempLongBytecode)
  		(3 142 142 genStoreAndPopRemoteTempLongBytecode)
  		(4 143 143 genPushClosureCopyCopiedValuesBytecode block v3:Block:Code:Size:)
  
  		(1 144 151 genShortUnconditionalJump			branch v3:ShortForward:Branch:Distance:)
  		(1 152 159 genShortJumpIfFalse					branch isBranchFalse isMapped "because of mustBeBoolean"
  															v3:ShortForward:Branch:Distance:)
  		(2 160 163 genLongUnconditionalBackwardJump	branch isMapped "because of interrupt check"
  															v3:Long:Branch:Distance:)
  		(2 164 167 genLongUnconditionalForwardJump		branch v3:Long:Branch:Distance:)
  		(2 168 171 genLongJumpIfTrue					branch isBranchTrue isMapped "because of mustBeBoolean"
  															v3:LongForward:Branch:Distance:)
  		(2 172 175 genLongJumpIfFalse					branch isBranchFalse isMapped "because of mustBeBoolean"
  															v3:LongForward:Branch:Distance:)
  
  		(1 176 197 genSpecialSelectorSend isMapped)
  		(1 198 198 genSpecialSelectorEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
  		(1 199 199 genSpecialSelectorClass needsFrameNever: notMapped 0) "not mapped because it is directly inlined (for now)"
+ 		(1 200 200 genSpecialSelectorNotEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
+ 		(1 201 207 genSpecialSelectorSend isMapped)
- 		(1 200 207 genSpecialSelectorSend isMapped)
  		(1 208 223 genSendLiteralSelector0ArgsBytecode isMapped)
  		(1 224 239 genSendLiteralSelector1ArgBytecode isMapped)
  		(1 240 255 genSendLiteralSelector2ArgsBytecode isMapped))!

Item was added:
+ ----- Method: SimpleStackBasedCogit>>genInlinedIdenticalOrNotIf: (in category 'bytecode generator support') -----
+ genInlinedIdenticalOrNotIf: orNot
+ 	| jumpNotEqual jumpPush |
+ 	<var: #jumpNotEqual type: #'AbstractInstruction *'>
+ 	<var: #jumpPush type: #'AbstractInstruction *'>
+ 	self PopR: Arg0Reg.
+ 	objectRepresentation
+ 		genEnsureOopInRegNotForwarded: Arg0Reg
+ 		scratchReg: TempReg.
+ 	self MoveMw: 0 r: SPReg R: ClassReg.
+ 	objectRepresentation
+ 		genEnsureOopInRegNotForwarded: ClassReg
+ 		scratchReg: TempReg.
+ 	self CmpR: Arg0Reg R: ClassReg.
+ 	jumpNotEqual := self genConditionalBranch: (orNot ifTrue: [JumpZero] ifFalse: [JumpZero]) operand: 0.
+ 	self annotate: (self genMoveTrueR: Arg0Reg)
+ 		objRef: objectMemory trueObject.
+ 	jumpPush := self Jump: 0.
+ 	jumpNotEqual jmpTarget: (self genMoveFalseR: Arg0Reg).
+ 	jumpPush jmpTarget: (self MoveR: Arg0Reg Mw: 0 r: SPReg).
+ 	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genSpecialSelectorEqualsEquals (in category 'bytecode generators') -----
  genSpecialSelectorEqualsEquals
+ 	^ self genInlinedIdenticalOrNotIf: false!
- 	| jumpNotEqual jumpPush |
- 	<var: #jumpNotEqual type: #'AbstractInstruction *'>
- 	<var: #jumpPush type: #'AbstractInstruction *'>
- 	self PopR: Arg0Reg.
- 	objectRepresentation
- 		genEnsureOopInRegNotForwarded: Arg0Reg
- 		scratchReg: TempReg.
- 	self MoveMw: 0 r: SPReg R: ClassReg.
- 	objectRepresentation
- 		genEnsureOopInRegNotForwarded: ClassReg
- 		scratchReg: TempReg.
- 	self CmpR: Arg0Reg R: ClassReg.
- 	jumpNotEqual := self JumpNonZero: 0.
- 	self annotate: (self genMoveTrueR: Arg0Reg)
- 		objRef: objectMemory trueObject.
- 	jumpPush := self Jump: 0.
- 	jumpNotEqual jmpTarget: (self genMoveFalseR: Arg0Reg).
- 	jumpPush jmpTarget: (self MoveR: Arg0Reg Mw: 0 r: SPReg).
- 	^0!

Item was added:
+ ----- Method: SimpleStackBasedCogit>>genSpecialSelectorNotEqualsEquals (in category 'bytecode generators') -----
+ genSpecialSelectorNotEqualsEquals
+ 	^ self genInlinedIdenticalOrNotIf: true!

Item was added:
+ ----- Method: SistaCogit>>genForwardersInlinedIdenticalOrNotIf: (in category 'bytecode generators') -----
+ genForwardersInlinedIdenticalOrNotIf: orNot
+ 	"Override to count inlined branches if followed by a conditional branch.
+ 	 We borrow the following conditional branch's counter and when about to
+ 	 inline the comparison we decrement the counter (without writing it back)
+ 	 and if it trips simply abort the inlining, falling back to the normal send which
+ 	 will then continue to the conditional branch which will trip and enter the abort."
+ 	| nextPC postBranchPC targetBytecodePC branchDescriptor counterReg fixup jumpEqual jumpNotEqual
+ 	  counterAddress countTripped unforwardArg unforwardRcvr argReg rcvrReg regMask |
+ 	<var: #fixup type: #'BytecodeFixup *'>
+ 	<var: #countTripped type: #'AbstractInstruction *'>
+ 	<var: #label type: #'AbstractInstruction *'>
+ 	<var: #branchDescriptor type: #'BytecodeDescriptor *'>
+ 	<var: #jumpEqual type: #'AbstractInstruction *'>
+ 	<var: #jumpNotEqual type: #'AbstractInstruction *'>
+ 
+ 	((coInterpreter isOptimizedMethod: methodObj) or: [needsFrame not]) ifTrue:
+ 		[^super genForwardersInlinedIdenticalOrNotIf: orNot].
+ 
+ 	regMask := 0.
+ 	
+ 	self extractMaybeBranchDescriptorInto: [ :descr :next :postBranch :target | 
+ 		branchDescriptor := descr. nextPC := next. postBranchPC := postBranch. targetBytecodePC := target ].
+ 	
+ 	unforwardRcvr := (objectRepresentation isUnannotatableConstant: (self ssValue: 1)) not.
+ 	unforwardArg := (objectRepresentation isUnannotatableConstant: self ssTop) not.
+ 	
+ 	"If an operand is an annotable constant, it may be forwarded, so we need to store it into a 
+ 	register so the forwarder check can jump back to the comparison after unforwarding the constant.
+ 	However, if one of the operand is an unnanotable constant, does not allocate a register for it 
+ 	(machine code will use operations on constants)."
+ 	rcvrReg:= argReg := NoReg.
+ 	self 
+ 		allocateEqualsEqualsRegistersArgNeedsReg: unforwardArg 
+ 		rcvrNeedsReg: unforwardRcvr 
+ 		into: [ :rcvr :arg | rcvrReg:= rcvr. argReg := arg ].
+ 		
+ 	argReg ~= NoReg ifTrue: [ regMask := self registerMaskFor: argReg ].
+ 	rcvrReg ~= NoReg ifTrue: [ regMask := regMask bitOr: (self registerMaskFor: rcvrReg) ].
+ 	
+ 	"Only interested in inlining if followed by a conditional branch."
+ 	(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifFalse:
+ 		[^ self 
+ 			genIdenticalNoBranchArgIsConstant: unforwardArg not
+ 			rcvrIsConstant: unforwardRcvr not
+ 			argReg: argReg 
+ 			rcvrReg: rcvrReg 
+ 			orNotIf: orNot].
+ 	
+ 	"If branching the stack must be flushed for the merge"
+ 	self ssFlushTo: simStackPtr - 2.
+ 	
+ 	unforwardArg ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: argReg scratchReg: TempReg ].
+ 	unforwardRcvr ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: rcvrReg scratchReg: TempReg ].
+ 	
+ 	counterReg := self allocateRegNotConflictingWith: regMask.
+ 	self 
+ 		genExecutionCountLogicInto: [ :cAddress :countTripBranch | 
+ 			counterAddress := cAddress. 
+ 			countTripped := countTripBranch ] 
+ 		counterReg: counterReg.
+ 	
+ 	self assert: (unforwardArg or: [ unforwardRcvr ]).
+ 	self genCmpArgIsConstant: unforwardArg not rcvrIsConstant: unforwardRcvr not argReg: argReg rcvrReg: rcvrReg.
+ 	self ssPop: 2.
+ 	
+ 	"We could use (branchDescriptor isBranchTrue xor: orNot) to simplify this."
+ 	orNot 
+ 		ifFalse: [branchDescriptor isBranchTrue
+ 					ifTrue: 
+ 						[ fixup := (self ensureNonMergeFixupAt: postBranchPC - initialPC) asUnsignedInteger.
+ 						self JumpZero:  (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger ]
+ 					ifFalse: "branchDescriptor is branchFalse"
+ 						[ fixup := (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
+ 						self JumpZero: (self ensureNonMergeFixupAt: postBranchPC - initialPC) asUnsignedInteger ]]
+ 		ifTrue: [branchDescriptor isBranchTrue
+ 					ifFalse: "branchDescriptor is branchFalse"
+ 						[ fixup := (self ensureNonMergeFixupAt: postBranchPC - initialPC) asUnsignedInteger.
+ 						self JumpZero:  (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger ]
+ 					ifTrue:
+ 						[ fixup := (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
+ 						self JumpZero: (self ensureNonMergeFixupAt: postBranchPC - initialPC) asUnsignedInteger ]].
+ 	
+ 	self genFallsThroughCountLogicCounterReg: counterReg counterAddress: counterAddress.
+ 	self Jump: fixup.
+ 	
+ 	countTripped jmpTarget: self Label.
+ 	
+ 	"inlined version of #== ignoring the branchDescriptor if the counter trips to have normal state for the optimizer"
+ 	self ssPop: -2. 
+ 	self genCmpArgIsConstant: unforwardArg not rcvrIsConstant: unforwardRcvr not argReg: argReg rcvrReg: rcvrReg.
+ 	self ssPop: 2. 
+ 	
+ 	"This code necessarily directly falls through the jumpIf: code which pops the top of the stack into TempReg. 
+ 	We therefore directly assign the result to TempReg to save one move instruction"
+ 	jumpEqual := orNot ifFalse: [self JumpZero: 0] ifTrue: [self JumpNonZero: 0].
+ 	self genMoveFalseR: TempReg.
+ 	jumpNotEqual := self Jump: 0.
+ 	jumpEqual jmpTarget: (self genMoveTrueR: TempReg).
+ 	jumpNotEqual jmpTarget: self Label.
+ 	self ssPushRegister: TempReg.
+ 	
+ 	(self fixupAt: nextPC - initialPC) notAFixup ifTrue: [ branchReachedOnlyForCounterTrip := true ].
+ 	
+ 	^ 0!

Item was removed:
- ----- Method: SistaCogit>>genSpecialSelectorEqualsEqualsWithForwarders (in category 'bytecode generators') -----
- genSpecialSelectorEqualsEqualsWithForwarders
- 	"Override to count inlined branches if followed by a conditional branch.
- 	 We borrow the following conditional branch's counter and when about to
- 	 inline the comparison we decrement the counter (without writing it back)
- 	 and if it trips simply abort the inlining, falling back to the normal send which
- 	 will then continue to the conditional branch which will trip and enter the abort."
- 	| nextPC postBranchPC targetBytecodePC branchDescriptor counterReg fixup jumpEqual jumpNotEqual
- 	  counterAddress countTripped unforwardArg unforwardRcvr argReg rcvrReg regMask |
- 	<var: #fixup type: #'BytecodeFixup *'>
- 	<var: #countTripped type: #'AbstractInstruction *'>
- 	<var: #label type: #'AbstractInstruction *'>
- 	<var: #branchDescriptor type: #'BytecodeDescriptor *'>
- 	<var: #jumpEqual type: #'AbstractInstruction *'>
- 	<var: #jumpNotEqual type: #'AbstractInstruction *'>
- 
- 	((coInterpreter isOptimizedMethod: methodObj) or: [needsFrame not]) ifTrue:
- 		[^super genSpecialSelectorEqualsEqualsWithForwarders].
- 
- 	regMask := 0.
- 	
- 	self extractMaybeBranchDescriptorInto: [ :descr :next :postBranch :target | 
- 		branchDescriptor := descr. nextPC := next. postBranchPC := postBranch. targetBytecodePC := target ].
- 	
- 	unforwardRcvr := (objectRepresentation isUnannotatableConstant: (self ssValue: 1)) not.
- 	unforwardArg := (objectRepresentation isUnannotatableConstant: self ssTop) not.
- 	
- 	"If an operand is an annotable constant, it may be forwarded, so we need to store it into a 
- 	register so the forwarder check can jump back to the comparison after unforwarding the constant.
- 	However, if one of the operand is an unnanotable constant, does not allocate a register for it 
- 	(machine code will use operations on constants)."
- 	rcvrReg:= argReg := NoReg.
- 	self 
- 		allocateEqualsEqualsRegistersArgNeedsReg: unforwardArg 
- 		rcvrNeedsReg: unforwardRcvr 
- 		into: [ :rcvr :arg | rcvrReg:= rcvr. argReg := arg ].
- 		
- 	argReg ~= NoReg ifTrue: [ regMask := self registerMaskFor: argReg ].
- 	rcvrReg ~= NoReg ifTrue: [ regMask := regMask bitOr: (self registerMaskFor: rcvrReg) ].
- 	
- 	"Only interested in inlining if followed by a conditional branch."
- 	(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifFalse:
- 		[^ self genEqualsEqualsNoBranchArgIsConstant: unforwardArg not rcvrIsConstant: unforwardRcvr not argReg: argReg rcvrReg: rcvrReg].
- 	
- 	"If branching the stack must be flushed for the merge"
- 	self ssFlushTo: simStackPtr - 2.
- 	
- 	unforwardArg ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: argReg scratchReg: TempReg ].
- 	unforwardRcvr ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: rcvrReg scratchReg: TempReg ].
- 	
- 	counterReg := self allocateRegNotConflictingWith: regMask.
- 	self 
- 		genExecutionCountLogicInto: [ :cAddress :countTripBranch | 
- 			counterAddress := cAddress. 
- 			countTripped := countTripBranch ] 
- 		counterReg: counterReg.
- 	
- 	self assert: (unforwardArg or: [ unforwardRcvr ]).
- 	
- 	self genEqualsEqualsComparisonArgIsConstant: unforwardArg not rcvrIsConstant: unforwardRcvr not argReg: argReg rcvrReg: rcvrReg.
- 	
- 	self ssPop: 2.
- 	
- 	branchDescriptor isBranchTrue 
- 		ifTrue: 
- 			[ fixup := self ensureNonMergeFixupAt: postBranchPC - initialPC.
- 			self JumpZero: (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger. ]
- 		ifFalse: 
- 			[ fixup := self ensureNonMergeFixupAt: targetBytecodePC - initialPC.
- 			self JumpZero: (self ensureNonMergeFixupAt: postBranchPC - initialPC) asUnsignedInteger. ].
- 	
- 	self genFallsThroughCountLogicCounterReg: counterReg counterAddress: counterAddress.
- 	self Jump: fixup.
- 	
- 	countTripped jmpTarget: self Label.
- 	
- 	"inlined version of #== ignoring the branchDescriptor if the counter trips to have normal state for the optimizer"
- 	self ssPop: -2. 
- 	self genEqualsEqualsComparisonArgIsConstant: unforwardArg not rcvrIsConstant: unforwardRcvr not argReg: argReg rcvrReg: rcvrReg.
- 	self ssPop: 2. 
- 	
- 	"This code necessarily directly falls through the jumpIf: code which pops the top of the stack into TempReg. 
- 	We therefore directly assign the result to TempReg to save one move instruction"
- 	jumpEqual := self JumpZero: 0.
- 	self genMoveFalseR: TempReg.
- 	jumpNotEqual := self Jump: 0.
- 	jumpEqual jmpTarget: (self genMoveTrueR: TempReg).
- 	jumpNotEqual jmpTarget: self Label.
- 	self ssPushRegister: TempReg.
- 	
- 	(self fixupAt: nextPC - initialPC) notAFixup ifTrue: [ branchReachedOnlyForCounterTrip := true ].
- 	
- 	^ 0!

Item was changed:
  ----- Method: StackInterpreter class>>initializeBytecodeTableForNewspeakV4 (in category 'initialization') -----
  initializeBytecodeTableForNewspeakV4
  	"StackInterpreter initializeBytecodeTableForNewspeakV4"
  	"Note: This table will be used to generate a C switch statement."
  
  	initializationOptions at: #NewsqueakV4BytecodeSet put: (NewsqueakV4BytecodeSet := true).
  	BytecodeTable := Array new: 256.
  	BytecodeEncoderClassName := #EncoderForNewsqueakV4.
  	BytecodeSetHasExtensions := true.
  	LongStoreBytecode := 234.
  	self table: BytecodeTable from:
  	#(	"1 byte bytecodes"
  		(   0  15 pushReceiverVariableBytecode)
  		( 16  31 pushLiteralVariable16CasesBytecode)
  		( 32  63 pushLiteralConstantBytecode)
  		( 64  75 pushTemporaryVariableBytecode)
  		( 76	 pushReceiverBytecode)
  		( 77	 extPushPseudoVariableOrOuterBytecode)
  		( 78	 pushConstantZeroBytecode)
  		( 79	 pushConstantOneBytecode)
  
  		( 80	 bytecodePrimAdd)
  		( 81	 bytecodePrimSubtract)
  		( 82	 bytecodePrimLessThanV4) "for booleanCheatV4:"
  		( 83	 bytecodePrimGreaterThanV4) "for booleanCheatV4:"
  		( 84	 bytecodePrimLessOrEqualV4) "for booleanCheatV4:"
  		( 85	 bytecodePrimGreaterOrEqualV4) "for booleanCheatV4:"
  		( 86	 bytecodePrimEqualV4) "for booleanCheatV4:"
  		( 87	 bytecodePrimNotEqualV4) "for booleanCheatV4:"
  		( 88	 bytecodePrimMultiply)
  		( 89	 bytecodePrimDivide)
  		( 90	 bytecodePrimMod)
  		( 91	 bytecodePrimMakePoint)
  		( 92	 bytecodePrimBitShift)
  		( 93	 bytecodePrimDiv)
  		( 94	 bytecodePrimBitAnd)
  		( 95	 bytecodePrimBitOr)
  
  		( 96	 bytecodePrimAt)
  		( 97	 bytecodePrimAtPut)
  		( 98	 bytecodePrimSize)
  		( 99	 bytecodePrimNext)
  		(100	 bytecodePrimNextPut)
  		(101	 bytecodePrimAtEnd)
  		(102	 bytecodePrimIdenticalV4) "for booleanCheatV4:"
  		(103	 bytecodePrimClass)
+ 		(104	 bytecodePrimNotIdenticalV4) "was blockCopy:"
- 		(104	 bytecodePrimSpecialSelector24) "was blockCopy:"
  		(105	 bytecodePrimValue)
  		(106	 bytecodePrimValueWithArg)
  		(107	 bytecodePrimDo)
  		(108	 bytecodePrimNew)
  		(109	 bytecodePrimNewWithArg)
  		(110	 bytecodePrimPointX)
  		(111	 bytecodePrimPointY)
  
  		(112 127	sendLiteralSelector0ArgsBytecode)
  		(128 143	sendLiteralSelector1ArgBytecode)
  		(144 159	sendLiteralSelector2ArgsBytecode)
  		(160 175	sendAbsentImplicit0ArgsBytecode)
  
  		(176 183	storeAndPopReceiverVariableBytecode)
  		(184 191	storeAndPopTemporaryVariableBytecode)
  
  		(192 199	shortUnconditionalJump)
  		(200 207	shortConditionalJumpTrue)
  		(208 215	shortConditionalJumpFalse)
  
  		(216		returnReceiver)
  		(217		returnTopFromMethod)
  		(218		extReturnTopFromBlock)
  
  		(219		duplicateTopBytecode)
  		(220		popStackBytecode)
  		(221		extNopBytecode)
  		(222 223	unknownBytecode)
  
  		"2 byte bytecodes"
  		(224		extABytecode)
  		(225		extBBytecode)
  
  		(226		extPushReceiverVariableBytecode)
  		(227		extPushLiteralVariableBytecode)
  		(228		extPushLiteralBytecode)
  		(229		extPushIntegerBytecode)
  		(230		longPushTemporaryVariableBytecode)
  		(231		pushNewArrayBytecode)
  		(232		extStoreReceiverVariableBytecode)
  		(233		extStoreLiteralVariableBytecode)
  		(234		longStoreTemporaryVariableBytecode)
  		(235		extStoreAndPopReceiverVariableBytecode)
  		(236		extStoreAndPopLiteralVariableBytecode)
  		(237		longStoreAndPopTemporaryVariableBytecode)
  
  		(238		extSendBytecode)
  		(239		extSendSuperBytecode)
  		(240		extSendAbsentImplicitBytecode)
  		(241		extSendAbsentDynamicSuperBytecode)
  
  		(242		extUnconditionalJump)
  		(243		extJumpIfTrue)
  		(244		extJumpIfFalse)
  
  		(245		extSendAbsentSelfBytecode)
  
  		(246 248	unknownBytecode)
  
  		"3 byte bytecodes"
  		(249		callPrimitiveBytecode)
  
  		(250		pushRemoteTempLongBytecode)
  		(251		storeRemoteTempLongBytecode)
  		(252		storeAndPopRemoteTempLongBytecode)
  		(253		extPushClosureBytecode)
  		(254		extSendAbsentOuterBytecode)
  
  		(255		unknownBytecode)
  	)!

Item was changed:
  ----- Method: StackInterpreter class>>initializeBytecodeTableForSistaV1 (in category 'initialization') -----
  initializeBytecodeTableForSistaV1
  	"See e.g. the cass comment for EncoderForSistaV1"
  	"StackInterpreter initializeBytecodeTableForSistaV1"
  	"Note: This table will be used to generate a C switch statement."
  
  	initializationOptions at: #SistaV1BytecodeSet put: (SistaV1BytecodeSet := true).
  
  	BytecodeTable := Array new: 256.
  	BytecodeEncoderClassName := #EncoderForSistaV1.
  	BytecodeSetHasDirectedSuperSend := true.
  	BytecodeSetHasExtensions := true.
  	LongStoreBytecode := 245.
  	self table: BytecodeTable from:
  	#(	"1 byte bytecodes"
  		(   0  15 pushReceiverVariableBytecode)
  		( 16  31 pushLiteralVariable16CasesBytecode)
  		( 32  63 pushLiteralConstantBytecode)
  		( 64  75 pushTemporaryVariableBytecode)
  		( 76	 pushReceiverBytecode)
  		( 77	 pushConstantTrueBytecode)
  		( 78	 pushConstantFalseBytecode)
  		( 79	 pushConstantNilBytecode)
  		( 80	 pushConstantZeroBytecode)
  		( 81	 pushConstantOneBytecode)
  		( 82	 extPushPseudoVariable)
  		( 83	 duplicateTopBytecode)
  	
  		( 84 87	unknownBytecode)
  		( 88	returnReceiver)
  		( 89	returnTrue)
  		( 90	returnFalse)
  		( 91	returnNil)
  		( 92	returnTopFromMethod)
  		( 93	returnNilFromBlock)
  		( 94	returnTopFromBlock)
  		( 95	extNopBytecode)
  
  		( 96	 bytecodePrimAdd)
  		( 97	 bytecodePrimSubtract)
  		( 98	 bytecodePrimLessThanSistaV1) "for booleanCheatSistaV1:"
  		( 99	 bytecodePrimGreaterThanSistaV1) "for booleanCheatSistaV1:"
  		(100	 bytecodePrimLessOrEqualSistaV1) "for booleanCheatSistaV1:"
  		(101	 bytecodePrimGreaterOrEqualSistaV1) "for booleanCheatSistaV1:"
  		(102	 bytecodePrimEqualSistaV1) "for booleanCheatSistaV1:"
  		(103	 bytecodePrimNotEqualSistaV1) "for booleanCheatSistaV1:"
  		(104	 bytecodePrimMultiply)
  		(105	 bytecodePrimDivide)
  		(106	 bytecodePrimMod)
  		(107	 bytecodePrimMakePoint)
  		(108	 bytecodePrimBitShift)
  		(109	 bytecodePrimDiv)
  		(110	 bytecodePrimBitAnd)
  		(111	 bytecodePrimBitOr)
  
  		(112	 bytecodePrimAt)
  		(113	 bytecodePrimAtPut)
  		(114	 bytecodePrimSize)
  		(115	 bytecodePrimNext)		 "i.e. a 0 arg special selector"
  		(116	 bytecodePrimNextPut)		 "i.e. a 1 arg special selector"
  		(117	 bytecodePrimAtEnd)
  		(118	 bytecodePrimIdenticalSistaV1) "for booleanCheatSistaV1:"
  		(119	 bytecodePrimClass)
+ 		(120	 bytecodePrimNotIdenticalSistaV1) "was blockCopy:"
- 		(120	 bytecodePrimSpecialSelector24) "was blockCopy:"
  		(121	 bytecodePrimValue)
  		(122	 bytecodePrimValueWithArg)
  		(123	 bytecodePrimDo)			"i.e. a 1 arg special selector"
  		(124	 bytecodePrimNew)			"i.e. a 0 arg special selector"
  		(125	 bytecodePrimNewWithArg)	"i.e. a 1 arg special selector"
  		(126	 bytecodePrimPointX)		"i.e. a 0 arg special selector"
  		(127	 bytecodePrimPointY)		"i.e. a 0 arg special selector"
  
  		(128 143	sendLiteralSelector0ArgsBytecode)
  		(144 159	sendLiteralSelector1ArgBytecode)
  		(160 175	sendLiteralSelector2ArgsBytecode)
  
  		(176 183	shortUnconditionalJump)
  		(184 191	shortConditionalJumpTrue)
  		(192 199	shortConditionalJumpFalse)
  	
  		(200 207	storeAndPopReceiverVariableBytecode)
  		(208 215	storeAndPopTemporaryVariableBytecode)
  		(216		popStackBytecode)
  		(217		unconditionnalTrapBytecode)
  
  		(218 223	unknownBytecode)
  
  		"2 byte bytecodes"
  		(224		extABytecode)
  		(225		extBBytecode)
  
  		(226		extPushReceiverVariableBytecode)
  		(227		extPushLiteralVariableBytecode)
  		(228		extPushLiteralBytecode)
  		(229		longPushTemporaryVariableBytecode)
  		(230		unknownBytecode)
  		(231		pushNewArrayBytecode)
  		(232		extPushIntegerBytecode)
  		(233		extPushCharacterBytecode)
  
  		(234		extSendBytecode)
  		(235		extSendSuperBytecode)
  
  		(236		unknownBytecode)
  
  		(237		extUnconditionalJump)
  		(238		extJumpIfTrue)
  		(239		extJumpIfFalse)
  
  		(240		extSistaStoreAndPopReceiverVariableBytecode)
  		(241		extSistaStoreAndPopLiteralVariableBytecode)
  		(242		longStoreAndPopTemporaryVariableBytecode)
  
  		(243		extSistaStoreReceiverVariableBytecode)
  		(244		extSistaStoreLiteralVariableBytecode)
  		(245		longStoreTemporaryVariableBytecode)
  
  		(246 247	unknownBytecode)
  
  		"3 byte bytecodes"
  		(248		callPrimitiveBytecode)
  		(249		extPushFullClosureBytecode)
  
  		(250		extPushClosureBytecode)
  		(251		extPushRemoteTempOrInstVarLongBytecode)
  		(252		extStoreRemoteTempOrInstVarLongBytecode)
  		(253		extStoreAndPopRemoteTempOrInstVarLongBytecode)
  				
  		(254		extJumpIfNotInstanceOfBehaviorsBytecode)
  
  		(255		unknownBytecode)
  	)!

Item was changed:
  ----- Method: StackInterpreter class>>initializeBytecodeTableForSqueakV3PlusClosures (in category 'initialization') -----
  initializeBytecodeTableForSqueakV3PlusClosures
  	"StackInterpreter initializeBytecodeTableForSqueakV3PlusClosures"
  	"Note: This table will be used to generate a C switch statement."
  
  	initializationOptions at: #SqueakV3PlusClosuresBytecodeSet put: (SqueakV3PlusClosuresBytecodeSet := true).
  
  	BytecodeTable := Array new: 256.
  	BytecodeEncoderClassName := #EncoderForV3PlusClosures.
  	LongStoreBytecode := 129.
  	self table: BytecodeTable from:
  	#(
  		(  0  15 pushReceiverVariableBytecode)
  		( 16  31 pushTemporaryVariableBytecode)
  		( 32  63 pushLiteralConstantBytecode)
  		( 64  95 pushLiteralVariableBytecode)
  		( 96 103 storeAndPopReceiverVariableBytecode)
  		(104 111 storeAndPopTemporaryVariableBytecode)
  		(112 pushReceiverBytecode)
  		(113 pushConstantTrueBytecode)
  		(114 pushConstantFalseBytecode)
  		(115 pushConstantNilBytecode)
  		(116 pushConstantMinusOneBytecode)
  		(117 pushConstantZeroBytecode)
  		(118 pushConstantOneBytecode)
  		(119 pushConstantTwoBytecode)
  		(120 returnReceiver)
  		(121 returnTrue)
  		(122 returnFalse)
  		(123 returnNil)
  		(124 returnTopFromMethod)
  		(125 returnTopFromBlock)
  
  		(126 127 unknownBytecode)
  
  		(128 extendedPushBytecode)
  		(129 extendedStoreBytecode)
  		(130 extendedStoreAndPopBytecode)
  		(131 singleExtendedSendBytecode)
  		(132 doubleExtendedDoAnythingBytecode)
  		(133 singleExtendedSuperBytecode)
  		(134 secondExtendedSendBytecode)
  		(135 popStackBytecode)
  		(136 duplicateTopBytecode)
  
  		(137 pushActiveContextBytecode)
  		(138 pushNewArrayBytecode)),
  
  	((initializationOptions at: #SpurObjectMemory ifAbsent: [false])
  		ifTrue: [#((139 callPrimitiveBytecode))]	"V3PlusClosures on Spur"
  		ifFalse: [#((139 unknownBytecode))]),	"V3PlusClosures on V3"
  
  	  #(
  		(140 pushRemoteTempLongBytecode)
  		(141 storeRemoteTempLongBytecode)
  		(142 storeAndPopRemoteTempLongBytecode)
  		(143 pushClosureCopyCopiedValuesBytecode)
  
  		(144 151 shortUnconditionalJump)
  		(152 159 shortConditionalJumpFalse)
  		(160 167 longUnconditionalJump)
  		(168 171 longJumpIfTrue)
  		(172 175 longJumpIfFalse)
  
  		"176-191 were sendArithmeticSelectorBytecode"
  		(176 bytecodePrimAdd)
  		(177 bytecodePrimSubtract)
  		(178 bytecodePrimLessThan)
  		(179 bytecodePrimGreaterThan)
  		(180 bytecodePrimLessOrEqual)
  		(181 bytecodePrimGreaterOrEqual)
  		(182 bytecodePrimEqual)
  		(183 bytecodePrimNotEqual)
  		(184 bytecodePrimMultiply)
  		(185 bytecodePrimDivide)
  		(186 bytecodePrimMod)
  		(187 bytecodePrimMakePoint)
  		(188 bytecodePrimBitShift)
  		(189 bytecodePrimDiv)
  		(190 bytecodePrimBitAnd)
  		(191 bytecodePrimBitOr)
  
  		"192-207 were sendCommonSelectorBytecode"
  		(192 bytecodePrimAt)
  		(193 bytecodePrimAtPut)
  		(194 bytecodePrimSize)
  		(195 bytecodePrimNext)
  		(196 bytecodePrimNextPut)
  		(197 bytecodePrimAtEnd)
  		(198 bytecodePrimIdentical)
  		(199 bytecodePrimClass)
+ 		(200 bytecodePrimNotIdentical) "was bytecodePrimSpecialSelector24 / blockCopy"
- 		(200 bytecodePrimSpecialSelector24)
  		(201 bytecodePrimValue)
  		(202 bytecodePrimValueWithArg)
  		(203 bytecodePrimDo)
  		(204 bytecodePrimNew)
  		(205 bytecodePrimNewWithArg)
  		(206 bytecodePrimPointX)
  		(207 bytecodePrimPointY)
  
  		(208 223 sendLiteralSelector0ArgsBytecode)
  		(224 239 sendLiteralSelector1ArgBytecode)
  		(240 255 sendLiteralSelector2ArgsBytecode)
  	)!

Item was added:
+ ----- Method: StackInterpreter>>bytecodePrimNotIdentical (in category 'common selector sends') -----
+ bytecodePrimNotIdentical
+ 	| rcvr arg |
+ 	rcvr := self internalStackValue: 1.
+ 	(objectMemory isOopForwarded: rcvr) ifTrue:
+ 		[rcvr := self handleSpecialSelectorSendFaultFor: rcvr].
+ 	arg := self internalStackValue: 0.
+ 	(objectMemory isOopForwarded: arg) ifTrue:
+ 		[arg := self handleSpecialSelectorSendFaultFor: arg].
+ 	self booleanCheat: rcvr ~= arg!

Item was added:
+ ----- Method: StackInterpreter>>bytecodePrimNotIdenticalSistaV1 (in category 'common selector sends') -----
+ bytecodePrimNotIdenticalSistaV1
+ 	| rcvr arg |
+ 	rcvr := self internalStackValue: 1.
+ 	arg := self internalStackValue: 0.
+ 	(objectMemory isOopForwarded: rcvr) ifTrue:
+ 		[rcvr := self handleSpecialSelectorSendFaultFor: rcvr].
+ 	(objectMemory isOopForwarded: arg) ifTrue:
+ 		[arg := self handleSpecialSelectorSendFaultFor: arg].
+ 	self booleanCheatSistaV1: rcvr ~= arg!

Item was added:
+ ----- Method: StackInterpreter>>bytecodePrimNotIdenticalV4 (in category 'common selector sends') -----
+ bytecodePrimNotIdenticalV4
+ 	| rcvr arg |
+ 	rcvr := self internalStackValue: 1.
+ 	arg := self internalStackValue: 0.
+ 	(objectMemory isOopForwarded: rcvr) ifTrue:
+ 		[rcvr := self handleSpecialSelectorSendFaultFor: rcvr].
+ 	(objectMemory isOopForwarded: arg) ifTrue:
+ 		[arg := self handleSpecialSelectorSendFaultFor: arg].
+ 	self booleanCheatV4: rcvr ~= arg!

Item was changed:
  ----- Method: StackToRegisterMappingCogit class>>initializeBytecodeTableForNewspeakV4 (in category 'class initialization') -----
  initializeBytecodeTableForNewspeakV4
  	"StackToRegisterMappingCogit initializeBytecodeTableForNewspeakV4"
  
  	numPushNilsFunction := #v4:Num:Push:Nils:.
  	pushNilSizeFunction := #v4PushNilSize:numInitialNils:.
  	NSSendIsPCAnnotated := true. "IsNSSendCall used by SendAbsentImplicit"
  	FirstSpecialSelector := 80.
  	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"
  		(1    0   15 genPushReceiverVariableBytecode isInstVarRef needsFrameNever: 1)
  		(1  16   31 genPushLiteralVariable16CasesBytecode needsFrameNever: 1)
  		(1  32   63 genPushLiteralConstantBytecode needsFrameNever: 1)
  		(1  64   75 genPushTemporaryVariableBytecode needsFrameIfMod16GENumArgs: 1)
  		(1  76   76 genPushReceiverBytecode needsFrameNever: 1)
  		(1  77   77 genExtPushPseudoVariableOrOuterBytecode needsFrameIfExtBGT2: 1)
  		(1  78   78 genPushConstantZeroBytecode needsFrameNever: 1)
  		(1  79   79 genPushConstantOneBytecode needsFrameNever: 1)
  
  		(1   80   80 genSpecialSelectorArithmetic isMapped AddRR)
  		(1   81   81 genSpecialSelectorArithmetic isMapped SubRR)
  		(1   82   82 genSpecialSelectorComparison isMapped JumpLess)
  		(1   83   83 genSpecialSelectorComparison isMapped JumpGreater)
  		(1   84   84 genSpecialSelectorComparison isMapped JumpLessOrEqual)
  		(1   85   85 genSpecialSelectorComparison isMapped JumpGreaterOrEqual)
  		(1   86   86 genSpecialSelectorComparison isMapped JumpZero)
  		(1   87   87 genSpecialSelectorComparison isMapped JumpNonZero)
  		(1   88   93 genSpecialSelectorSend isMapped)	 " #* #/ #\\ #@ #bitShift: //"
  		(1   94   94 genSpecialSelectorArithmetic isMapped AndRR)
  		(1   95   95 genSpecialSelectorArithmetic isMapped OrRR)
  		(1   96 101 genSpecialSelectorSend isMapped) "#at: #at:put: #size #next #nextPut: #atEnd"
  		(1 102 102 genSpecialSelectorEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
  		(1 103 103 genSpecialSelectorClass needsFrameIfStackGreaterThanOne: notMapped 0) "not mapped because it is directly inlined (for now)"
+ 		(1 104 104 genSpecialSelectorNotEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
+ 		(1 105 111 genSpecialSelectorSend isMapped) " #value #value: #do: #new #new: #x #y"
- 		(1 104 111 genSpecialSelectorSend isMapped) "#blockCopy: #value #value: #do: #new #new: #x #y"
  
  		(1 112 127 genSendLiteralSelector0ArgsBytecode isMapped)
  		(1 128 143 genSendLiteralSelector1ArgBytecode isMapped)
  		(1 144 159 genSendLiteralSelector2ArgsBytecode isMapped)
  		(1 160 175	genSendAbsentImplicit0ArgsBytecode isMapped hasIRC)
  			
  		(1 176 183 genStoreAndPopReceiverVariableBytecode isInstVarRef is1ByteInstVarStore isMappedIfImmutability needsFrameIfImmutability: -1)
  			
  		(1 184 191 genStoreAndPopTemporaryVariableBytecode)
  
  		(1 192 199 genShortUnconditionalJump	branch v3:ShortForward:Branch:Distance:)
  		(1 200 207 genShortJumpIfTrue			branch isBranchTrue isMapped "because of mustBeBoolean"
  													v3:ShortForward:Branch:Distance:)
  		(1 208 215 genShortJumpIfFalse			branch isBranchFalse isMapped "because of mustBeBoolean"
  													v3:ShortForward:Branch:Distance:)
  
  		(1 216 216 genReturnReceiver				return needsFrameIfInBlock: isMappedInBlock 0)
  		(1 217 217 genReturnTopFromMethod		return needsFrameIfInBlock: isMappedInBlock -1)
  		(1 218 218 genExtReturnTopFromBlock	return needsFrameNever: -1)
  
  		(1 219 219 duplicateTopBytecode			needsFrameNever: 1)
  		(1 220 220 genPopStackBytecode			needsFrameNever: -1)
  		(1 221 221 genExtNopBytecode			needsFrameNever: 0)
  		(1 222 223	unknownBytecode)
  
  		"2 byte bytecodes"
  		(2 224 224 extABytecode extension					needsFrameNever: 0)
  		(2 225 225 extBBytecode extension					needsFrameNever: 0)
  		(2 226 226 genExtPushReceiverVariableBytecode isInstVarRef)
  		(2 227 227 genExtPushLiteralVariableBytecode		needsFrameNever: 1)
  		(2 228 228 genExtPushLiteralBytecode					needsFrameNever: 1)
  		(2 229 229 genExtPushIntegerBytecode				needsFrameNever: 1)
  		(2 230 230 genLongPushTemporaryVariableBytecode)
  		(2 231 231 genPushNewArrayBytecode)
  		(2 232 232 genExtStoreReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
  		(2 233 233 genExtStoreLiteralVariableBytecode isMappedIfImmutability)
  		(2 234 234 genLongStoreTemporaryVariableBytecode)
  		(2 235 235 genExtStoreAndPopReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
  		(2 236 236 genExtStoreAndPopLiteralVariableBytecode isMappedIfImmutability)
  		(2 237 237 genLongStoreAndPopTemporaryVariableBytecode)
  
  		(2 238 238 genExtSendBytecode isMapped)
  		(2 239 239 genExtSendSuperBytecode isMapped)
  		(2 240 240 genExtSendAbsentImplicitBytecode isMapped hasIRC)
  		(2 241 241 genExtSendAbsentDynamicSuperBytecode isMapped hasIRC)
  
  		(2 242 242 genExtUnconditionalJump	branch isMapped "because of interrupt check" v4:Long:Branch:Distance:)
  		(2 243 243 genExtJumpIfTrue			branch isBranchTrue isMapped "because of mustBeBoolean" v4:Long:Branch:Distance:)
  		(2 244 244 genExtJumpIfFalse			branch isBranchFalse isMapped "because of mustBeBoolean" v4:Long:Branch:Distance:)
  
  		(2 245 245	genExtSendAbsentSelfBytecode isMapped hasIRC)
  
  		(2 246 248	unknownBytecode)
  
  		"3 byte bytecodes"
  		(3 249 249 genCallPrimitiveBytecode)
  		(3 250 250 genPushRemoteTempLongBytecode)
  		(3 251 251 genStoreRemoteTempLongBytecode)
  		(3 252 252 genStoreAndPopRemoteTempLongBytecode)
  		(3 253 253 genExtPushClosureBytecode block v4:Block:Code:Size:)
  		(3 254 254	genExtSendAbsentOuterBytecode isMapped hasIRC)
  
  		(3 255 255	unknownBytecode))!

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 120 genSpecialSelectorNotEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
+ 		(1 121 127 genSpecialSelectorSend isMapped) "#value #value: #do: #new #new: #x #y"
- 		(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 is1ByteInstVarStore 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 unknownBytecode)
  		(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 genSistaExtStoreAndPopReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
  		(2 241 241 genSistaExtStoreAndPopLiteralVariableBytecode isMappedIfImmutability)
  		(2 242 242 genLongStoreAndPopTemporaryVariableBytecode)
  		(2 243 243 genSistaExtStoreReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
  		(2 244 244 genSistaExtStoreLiteralVariableBytecode isMappedIfImmutability)
  		(2 245 245 genLongStoreTemporaryVariableBytecode)
  
  		(2 246 247	unknownBytecode)
  
  		"3 byte bytecodes"
  		(3 248 248 genCallPrimitiveBytecode)
  		(3 249 249 genExtPushFullClosureBytecode)
  		(3 250 250 genExtPushClosureBytecode block v4:Block:Code:Size:)
  		(3 251 251 genExtPushRemoteTempOrInstVarLongBytecode)
  		(3 252 252 genExtStoreRemoteTempOrInstVarLongBytecode isMappedIfImmutability)
  		(3 253 253 genExtStoreAndPopRemoteTempOrInstVarLongBytecode isMappedIfImmutability)
  
  		(3 254 254	genExtJumpIfNotInstanceOfBehaviorsBytecode branch v4:Long:BranchIfNotInstanceOf:Distance:)
  		
  		(3 255 255	unknownBytecode))!

Item was changed:
  ----- Method: StackToRegisterMappingCogit class>>initializeBytecodeTableForSqueakV3PlusClosures (in category 'class initialization') -----
  initializeBytecodeTableForSqueakV3PlusClosures
  	"StackToRegisterMappingCogit initializeBytecodeTableForSqueakV3PlusClosures"
  
  	numPushNilsFunction := #v3:Num:Push:Nils:.
  	pushNilSizeFunction := #v3PushNilSize:numInitialNils:.
  	FirstSpecialSelector := 176.
  	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    0   15 genPushReceiverVariableBytecode isInstVarRef needsFrameNever: 1)
  		(1  16   31 genPushTemporaryVariableBytecode needsFrameIfMod16GENumArgs: 1)
  		(1  32   63 genPushLiteralConstantBytecode needsFrameNever: 1)
  		(1  64   95 genPushLiteralVariableBytecode needsFrameNever: 1)
  		(1  96 103 genStoreAndPopReceiverVariableBytecode isInstVarRef is1ByteInstVarStore isMappedIfImmutability needsFrameIfImmutability: -1)
  		(1 104 111 genStoreAndPopTemporaryVariableBytecode)
  		(1 112 112 genPushReceiverBytecode needsFrameNever: 1)
  		(1 113 113 genPushConstantTrueBytecode needsFrameNever: 1)
  		(1 114 114 genPushConstantFalseBytecode needsFrameNever: 1)
  		(1 115 115 genPushConstantNilBytecode needsFrameNever: 1)
  		(1 116 119 genPushQuickIntegerConstantBytecode needsFrameNever: 1)
  		"method returns in blocks need a frame because of nonlocalReturn:through:"
  		(1 120 120 genReturnReceiver				return needsFrameIfInBlock: isMappedInBlock 0)
  		(1 121 121 genReturnTrue					return needsFrameIfInBlock: isMappedInBlock 0)
  		(1 122 122 genReturnFalse					return needsFrameIfInBlock: isMappedInBlock 0)
  		(1 123 123 genReturnNil					return needsFrameIfInBlock: isMappedInBlock 0)
  		(1 124 124 genReturnTopFromMethod		return needsFrameIfInBlock: isMappedInBlock -1)
  		(1 125 125 genReturnTopFromBlock		return needsFrameNever: -1)
  
  		(1 126 127 unknownBytecode)
  
  		(2 128 128 extendedPushBytecode isInstVarRef) "well, maybe inst var ref"
  		(2 129 129 extendedStoreBytecode isInstVarRef isMappedIfImmutability) "well, maybe inst var ref"
  		(2 130 130 extendedStoreAndPopBytecode isInstVarRef isMappedIfImmutability) "well, maybe inst var ref"
  		(2 131 131 genExtendedSendBytecode isMapped)
  		(3 132 132 doubleExtendedDoAnythingBytecode isMapped) "well, maybe inst var ref"
  		(2 133 133 genExtendedSuperBytecode isInstVarRef isMapped)
  		(2 134 134 genSecondExtendedSendBytecode isMapped)
  		(1 135 135 genPopStackBytecode needsFrameNever: -1)
  		(1 136 136 duplicateTopBytecode needsFrameNever: 1)
  
  		(1 137 137 genPushActiveContextBytecode)
  		(2 138 138 genPushNewArrayBytecode)),
  
  		((initializationOptions at: #SpurObjectMemory ifAbsent: [false])
  			ifTrue: [#((3 139 139 genCallPrimitiveBytecode))]
  			ifFalse: [#((1 139 139 unknownBytecode))]),
  
  	   #(
  		(3 140 140 genPushRemoteTempLongBytecode)
  		(3 141 141 genStoreRemoteTempLongBytecode)
  		(3 142 142 genStoreAndPopRemoteTempLongBytecode)
  		(4 143 143 genPushClosureCopyCopiedValuesBytecode block v3:Block:Code:Size:)
  
  		(1 144 151 genShortUnconditionalJump			branch v3:ShortForward:Branch:Distance:)
  		(1 152 159 genShortJumpIfFalse					branch isBranchFalse isMapped "because of mustBeBoolean"
  															v3:ShortForward:Branch:Distance:)
  		(2 160 163 genLongUnconditionalBackwardJump	branch isMapped "because of interrupt check"
  															v3:Long:Branch:Distance:)
  		(2 164 167 genLongUnconditionalForwardJump		branch v3:Long:Branch:Distance:)
  		(2 168 171 genLongJumpIfTrue					branch isBranchTrue isMapped "because of mustBeBoolean"
  															v3:LongForward:Branch:Distance:)
  		(2 172 175 genLongJumpIfFalse					branch isBranchFalse isMapped "because of mustBeBoolean"
  															v3:LongForward:Branch:Distance:)
  
  		(1 176 176 genSpecialSelectorArithmetic isMapped AddRR)
  		(1 177 177 genSpecialSelectorArithmetic isMapped SubRR)
  		(1 178 178 genSpecialSelectorComparison isMapped JumpLess)
  		(1 179 179 genSpecialSelectorComparison isMapped JumpGreater)
  		(1 180 180 genSpecialSelectorComparison isMapped JumpLessOrEqual)
  		(1 181 181 genSpecialSelectorComparison isMapped JumpGreaterOrEqual)
  		(1 182 182 genSpecialSelectorComparison isMapped JumpZero)
  		(1 183 183 genSpecialSelectorComparison isMapped JumpNonZero)
  		(1 184 189 genSpecialSelectorSend isMapped)	 " #* #/ #\\ #@ #bitShift: //"
  		(1 190 190 genSpecialSelectorArithmetic isMapped AndRR)
  		(1 191 191 genSpecialSelectorArithmetic isMapped OrRR)
  		(1 192 197 genSpecialSelectorSend isMapped) "#at: #at:put: #size #next #nextPut: #atEnd"
  		(1 198 198 genSpecialSelectorEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
  		(1 199 199 genSpecialSelectorClass needsFrameIfStackGreaterThanOne: notMapped 0) "not mapped because it is directly inlined (for now)"
+ 		(1 200 200 genSpecialSelectorNotEqualsEquals needsFrameNever: notMapped -1) "not mapped because it is directly inlined (for now)"
+ 		(1 201 207 genSpecialSelectorSend isMapped) " #value #value: #do: #new #new: #x #y"
- 		(1 200 207 genSpecialSelectorSend isMapped) "#blockCopy: #value #value: #do: #new #new: #x #y"
  		(1 208 223 genSendLiteralSelector0ArgsBytecode isMapped)
  		(1 224 239 genSendLiteralSelector1ArgBytecode isMapped)
  		(1 240 255 genSendLiteralSelector2ArgsBytecode isMapped))!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: (in category 'bytecode generator support') -----
+ genCmpArgIsConstant: argIsConstant rcvrIsConstant: rcvrIsConstant argReg: argReg rcvrReg: rcvrReg
+ 	"Generates the Cmp instruction for the top two ssStack values. 
+ 	ssTop is called the argument and ssValue: 1 is called the receiver.
+ 	0 or 1 value on ssStack is a constant (but not 2). If a value is a constant, then noReg is passed as argReg or rcvrReg.
+ 	The instruction is different if one of the operands is a constant.
+ 	In the case of the v3 memory manager, the constant could be annotable."
+ 	<inline: true>
+ 	self assert: (argReg ~= NoReg or: [rcvrReg ~= NoReg]).
+ 	argIsConstant 
+ 		ifTrue: [ self genCmpConstant: self ssTop constant R: rcvrReg ]
+ 		ifFalse: [ rcvrIsConstant
+ 			ifTrue: [ self genCmpConstant: (self ssValue: 1) constant R: argReg ]
+ 			ifFalse: [ self CmpR: argReg R: rcvrReg ] ].!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genEqualsEqualsComparisonArgIsConstant:rcvrIsConstant:argReg:rcvrReg: (in category 'bytecode generator support') -----
- genEqualsEqualsComparisonArgIsConstant: argIsConstant rcvrIsConstant: rcvrIsConstant argReg: argReg rcvrReg: rcvrReg
- 	"Generates the Cmp instruction for #==. The instruction is different if one of the operands is a constant.
- 	In the case of the v3 memory manager, the constant could be annotable." 
- 	<inline: true>
- 	argIsConstant 
- 		ifTrue: [ self genCmpConstant: self ssTop constant R: rcvrReg ]
- 		ifFalse: [ rcvrIsConstant
- 			ifTrue: [ self genCmpConstant: (self ssValue: 1) constant R: argReg ]
- 			ifFalse: [ self CmpR: argReg R: rcvrReg ] ].!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genEqualsEqualsNoBranchArgIsConstant:rcvrIsConstant:argReg:rcvrReg: (in category 'bytecode generator support') -----
- genEqualsEqualsNoBranchArgIsConstant: argIsConstant rcvrIsConstant: rcvrIsConstant argReg: argReg rcvrReg: rcvrRegOrNone
- 	"Generates the machine code for #== in the case where the instruction is not followed by a branch"
- 	| label jumpEqual jumpNotEqual resultReg |
- 	<var: #label type: #'AbstractInstruction *'>
- 	<var: #jumpEqual type: #'AbstractInstruction *'>
- 	<var: #jumpNotEqual type: #'AbstractInstruction *'>
- 	label := self Label.
- 	self genEqualsEqualsComparisonArgIsConstant: argIsConstant rcvrIsConstant: rcvrIsConstant argReg: argReg rcvrReg: rcvrRegOrNone.
- 	self ssPop: 2.
- 	resultReg := rcvrRegOrNone = NoReg ifTrue: [argReg] ifFalse: [rcvrRegOrNone].
- 	jumpEqual := self JumpZero: 0.
- 	 argIsConstant ifFalse:
- 		[objectRepresentation genEnsureOopInRegNotForwarded: argReg scratchReg: TempReg jumpBackTo: label].
- 	 rcvrIsConstant ifFalse:
- 		[objectRepresentation genEnsureOopInRegNotForwarded: rcvrRegOrNone scratchReg: TempReg jumpBackTo: label].
- 	 self genMoveFalseR: resultReg.
- 	 jumpNotEqual := self Jump: 0.
- 	 jumpEqual jmpTarget: (self genMoveTrueR: resultReg).
- 	 jumpNotEqual jmpTarget: self Label.
- 	 self ssPushRegister: resultReg.
- 	 ^0!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genForwardersInlinedIdenticalOrNotIf: (in category 'bytecode generators') -----
+ genForwardersInlinedIdenticalOrNotIf: orNot
+ 	| nextPC branchDescriptor unforwardRcvr argReg targetBytecodePC
+ 	unforwardArg  rcvrReg postBranchPC label fixup |
+ 	<var: #branchDescriptor type: #'BytecodeDescriptor *'>
+ 	<var: #label type: #'AbstractInstruction *'>
+ 	
+ 	self extractMaybeBranchDescriptorInto: [ :descr :next :postBranch :target | 
+ 		branchDescriptor := descr. nextPC := next. postBranchPC := postBranch. targetBytecodePC := target ].
+ 
+ 	"If an operand is an annotable constant, it may be forwarded, so we need to store it into a 
+ 	register so the forwarder check can jump back to the comparison after unforwarding the constant.
+ 	However, if one of the operand is an unnanotable constant, does not allocate a register for it 
+ 	(machine code will use operations on constants) and does not generate forwarder checks."
+ 	unforwardRcvr := (objectRepresentation isUnannotatableConstant: (self ssValue: 1)) not.
+ 	unforwardArg := (objectRepresentation isUnannotatableConstant: self ssTop) not.
+ 
+ 	self 
+ 		allocateEqualsEqualsRegistersArgNeedsReg: unforwardArg 
+ 		rcvrNeedsReg: unforwardRcvr 
+ 		into: [ :rcvr :arg | rcvrReg:= rcvr. argReg := arg ].
+ 
+ 	"If not followed by a branch, resolve to true or false."
+ 	(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifFalse:
+ 		[^ self 
+ 			genIdenticalNoBranchArgIsConstant: unforwardArg not
+ 			rcvrIsConstant: unforwardRcvr not
+ 			argReg: argReg 
+ 			rcvrReg: rcvrReg 
+ 			orNotIf: orNot].
+ 	
+ 	"If branching the stack must be flushed for the merge"
+ 	self ssFlushTo: simStackPtr - 2.
+ 	
+ 	label := self Label.
+ 	self genCmpArgIsConstant: unforwardArg not rcvrIsConstant: unforwardRcvr not argReg: argReg rcvrReg: rcvrReg.
+ 	self ssPop: 2.
+ 
+ 	"Further since there is a following conditional jump bytecode, define
+ 	 non-merge fixups and leave the cond bytecode to set the mergeness."
+ 	(self fixupAt: nextPC - initialPC) notAFixup
+ 		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]).
+ 	"We could use (branchDescriptor isBranchTrue xor: orNot) to simplify this."
+ 	orNot 
+ 		ifFalse: [branchDescriptor isBranchTrue
+ 					ifTrue: 
+ 						[ fixup := (self ensureNonMergeFixupAt: postBranchPC - initialPC) asUnsignedInteger.
+ 						self JumpZero:  (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger ]
+ 					ifFalse: "branchDescriptor is branchFalse"
+ 						[ fixup := (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
+ 						self JumpZero: (self ensureNonMergeFixupAt: postBranchPC - initialPC) asUnsignedInteger ]]
+ 		ifTrue: [branchDescriptor isBranchTrue
+ 					ifFalse: "branchDescriptor is branchFalse"
+ 						[ fixup := (self ensureNonMergeFixupAt: postBranchPC - initialPC) asUnsignedInteger.
+ 						self JumpZero:  (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger ]
+ 					ifTrue:
+ 						[ fixup := (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
+ 						self JumpZero: (self ensureNonMergeFixupAt: postBranchPC - initialPC) asUnsignedInteger ]].
+ 		
+ 	"The forwarders checks need to jump back to the comparison (label) if a forwarder is found, else 
+ 	jump forward either to the next forwarder check or to the postBranch or branch target (fixup)."
+ 	unforwardArg ifTrue: 
+ 		[ unforwardRcvr
+ 			ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: argReg scratchReg: TempReg jumpBackTo: label ]
+ 			ifFalse: [ objectRepresentation 
+ 				genEnsureOopInRegNotForwarded: argReg 
+ 				scratchReg: TempReg 
+ 				ifForwarder: label
+ 				ifNotForwarder: fixup ] ].
+ 	unforwardRcvr ifTrue: 
+ 		[ objectRepresentation 
+ 			genEnsureOopInRegNotForwarded: rcvrReg 
+ 			scratchReg: TempReg 
+ 			ifForwarder: label
+ 			ifNotForwarder: fixup ].
+ 		
+ 	"Not reached, execution flow have jumped to fixup"
+ 	
+ 	^0!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genIdenticalNoBranchArgIsConstant:rcvrIsConstant:argReg:rcvrReg:orNotIf: (in category 'bytecode generator support') -----
+ genIdenticalNoBranchArgIsConstant: argIsConstant rcvrIsConstant: rcvrIsConstant argReg: argReg rcvrReg: rcvrRegOrNone orNotIf: orNot
+ 	"Generates the machine code for #== in the case where the instruction is not followed by a branch"
+ 	| label jumpEqual jumpNotEqual resultReg |
+ 	<var: #label type: #'AbstractInstruction *'>
+ 	<var: #jumpEqual type: #'AbstractInstruction *'>
+ 	<var: #jumpNotEqual type: #'AbstractInstruction *'>
+ 	label := self Label.
+ 	self genCmpArgIsConstant: argIsConstant rcvrIsConstant: rcvrIsConstant argReg: argReg rcvrReg: rcvrRegOrNone.
+ 	self ssPop: 2.
+ 	resultReg := rcvrRegOrNone = NoReg ifTrue: [argReg] ifFalse: [rcvrRegOrNone].
+ 	jumpEqual := self JumpZero: 0.
+ 	 argIsConstant ifFalse:
+ 		[objectRepresentation genEnsureOopInRegNotForwarded: argReg scratchReg: TempReg jumpBackTo: label].
+ 	 rcvrIsConstant ifFalse:
+ 		[objectRepresentation genEnsureOopInRegNotForwarded: rcvrRegOrNone scratchReg: TempReg jumpBackTo: label].
+ 	 orNot ifFalse: [self genMoveFalseR: resultReg] ifTrue: [self genMoveTrueR: resultReg].
+ 	 jumpNotEqual := self Jump: 0.
+ 	 jumpEqual jmpTarget: (orNot ifFalse: [self genMoveTrueR: resultReg] ifTrue: [self genMoveFalseR: resultReg]).
+ 	 jumpNotEqual jmpTarget: self Label.
+ 	 self ssPushRegister: resultReg.
+ 	 ^0!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genInlinedIdenticalOrNotIf: (in category 'bytecode generators') -----
+ genInlinedIdenticalOrNotIf: orNot
+ 	"Decompose code generation for #== into a common constant-folding version,
+ 	 followed by a double dispatch throguh the objectRepresentation to a version
+ 	 that doesn't deal with forwarders and a version that does."
+ 	| primDescriptor result |
+ 	<var: #primDescriptor type: #'BytecodeDescriptor *'>
+ 	primDescriptor := self generatorAt: byte0.
+ 	
+ 	((objectRepresentation isUnannotatableConstant: self ssTop)
+ 	 and: [ objectRepresentation isUnannotatableConstant: (self ssValue: 1) ]) ifTrue:
+ 		[self assert: primDescriptor isMapped not.
+ 		 result := (orNot
+ 					ifFalse: [self ssTop constant = (self ssValue: 1) constant]
+ 					ifTrue: [self ssTop constant ~= (self ssValue: 1) constant])
+ 									ifTrue: [objectMemory trueObject]
+ 									ifFalse: [objectMemory falseObject].
+ 		 self ssPop: 2.
+ 		 ^self ssPushConstant: result].
+ 
+ 	^objectRepresentation genInlinedIdenticalOrNotIfGuts: orNot!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genSpecialSelectorEqualsEquals (in category 'bytecode generators') -----
- genSpecialSelectorEqualsEquals
- 	"Decompose code generation for #== into a common constant-folding version,
- 	 followed by a double dispatch throguh the objectRepresentation to a version
- 	 that doesn't deal with forwarders and a version that does."
- 	| primDescriptor result |
- 	<var: #primDescriptor type: #'BytecodeDescriptor *'>
- 	primDescriptor := self generatorAt: byte0.
- 	
- 	((objectRepresentation isUnannotatableConstant: self ssTop)
- 	 and: [ objectRepresentation isUnannotatableConstant: (self ssValue: 1) ]) ifTrue:
- 		[self assert: primDescriptor isMapped not.
- 		 result := self ssTop constant = (self ssValue: 1) constant
- 									ifTrue: [objectMemory trueObject]
- 									ifFalse: [objectMemory falseObject].
- 		 self ssPop: 2.
- 		 ^self ssPushConstant: result].
- 
- 	^objectRepresentation genSpecialSelectorEqualsEqualsGuts!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genSpecialSelectorEqualsEqualsWithForwarders (in category 'bytecode generators') -----
- genSpecialSelectorEqualsEqualsWithForwarders
- 	| nextPC branchDescriptor unforwardRcvr argReg targetBytecodePC
- 	unforwardArg  rcvrReg postBranchPC label fixup |
- 	<var: #branchDescriptor type: #'BytecodeDescriptor *'>
- 	<var: #label type: #'AbstractInstruction *'>
- 	
- 	self extractMaybeBranchDescriptorInto: [ :descr :next :postBranch :target | 
- 		branchDescriptor := descr. nextPC := next. postBranchPC := postBranch. targetBytecodePC := target ].
- 
- 	"If an operand is an annotable constant, it may be forwarded, so we need to store it into a 
- 	register so the forwarder check can jump back to the comparison after unforwarding the constant.
- 	However, if one of the operand is an unnanotable constant, does not allocate a register for it 
- 	(machine code will use operations on constants) and does not generate forwarder checks."
- 	unforwardRcvr := (objectRepresentation isUnannotatableConstant: (self ssValue: 1)) not.
- 	unforwardArg := (objectRepresentation isUnannotatableConstant: self ssTop) not.
- 
- 	self 
- 		allocateEqualsEqualsRegistersArgNeedsReg: unforwardArg 
- 		rcvrNeedsReg: unforwardRcvr 
- 		into: [ :rcvr :arg | rcvrReg:= rcvr. argReg := arg ].
- 
- 	"If not followed by a branch, resolve to true or false."
- 	(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifFalse:
- 		[^ self genEqualsEqualsNoBranchArgIsConstant: unforwardArg not rcvrIsConstant: unforwardRcvr not argReg: argReg rcvrReg: rcvrReg].
- 	
- 	"If branching the stack must be flushed for the merge"
- 	self ssFlushTo: simStackPtr - 2.
- 	
- 	label := self Label.
- 	self genEqualsEqualsComparisonArgIsConstant: unforwardArg not rcvrIsConstant: unforwardRcvr not argReg: argReg rcvrReg: rcvrReg.
- 	self ssPop: 2.
- 
- 	"Further since there is a following conditional jump bytecode, define
- 	 non-merge fixups and leave the cond bytecode to set the mergeness."
- 	(self fixupAt: nextPC - initialPC) notAFixup
- 		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: 
- 			[ fixup := (self ensureNonMergeFixupAt: postBranchPC - initialPC) asUnsignedInteger.
- 			self JumpZero:  (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger ]
- 		ifFalse: "branchDescriptor is branchFalse"
- 			[ fixup := (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
- 			self JumpZero: (self ensureNonMergeFixupAt: postBranchPC - initialPC) asUnsignedInteger ].
- 		
- 	"The forwarders checks need to jump back to the comparison (label) if a forwarder is found, else 
- 	jump forward either to the next forwarder check or to the postBranch or branch target (fixup)."
- 	unforwardArg ifTrue: 
- 		[ unforwardRcvr
- 			ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: argReg scratchReg: TempReg jumpBackTo: label ]
- 			ifFalse: [ objectRepresentation 
- 				genEnsureOopInRegNotForwarded: argReg 
- 				scratchReg: TempReg 
- 				ifForwarder: label
- 				ifNotForwarder: fixup ] ].
- 	unforwardRcvr ifTrue: 
- 		[ objectRepresentation 
- 			genEnsureOopInRegNotForwarded: rcvrReg 
- 			scratchReg: TempReg 
- 			ifForwarder: label
- 			ifNotForwarder: fixup ].
- 		
- 	"Not reached, execution flow have jumped to fixup"
- 	
- 	^0!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genVanillaInlinedIdenticalOrNotIf: (in category 'bytecode generators') -----
+ genVanillaInlinedIdenticalOrNotIf: orNot
+ 	| nextPC postBranchPC targetBytecodePC branchDescriptor
+ 	  rcvrReg argReg argIsConstant rcvrIsConstant  |
+ 	<var: #branchDescriptor type: #'BytecodeDescriptor *'>
+ 	
+ 	self extractMaybeBranchDescriptorInto: [ :descr :next :postBranch :target | 
+ 		branchDescriptor := descr. nextPC := next. postBranchPC := postBranch. targetBytecodePC := target ].
+ 	
+ 	argIsConstant := self ssTop type = SSConstant.
+ 	"They can't be both constants to use correct machine opcodes.
+ 	 However annotable constants can't be resolved statically, hence we need to careful."
+ 	rcvrIsConstant := argIsConstant not and: [(self ssValue: 1) type = SSConstant].
+ 	
+ 	self 
+ 		allocateEqualsEqualsRegistersArgNeedsReg: argIsConstant not 
+ 		rcvrNeedsReg: rcvrIsConstant not 
+ 		into: [ :rcvr :arg | rcvrReg:= rcvr. argReg := arg ].
+ 	
+ 	"If not followed by a branch, resolve to true or false."
+ 	(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifFalse:
+ 		[^ self 
+ 			genIdenticalNoBranchArgIsConstant: argIsConstant 
+ 			rcvrIsConstant: rcvrIsConstant 
+ 			argReg: argReg 
+ 			rcvrReg: rcvrReg 
+ 			orNotIf: orNot].
+ 	
+ 	"If branching the stack must be flushed for the merge"
+ 	self ssFlushTo: simStackPtr - 2.
+ 	
+ 	self genCmpArgIsConstant: argIsConstant rcvrIsConstant: rcvrIsConstant argReg: argReg rcvrReg: rcvrReg.
+ 	self ssPop: 2.
+ 
+ 	"Further since there is a following conditional jump bytecode, define
+ 	 non-merge fixups and leave the cond bytecode to set the mergeness."
+ 	(self fixupAt: nextPC - initialPC) notAFixup
+ 		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"
+ 		
+ 	"We could simplify this with a xor:"
+ 	self genConditionalBranch: (orNot 
+ 						ifFalse: [branchDescriptor isBranchTrue ifTrue: [JumpZero] ifFalse: [JumpNonZero]]
+ 						ifTrue: [branchDescriptor isBranchTrue ifTrue: [JumpNonZero] ifFalse: [JumpZero]])
+ 		operand: (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
+ 
+ 	"If the branch is dead, then we can just fall through postBranchPC (only a nop in-between), else 
+ 	we need to jump over the code of the branch"
+ 	deadCode ifFalse: [self Jump: (self ensureNonMergeFixupAt: postBranchPC - initialPC)].
+ 	^0!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genVanillaSpecialSelectorEqualsEquals (in category 'bytecode generators') -----
- genVanillaSpecialSelectorEqualsEquals
- 	| nextPC postBranchPC targetBytecodePC branchDescriptor
- 	  rcvrReg argReg argIsConstant rcvrIsConstant  |
- 	<var: #branchDescriptor type: #'BytecodeDescriptor *'>
- 	
- 	self extractMaybeBranchDescriptorInto: [ :descr :next :postBranch :target | 
- 		branchDescriptor := descr. nextPC := next. postBranchPC := postBranch. targetBytecodePC := target ].
- 	
- 	argIsConstant := self ssTop type = SSConstant.
- 	"they can't be both constants because we do not have instructions manipulating two constants, 
- 	if this is the case, which can happen due to annotable constants that can be moved in memory 
- 	with become and therefore can't resolve #== at compilation time, still write the rcvr into a 
- 	register as if it was not a constant. It's uncommon anyway."
- 	rcvrIsConstant := argIsConstant not and: [(self ssValue: 1) type = SSConstant]. 
- 	
- 	self 
- 		allocateEqualsEqualsRegistersArgNeedsReg: argIsConstant not 
- 		rcvrNeedsReg: rcvrIsConstant not 
- 		into: [ :rcvr :arg | rcvrReg:= rcvr. argReg := arg ].
- 	
- 	"If not followed by a branch, resolve to true or false."
- 	(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifFalse:
- 		[ ^ self genEqualsEqualsNoBranchArgIsConstant: argIsConstant rcvrIsConstant: rcvrIsConstant argReg: argReg rcvrReg: rcvrReg].
- 	
- 	"If branching the stack must be flushed for the merge"
- 	self ssFlushTo: simStackPtr - 2.
- 	
- 	self genEqualsEqualsComparisonArgIsConstant: argIsConstant rcvrIsConstant: rcvrIsConstant argReg: argReg rcvrReg: rcvrReg.
- 	self ssPop: 2.
- 
- 	"Further since there is a following conditional jump bytecode, define
- 	 non-merge fixups and leave the cond bytecode to set the mergeness."
- 	(self fixupAt: nextPC - initialPC) notAFixup
- 		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 genConditionalBranch: (branchDescriptor isBranchTrue ifTrue: [JumpZero] ifFalse: [JumpNonZero])
- 		operand: (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
- 
- 	"If the branch is dead, then we can just fall through postBranchPC (only a nop in-between), else 
- 	we need to jump over the code of the branch"
- 	deadCode ifFalse: [self Jump: (self ensureNonMergeFixupAt: postBranchPC - initialPC)].
- 	^0!



More information about the Vm-dev mailing list