[Vm-dev] VM Maker Inbox: VMMaker.oscog-nice.2544.mcz

commits at source.squeak.org commits at source.squeak.org
Wed Aug 28 17:27:59 UTC 2019


Nicolas Cellier uploaded a new version of VMMaker to project VM Maker Inbox:
http://source.squeak.org/VMMakerInbox/VMMaker.oscog-nice.2544.mcz

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

Name: VMMaker.oscog-nice.2544
Author: nice
Time: 28 August 2019, 7:26:54.426373 pm
UUID: 4374ee05-0600-824c-a199-2f65d79a54ca
Ancestors: VMMaker.oscog-nice.2543

Experiment a vm parameter (75) for making the arithmetic/comparison primitive fail in case of mixed SmallInteger/Float rather than attempting a conversion.

By default, mixed arithmetic is authorized at VM startup, and there is no provision for storing that bit of information in the image header.

It is thus image responsibility to set (Smalltalk vmParameterAt: 75 put: false) in some early startup for those prefering a primitive failure.

Care to flush the method cache when the parameter changes (with the hope that it will reset the jitted primitives - I didn't check but I believe it).

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

Item was added:
+ ----- Method: CoInterpreter>>getPrimitiveDoMixedArithmetic (in category 'cog jit support') -----
+ getPrimitiveDoMixedArithmetic
+ 	<api>
+ 	^primitiveDoMixedArithmetic!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatAdd (in category 'primitive generators') -----
  genPrimitiveFloatAdd
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleArithmetic: AddRdRd preOpCheck: nil]
+ 		ifFalse: [self genPureDoubleArithmetic: AddRdRd preOpCheck: nil]!
- 	^self genDoubleArithmetic: AddRdRd preOpCheck: nil!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatDivide (in category 'primitive generators') -----
  genPrimitiveFloatDivide
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]
+ 		ifFalse: [self genPureDoubleArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]!
- 	^self 
- 		genDoubleArithmetic: DivRdRd
- 		preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatEqual (in category 'primitive generators') -----
  genPrimitiveFloatEqual
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPEqual: invert: false]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPEqual: invert: false]!
- 	^self genDoubleComparison: #JumpFPEqual: invert: false!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatGreaterOrEqual (in category 'primitive generators') -----
  genPrimitiveFloatGreaterOrEqual
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: invert: false]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: false]!
- 	^self genDoubleComparison: #JumpFPGreaterOrEqual: invert: false!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatGreaterThan (in category 'primitive generators') -----
  genPrimitiveFloatGreaterThan
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPGreater: invert: false]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: false]!
- 	^self genDoubleComparison: #JumpFPGreater: invert: false!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatLessOrEqual (in category 'primitive generators') -----
  genPrimitiveFloatLessOrEqual
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: invert: true]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: true]!
- 	^self genDoubleComparison: #JumpFPGreaterOrEqual: invert: true!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatLessThan (in category 'primitive generators') -----
  genPrimitiveFloatLessThan
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPGreater: invert: true]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: true]!
- 	^self genDoubleComparison: #JumpFPGreater: invert: true!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatMultiply (in category 'primitive generators') -----
  genPrimitiveFloatMultiply
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleArithmetic: MulRdRd preOpCheck: nil]
+ 		ifFalse: [self genPureDoubleArithmetic: MulRdRd preOpCheck: nil]!
- 	^self genDoubleArithmetic: MulRdRd preOpCheck: nil!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatNotEqual (in category 'primitive generators') -----
  genPrimitiveFloatNotEqual
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPNotEqual: invert: false]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPNotEqual: invert: false]!
- 	^self genDoubleComparison: #JumpFPNotEqual: invert: false!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatSubtract (in category 'primitive generators') -----
  genPrimitiveFloatSubtract
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleArithmetic: SubRdRd preOpCheck: nil]
+ 		ifFalse: [self genPureDoubleArithmetic: SubRdRd preOpCheck: nil]!
- 	^self genDoubleArithmetic: SubRdRd preOpCheck: nil!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatAdd (in category 'primitive generators') -----
  genPrimitiveSmallFloatAdd
  	<option: #Spur64BitMemoryManager>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatArithmetic: AddRdRd preOpCheck: nil]
+ 		ifFalse: [self genPureSmallFloatArithmetic: AddRdRd preOpCheck: nil]!
- 	^self genSmallFloatArithmetic: AddRdRd preOpCheck: nil!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatDivide (in category 'primitive generators') -----
  genPrimitiveSmallFloatDivide
  	<option: #Spur64BitMemoryManager>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]
+ 		ifFalse: [self genPureSmallFloatArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]!
- 	^self genSmallFloatArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatEqual (in category 'primitive generators') -----
  genPrimitiveSmallFloatEqual
  	<option: #Spur64BitMemoryManager>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatComparison: #JumpFPEqual: orIntegerComparison: JumpZero invert: false]
+ 		ifFalse: [self genPureSmallFloatComparison: #JumpFPEqual: invert: false]!
- 	^self genSmallFloatComparison: #JumpFPEqual: orIntegerComparison: JumpZero invert: false!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatGreaterOrEqual (in category 'primitive generators') -----
  genPrimitiveSmallFloatGreaterOrEqual
  	<option: #Spur64BitMemoryManager>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual invert: false]
+ 		ifFalse: [self genPureSmallFloatComparison: #JumpFPGreaterOrEqual: invert: false]!
- 	^self genSmallFloatComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual invert: false!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatGreaterThan (in category 'primitive generators') -----
  genPrimitiveSmallFloatGreaterThan
  	<option: #Spur64BitMemoryManager>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatComparison: #JumpFPGreater: orIntegerComparison: JumpGreater invert: false]
+ 		ifFalse: [self genPureSmallFloatComparison: #JumpFPGreater: invert: false]!
- 	^self genSmallFloatComparison: #JumpFPGreater: orIntegerComparison: JumpGreater invert: false!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatLessOrEqual (in category 'primitive generators') -----
  genPrimitiveSmallFloatLessOrEqual
  	<option: #Spur64BitMemoryManager>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpLessOrEqual invert: true]
+ 		ifFalse: [self genPureSmallFloatComparison: #JumpFPGreaterOrEqual: invert: true]!
- 	^self genSmallFloatComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpLessOrEqual invert: true!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatLessThan (in category 'primitive generators') -----
  genPrimitiveSmallFloatLessThan
  	<option: #Spur64BitMemoryManager>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatComparison: #JumpFPGreater: orIntegerComparison: JumpLess invert: true]
+ 		ifFalse: [self genPureSmallFloatComparison: #JumpFPGreater: invert: true]!
- 	^self genSmallFloatComparison: #JumpFPGreater: orIntegerComparison: JumpLess invert: true!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatMultiply (in category 'primitive generators') -----
  genPrimitiveSmallFloatMultiply
  	<option: #Spur64BitMemoryManager>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatArithmetic: MulRdRd preOpCheck: nil]
+ 		ifFalse: [self genPureSmallFloatArithmetic: MulRdRd preOpCheck: nil]!
- 	^self genSmallFloatArithmetic: MulRdRd preOpCheck: nil!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatNotEqual (in category 'primitive generators') -----
  genPrimitiveSmallFloatNotEqual
  	<option: #Spur64BitMemoryManager>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero invert: false]
+ 		ifFalse: [self genPureSmallFloatComparison: #JumpFPNotEqual: invert: false]!
- 	^self genSmallFloatComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero invert: false!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatSubtract (in category 'primitive generators') -----
  genPrimitiveSmallFloatSubtract
  	<option: #Spur64BitMemoryManager>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatArithmetic: SubRdRd preOpCheck: nil]
+ 		ifFalse: [self genPureSmallFloatArithmetic: SubRdRd preOpCheck: nil]!
- 	^self genSmallFloatArithmetic: SubRdRd preOpCheck: nil!

Item was added:
+ ----- Method: CogObjectRepresentation>>genPureDoubleArithmetic:preOpCheck: (in category 'primitive generators') -----
+ genPureDoubleArithmetic: arithmeticOperator preOpCheck: preOpCheckOrNil
+ 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
+ 	<option: #DPFPReg0>
+ 	<var: #preOpCheckOrNil declareC: 'AbstractInstruction *(*preOpCheckOrNil)(int rcvrReg, int argReg)'>
+ 	| jumpFailClass jumpFailAlloc jumpFailCheck jumpImmediate doOp |
+ 	<var: #jumpFailClass type: #'AbstractInstruction *'>
+ 	<var: #jumpFailAlloc type: #'AbstractInstruction *'>
+ 	<var: #jumpImmediate type: #'AbstractInstruction *'>
+ 	<var: #jumpFailCheck type: #'AbstractInstruction *'>
+ 	<var: #doOp type: #'AbstractInstruction *'>
+ 	cogit processorHasDoublePrecisionFloatingPointSupport ifFalse:
+ 		[^UnimplementedPrimitive].
+ 	cogit genLoadArgAtDepth: 0 into: Arg0Reg.
+ 	self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
+ 	cogit MoveR: Arg0Reg R: ClassReg.
+ 	jumpImmediate := self genJumpImmediate: Arg0Reg.
+ 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
+ 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
+ 	jumpFailClass := cogit JumpNonZero: 0.
+ 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
+ 	doOp := cogit Label.
+ 	preOpCheckOrNil ifNotNil:
+ 		[jumpFailCheck := cogit perform: preOpCheckOrNil with: DPFPReg0 with: DPFPReg1].
+ 	cogit gen: arithmeticOperator operand: DPFPReg1 operand: DPFPReg0.
+ 	jumpFailAlloc := self
+ 						genAllocFloatValue: DPFPReg0
+ 						into: SendNumArgsReg
+ 						scratchReg: ClassReg
+ 						scratchReg: TempReg.
+ 	cogit MoveR: SendNumArgsReg R: ReceiverResultReg.
+ 	cogit genPrimReturn.
+ 	jumpImmediate jmpTarget: cogit Label.
+ 	self maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: doOp.
+ 	jumpFailAlloc jmpTarget:  (jumpFailClass jmpTarget: cogit Label).
+ 	preOpCheckOrNil ifNotNil:
+ 		[jumpFailCheck jmpTarget: jumpFailClass getJmpTarget].
+ 	^0!

Item was added:
+ ----- Method: CogObjectRepresentation>>genPureDoubleComparison:invert: (in category 'primitive generators') -----
+ genPureDoubleComparison: jumpOpcodeGenerator invert: invertComparison
+ 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
+ 	<option: #DPFPReg0>
+ 	<var: #jumpOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpOpcodeGenerator)(void *)'>
+ 	| jumpFail jumpImmediate jumpCond compare |
+ 	<var: #jumpImmediate type: #'AbstractInstruction *'>
+ 	<var: #jumpCond type: #'AbstractInstruction *'>
+ 	<var: #compare type: #'AbstractInstruction *'>
+ 	<var: #jumpFail type: #'AbstractInstruction *'>
+ 	cogit processorHasDoublePrecisionFloatingPointSupport ifFalse:
+ 		[^UnimplementedPrimitive].
+ 	cogit genLoadArgAtDepth: 0 into: Arg0Reg.
+ 	self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
+ 	jumpImmediate := self genJumpImmediate: Arg0Reg.
+ 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
+ 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
+ 	jumpFail := cogit JumpNonZero: 0.
+ 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
+ 	invertComparison "May need to invert for NaNs"
+ 		ifTrue: [compare := cogit CmpRd: DPFPReg0 Rd: DPFPReg1]
+ 		ifFalse: [compare := cogit CmpRd: DPFPReg1 Rd: DPFPReg0].
+ 	jumpCond := cogit perform: jumpOpcodeGenerator with: 0. "FP jumps are a little weird"
+ 	cogit genMoveFalseR: ReceiverResultReg.
+ 	cogit genPrimReturn.
+ 	jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).
+ 	cogit genPrimReturn.
+ 	jumpImmediate jmpTarget: cogit Label.
+ 	self maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: compare.
+ 	jumpFail jmpTarget: cogit Label.
+ 	^CompletePrimitive!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatEqual (in category 'primitive generators') -----
  genPrimitiveFloatEqual
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPEqual: orIntegerComparison: JumpZero invert: false]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPEqual: invert: false]!
- 	^self genDoubleComparison: #JumpFPEqual: orIntegerComparison: JumpZero invert: false!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatGreaterOrEqual (in category 'primitive generators') -----
  genPrimitiveFloatGreaterOrEqual
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual invert: false]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: false]!
- 	^self genDoubleComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual invert: false!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatGreaterThan (in category 'primitive generators') -----
  genPrimitiveFloatGreaterThan
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPGreater: orIntegerComparison: JumpGreater invert: false]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: false]!
- 	^self genDoubleComparison: #JumpFPGreater: orIntegerComparison: JumpGreater invert: false!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatLessOrEqual (in category 'primitive generators') -----
  genPrimitiveFloatLessOrEqual
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpLessOrEqual invert: true]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: true]!
- 	^self genDoubleComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpLessOrEqual invert: true!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatLessThan (in category 'primitive generators') -----
  genPrimitiveFloatLessThan
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPGreater: orIntegerComparison: JumpLess invert: true]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: true]!
- 	^self genDoubleComparison: #JumpFPGreater: orIntegerComparison: JumpLess invert: true!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatNotEqual (in category 'primitive generators') -----
  genPrimitiveFloatNotEqual
  	<option: #DPFPReg0>
+ 	^self getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero invert: false]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPNotEqual: invert: false]!
- 	^self genDoubleComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero invert: false!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genPureDoubleArithmetic:preOpCheck: (in category 'primitive generators') -----
+ genPureDoubleArithmetic: arithmeticOperator preOpCheck: preOpCheckOrNil
+ 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
+ 	<inline: true>
+ 	^self genPureFloatArithmetic: arithmeticOperator preOpCheck: preOpCheckOrNil boxed: true!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genPureDoubleComparison:invert: (in category 'primitive generators') -----
+ genPureDoubleComparison: jumpOpcodeGenerator invert: invertComparison
+ 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
+ 	<inline: true>
+ 	^self genPureFloatComparison: jumpOpcodeGenerator invert: invertComparison boxed: true!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genPureFloatArithmetic:preOpCheck:boxed: (in category 'primitive generators') -----
+ genPureFloatArithmetic: arithmeticOperator preOpCheck: preOpCheckOrNil boxed: rcvrBoxed
+ 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
+ 	<var: #preOpCheckOrNil declareC: 'AbstractInstruction *(*preOpCheckOrNil)(int rcvrReg, int argReg)'>
+ 	<inline: false>
+ 	| jumpFailAlloc jumpFailCheck jumpImmediate jumpNotSmallFloat jumpNotBoxedFloat doOp |
+ 	<var: #jumpNotBoxedFloat type: #'AbstractInstruction *'>
+ 	<var: #jumpNotSmallFloat type: #'AbstractInstruction *'>
+ 	<var: #jumpImmediate type: #'AbstractInstruction *'>
+ 	<var: #jumpFailCheck type: #'AbstractInstruction *'>
+ 	<var: #jumpFailAlloc type: #'AbstractInstruction *'>
+ 	<var: #doOp type: #'AbstractInstruction *'>
+ 	cogit genLoadArgAtDepth: 0 into: Arg0Reg.
+ 	rcvrBoxed
+ 		ifTrue: [self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0]
+ 		ifFalse: [self genGetSmallFloatValueOf: ReceiverResultReg scratch: TempReg into: DPFPReg0].
+ 	jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.
+ 	self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.
+ 	doOp := cogit Label.
+ 	preOpCheckOrNil ifNotNil:
+ 		[jumpFailCheck := cogit perform: preOpCheckOrNil with: DPFPReg0 with: DPFPReg1].
+ 	cogit gen: arithmeticOperator operand: DPFPReg1 operand: DPFPReg0.
+ 	jumpFailAlloc := self genAllocFloatValue: DPFPReg0 into: SendNumArgsReg scratchReg: ClassReg scratchReg: TempReg.
+ 	cogit MoveR: SendNumArgsReg R: ReceiverResultReg.
+ 	cogit genPrimReturn.
+ 	jumpNotSmallFloat jmpTarget: cogit Label.
+ 	jumpImmediate := self genJumpImmediate: Arg0Reg.
+ 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
+ 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
+ 	jumpNotBoxedFloat := cogit JumpNonZero: 0.
+ 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
+ 	cogit Jump: doOp.
+ 	jumpImmediate jmpTarget:
+ 	(jumpNotBoxedFloat jmpTarget:
+ 	(jumpFailAlloc jmpTarget: cogit Label)).
+ 	preOpCheckOrNil ifNotNil:
+ 		[jumpFailCheck jmpTarget: jumpFailAlloc getJmpTarget].
+ 	^0!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genPureFloatComparison:invert:boxed: (in category 'primitive generators') -----
+ genPureFloatComparison: jumpFPOpcodeGenerator invert: invertComparison boxed: rcvrBoxed
+ 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
+ 	<var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction *(*jumpFPOpcodeGenerator)(void *)'>
+ 	<inline: false>
+ 	| jumpImmediate jumpNotSmallFloat jumpNotBoxedFloat jumpCond compareFloat |
+ 	<var: #jumpNotBoxedFloat type: #'AbstractInstruction *'>
+ 	<var: #jumpNotSmallFloat type: #'AbstractInstruction *'>
+ 	<var: #jumpImmediate type: #'AbstractInstruction *'>
+ 	<var: #jumpCond type: #'AbstractInstruction *'>
+ 	<var: #compareFloat type: #'AbstractInstruction *'>
+ 	cogit genLoadArgAtDepth: 0 into: Arg0Reg.
+ 	rcvrBoxed
+ 		ifTrue: [self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0]
+ 		ifFalse: [self genGetSmallFloatValueOf: ReceiverResultReg scratch: TempReg into: DPFPReg0].
+ 	jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.
+ 	self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.
+ 	compareFloat := invertComparison "May need to invert for NaNs"
+ 					ifTrue: [cogit CmpRd: DPFPReg0 Rd: DPFPReg1]
+ 					ifFalse: [cogit CmpRd: DPFPReg1 Rd: DPFPReg0].
+ 	jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"
+ 	cogit genMoveFalseR: ReceiverResultReg.
+ 	cogit genPrimReturn.
+ 	jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).
+ 	cogit genPrimReturn.
+ 	
+ 	"not a Small Float, check for Boxed Float argument"
+ 	jumpNotSmallFloat jmpTarget: cogit Label.
+ 	jumpImmediate := self genJumpImmediate: Arg0Reg.
+ 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
+ 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
+ 	jumpNotBoxedFloat := cogit JumpNonZero: 0.
+ 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
+ 	cogit Jump: compareFloat.
+ 	
+ 	jumpImmediate jmpTarget:
+ 	(jumpNotBoxedFloat jmpTarget: cogit Label).
+ 	^CompletePrimitive!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genPureSmallFloatArithmetic:preOpCheck: (in category 'primitive generators') -----
+ genPureSmallFloatArithmetic: arithmeticOperator preOpCheck: preOpCheckOrNil
+ 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
+ 	<inline: true>
+ 	^self genPureFloatArithmetic: arithmeticOperator preOpCheck: preOpCheckOrNil boxed: false!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genPureSmallFloatComparison:invert: (in category 'primitive generators') -----
+ genPureSmallFloatComparison: jumpOpcodeGenerator invert: invertComparison
+ 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
+ 	<inline: true>
+ 	^self genPureFloatComparison: jumpOpcodeGenerator invert: invertComparison boxed: false!

Item was added:
+ ----- Method: CurrentImageCoInterpreterFacade>>getPrimitiveDoMixedArithmetic (in category 'cog jit support') -----
+ getPrimitiveDoMixedArithmetic
+ 	^coInterpreter getPrimitiveDoMixedArithmetic ifNil: [true]!

Item was changed:
  ----- Method: Spur32BitMemoryManager>>loadFloatOrIntFrom: (in category 'interpreter access') -----
  loadFloatOrIntFrom: floatOrInt
+ 	"If floatOrInt is an integer and we enable mixed arithmetic in primitives, then convert it to a C double float and return it.
- 	"If floatOrInt is an integer, then convert it to a C double float and return it.
  	 If it is a Float, then load its value and return it.
  	 Otherwise fail -- ie return with primErrorCode non-zero."
  
  	<inline: true>
  	<returnTypeC: #double>
  
+ 	(self primitiveDoMixedArithmetic and: [self isIntegerObject: floatOrInt]) ifTrue:
- 	(self isIntegerObject: floatOrInt) ifTrue:
  		[^(self integerValueOf: floatOrInt) asFloat].
  	^self floatValueOf: floatOrInt!

Item was changed:
  ----- Method: Spur64BitMemoryManager>>loadFloatOrIntFrom: (in category 'interpreter access') -----
  loadFloatOrIntFrom: floatOrIntOop
+ 	"If floatOrInt is an integer and we enable mixed arithmetic in primitives, then convert it to a C double float and return it.
- 	"If floatOrInt is an integer, then convert it to a C double float and return it.
  	 If it is a Float, then load its value and return it.
  	 Otherwise fail -- ie return with primErrorCode non-zero."
  
  	<inline: true>
  	<returnTypeC: #double>
  	| result tagBits |
  	<var: #result type: #double>
  
  	(tagBits := floatOrIntOop bitAnd: self tagMask) ~= 0
  		ifTrue:
  			[tagBits = self smallFloatTag ifTrue:
  				[^self smallFloatValueOf: floatOrIntOop].
+ 			 (self primitiveDoMixedArithmetic and: [tagBits = self smallIntegerTag]) ifTrue:
- 			 tagBits = self smallIntegerTag ifTrue:
  				[^(self integerValueOf: floatOrIntOop) asFloat]]
  		ifFalse:
  			[(self classIndexOf: floatOrIntOop) = ClassFloatCompactIndex ifTrue:
  				[self cCode: '' inSmalltalk: [result := Float new: 2].
  				 self fetchFloatAt: floatOrIntOop + self baseHeaderSize into: result.
  				 ^result]].
  	coInterpreter primitiveFail.
  	^0.0!

Item was changed:
  InterpreterPrimitives subclass: #StackInterpreter
(excessive size, no diff calculated)

Item was changed:
  ----- Method: StackInterpreter class>>declareCVarsIn: (in category 'translation') -----
  declareCVarsIn: aCCodeGenerator
  	| vmClass |
  	self class == thisContext methodClass ifFalse: [^self]. "Don't duplicate decls in subclasses"
  	vmClass := aCCodeGenerator vmClass. "Generate primitiveTable etc based on vmClass, not just StackInterpreter"
  	aCCodeGenerator
  		addHeaderFile:'<stddef.h> /* for e.g. alloca */';
  		addHeaderFile:'<setjmp.h>';
  		addHeaderFile:'<wchar.h> /* for wint_t */';
  		addHeaderFile:'"vmCallback.h"';
  		addHeaderFile:'"sqMemoryFence.h"';
  		addHeaderFile:'"dispdbg.h"'.
  	LowcodeVM ifTrue: [ aCCodeGenerator addHeaderFile:'"sqLowcodeFFI.h"'].
  
  	vmClass declareInterpreterVersionIn: aCCodeGenerator defaultName: 'Stack'.
  	aCCodeGenerator
  		var: #interpreterProxy  type: #'struct VirtualMachine*'.
  	aCCodeGenerator
  		declareVar: #sendTrace type: 'volatile int';
  		declareVar: #byteCount type: #usqInt.
  	"These need to be pointers or unsigned."
  	self declareC: #(instructionPointer method newMethod)
  		as: #usqInt
  		in: aCCodeGenerator.
  	"These are all pointers; char * because Slang has no support for C pointer arithmetic."
  	self declareC: #(localIP localSP localFP stackPointer framePointer stackLimit breakSelector)
  		as: #'char *'
  		in: aCCodeGenerator.
  	aCCodeGenerator
  		var: #breakSelectorLength
  		declareC: 'sqInt breakSelectorLength = MinSmallInteger'.
  	self declareC: #(stackPage overflowedPage)
  		as: #'StackPage *'
  		in: aCCodeGenerator.
  	aCCodeGenerator removeVariable: 'stackPages'.  "this is an implicit receiver in the translated code."
  	"This defines bytecodeSetSelector as 0 if MULTIPLEBYTECODESETS
  	 is not defined, for the benefit of the interpreter on slow machines."
  	aCCodeGenerator addConstantForBinding: (self bindingOf: #MULTIPLEBYTECODESETS).
  	MULTIPLEBYTECODESETS == false ifTrue:
  		[aCCodeGenerator
  			removeVariable: 'bytecodeSetSelector'].
  	BytecodeSetHasExtensions == false ifTrue:
  		[aCCodeGenerator
  			removeVariable: 'extA';
  			removeVariable: 'extB'].
  	aCCodeGenerator
  		var: #methodCache
  		declareC: 'sqIntptr_t methodCache[MethodCacheSize + 1 /* ', (MethodCacheSize + 1) printString, ' */]'.
  	NewspeakVM
  		ifTrue:
  			[aCCodeGenerator
  				var: #nsMethodCache
  				declareC: 'sqIntptr_t nsMethodCache[NSMethodCacheSize + 1 /* ', (NSMethodCacheSize + 1) printString, ' */]']
  		ifFalse:
  			[aCCodeGenerator
  				removeVariable: #nsMethodCache;
  				removeVariable: 'localAbsentReceiver';
  				removeVariable: 'localAbsentReceiverOrZero'].
  	AtCacheTotalSize isInteger ifTrue:
  		[aCCodeGenerator
  			var: #atCache
  			declareC: 'sqInt atCache[AtCacheTotalSize + 1 /* ', (AtCacheTotalSize + 1) printString, ' */]'].
  	aCCodeGenerator
  		var: #primitiveTable
  		declareC: 'void (*primitiveTable[MaxPrimitiveIndex + 2 /* ', (MaxPrimitiveIndex + 2) printString, ' */])(void) = ', vmClass primitiveTableString.
  	vmClass primitiveTable do:
  		[:symbolOrNot|
  		(symbolOrNot isSymbol
  		 and: [symbolOrNot ~~ #primitiveFail]) ifTrue:
  			[(aCCodeGenerator methodNamed: symbolOrNot) ifNotNil:
  				[:tMethod| tMethod returnType: #void]]].
  	vmClass objectMemoryClass hasSpurMemoryManagerAPI
  		ifTrue:
  			[aCCodeGenerator
  				var: #primitiveAccessorDepthTable
  				type: 'signed char'
  				sizeString: 'MaxPrimitiveIndex + 2 /* ', (MaxPrimitiveIndex + 2) printString, ' */'
  				array: vmClass primitiveAccessorDepthTable]
  		ifFalse:
  			[aCCodeGenerator removeVariable: #primitiveAccessorDepthTable].
  	aCCodeGenerator
  		var: #displayBits type: #'void *'.
  	self declareC: #(displayWidth displayHeight displayDepth) as: #int in: aCCodeGenerator.
  	aCCodeGenerator
  		var: #primitiveFunctionPointer
  			declareC: 'void (*primitiveFunctionPointer)()';
  		var: #externalPrimitiveTable
  			declareC: 'void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* ', (MaxExternalPrimitiveTableSize + 1) printString, ' */])(void)';
  		var: #interruptCheckChain
  			declareC: 'void (*interruptCheckChain)(void) = 0';
  		var: #showSurfaceFn
  			declareC: 'int (*showSurfaceFn)(sqIntptr_t, int, int, int, int)';
  		var: #jmpBuf
  			declareC: 'jmp_buf jmpBuf[MaxJumpBuf + 1 /* ', (MaxJumpBuf + 1) printString, ' */]';
  		var: #suspendedCallbacks
  			declareC: 'usqInt suspendedCallbacks[MaxJumpBuf + 1 /* ', (MaxJumpBuf + 1) printString, ' */]';
  		var: #suspendedMethods
  			declareC: 'usqInt suspendedMethods[MaxJumpBuf + 1 /* ', (MaxJumpBuf + 1) printString, ' */]'.
  
  	self declareCAsUSqLong: #(nextPollUsecs nextWakeupUsecs longRunningPrimitiveGCUsecs
  								longRunningPrimitiveStartUsecs longRunningPrimitiveStopUsecs
  								"these are high-frequency enough that they're overflowing quite quickly on modern hardware"
  								statProcessSwitch statIOProcessEvents statForceInterruptCheck
  								statCheckForEvents statStackOverflow statStackPageDivorce
  								statIdleUsecs)
  		in: aCCodeGenerator.
  	aCCodeGenerator var: #nextProfileTick type: #sqLong.
  	aCCodeGenerator
  		var: #reenterInterpreter
  		declareC: 'jmp_buf reenterInterpreter; /* private export */'.
  	LowcodeVM
  		ifTrue:
  			[aCCodeGenerator
  				var: #lowcodeCalloutState type: #'sqLowcodeCalloutState*'.
  			 self declareC: #(nativeSP nativeStackPointer shadowCallStackPointer)
  				as: #'char *'
  				in: aCCodeGenerator]
  		ifFalse:
  			[#(lowcodeCalloutState nativeSP nativeStackPointer shadowCallStackPointer) do:
+ 				[:var| aCCodeGenerator removeVariable: var]].
+ 		
+ 	aCCodeGenerator
+ 		var: #primitiveDoMixedArithmetic
+ 		declareC: 'sqInt primitiveDoMixedArithmetic = 1'.!
- 				[:var| aCCodeGenerator removeVariable: var]]!

Item was changed:
  ----- Method: StackInterpreter>>initialize (in category 'initialization') -----
  initialize
  	"Here we can initialize the variables C initializes to zero.  #initialize methods do /not/ get translated."
  	super initialize.
+ 	primitiveDoMixedArithmetic := true. "whether we authorize primitives to perform mixed arithmetic or not"
  	checkAllocFiller := false. "must precede initializeObjectMemory:"
  	stackLimit := 0. "This is also the initialization flag for the stack system."
  	stackPage := overflowedPage := 0.
  	extraFramesToMoveOnOverflow := 0.
  	bytecodeSetSelector := 0.
  	highestRunnableProcessPriority := 0.
  	nextPollUsecs := 0.
  	nextWakeupUsecs := 0.
  	tempOop := tempOop2 := theUnknownShort := 0.
  	interruptPending := false.
  	inIOProcessEvents := 0.
  	fullScreenFlag := 0.
  	sendWheelEvents := deferDisplayUpdates := false.
  	displayBits := displayWidth := displayHeight := displayDepth := 0.
  	pendingFinalizationSignals := statPendingFinalizationSignals := 0.
  	globalSessionID := 0.
  	jmpDepth := 0.
  	longRunningPrimitiveStartUsecs := longRunningPrimitiveStopUsecs := 0.
  	maxExtSemTabSizeSet := false.
  	debugCallbackInvokes := debugCallbackPath := debugCallbackReturns := 0.
  	statForceInterruptCheck := statStackOverflow := statCheckForEvents :=
  	statProcessSwitch := statIOProcessEvents := statStackPageDivorce :=
  	statIdleUsecs := 0!

Item was added:
+ ----- Method: StackInterpreter>>primitiveDoMixedArithmetic (in category 'primitive support') -----
+ primitiveDoMixedArithmetic
+ 	"If primitiveDoMixedArithmetic is true, then primitive can handle the conversions:
+ 	SmallInteger arithmeticOp: Float (Small or Boxed)
+ 	SmallInteger compareOp: Float (Small or Boxed)
+ 	Else, the primitive fail in case of mixed arithmetic, and conversion should be performed at image side"
+ 	<cmacro: '() primitiveDoMixedArithmetic'>
+ 	^primitiveDoMixedArithmetic!

Item was added:
+ ----- Method: StackInterpreter>>setPrimitiveDoMixedArithmetic: (in category 'primitive support') -----
+ setPrimitiveDoMixedArithmetic: aBool
+ 	"See #primitiveDoMixedArithmetic method"
+ 	primitiveDoMixedArithmetic = aBool ifFalse: [self flushMethodCache].
+ 	primitiveDoMixedArithmetic := aBool!

Item was changed:
  ----- Method: StackInterpreterPrimitives>>primitiveAllVMParameters: (in category 'system control primitives') -----
  primitiveAllVMParameters: paramsArraySize
  	"See primitiveVMParameter method comment"
  
  	| result |
  	result := objectMemory instantiateClass: (objectMemory splObj: ClassArray) indexableSize: paramsArraySize.
  	objectMemory storePointerUnchecked: 0	ofObject: result withValue: (self positiveMachineIntegerFor: objectMemory oldSpaceSize).
  	objectMemory storePointerUnchecked: 1	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory newSpaceSize).
  	objectMemory storePointerUnchecked: 2	ofObject: result withValue: (self positiveMachineIntegerFor: objectMemory totalMemorySize).
  	"objectMemory storePointerUnchecked: 3	ofObject: result withValue: objectMemory nilObject was allocationCount".
  	"objectMemory storePointerUnchecked: 4	ofObject: result withValue: objectMemory nilObject allocationsBetweenGCs".
  	objectMemory storePointerUnchecked: 5	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory tenuringThreshold).
  	objectMemory storePointerUnchecked: 6	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statFullGCs).
  	objectMemory storePointerUnchecked: 7	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statFullGCUsecs + 500 // 1000).
  	objectMemory
  		storePointerUnchecked: 8
  		ofObject: result
  		withValue: (objectMemory integerObjectOf: (objectMemory hasSpurMemoryManagerAPI
  														ifTrue: [objectMemory statScavenges]
  														ifFalse: [objectMemory statIncrGCs])).
  	objectMemory
  		storePointerUnchecked: 9
  		ofObject: result
  		withValue: (objectMemory integerObjectOf: (objectMemory hasSpurMemoryManagerAPI
  														ifTrue: [objectMemory statScavengeGCUsecs]
  														ifFalse: [objectMemory statIncrGCUsecs]) + 500 // 1000).
  	objectMemory storePointerUnchecked: 10	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statTenures).
  	"JITTER VM info unused; 11 - 14/12 - 15 available for reuse"
  	11 to: 18 do:
  		[:i | objectMemory storePointerUnchecked: i ofObject: result withValue: ConstZero].
  	objectMemory storePointerUnchecked: 15 ofObject: result withValue: (objectMemory positive64BitIntegerFor: statIdleUsecs).
  	(SistaVM and: [self isCog]) ifTrue:
  		[objectMemory storePointerUnchecked: 16 ofObject: result withValue: (objectMemory floatObjectOf: self getCogCodeZoneThreshold)].
  	objectMemory hasSpurMemoryManagerAPI ifTrue:
  		[objectMemory
  			storePointerUnchecked: 17	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statCompactionUsecs + 500 // 1000);
  			storePointerUnchecked: 18	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory scavengeThresholdAsExtent)].
  	objectMemory storePointerUnchecked: 19	ofObject: result withValue: (objectMemory positive64BitIntegerFor: self ioUTCStartMicroseconds).
  	objectMemory storePointerUnchecked: 20	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory rootTableCount).
  	objectMemory storePointerUnchecked: 21	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statRootTableOverflows).
  	objectMemory storePointerUnchecked: 22	ofObject: result withValue: (objectMemory integerObjectOf: extraVMMemory).
  	objectMemory storePointerUnchecked: 23	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory shrinkThreshold).
  	objectMemory storePointerUnchecked: 24	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory growHeadroom).
  	objectMemory storePointerUnchecked: 25	ofObject: result withValue: (objectMemory integerObjectOf: self ioHeartbeatMilliseconds).
  	objectMemory storePointerUnchecked: 26	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statMarkCount).
  	objectMemory storePointerUnchecked: 27	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statSweepCount).
  	objectMemory storePointerUnchecked: 28	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statMkFwdCount).
  	objectMemory storePointerUnchecked: 29	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statCompMoveCount).
  	objectMemory storePointerUnchecked: 30	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statGrowMemory).
  	objectMemory storePointerUnchecked: 31	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statShrinkMemory).
  	objectMemory storePointerUnchecked: 32	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statRootTableCount).
  	objectMemory hasSpurMemoryManagerAPI ifTrue: "was statAllocationCount"
  		[objectMemory storePointerUnchecked: 33	ofObject: result withValue: (objectMemory positive64BitIntegerFor: objectMemory currentAllocatedBytes)].
  	objectMemory storePointerUnchecked: 34	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statSurvivorCount).
  	objectMemory storePointerUnchecked: 35	ofObject: result withValue: (objectMemory integerObjectOf: (self microsecondsToMilliseconds: objectMemory statGCEndUsecs)).
  	objectMemory storePointerUnchecked: 36	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statSpecialMarkCount).
  	objectMemory storePointerUnchecked: 37	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statIGCDeltaUsecs + 500 // 1000).
  	objectMemory storePointerUnchecked: 38	ofObject: result withValue: (objectMemory integerObjectOf: statPendingFinalizationSignals).
  	objectMemory storePointerUnchecked: 39	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory wordSize).
  	objectMemory storePointerUnchecked: 40	ofObject: result withValue: (objectMemory integerObjectOf: self imageFormatVersion).
  	objectMemory storePointerUnchecked: 41	ofObject: result withValue: (objectMemory integerObjectOf: numStackPages).
  	objectMemory storePointerUnchecked: 42	ofObject: result withValue: (objectMemory integerObjectOf: desiredNumStackPages).
  	objectMemory storePointerUnchecked: 43	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory edenBytes).
  	objectMemory storePointerUnchecked: 44	ofObject: result withValue: (objectMemory integerObjectOf: desiredEdenBytes).
  	objectMemory storePointerUnchecked: 45	ofObject: result withValue: self getCogCodeSize.
  	objectMemory storePointerUnchecked: 46	ofObject: result withValue: self getDesiredCogCodeSize.
  	objectMemory storePointerUnchecked: 47	ofObject: result withValue: self getCogVMFlags.
  	objectMemory storePointerUnchecked: 48	ofObject: result withValue: (objectMemory integerObjectOf: self ioGetMaxExtSemTableSize).
  	"50 & 51 (49 & 50) reserved for parameters that persist in the image"
  	objectMemory storePointerUnchecked: 51	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory rootTableCapacity).
  	objectMemory hasSpurMemoryManagerAPI ifTrue:
  		[objectMemory
  			storePointerUnchecked: 52 ofObject: result withValue: (objectMemory integerObjectOf: objectMemory numSegments);
  			storePointerUnchecked: 53 ofObject: result withValue: (objectMemory integerObjectOf: objectMemory freeSize);
  			storePointerUnchecked: 54 ofObject: result withValue: (objectMemory floatObjectOf: objectMemory getHeapGrowthToSizeGCRatio)].
  	objectMemory storePointerUnchecked: 55	ofObject: result withValue: (self positive64BitIntegerFor: statProcessSwitch).
  	objectMemory storePointerUnchecked: 56	ofObject: result withValue: (self positive64BitIntegerFor: statIOProcessEvents).
  	objectMemory storePointerUnchecked: 57	ofObject: result withValue: (self positive64BitIntegerFor: statForceInterruptCheck).
  	objectMemory storePointerUnchecked: 58	ofObject: result withValue: (self positive64BitIntegerFor: statCheckForEvents).
  	objectMemory storePointerUnchecked: 59	ofObject: result withValue: (self positive64BitIntegerFor: statStackOverflow).
  	objectMemory storePointerUnchecked: 60	ofObject: result withValue: (self positive64BitIntegerFor: statStackPageDivorce).
  	objectMemory storePointerUnchecked: 61	ofObject: result withValue: self getCodeCompactionCount.
  	objectMemory storePointerUnchecked: 62	ofObject: result withValue: self getCodeCompactionMSecs.
  	objectMemory storePointerUnchecked: 63	ofObject: result withValue: self getCogMethodCount.
  	objectMemory storePointerUnchecked: 64	ofObject: result withValue: self getCogVMFeatureFlags.
  	objectMemory storePointerUnchecked: 65	ofObject: result withValue: (objectMemory integerObjectOf: self stackPageByteSize).
  	objectMemory hasSpurMemoryManagerAPI ifTrue:
  		[objectMemory
  			storePointerUnchecked: 66 ofObject: result withValue: (objectMemory integerObjectOf: objectMemory maxOldSpaceSize)].
  	objectMemory storePointerUnchecked: 67 ofObject: result withValue: (objectMemory floatObjectOf: stackPages statAverageLivePagesWhenMapping).
  	objectMemory storePointerUnchecked: 68 ofObject: result withValue: (objectMemory integerObjectOf: stackPages statMaxPageCountWhenMapping).
  	objectMemory
  		storePointerUnchecked: 69
  		ofObject: result
  		withValue: (objectMemory integerObjectOf: (self cCode: 'VM_PROXY_MAJOR' inSmalltalk: [self class vmProxyMajorVersion])).
  	objectMemory
  		storePointerUnchecked: 70
  		ofObject: result
  		withValue: (objectMemory integerObjectOf: (self cCode: 'VM_PROXY_MINOR' inSmalltalk: [self class vmProxyMinorVersion])).	
  	objectMemory storePointerUnchecked: 71	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statMarkUsecs + 500 // 1000).
  	objectMemory storePointerUnchecked: 72	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statSweepUsecs + 500 // 1000).
  	objectMemory hasSpurMemoryManagerAPI ifTrue:
  		[objectMemory
  			storePointerUnchecked: 73	ofObject: result withValue: (objectMemory integerObjectOf: objectMemory statMaxAllocSegmentTime + 500 // 1000)].
+ 	objectMemory storePointerUnchecked: 74	ofObject: result withValue: (objectMemory booleanObjectOf: self primitiveDoMixedArithmetic).
  
  	objectMemory beRootIfOld: result.
  	self methodReturnValue: result!

Item was changed:
  ----- Method: StackInterpreterPrimitives>>primitiveGetVMParameter: (in category 'system control primitives') -----
  primitiveGetVMParameter: arg 
  	"See primitiveVMParameter method comment.
  	 N.B. written as a returning case to avoid branch limits in the V3 bytecode set."
  	arg caseOf: {
  			[1]  ->	[^self positiveMachineIntegerFor: objectMemory oldSpaceSize].
  			[2]  ->	[^objectMemory integerObjectOf: objectMemory newSpaceSize].
  			[3]  ->	[^self positiveMachineIntegerFor: objectMemory totalMemorySize].
  			[6]  ->	[^objectMemory integerObjectOf: objectMemory tenuringThreshold].
  			[7]  ->	[^objectMemory integerObjectOf: objectMemory statFullGCs].
  			[8]  ->	[^objectMemory integerObjectOf: objectMemory statFullGCUsecs + 500 // 1000].
  			[9]  ->	[^objectMemory integerObjectOf: (objectMemory hasSpurMemoryManagerAPI
  														ifTrue: [objectMemory statScavenges]
  														ifFalse: [objectMemory statIncrGCs])].
  			[10] ->	[^objectMemory integerObjectOf: (objectMemory hasSpurMemoryManagerAPI
  														ifTrue: [objectMemory statScavengeGCUsecs]
  														ifFalse: [objectMemory statIncrGCUsecs]) + 500 // 1000].
  			[11] ->	[^objectMemory integerObjectOf: objectMemory statTenures].
  			[12] ->	[^ConstZero]. "Was JITTER VM info"
  			[13] ->	[^ConstZero]. "Was JITTER VM info"
  			[14] ->	[^ConstZero]. "Was JITTER VM info"
  			[15] ->	[^ConstZero]. "Was JITTER VM info"
  			[16] ->	[^self positive64BitIntegerFor: statIdleUsecs].
  			[17] ->	[^(SistaVM and: [self isCog])
  						ifTrue: [objectMemory floatObjectOf: self getCogCodeZoneThreshold]
  						ifFalse: [ConstZero]].
  			[18] ->	[^objectMemory hasSpurMemoryManagerAPI
  						ifTrue: [objectMemory integerObjectOf: objectMemory statCompactionUsecs + 500 // 1000]
  						ifFalse: [ConstZero]].
  			[19] ->	[^objectMemory hasSpurMemoryManagerAPI
  						ifTrue: [objectMemory integerObjectOf: objectMemory scavengeThresholdAsExtent]
  						ifFalse: [ConstZero]].
  			[20] ->	[^objectMemory positive64BitIntegerFor: self ioUTCStartMicroseconds].
  			[21] ->	[^objectMemory integerObjectOf: objectMemory rootTableCount].
  			[22] ->	[^objectMemory integerObjectOf: objectMemory statRootTableOverflows].
  			[23] ->	[^objectMemory integerObjectOf: extraVMMemory].
  			[24] ->	[^objectMemory integerObjectOf: objectMemory shrinkThreshold].
  			[25] ->	[^objectMemory integerObjectOf: objectMemory growHeadroom].
  			[26] ->	[^objectMemory integerObjectOf: self ioHeartbeatMilliseconds].
  			[27] ->	[^objectMemory integerObjectOf: objectMemory statMarkCount].
  			[28] ->	[^objectMemory integerObjectOf: objectMemory statSweepCount].
  			[29] ->	[^objectMemory integerObjectOf: objectMemory statMkFwdCount].
  			[30] ->	[^objectMemory integerObjectOf: objectMemory statCompMoveCount].
  			[31] ->	[^objectMemory integerObjectOf: objectMemory statGrowMemory].
  			[32] ->	[^objectMemory integerObjectOf: objectMemory statShrinkMemory].
  			[33] ->	[^objectMemory integerObjectOf: objectMemory statRootTableCount].
  			[34] ->	[^objectMemory hasSpurMemoryManagerAPI ifTrue:"was statAllocationCount"
  						[objectMemory positive64BitIntegerFor: objectMemory currentAllocatedBytes]].
  			[35] ->	[^objectMemory integerObjectOf: objectMemory statSurvivorCount].
  			[36] ->	[^objectMemory integerObjectOf: (self microsecondsToMilliseconds: objectMemory statGCEndUsecs)].
  			[37] ->	[^objectMemory integerObjectOf: objectMemory statSpecialMarkCount].
  			[38] ->	[^objectMemory integerObjectOf: objectMemory statIGCDeltaUsecs + 500 // 1000].
  			[39] ->	[^objectMemory integerObjectOf: statPendingFinalizationSignals].
  			[40] ->	[^objectMemory integerObjectOf: objectMemory wordSize].
  			[41] ->	[^objectMemory integerObjectOf: self imageFormatVersion].
  			[42] ->	[^objectMemory integerObjectOf: numStackPages].
  			[43] ->	[^objectMemory integerObjectOf: desiredNumStackPages].
  			[44] ->	[^objectMemory integerObjectOf: objectMemory edenBytes].
  			[45] ->	[^objectMemory integerObjectOf: desiredEdenBytes].
  			[46] ->	[^self getCogCodeSize].
  			[47] ->	[^self getDesiredCogCodeSize].
  			[48] ->	[^self getCogVMFlags].
  			[49] ->	[^objectMemory integerObjectOf: self ioGetMaxExtSemTableSize].
  			[52] ->	[^objectMemory integerObjectOf: objectMemory rootTableCapacity].
  			[53] ->	[^objectMemory hasSpurMemoryManagerAPI ifTrue:
  						[objectMemory integerObjectOf: objectMemory numSegments]].
  			[54] ->	[^objectMemory hasSpurMemoryManagerAPI ifTrue:
  						[objectMemory integerObjectOf: objectMemory freeSize]].
  			[55] ->	[^objectMemory hasSpurMemoryManagerAPI ifTrue:
  						[objectMemory floatObjectOf: objectMemory getHeapGrowthToSizeGCRatio]].
  			[56] ->	[^self positive64BitIntegerFor: statProcessSwitch].
  			[57] ->	[^self positive64BitIntegerFor: statIOProcessEvents].
  			[58] ->	[^self positive64BitIntegerFor: statForceInterruptCheck].
  			[59] ->	[^self positive64BitIntegerFor: statCheckForEvents].
  			[60] ->	[^self positive64BitIntegerFor: statStackOverflow].
  			[61] ->	[^self positive64BitIntegerFor: statStackPageDivorce].
  			[62] ->	[^self getCodeCompactionCount].
  			[63] ->	[^self getCodeCompactionMSecs].
  			[64] ->	[^self getCogMethodCount].
  			[65] ->	[^self getCogVMFeatureFlags].
  			[66] ->	[^objectMemory integerObjectOf: self stackPageByteSize].
  			[67] ->	[^objectMemory hasSpurMemoryManagerAPI ifTrue:
  						[objectMemory integerObjectOf: objectMemory maxOldSpaceSize]].
  			[68] ->	[^objectMemory floatObjectOf: stackPages statAverageLivePagesWhenMapping].
  			[69] ->	[^objectMemory integerObjectOf: stackPages statMaxPageCountWhenMapping].
  			[70] ->	[^self integerObjectOf: (self cCode: 'VM_PROXY_MAJOR' inSmalltalk: [self class vmProxyMajorVersion])].
  			[71] ->	[^self integerObjectOf: (self cCode: 'VM_PROXY_MINOR' inSmalltalk: [self class vmProxyMinorVersion])].
  			[72] ->	[^objectMemory integerObjectOf: objectMemory statMarkUsecs + 500 // 1000].
  			[73] ->	[^objectMemory integerObjectOf: objectMemory statSweepUsecs + 500 // 1000].
  			[74] ->	[^objectMemory hasSpurMemoryManagerAPI ifTrue:
+ 						[objectMemory integerObjectOf: objectMemory statMaxAllocSegmentTime + 500 // 1000]].
+ 			[75] ->	[^objectMemory booleanObjectOf: self primitiveDoMixedArithmetic] }
- 						[objectMemory integerObjectOf: objectMemory statMaxAllocSegmentTime + 500 // 1000]] }
  		otherwise: [^nil]!

Item was changed:
  ----- Method: StackInterpreterPrimitives>>primitiveSetVMParameter:arg: (in category 'system control primitives') -----
  primitiveSetVMParameter: index arg: argOop
  	"See primitiveVMParameter method comment"
  	| arg result |
  
  	"argOop read & checks; in most cases this is an integer parameter.  In some it is either an integer or a Float"
+ 	index = 75
- 	(index = 17 or: [index = 55 or: [index = 68]])
  		ifTrue:
+ 			[ arg := objectMemory booleanValueOf: argOop.
+ 			self failed ifTrue: [^self primitiveFailFor: PrimErrBadArgument]]
+ 		ifFalse: [(index = 17 or: [index = 55 or: [index = 68]])
+ 			ifTrue:
+ 				[((objectMemory isFloatInstance: argOop)
+ 			 	 or: [objectMemory isIntegerObject: argOop]) ifFalse:
+ 					[^self primitiveFailFor: PrimErrBadArgument]]
+ 			ifFalse: [(objectMemory isIntegerObject: argOop) ifFalse:
+ 					[^self primitiveFailFor: PrimErrBadArgument].
+ 				 arg := objectMemory integerValueOf: argOop]].
- 			[((objectMemory isFloatInstance: argOop)
- 			  or: [objectMemory isIntegerObject: argOop]) ifFalse:
- 				[^self primitiveFailFor: PrimErrBadArgument]]
- 		ifFalse:
- 			[(objectMemory isIntegerObject: argOop) ifFalse:
- 				[^self primitiveFailFor: PrimErrBadArgument].
- 			 arg := objectMemory integerValueOf: argOop].
  
  	"assume failure, then set success for handled indices"
  	self primitiveFailFor: PrimErrBadArgument.
  	index caseOf: {
  		[5] ->	[objectMemory hasSpurMemoryManagerAPI ifFalse:
  					["Was:
  							result := allocationsBetweenGCs.
  							allocationsBetweenGCs := arg."
  						"Ignore for now, because old images won't start up otherwise.
  						 See 45 for eden size setting."
  					 result := objectMemory nilObject.
  					 self initPrimCall]].
  		[6] ->	[result := objectMemory integerObjectOf: objectMemory tenuringThreshold.
  				 primFailCode := objectMemory tenuringThreshold: arg].
  		[11] ->	[arg >= 0 ifTrue:
  					[result := objectMemory integerObjectOf: objectMemory statTenures.
  					 objectMemory statTenures: arg.
  					 self initPrimCall]].
  		[17] ->	[(SistaVM and: [self isCog]) ifTrue:
  					[result := objectMemory floatObjectOf: self getCogCodeZoneThreshold.
  					 primFailCode := self setCogCodeZoneThreshold: (self noInlineLoadFloatOrIntFrom: argOop)]].
  		[23] ->	[result := objectMemory integerObjectOf: extraVMMemory.
  				 extraVMMemory := arg.
  				 self initPrimCall].
  		[24] ->	[arg > 0 ifTrue:
  					[result := objectMemory integerObjectOf: objectMemory shrinkThreshold.
  					 objectMemory shrinkThreshold: arg.
  					 self initPrimCall]].
  		[25] ->	[arg > 0 ifTrue:
  					[result := objectMemory integerObjectOf: objectMemory growHeadroom.
  					 objectMemory growHeadroom: arg.
  					 self initPrimCall]].
  		[26] ->	[arg >= 0 ifTrue: "0 turns off the heartbeat"
  					[result := objectMemory integerObjectOf: self ioHeartbeatMilliseconds.
  					 self ioSetHeartbeatMilliseconds: arg.
  					 self initPrimCall]].
  		[34] ->	[(objectMemory hasSpurMemoryManagerAPI "was statAllocationCount; now statAllocatedBytes"
  				  and: [arg >= 0]) ifTrue:
  					[result := objectMemory positive64BitIntegerFor: objectMemory currentAllocatedBytes.
  					 objectMemory setCurrentAllocatedBytesTo: arg.
  					 self initPrimCall]].
  		[43] ->	[(arg between: 0 and: 65535) ifTrue:
  					[result := objectMemory integerObjectOf: desiredNumStackPages.
  					 desiredNumStackPages := arg.
  					 self initPrimCall]].
  		[45] ->	[arg >= 0 ifTrue:
  					[result := objectMemory integerObjectOf: desiredEdenBytes.
  					 desiredEdenBytes := arg.
  					 self initPrimCall]].
  		[47] ->	[(self isCog
  				  and: [arg between: 0 and: self maxCogCodeSize]) ifTrue:
  					[result := objectMemory integerObjectOf: self getDesiredCogCodeSize.
  					 self setDesiredCogCodeSize: arg.
  					 self initPrimCall]].
  		[48] ->	[arg >= 0 ifTrue:
  					[result := objectMemory integerObjectOf: self getCogVMFlags.
  					 self initPrimCall. "i.e. setCogVMFlags: can fail"
  					 self setCogVMFlags: arg]].
  		[49] ->	[(arg between: 0 and: 65535) ifTrue:
  					[result := objectMemory integerObjectOf: self ioGetMaxExtSemTableSize.
  					 self initPrimCall. "i.e. ioSetMaxExtSemTableSize: is allowed to fail"
  					 self setMaxExtSemSizeTo: arg]].
  		[55] ->	[objectMemory hasSpurMemoryManagerAPI ifTrue:
  					[result := objectMemory floatObjectOf: objectMemory getHeapGrowthToSizeGCRatio.
  					 primFailCode := objectMemory setHeapGrowthToSizeGCRatio: (self noInlineLoadFloatOrIntFrom: argOop)]].
  		[67] ->	[(arg >= 0
  				  and: [objectMemory hasSpurMemoryManagerAPI]) ifTrue:
  					[result := objectMemory integerObjectOf: objectMemory maxOldSpaceSize.
  					 primFailCode := objectMemory setMaxOldSpaceSize: arg]].
  		[68] ->	[result := objectMemory floatObjectOf: stackPages statAverageLivePagesWhenMapping.
  				 self initPrimCall. "i.e. statAverageLivePagesWhenMapping: is allowed to fail"
  				 stackPages statAverageLivePagesWhenMapping: (self noInlineLoadFloatOrIntFrom: argOop)].
  		[69] ->	[arg >= 0 ifTrue:
  					[result := objectMemory integerObjectOf: stackPages statMaxPageCountWhenMapping.
  					 stackPages statMaxPageCountWhenMapping: arg.
  					 self initPrimCall]].
  		[74] ->	[(arg >= 0
  				  and: [objectMemory hasSpurMemoryManagerAPI]) ifTrue:
  					[result := objectMemory integerObjectOf: objectMemory statMaxAllocSegmentTime + 500 // 1000.
  					 stackPages statMaxAllocSegmentTime: arg. "usually 0"
+ 					 self initPrimCall]].
+ 		[75] ->	[result := objectMemory booleanObjectOf: self primitiveDoMixedArithmetic.
+ 				self setPrimitiveDoMixedArithmetic: arg.
+ 				self initPrimCall] }
- 					 self initPrimCall]] }
  		otherwise: [].
  
  	self successful
  		ifTrue: [self methodReturnValue: result]  "return old value"
  		ifFalse: [self primitiveFailFor: PrimErrInappropriate] "attempting to write a read-only or non-existent parameter"!

Item was changed:
  ----- Method: StackInterpreterPrimitives>>primitiveVMParameter (in category 'system control primitives') -----
  primitiveVMParameter
  	"Behaviour depends on argument count:
  		0 args:	return an Array of VM parameter values;
  		1 arg:	return the indicated VM parameter;
  		2 args:	set the VM indicated parameter.
  	VM parameters are numbered as follows:
  		1	end (v3)/size(Spur) of old-space (0-based, read-only)
  		2	end (v3)/size(Spur) of young/new-space (read-only)
  		3	end (v3)/size(Spur) of heap (read-only)
  		4	nil (was allocationCount (read-only))
  		5	nil (was allocations between GCs (read-write)
  		6	survivor count tenuring threshold (read-write)
  		7	full GCs since startup (read-only)
  		8	total milliseconds in full GCs since startup (read-only)
  		9	incremental GCs (SqueakV3) or scavenges (Spur) since startup (read-only)
  		10	total milliseconds in incremental GCs (SqueakV3) or scavenges (Spur) since startup (read-only)
  		11	tenures of surving objects since startup or reset (read-write)
  		12-20 were specific to ikp's JITTER VM, now 12-15 are open for use
  		16	total microseconds at idle since start-up (if non-zero)
  		17	fraction of the code zone to use (Sista only; used to control code zone use to preserve sendAndBranchData on counter tripped callback)
  		18	total milliseconds in compaction phase of full GC since start-up (Spur only)
  		19	scavenge threshold, the effective size of eden.  When eden fills to the threshold a scavenge is scheduled. Newer Spur VMs only.
  		20	utc microseconds at VM start-up (actually at time initialization, which precedes image load).
  		21	root/remembered table size (occupancy) (read-only)
  		22	root table overflows since startup (read-only)
  		23	bytes of extra memory to reserve for VM buffers, plugins, etc (stored in image file header).
  		24	memory threshold above which shrinking object memory (rw)
  		25	memory headroom when growing object memory (rw)
  		26	interruptChecksEveryNms - force an ioProcessEvents every N milliseconds (rw)
  		27	number of times mark loop iterated for current IGC/FGC (read-only) includes ALL marking
  		28	number of times sweep loop iterated for current IGC/FGC (read-only)
  		29	number of times make forward loop iterated for current IGC/FGC (read-only)
  		30	number of times compact move loop iterated for current IGC/FGC (read-only)
  		31	number of grow memory requests (read-only)
  		32	number of shrink memory requests (read-only)
  		33	number of root table entries used for current IGC/FGC (read-only)
  		34	Spur: bytes allocated in total since start-up or reset (read-write) (Used to be number of allocations done before current IGC/FGC (read-only))
  		35	number of survivor objects after current IGC/FGC (read-only)
  		36	millisecond clock when current IGC/FGC completed (read-only)
  		37	number of marked objects for Roots of the world, not including Root Table entries for current IGC/FGC (read-only)
  		38	milliseconds taken by current IGC (read-only)
  		39	Number of finalization signals for Weak Objects pending when current IGC/FGC completed (read-only)
  		40	BytesPerOop for this image
  		41	imageFormatVersion for the VM
  		42	number of stack pages in use
  		43	desired number of stack pages (stored in image file header, max 65535)
  		44	size of eden, in bytes
  		45	desired size of eden, in bytes (stored in image file header)
  		46	machine code zone size, in bytes (Cog only; otherwise nil)
  		47	desired machine code zone size (stored in image file header; Cog only; otherwise nil)
  		48	various header flags.  See getCogVMFlags.
  		49	max size the image promises to grow the external semaphore table to (0 sets to default, which is 256 as of writing)
  		50-51 nil; reserved for VM parameters that persist in the image (such as eden above)
  		52	root/remembered table capacity
  		53	number of segments (Spur only; otherwise nil)
  		54	total size of free old space (Spur only, otherwise nil)
  		55	ratio of growth and image size at or above which a GC will be performed post scavenge
  		56	number of process switches since startup (read-only)
  		57	number of ioProcessEvents calls since startup (read-only)
  		58	number of ForceInterruptCheck calls since startup (read-only)
  		59	number of check event calls since startup (read-only)
  		60	number of stack page overflows since startup (read-only)
  		61	number of stack page divorces since startup (read-only)
  		62	compiled code compactions since startup (read-only; Cog only; otherwise nil)
  		63	total milliseconds in compiled code compactions since startup (read-only; Cog only; otherwise nil)
  		64	the number of methods that currently have jitted machine-code
  		65	whether the VM supports a certain feature, MULTIPLE_BYTECODE_SETS is bit 0, IMMUTABILITY is bit 1
  		66	the byte size of a stack page
  		67	the max allowed size of old space (Spur only; nil otherwise; 0 implies no limit except that of the underlying platform)
  		68	the average number of live stack pages when scanned by GC (at scavenge/gc/become et al) (read-write)
  		69	the maximum number of live stack pages when scanned by GC (at scavenge/gc/become et al) (read-write)
  		70	the vmProxyMajorVersion (the interpreterProxy VM_MAJOR_VERSION)
  		71	the vmProxyMinorVersion (the interpreterProxy VM_MINOR_VERSION)
  		72 total milliseconds in full GCs Mark phase since startup (read-only)
  		73 total milliseconds in full GCs Sweep phase since startup (read-only, can be 0 depending on compactors)
  		74 maximum pause time due to segment allocation
+ 		75 whether the arithmetic primitives perform conversion in case of mixed SmallInteger/Float (true) or fail (false)
  		
  	Note: Thanks to Ian Piumarta for this primitive."
  
  	| paramsArraySize index |
+ 	paramsArraySize := 75.
- 	paramsArraySize := 74.
  	argumentCount = 0 ifTrue: [^self primitiveAllVMParameters: paramsArraySize].
  	argumentCount > 2 ifTrue: [^self primitiveFailFor: PrimErrBadNumArgs].
  	
  	"index read & checks"
  	index := self stackValue: (argumentCount = 1 ifTrue: [0] ifFalse: [1]).
  	(objectMemory isIntegerObject: index) ifFalse: [^self primitiveFailFor: PrimErrBadArgument].
  	index := objectMemory integerValueOf: index.
  	(index < 1 or: [index > paramsArraySize]) ifTrue: [^self primitiveFailFor: PrimErrBadIndex].
  	
  	argumentCount = 1 ifTrue:	 "read VM parameter; written this way to avoid branch limits in V3 bytecode set"
  		[| result |
  		 result := self primitiveGetVMParameter: index.
  		 ^self methodReturnValue: (result ifNil: [objectMemory nilObject])].
  
  	"write a VM parameter"
  	self primitiveSetVMParameter: index arg: self stackTop!



More information about the Vm-dev mailing list