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

commits at source.squeak.org commits at source.squeak.org
Mon Jul 25 11:54:51 UTC 2016


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

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

Name: VMMaker.oscog-cb.1907
Author: cb
Time: 25 July 2016, 1:53:25.249279 pm
UUID: 3597b83b-6797-4bfa-b629-5b36c88d9297
Ancestors: VMMaker.oscog-cb.1906

Fixed twoPath compilation both with and without immutability. I changed the test from "isInstVarStore" to "is1ByteInstVarStore" because other instVarStore may happen on context objects, requiring a frame. The compilation of Context>>setSender:receiver:method:closure:startpc: requires a frame for example. Without immutability, the two path is done for methods with multiple inst var stores and branch on the receiver's age. With immutability, all setters are compiled with two paths and branch on the receiver mutability and age. That's very funny because now the VM with immutability is clearly faster on binary tree than the VM before the two paths compilation (obviously we backported that to the non-immutability VM, so the VM without immutability is still faster). 

Added extB 3rd bit flag to mark if the store requires the immutability check or not in multiple store instructions (LitVar, instVar, RemoteInstVar). Fixed a zip (flag was inverted for no store check).

Recategorized heap store code generation to "bytecode-store" and all the ext tests to "testing". That can be reverted if one is not happy about that. 

Now that immutability is rock stable, I made two generic store methods, one for stores into maybe context objects, one for stores into non context objects. Both methods require multiple parameters such as "requireImmutabilityCheck" and "requireStoreCheck". The generic methods test for the IMMUTABILITY flag to know if they need to generate the test or not in addition to the parameter. Every heap store calls one of these two methods, so there's no code duplication. 

Fixed some methods to return error codes instead of 0.

Tried to improve multiple comments. When merging methods, I tried to keep all the comments from all methods. 

The simulator works fine, the VM compiles to C, but for some reason I can't compile from C to executable right now: ""_ioScreenScaleFactor", referenced from: _primitiveScreenScaleFactor in gcc3x-cointerp.o" so I'm only 99% sure this is working just fine.

=============== Diff against VMMaker.oscog-cb.1906 ===============

Item was changed:
  VMStructType subclass: #CogBytecodeDescriptor
+ 	instanceVariableNames: 'generator spanFunction needsFrameFunction stackDelta opcode numBytes isBranchTrue isBranchFalse isReturn isBlockCreation isMapped isMappedInBlock isExtension isInstVarRef is1ByteInstVarStore hasIRC'
- 	instanceVariableNames: 'generator spanFunction needsFrameFunction stackDelta opcode numBytes isBranchTrue isBranchFalse isReturn isBlockCreation isMapped isMappedInBlock isExtension isInstVarRef isInstVarStore hasIRC'
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'VMMaker-JIT'!
  
  !CogBytecodeDescriptor commentStamp: 'eem 11/18/2010 06:32' prior: 0!
  I am an entry in the Cogit's dispatch table for bytecodes.  I hold the routine to call to generate code for the partcular bytecode I represent and the number of bytes the bytecode has.  For eliminating temps in frameless blocks I maintain a stack delta for bytecodes that are valid in a frameless block.  The order of my instance variables is chosen for compact struct packing.!

Item was added:
+ ----- Method: CogBytecodeDescriptor>>is1ByteInstVarStore (in category 'accessing') -----
+ is1ByteInstVarStore
+ 	"Answer the value of is1ByteInstVarStore"
+ 
+ 	^ is1ByteInstVarStore!

Item was added:
+ ----- Method: CogBytecodeDescriptor>>is1ByteInstVarStore: (in category 'accessing') -----
+ is1ByteInstVarStore: anObject
+ 	"Set the value of is1ByteInstVarStore"
+ 
+ 	^is1ByteInstVarStore := anObject!

Item was removed:
- ----- Method: CogBytecodeDescriptor>>isInstVarStore (in category 'accessing') -----
- isInstVarStore
- 	"Answer the value of isInstVarStore"
- 
- 	^ isInstVarStore!

Item was removed:
- ----- Method: CogBytecodeDescriptor>>isInstVarStore: (in category 'accessing') -----
- isInstVarStore: anObject
- 	"Set the value of isInstVarStore"
- 
- 	^isInstVarStore := anObject!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genStoreWithImmutabilityCheckSourceReg:slotIndex:destReg:scratchReg:needsStoreCheck:needRestoreRcvr: (in category 'compile abstract instructions') -----
  genStoreWithImmutabilityCheckSourceReg: sourceReg slotIndex: index destReg: destReg scratchReg: scratchReg needsStoreCheck: needsStoreCheck needRestoreRcvr: needRestoreRcvr
+ 	<option: #IMMUTABILITY>
  	"We know there is a frame as immutability check requires a frame"
  	"needRestoreRcvr has to be true to keep RcvrResultReg live with the receiver in it across the trampoline"
+ 	
- 	<option: #IMMUTABILITY>
  	"Trampoline convention..."
  	self assert: destReg == ReceiverResultReg.
  	self assert: scratchReg == TempReg.
    	self assert: sourceReg == ClassReg.
  	
+ 	"The two paths are very different as the trampoline is shared in 1 case so we split here"
  	needsStoreCheck
  		ifTrue: 
  			[ self 
  				genStoreWithImmutabilityAndStoreCheckSourceReg: sourceReg 
  				slotIndex: index 
  				destReg: destReg 
  				scratchReg: scratchReg 
  				needRestoreRcvr: needRestoreRcvr ]
  		ifFalse: 
  			[ self 
  				genStoreWithImmutabilityButNoStoreCheckSourceReg: sourceReg 
  				slotIndex: index 
  				destReg: destReg 
  				scratchReg: scratchReg 
  				needRestoreRcvr: needRestoreRcvr ].
  	^ 0!

Item was changed:
  ----- Method: Cogit class>>generatorTableFrom: (in category 'class initialization') -----
  generatorTableFrom: anArray
  	| blockCreationBytecodeSize |
  	generatorTable := CArrayAccessor on: (Array new: 256).
  	anArray do:
  		[:tuple| | descriptor |
  		(descriptor := CogBytecodeDescriptor new)
  						numBytes: tuple first;
  						generator: tuple fourth;
  						isReturn: (tuple includes: #return);
  						isMapped: ((tuple includes: #isMappedIfImmutability)
  										ifTrue: [self bindingOf: #IMMUTABILITY]
  										ifFalse: [tuple includes: #isMapped]);
  						isMappedInBlock: (tuple includes: #isMappedInBlock);
  						isBlockCreation: (tuple includes: #block);
  						spanFunction: (((tuple includes: #block) or: [(tuple includes: #branch)]) ifTrue:
  										[tuple detect: [:thing| thing isSymbol and: [thing numArgs = 4]]]);
  						isBranchTrue: (tuple includes: #isBranchTrue);
  						isBranchFalse: (tuple includes: #isBranchFalse);
  						isExtension: (tuple includes: #extension);
  						isInstVarRef: (tuple includes: #isInstVarRef);	"for Spur"
+ 						is1ByteInstVarStore: (tuple includes: #is1ByteInstVarStore);	"for Spur"
- 						isInstVarStore: (tuple includes: #isInstVarStore);	"for Spur"
  						hasIRC: (tuple includes: #hasIRC);			"for Newspeak"
  						yourself.
  		"As a hack to cut down on descriptor flags, use opcode to tag unusedBytecode for scanning.
  		 Currently descriptors are exactly 16 bytes with all 8 flag bits used (in Newspeak at least 17 bytes,
  		 9 flag bits).  As another hack to eliminate a test in scanMethod mark unknowns as extensions."
  		descriptor generator == #unknownBytecode ifTrue:
  			[descriptor opcode: Nop; isExtension: true].
  		descriptor isBlockCreation ifTrue:
  			[blockCreationBytecodeSize
  				ifNil: [blockCreationBytecodeSize := descriptor numBytes]
  				ifNotNil: [self assert: blockCreationBytecodeSize = descriptor numBytes]].
  		tuple do:
  			[:thing|
  			thing isSymbol ifTrue:
  				[(thing beginsWith: #needsFrame) ifTrue:
  					[descriptor needsFrameFunction: thing].
  				 (CogRTLOpcodes classPool at: thing ifAbsent: []) ifNotNil:
  					[:opcode| descriptor opcode: opcode]]].
  		tuple last isInteger
  			ifTrue: [descriptor stackDelta: tuple last]
  			ifFalse:
  				[descriptor needsFrameFunction ifNotNil:
  					[self error: 'frameless block bytecodes must specify a stack delta']].
  		tuple second to: tuple third do:
  			[:index|
  			generatorTable at: index put: descriptor]].
  	BlockCreationBytecodeSize := blockCreationBytecodeSize.
  	^generatorTable!

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 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 176 183 genStoreAndPopReceiverVariableBytecode isInstVarRef isInstVarStore 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 232 232 genExtStoreReceiverVariableBytecode isInstVarRef isInstVarStore isMappedIfImmutability)
  		(2 233 233 genExtStoreLiteralVariableBytecode isMappedIfImmutability)
  		(2 234 234 genLongStoreTemporaryVariableBytecode)
+ 		(2 235 235 genExtStoreAndPopReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
- 		(2 235 235 genExtStoreAndPopReceiverVariableBytecode isInstVarRef isInstVarStore 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 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 200 207 genStoreAndPopReceiverVariableBytecode isInstVarRef isInstVarStore 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 genSistaExtStoreAndPopReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
- 		(2 240 240 genSistaExtStoreAndPopReceiverVariableBytecode isInstVarRef isInstVarStore isMappedIfImmutability)
  		(2 241 241 genSistaExtStoreAndPopLiteralVariableBytecode isMappedIfImmutability)
  		(2 242 242 genLongStoreAndPopTemporaryVariableBytecode)
+ 		(2 243 243 genSistaExtStoreReceiverVariableBytecode isInstVarRef isMappedIfImmutability)
- 		(2 243 243 genSistaExtStoreReceiverVariableBytecode isInstVarRef isInstVarStore isMappedIfImmutability)
  		(2 244 244 genSistaExtStoreLiteralVariableBytecode 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 genExtPushRemoteTempOrInstVarLongBytecode)
  		(3 252 252 genExtStoreRemoteTempOrInstVarLongBytecode isMappedIfImmutability)
  		(3 253 253 genExtStoreAndPopRemoteTempOrInstVarLongBytecode isMappedIfImmutability)
  
  		(3 254 254	genExtJumpIfNotInstanceOfBehaviorsOrPopBytecode branch v4:Long:BranchIfNotInstanceOf:Distance:)
  		
  		(3 255 255	genExtPushFullClosureBytecode))!

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  96 103 genStoreAndPopReceiverVariableBytecode isInstVarRef isInstVarStore 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 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 changed:
  ----- Method: StackToRegisterMappingCogit>>compileTwoPathFrameBuild (in category 'compile abstract instructions') -----
  compileTwoPathFrameBuild
  	"We are in a method where the frame is needed *only* for instance variable store, typically a setter method.
  	This case has 20% overhead with Immutability compared to setter without immutability because of the stack
  	frame creation. We compile two path, one where the object is immutable, one where it isn't. At the beginning 
  	of the frame build, we take one path or the other depending on the receiver mutability.
  	
  	Note: this specific case happens only where there are only instance variabel stores. We could do something
  	similar for literal variable stores, but we don't as it's too uncommon."
  	<option: #IMMUTABILITY>
+ 	| jumpImmutable jumpOld |
- 	| jumpImmutable |
- 	self assert: needsFrame.
  	self assert: useTwoPaths.
  	self assert: blockCount = 0.
  	jumpImmutable := objectRepresentation genJumpImmutable: ReceiverResultReg scratchReg: TempReg.
+ 	jumpOld := objectRepresentation genJumpInOldSpace: ReceiverResultReg.
  	"first path. The receiver is mutable"
+ 	self assert: needsFrame not.
- 	needsFrame := false.
  	self initSimStackForFramelessMethod: initialPC.
  	self compileMethodBody.
  	"second path. The receiver is mutable"
  	useTwoPaths := false. "reset because it impacts inst var store compilation"
  	needsFrame := true.
+ 	jumpOld jmpTarget: (jumpImmutable jmpTarget: self Label).
- 	jumpImmutable jmpTarget: self Label.
  	self genPushRegisterArgs.
  	super compileFrameBuild.
  	self initSimStackForFramefulMethod: initialPC!

Item was changed:
+ ----- Method: StackToRegisterMappingCogit>>extASpecifiesNoMustBeBoolean (in category 'testing') -----
- ----- Method: StackToRegisterMappingCogit>>extASpecifiesNoMustBeBoolean (in category 'bytecode generator support') -----
  extASpecifiesNoMustBeBoolean
  	<inline: true>
+ 	^ extA anyMask: 1!
- 	^ (extA anyMask: 1)!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>extBSpecifiesImmCheck (in category 'testing') -----
+ extBSpecifiesImmCheck 
+ 	"This is a negative check"
+ 	<inline: true>
+ 	^ extB noMask: 4!

Item was changed:
+ ----- Method: StackToRegisterMappingCogit>>extBSpecifiesInitializeInstance (in category 'testing') -----
- ----- Method: StackToRegisterMappingCogit>>extBSpecifiesInitializeInstance (in category 'bytecode generators') -----
  extBSpecifiesInitializeInstance
  	"This is a negative; do not intialize if 1 is present in extB.  This is also the no-store-check bit."
  	<inline: true>
  	^ extB noMask: 1!

Item was changed:
+ ----- Method: StackToRegisterMappingCogit>>extBSpecifiesMaybeContext (in category 'testing') -----
- ----- Method: StackToRegisterMappingCogit>>extBSpecifiesMaybeContext (in category 'bytecode generators') -----
  extBSpecifiesMaybeContext
  	<inline: true>
  	^ extB anyMask: 2!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>extBSpecifiesNoImmCheck (in category 'testing') -----
+ extBSpecifiesNoImmCheck 
+ 	<inline: true>
+ 	^ extB anyMask: 4!

Item was changed:
+ ----- Method: StackToRegisterMappingCogit>>extBSpecifiesNoStoreCheck (in category 'testing') -----
- ----- Method: StackToRegisterMappingCogit>>extBSpecifiesNoStoreCheck (in category 'bytecode generator support') -----
  extBSpecifiesNoStoreCheck 
  	<inline: true>
+ 	^ extB anyMask: 1!
- 	^ extB noMask: 1!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genExtStorePopRemoteTempOrInstVarLongBytecodePopBoolean: (in category 'bytecode generators') -----
  genExtStorePopRemoteTempOrInstVarLongBytecodePopBoolean: boolean
+ 	| index maybeContext needsStoreCheck needsImmCheck |
- 	| index maybeContext needsStoreCheck |
  	needsStoreCheck := self sistaNeedsStoreCheck.
  	maybeContext := self extBSpecifiesMaybeContext.
+ 	needsImmCheck := self extBSpecifiesImmCheck.
  	extB := 0.
  	(byte2 noMask: coInterpreter remoteIsInstVarAccess)
  		ifTrue: 
+ 			[ self 
+ 				genStorePop: boolean 
+ 				RemoteTemp: byte1 
+ 				At: byte2 
+ 				needsStoreCheck: needsStoreCheck.
- 			[ self genStorePop: boolean RemoteTemp: byte1 At: byte2 needsStoreCheck: needsStoreCheck.
  			self cppIf: IMMUTABILITY ifTrue: [ self annotateBytecode: self Label ] ]
  		ifFalse: 
+ 			[index := byte1 + (extA << 8).
+ 			 extA := 0.
+ 			 ((coInterpreter isWriteMediatedContextInstVarIndex: index) and: [ maybeContext ])
+ 				ifTrue: [self 
- 			[ index := byte1 + (extA << 8).
- 			extA := 0.
- 			((coInterpreter isWriteMediatedContextInstVarIndex: index) and: [ maybeContext ])
- 				ifTrue: [ self 
  						genStorePop: boolean 
  						MaybeContextRemoteInstVar: index 
  						ofObjectAt: byte2 - coInterpreter remoteIsInstVarAccess 
+ 						needsStoreCheck: needsStoreCheck
+ 						needsImmutabilityCheck: needsImmCheck ]
+ 				ifFalse: [self 
- 						needsStoreCheck: needsStoreCheck ]
- 				ifFalse: [ self 
  						genStorePop: boolean 
  						RemoteInstVar: index 
  						ofObjectAt: byte2 - coInterpreter remoteIsInstVarAccess 
+ 						needsStoreCheck: needsStoreCheck
+ 						needsImmutabilityCheck: needsImmCheck ] ].
- 						needsStoreCheck: needsStoreCheck ] ].
  	^ 0!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genGenericStorePop:MaybeContextSlotIndex:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: (in category 'bytecode generator stores') -----
+ genGenericStorePop: popBoolean MaybeContextSlotIndex: slotIndex needsStoreCheck: needsStoreCheck needsRestoreRcvr: needsRestoreReceiver needsImmutabilityCheck: needsImmCheck
+ 	"Generates a store into an object that *may* be a context.
+ 	Multiple settings:
+ 	- needsStoreCheck (young into old object check)
+ 	- needRestoreRcvr (ensures the recevier is live across the store)
+ 	- needsImmCheck (do the call-back if the receiver is immutable)"
+ 	<inline: true>
+ 	| jmpSingle jmpDone |
+ 	<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."
+ 	"Context stores do not require Imm checks as contexts can't be immutable"
+ 	self assert: needsFrame.
+ 	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.
+ 	jmpSingle := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
+ 	self MoveCq: slotIndex R: SendNumArgsReg.
+ 	self CallRT: ceStoreContextInstVarTrampoline.
+ 	jmpDone := self Jump: 0.
+ 	jmpSingle jmpTarget: self Label.
+ 	(IMMUTABILITY and: [needsImmCheck])
+ 		ifTrue: 
+ 			[objectRepresentation 
+ 				genStoreWithImmutabilityCheckSourceReg: ClassReg 
+ 				slotIndex: slotIndex 
+ 				destReg: ReceiverResultReg 
+ 				scratchReg: TempReg 
+ 				needsStoreCheck: needsStoreCheck 
+ 				needRestoreRcvr: true]
+ 		ifFalse:
+ 			[objectRepresentation
+ 				genStoreSourceReg: ClassReg
+ 				slotIndex: slotIndex
+ 				destReg: ReceiverResultReg
+ 				scratchReg: TempReg
+ 				inFrame: true
+ 				needsStoreCheck: needsStoreCheck].
+ 	jmpDone jmpTarget: self Label.
+ 	^0!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: (in category 'bytecode generator stores') -----
+ genGenericStorePop: popBoolean slotIndex: slotIndex destReg: destReg needsStoreCheck: needsStoreCheck needsRestoreRcvr: needsRestoreReceiver needsImmutabilityCheck: needsImmCheck
+ 	"Generates a store into an object that *cannot* be a context.
+ 	 This code is common between multiple stores (litVar, instVar, remoteInstVar, RemoteTemp)
+ 	 Multiple settings:
+ 	- needsStoreCheck (young into old object check)
+ 	- needRestoreRcvr (ensures the receiver is live across the store)
+ 	- needsImmCheck (do the call-back if the receiver is immutable)"
+ 	<inline: true>
+ 	"We have two very different paths as only the immutability path requires a specific register 
+ 	for the value on top of stack as well as the stack flush"
+ 	(IMMUTABILITY and: [needsImmCheck])
+ 		ifTrue: 
+ 			[self ssAllocateRequiredReg: ClassReg.
+ 			 "we replace the top value for the flush"
+ 			 self ssStoreAndReplacePop: popBoolean toReg: ClassReg.
+ 			 self ssFlushTo: simStackPtr.
+ 			 objectRepresentation 
+ 				genStoreWithImmutabilityCheckSourceReg: ClassReg 
+ 				slotIndex: slotIndex 
+ 				destReg: destReg 
+ 				scratchReg: TempReg 
+ 				needsStoreCheck: needsStoreCheck 
+ 				needRestoreRcvr: needsRestoreReceiver ]
+ 		ifFalse:
+ 			[| topReg |
+ 			 topReg := self 
+ 						allocateRegForStackEntryAt: 0 
+ 						notConflictingWith: (self registerMaskFor: destReg). 
+ 			 self ssStorePop: popBoolean toReg: topReg.
+ 			 objectRepresentation
+ 				genStoreSourceReg: topReg
+ 				slotIndex: slotIndex
+ 				destReg: destReg
+ 				scratchReg: TempReg
+ 				inFrame: needsFrame
+ 				needsStoreCheck: needsStoreCheck].
+ 	^ 0
+ 	!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genImmCheckStorePop:MaybeContextSlotIndex:needsStoreCheck: (in category 'bytecode generator support') -----
- genImmCheckStorePop: popBoolean MaybeContextSlotIndex: slotIndex needsStoreCheck: needsStoreCheck
- 	<inline: true>
- 	| jmpSingle jmpDone |
- 	<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 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: needsStoreCheck 
- 		needRestoreRcvr: true.
- 	jmpDone jmpTarget: self Label.
- 	^0!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genImmCheckStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: (in category 'bytecode generator support') -----
- genImmCheckStorePop: popBoolean slotIndex: slotIndex destReg: destReg needsStoreCheck: needsStoreCheck needsRestoreRcvr: needsRestoreReceiver
- 	<inline: true>
- 	self ssAllocateRequiredReg: ClassReg.
- 	"we replace the top value for the flush"
- 	self ssStoreAndReplacePop: popBoolean toReg: ClassReg.
- 	self ssFlushTo: simStackPtr.
- 	objectRepresentation 
- 		genStoreWithImmutabilityCheckSourceReg: ClassReg 
- 		slotIndex: slotIndex 
- 		destReg: destReg 
- 		scratchReg: TempReg 
- 		needsStoreCheck: needsStoreCheck 
- 		needRestoreRcvr: needsRestoreReceiver.!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genSistaExtStoreAndPopReceiverVariableBytecodePopBoolean: (in category 'bytecode generators') -----
  genSistaExtStoreAndPopReceiverVariableBytecodePopBoolean: boolean
  	<inline: true>
+ 	| index needsStoreCheck needsImmCheck |
- 	| index needsStoreCheck |
  	needsStoreCheck := self sistaNeedsStoreCheck.
+ 	needsImmCheck := self extBSpecifiesImmCheck.
  	extB := 0.
  	index := byte1 + (extA << 8).
  	extA := 0.
  	^(coInterpreter isWriteMediatedContextInstVarIndex: index)
+ 		ifTrue: [self 
+ 				genStorePop: boolean 
+ 				MaybeContextReceiverVariable: index 
+ 				needsStoreCheck: needsStoreCheck 
+ 				needsImmutabilityCheck: needsImmCheck]
+ 		ifFalse: [self 
+ 				 genStorePop: boolean 
+ 				 ReceiverVariable: index 
+ 				 needsStoreCheck: needsStoreCheck 
+ 				 needsImmutabilityCheck: needsImmCheck]!
- 		ifTrue: [self genStorePop: boolean MaybeContextReceiverVariable: index needsStoreCheck: needsStoreCheck]
- 		ifFalse: [self genStorePop: boolean ReceiverVariable: index needsStoreCheck: needsStoreCheck]!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genSistaExtStoreLiteralVariableBytecodePopBoolean: (in category 'bytecode generators') -----
  genSistaExtStoreLiteralVariableBytecodePopBoolean: boolean
  	<inline: true>
+ 	| index needsStoreCheck needsImmCheck |
+ 	needsStoreCheck := self sistaNeedsStoreCheck.
+ 	needsImmCheck := self extBSpecifiesImmCheck.
- 	| index needsStoreCheck |
- 	needsStoreCheck := self sistaNeedsStoreCheck and: [self ssTopNeedsStoreCheck].
  	index := byte1 + (extA << 8).
  	extA := extB := 0.
+ 	^self 
+ 		genStorePop: boolean 
+ 		LiteralVariable: index 
+ 		needsStoreCheck: needsStoreCheck 
+ 		needsImmutabilityCheck: needsImmCheck!
- 	^self genStorePop: boolean LiteralVariable: index needsStoreCheck: needsStoreCheck!

Item was changed:
+ ----- Method: StackToRegisterMappingCogit>>genStorePop:LiteralVariable: (in category 'bytecode generator stores') -----
- ----- Method: StackToRegisterMappingCogit>>genStorePop:LiteralVariable: (in category 'bytecode generator support') -----
  genStorePop: popBoolean LiteralVariable: litVarIndex
  	<inline: false>
+ 	^self 
+ 		genStorePop: popBoolean 
+ 		LiteralVariable: litVarIndex 
+ 		needsStoreCheck: self ssTopNeedsStoreCheck
+ 		needsImmutabilityCheck: true "The generic store checks for IMMUTABILITY flag"
- 	self genStorePop: popBoolean LiteralVariable: litVarIndex needsStoreCheck: self ssTopNeedsStoreCheck.
- 	^ 0
  		!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genStorePop:LiteralVariable:needsStoreCheck: (in category 'bytecode generator support') -----
- genStorePop: popBoolean LiteralVariable: litVarIndex needsStoreCheck: needsStoreCheck
- 	<inline: false>
- 	"We need a frame because the association has to be in ReceiverResultReg for the various trampolines
- 	and ReceiverResultReg holds only the receiver in frameless methods."
- 	self assert: needsFrame.
- 	self genLoadLiteralVariable: litVarIndex in: ReceiverResultReg.
- 	self 
- 		genStorePop: popBoolean 
- 		slotIndex: ValueIndex 
- 		destReg: ReceiverResultReg
- 		needsStoreCheck: needsStoreCheck
- 		needsRestoreRcvr: false.
- 	^ 0
- 		!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genStorePop:LiteralVariable:needsStoreCheck:needsImmutabilityCheck: (in category 'bytecode generator stores') -----
+ genStorePop: popBoolean LiteralVariable: litVarIndex needsStoreCheck: needsStoreCheck needsImmutabilityCheck: needsImmCheck
+ 	<inline: false>
+ 	"We need a frame because the association has to be in ReceiverResultReg for the various trampolines
+ 	and ReceiverResultReg holds only the receiver in frameless methods."
+ 	self assert: needsFrame.
+ 	self genLoadLiteralVariable: litVarIndex in: ReceiverResultReg.
+ 	self 
+ 		genGenericStorePop: popBoolean 
+ 		slotIndex: ValueIndex 
+ 		destReg: ReceiverResultReg
+ 		needsStoreCheck: needsStoreCheck
+ 		needsRestoreRcvr: false
+ 		needsImmutabilityCheck: needsImmCheck.
+ 	^ 0
+ 		!

Item was changed:
+ ----- Method: StackToRegisterMappingCogit>>genStorePop:MaybeContextReceiverVariable: (in category 'bytecode generator stores') -----
- ----- Method: StackToRegisterMappingCogit>>genStorePop:MaybeContextReceiverVariable: (in category 'bytecode generator support') -----
  genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex 
  	<inline: false>
+ 	^self 
+ 		genStorePop: popBoolean 
+ 		MaybeContextReceiverVariable: slotIndex 
+ 		needsStoreCheck: self ssTopNeedsStoreCheck
+ 		needsImmutabilityCheck: true "The generic store checks for IMMUTABILITY flag"!
- 	self genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex needsStoreCheck: self ssTopNeedsStoreCheck.
- 	^ 0!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genStorePop:MaybeContextReceiverVariable:needsStoreCheck: (in category 'bytecode generator support') -----
- genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex needsStoreCheck: needsStoreCheck
- 	<inline: false>
- 	"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.
- 	self ensureReceiverResultRegContainsSelf.
- 	self genStorePop: popBoolean MaybeContextSlotIndex: slotIndex needsStoreCheck: needsStoreCheck.
- 	^ 0!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genStorePop:MaybeContextReceiverVariable:needsStoreCheck:needsImmutabilityCheck: (in category 'bytecode generator stores') -----
+ genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex needsStoreCheck: needsStoreCheck needsImmutabilityCheck: needsImmCheck
+ 	<inline: false>
+ 	"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.
+ 	self ensureReceiverResultRegContainsSelf.
+ 	self 
+ 		genGenericStorePop: popBoolean 
+ 		MaybeContextSlotIndex: slotIndex 
+ 		needsStoreCheck: needsStoreCheck
+ 		needsRestoreRcvr: true
+ 		needsImmutabilityCheck: needsImmCheck.
+ 	^ 0!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genStorePop:MaybeContextRemoteInstVar:ofObjectAt:needsStoreCheck: (in category 'bytecode generator support') -----
- genStorePop: popBoolean MaybeContextRemoteInstVar: slotIndex ofObjectAt: objectIndex needsStoreCheck: needsStoreCheck
- 	<inline: false>
- 	"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 genLoadTemp: objectIndex in: ReceiverResultReg.
- 	self genStorePop: popBoolean MaybeContextSlotIndex: slotIndex needsStoreCheck: needsStoreCheck.
- 	^ 0!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genStorePop:MaybeContextRemoteInstVar:ofObjectAt:needsStoreCheck:needsImmutabilityCheck: (in category 'bytecode generator stores') -----
+ genStorePop: popBoolean MaybeContextRemoteInstVar: slotIndex ofObjectAt: objectIndex needsStoreCheck: needsStoreCheck needsImmutabilityCheck: needsImmCheck
+ 	<inline: false>
+ 	"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 genLoadTemp: objectIndex in: ReceiverResultReg.
+ 	self 
+ 		genGenericStorePop: popBoolean 
+ 		MaybeContextSlotIndex: slotIndex 
+ 		needsStoreCheck: needsStoreCheck
+ 		needsRestoreRcvr: false
+ 		needsImmutabilityCheck: needsImmCheck.
+ 	^ 0!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genStorePop:MaybeContextSlotIndex:needsStoreCheck: (in category 'bytecode generator support') -----
- genStorePop: popBoolean MaybeContextSlotIndex: slotIndex needsStoreCheck: needsStoreCheck
- 	<inline: true>
- 	"This method expects ReceiverResultReg to hold the object to store into. It has to be ReceiverResultReg for the contextINstVarTrampoline"
- 	self 
- 		cppIf: IMMUTABILITY
- 		ifTrue: 
- 			[ self 
- 				genImmCheckStorePop: popBoolean 
- 				MaybeContextSlotIndex: slotIndex 
- 				needsStoreCheck: needsStoreCheck ]
- 		ifFalse: 
- 			[ self 
- 				genVanillaStorePop: popBoolean 
- 				MaybeContextSlotIndex: slotIndex 
- 				needsStoreCheck: needsStoreCheck ].!

Item was changed:
+ ----- Method: StackToRegisterMappingCogit>>genStorePop:ReceiverVariable: (in category 'bytecode generator stores') -----
- ----- Method: StackToRegisterMappingCogit>>genStorePop:ReceiverVariable: (in category 'bytecode generator support') -----
  genStorePop: popBoolean ReceiverVariable: slotIndex
  	<inline: false>
+ 	^self 
+ 		genStorePop: popBoolean 
+ 		ReceiverVariable: slotIndex 
+ 		needsStoreCheck: self ssTopNeedsStoreCheck
+ 		needsImmutabilityCheck: true "The generic store checks for IMMUTABILITY flag"
- 	self genStorePop: popBoolean ReceiverVariable: slotIndex needsStoreCheck: self ssTopNeedsStoreCheck.
- 	^ 0
  		!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genStorePop:ReceiverVariable:needsStoreCheck: (in category 'bytecode generator support') -----
- genStorePop: popBoolean ReceiverVariable: slotIndex needsStoreCheck: needsStoreCheck
- 	<inline: false>
- 	self ssFlushUpThroughReceiverVariable: slotIndex.
- 	self ensureReceiverResultRegContainsSelf.
- 	self 
- 		genStorePop: popBoolean 
- 		slotIndex: slotIndex 
- 		destReg: ReceiverResultReg 
- 		needsStoreCheck: needsStoreCheck
- 		needsRestoreRcvr: true.
- 	^ 0
- 		!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genStorePop:ReceiverVariable:needsStoreCheck:needsImmutabilityCheck: (in category 'bytecode generator stores') -----
+ genStorePop: popBoolean ReceiverVariable: slotIndex needsStoreCheck: needsStoreCheck needsImmutabilityCheck: needsImmCheck
+ 	<inline: false>
+ 	self ssFlushUpThroughReceiverVariable: slotIndex.
+ 	self ensureReceiverResultRegContainsSelf.
+ 	"In two path compilation the receiver is young AND mutable, hence no store check nor immutability check is needed"
+ 	self 
+ 		genGenericStorePop: popBoolean 
+ 		slotIndex: slotIndex 
+ 		destReg: ReceiverResultReg 
+ 		needsStoreCheck: (useTwoPaths not and: [needsStoreCheck])
+ 		needsRestoreRcvr: true "ReceiverResultReg is kept live with the receiver across the operation"
+ 		needsImmutabilityCheck: (needsImmCheck and: [useTwoPaths not]). 
+ 	^ 0
+ 		!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genStorePop:RemoteInstVar:ofObjectAt:needsStoreCheck: (in category 'bytecode generator support') -----
- genStorePop: popBoolean RemoteInstVar: slotIndex ofObjectAt: objectIndex needsStoreCheck: needsStoreCheck
- 	<inline: false>
- 	self assert: needsFrame.
- 	self genLoadTemp: objectIndex in: ReceiverResultReg.
- 	self 
- 		genStorePop: popBoolean 
- 		slotIndex: slotIndex 
- 		destReg: ReceiverResultReg 
- 		needsStoreCheck: needsStoreCheck
- 		needsRestoreRcvr: false.
- 	^ 0!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genStorePop:RemoteInstVar:ofObjectAt:needsStoreCheck:needsImmutabilityCheck: (in category 'bytecode generator stores') -----
+ genStorePop: popBoolean RemoteInstVar: slotIndex ofObjectAt: objectIndex needsStoreCheck: needsStoreCheck needsImmutabilityCheck: needsImmCheck
+ 	<inline: false>
+ 	self assert: needsFrame.
+ 	self genLoadTemp: objectIndex in: ReceiverResultReg.
+ 	self 
+ 		genGenericStorePop: popBoolean 
+ 		slotIndex: slotIndex 
+ 		destReg: ReceiverResultReg 
+ 		needsStoreCheck: needsStoreCheck
+ 		needsRestoreRcvr: false
+ 		needsImmutabilityCheck: needsImmCheck.
+ 	^ 0!

Item was changed:
+ ----- Method: StackToRegisterMappingCogit>>genStorePop:RemoteTemp:At: (in category 'bytecode generator stores') -----
- ----- Method: StackToRegisterMappingCogit>>genStorePop:RemoteTemp:At: (in category 'bytecode generator support') -----
  genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex
  	<inline: false>
  	^ self genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex needsStoreCheck: self ssTopNeedsStoreCheck!

Item was changed:
+ ----- Method: StackToRegisterMappingCogit>>genStorePop:RemoteTemp:At:needsStoreCheck: (in category 'bytecode generator stores') -----
- ----- Method: StackToRegisterMappingCogit>>genStorePop:RemoteTemp:At:needsStoreCheck: (in category 'bytecode generator support') -----
  genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex needsStoreCheck: needsStoreCheck
  	<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.
  	"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."
  	self ssAllocateRequiredReg: ReceiverResultReg. 
  	optStatus isReceiverResultRegLive: false.
  	self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r: FPReg R: ReceiverResultReg.
+ 	self 
+ 		genGenericStorePop: popBoolean 
+ 		slotIndex: slotIndex 
+ 		destReg: ReceiverResultReg 
+ 		needsStoreCheck: needsStoreCheck
+ 		needsRestoreRcvr: false "We don't keep ReceiverResultReg live with the receiver across this operation"
+ 		needsImmutabilityCheck: false. "never do immutability check on temp vectors"
- 	self genVanillaStorePop: popBoolean slotIndex: slotIndex destReg: ReceiverResultReg needsStoreCheck: needsStoreCheck.
  	^ 0!

Item was changed:
+ ----- Method: StackToRegisterMappingCogit>>genStorePop:TemporaryVariable: (in category 'bytecode generator stores') -----
- ----- Method: StackToRegisterMappingCogit>>genStorePop:TemporaryVariable: (in category 'bytecode generator support') -----
  genStorePop: popBoolean TemporaryVariable: tempIndex
  	<inline: false>
  	| reg |
  	self ssFlushUpThroughTemporaryVariable: tempIndex.
  	reg := self ssStorePop: popBoolean toPreferredReg: TempReg.
  	self MoveR: reg
  		Mw: (self frameOffsetOfTemporary: tempIndex)
  		r: FPReg.
  	^0!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: (in category 'bytecode generator support') -----
- genStorePop: popBoolean slotIndex: slotIndex destReg: destReg needsStoreCheck: needsStoreCheck needsRestoreRcvr: needsRestoreReceiver
- 	<inline: true>
- 	"This method expects destReg to hold the object to store into. In practice, it is almost always RcvrResultReg because it is mandatory for the various store checks. We could put any register there if no store check is needed"
- 	self 
- 		cppIf: IMMUTABILITY
- 		ifTrue: 
- 			[useTwoPaths
- 				ifTrue: 
- 					[self  "first path, receiver is mutable"
- 						genVanillaStorePop: popBoolean 
- 						slotIndex: slotIndex 
- 						destReg: destReg 
- 						needsStoreCheck: needsStoreCheck]
- 				ifFalse: 
- 					[self 
- 						genImmCheckStorePop: popBoolean 
- 						slotIndex: slotIndex 
- 						destReg: destReg 
- 						needsStoreCheck: needsStoreCheck
- 						needsRestoreRcvr: needsRestoreReceiver]]
- 		ifFalse: 
- 			[self 
- 				genVanillaStorePop: popBoolean 
- 				slotIndex: slotIndex 
- 				destReg: destReg 
- 				needsStoreCheck: needsStoreCheck].
- 		!

Item was changed:
+ ----- Method: StackToRegisterMappingCogit>>genTraceStores (in category 'bytecode generator stores') -----
- ----- Method: StackToRegisterMappingCogit>>genTraceStores (in category 'bytecode generator support') -----
  genTraceStores
  	<inline: true>
  	traceStores > 0 ifTrue: 
  		[ self MoveR: ClassReg R: TempReg.
  		self CallRT: ceTraceStoreTrampoline ].!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genVanillaStorePop:MaybeContextSlotIndex:needsStoreCheck: (in category 'bytecode generator support') -----
- genVanillaStorePop: popBoolean MaybeContextSlotIndex: slotIndex needsStoreCheck: needsStoreCheck
- 	<inline: true>
- 	| jmpSingle jmpDone |
- 	<var: #jmpSingle type: #'AbstractInstruction *'>
- 	<var: #jmpDone type: #'AbstractInstruction *'>
- 
- 	self deny: (needsStoreCheck and: [self ssTopNeedsStoreCheck not]).
- 	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: needsStoreCheck.
- 	jmpDone jmpTarget: self Label.
- 	
- 	^0!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>genVanillaStorePop:slotIndex:destReg:needsStoreCheck: (in category 'bytecode generator support') -----
- genVanillaStorePop: popBoolean slotIndex: slotIndex destReg: destReg needsStoreCheck: needsStoreCheck
- 	<inline: true>
- 	| topReg |
- 
- 	self deny: (needsStoreCheck and: [self ssTopNeedsStoreCheck not]).
- 	self cppIf: IMMUTABILITY
- 		ifTrue: []
- 		ifFalse: "First path, receiver is in newSpace"
- 			[(destReg = ReceiverResultReg and: [needsFrame not and: [useTwoPaths]]) ifTrue:
- 				[topReg := self ssStorePop: popBoolean toPreferredReg: TempReg.
- 				 self MoveR: topReg
- 					Mw: slotIndex * objectMemory wordSize + objectMemory baseHeaderSize
- 					r: ReceiverResultReg.
- 				 traceStores > 0 ifTrue:
- 					[topReg ~= TempReg ifTrue:
- 						[self MoveR: topReg R: TempReg].
- 					 self CallRT: ceTraceStoreTrampoline].
- 				 ^0]].
- 	topReg := self 
- 				allocateRegForStackEntryAt: 0 
- 				notConflictingWith: (self registerMaskFor: destReg). 
- 	self ssStorePop: popBoolean toReg: topReg.
- 	objectRepresentation
- 		genStoreSourceReg: topReg
- 		slotIndex: slotIndex
- 		destReg: destReg
- 		scratchReg: TempReg
- 		inFrame: needsFrame
- 		needsStoreCheck: needsStoreCheck!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>scanMethod (in category 'compile abstract instructions') -----
  scanMethod
  	"Scan the method (and all embedded blocks) to determine
  		- what the last bytecode is; extra bytes at the end of a method are used to encode things like source pointers or temp names
  		- if the method needs a frame or not
  		- what are the targets of any backward branches.
  		- how many blocks it creates
  	 Answer the block count or on error a negative error code"
  	| latestContinuation nExts descriptor pc numBlocks distance targetPC framelessStackDelta seenInstVarStore |
  	<var: #descriptor type: #'BytecodeDescriptor *'>
  	needsFrame := useTwoPaths := seenInstVarStore := false.
  	self maybeInitNumFixups.
  	self maybeInitNumCounters.
  	prevBCDescriptor := nil.
  	NewspeakVM ifTrue:
  		[numIRCs := 0].
  	(primitiveIndex > 0
  	 and: [coInterpreter isQuickPrimitiveIndex: primitiveIndex]) ifTrue:
  		[^0].
  	pc := latestContinuation := initialPC.
  	numBlocks := framelessStackDelta := nExts := extA := extB := 0.
  	[pc <= endPC] whileTrue:
  		[byte0 := (objectMemory fetchByte: pc ofObject: methodObj) + bytecodeSetOffset.
  		 descriptor := self generatorAt: byte0.
  		 descriptor isExtension ifTrue:
  			[descriptor opcode = Nop ifTrue: "unknown bytecode tag; see Cogit class>>#generatorTableFrom:"
  				[^EncounteredUnknownBytecode].
  			 self loadSubsequentBytesForDescriptor: descriptor at: pc.
  			 self perform: descriptor generator].
  		 (descriptor isReturn
  		  and: [pc >= latestContinuation]) ifTrue:
  			[endPC := pc].
  
  		  needsFrame ifFalse:
  			[(descriptor needsFrameFunction isNil
  			  or: [self perform: descriptor needsFrameFunction with: framelessStackDelta])
  					ifTrue:
+ 						["With immutability we win simply by avoiding a frame build if the receiver is young and not immutable."
+ 						 self cppIf: IMMUTABILITY
+ 							ifTrue: [descriptor is1ByteInstVarStore
+ 									ifTrue: [useTwoPaths := true]
+ 									ifFalse: [needsFrame := true. useTwoPaths := false]]
+ 							ifFalse: [needsFrame := true]]
- 						[needsFrame := true]
  					ifFalse:
  						[framelessStackDelta := framelessStackDelta + descriptor stackDelta.
+ 						 "Without immutability we win if there are two or more stores and the receiver is new."
- 						 "With immutability we win simply by avoiding a frame build if the receiver is not immutable.
- 						  Without immutability we win if there are two or more stores amd the receiver is new."
  						 self cppIf: IMMUTABILITY
+ 							ifTrue: []
- 							ifTrue: [useTwoPaths := descriptor isInstVarStore]
  							ifFalse:
+ 								[descriptor is1ByteInstVarStore ifTrue:
- 								[descriptor isInstVarStore ifTrue:
  									[seenInstVarStore
  										ifTrue: [useTwoPaths := true]
  										ifFalse: [seenInstVarStore := true]]]]].
  
  		 descriptor isBranch ifTrue:
  			[distance := self spanFor: descriptor at: pc exts: nExts in: methodObj.
  			 targetPC := pc + descriptor numBytes + distance.
  			 (self isBackwardBranch: descriptor at: pc exts: nExts in: methodObj)
  				ifTrue: [self initializeFixupAt: targetPC - initialPC]
  				ifFalse:
  					[latestContinuation := latestContinuation max: targetPC.
  					 self maybeCountFixup.
  					 self maybeCountCounter]].
  		 descriptor isBlockCreation ifTrue:
  			[numBlocks := numBlocks + 1.
  			 distance := self spanFor: descriptor at: pc exts: nExts in: methodObj.
  			 targetPC := pc + descriptor numBytes + distance.
  			 latestContinuation := latestContinuation max: targetPC.
  			 self maybeCountFixup].
  
  		 NewspeakVM ifTrue:
  			[descriptor hasIRC ifTrue:
  				[numIRCs := numIRCs + 1]].
  		 pc := pc + descriptor numBytes.
  		 descriptor isExtension
  			ifTrue: [nExts := nExts + 1]
  			ifFalse: [nExts := extA := extB := 0].
  		 prevBCDescriptor := descriptor].
  	^numBlocks!

Item was changed:
+ ----- Method: StackToRegisterMappingCogit>>sistaNeedsStoreCheck (in category 'testing') -----
- ----- Method: StackToRegisterMappingCogit>>sistaNeedsStoreCheck (in category 'bytecode generator support') -----
  sistaNeedsStoreCheck
  	<inline: true>
  	"The store check can be ignored if the value assigned doesn't need it (immediate, etc)
  	In addition, the extB low bit is marked by the optimizer if the store check is not required"
  	^ self ssTopNeedsStoreCheck and: [ self extBSpecifiesNoStoreCheck ]!

Item was changed:
+ ----- Method: StackToRegisterMappingCogit>>ssTopNeedsStoreCheck (in category 'testing') -----
- ----- Method: StackToRegisterMappingCogit>>ssTopNeedsStoreCheck (in category 'bytecode generator support') -----
  ssTopNeedsStoreCheck
  	<inline: true>
  	^self ssTop type ~= SSConstant
  	  or: [(objectMemory isNonImmediate: self ssTop constant)
  		and: [objectRepresentation shouldAnnotateObjectReference:  self ssTop constant]]!



More information about the Vm-dev mailing list