[Vm-dev] VM Maker: VMMaker.oscog-cb.1651.mcz
Clément Bera
bera.clement at gmail.com
Mon Jan 18 18:54:54 UTC 2016
I forgot to put the URL, load this package:
http://smalltalkhub.com/mc/ClementBera/Immutability/main
to try to use immutability on the Stack VM compiled with #(IMMUTABILITY
true), Spur only.
The JIT is still crashing (I think there are problems in the bcpc to mcpc
mapping in what I did I will have a look later).
2016-01-18 18:29 GMT+01:00 <commits at source.squeak.org>:
>
> Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
> http://source.squeak.org/VMMaker/VMMaker.oscog-cb.1651.mcz
>
> ==================== Summary ====================
>
> Name: VMMaker.oscog-cb.1651
> Author: cb
> Time: 18 January 2016, 6:29:12.307 pm
> UUID: b53b4619-89ec-4131-bc40-8740fbb218fb
> Ancestors: VMMaker.oscog-eem.1650
>
> In this version, the Stack VM compiled to C is fully working with
> Immutability ON.
>
> Load the package to try to use it.
>
> I fixed the primitive not popping enough the stack...
>
> Fixed a zip in Cogit.
>
> Important change in the stack interpreter: if the cannotAssign:withValue:
> callback was called, its sender pc was ahead by one due to the
> fetchNextBytecode before the normalSend. I postponed the fetchNextBytecode
> after the immutability check, which works fine in the compiled VM.
>
> I think the Simulator works fine too but I might need to fix something
> there.
>
> =============== Diff against VMMaker.oscog-eem.1650 ===============
>
> Item was changed:
> ----- Method: CoInterpreter>>extendedStoreBytecodePop: (in category
> 'stack bytecodes') -----
> extendedStoreBytecodePop: popBoolean
> "Override to use itemporary:in:put:"
> | descriptor variableType variableIndex value |
> <inline: true>
> descriptor := self fetchByte.
> - self fetchNextBytecode.
> variableType := descriptor >> 6 bitAnd: 3.
> variableIndex := descriptor bitAnd: 63.
> value := self internalStackTop.
> popBoolean ifTrue: [ self internalPop: 1 ].
> variableType = 0 ifTrue:
> + [objectMemory storePointerImmutabilityCheck: variableIndex
> ofObject: self receiver withValue: value.
> + ^ self fetchNextBytecode.].
> - [^objectMemory storePointerImmutabilityCheck:
> variableIndex ofObject: self receiver withValue: value].
> variableType = 1 ifTrue:
> + [ self fetchNextBytecode.
> + ^self itemporary: variableIndex in: localFP put: value].
> - [^self itemporary: variableIndex in: localFP put: value].
> variableType = 3 ifTrue:
> + [self storeLiteralVariable: variableIndex withValue: value.
> + ^ self fetchNextBytecode.].
> - [^self storeLiteralVariable: variableIndex withValue:
> value].
> self error: 'illegal store'!
>
> Item was changed:
> ----- Method:
> CogObjectRepresentationForSpur>>genImmutableCheck:slotIndex:sourceReg:scratchReg:popBoolean:needRestoreRcvr:
> (in category 'compile abstract instructions') -----
> genImmutableCheck: regHoldingObjectMutated slotIndex: index sourceReg:
> regHoldingValueToStore scratchReg: scratchReg popBoolean: popBoolean
> needRestoreRcvr: needRestoreRcvr
> | mutableJump fail |
> <var: #mutableJump type: #'AbstractInstruction *'>
> <var: #fail type: #'AbstractInstruction *'>
> <inline: true>
> <option: #IMMUTABILITY>
> "Trampoline convention:
> - objectMutated passed in ReceiverResultReg
> - index (unboxed) passed in TempReg
> - valueToStore passed in ClassReg.
> Simulated stack is flushed until simulatedStackPointer - 1, which
> implies full flush
> if popBoolean is true, else top value may not be flushed.
> We spill the top value (the value to store) for the trampoline if
> needed."
> self assert: regHoldingObjectMutated == ReceiverResultReg.
> self assert: scratchReg == TempReg.
> self assert: regHoldingValueToStore == ClassReg.
> mutableJump := self genJumpMutable: ClassReg scratchReg: TempReg.
>
> "We reach this code if the object mutated is immutable."
> "simulatedStack state altered for the trampoline, spill top value
> if needed"
> (popBoolean or: [ cogit ssTop spilled ]) ifFalse:
> [ self assert: (cogit ssTop type = SSRegister and: [cogit
> ssTop register = ClassReg]).
> cogit PushR: ClassReg ].
> "pass the unboxed index using TempReg"
> cogit MoveCq: index R: TempReg.
> "trampoline call and mcpc to bcpc annotation."
> cogit CallRT: ceCannotAssignToWithIndexTrampoline.
> cogit annotateBytecode: cogit Label.
> "Top of stack is consumed by the trampoline. In case of store with
> non spilled value,
> restore ClassReg to match simulated stack state"
> (popBoolean or: [ cogit ssTop spilled ]) ifFalse:
> [cogit popR: ClassReg].
> "restore ReceiverResultReg state if needed"
> + needRestoreRcvr ifTrue: [ cogit putSelfInReceiverResultReg ].
> - needRestoreRcvr ifTrue: [ self putSelfInReceiverResultReg ].
> fail := cogit Jump: 0.
>
> "We reach this code is the object mutated is mutable"
> mutableJump jmpTarget: cogit Label.
>
> ^ fail!
>
> Item was changed:
> ----- Method: InterpreterPrimitives>>primitiveGetImmutability (in
> category 'object access primitives') -----
> primitiveGetImmutability
> <option: #IMMUTABILITY>
> | rcvr bool |
> rcvr := self stackValue: 0.
> bool := (objectMemory isOopImmutable: rcvr)
> ifTrue: [ TrueObject ]
> ifFalse: [ FalseObject ].
> + self pop: argumentCount + 1 thenPush: (self splObj: bool)!
> - self pop: argumentCount thenPush: (self splObj: bool)!
>
> Item was changed:
> ----- Method: InterpreterPrimitives>>primitiveSetImmutability (in
> category 'object access primitives') -----
> primitiveSetImmutability
> <option: #IMMUTABILITY>
> | rcvr boolean wasImmutable |
> rcvr := self stackValue: 1.
> (objectMemory isImmediate: rcvr) ifTrue: [ ^ self
> primitiveFailFor: PrimErrInappropriate ].
> boolean := self booleanValueOf: self stackTop.
> self successful ifFalse:
> [^self primitiveFailFor: PrimErrBadArgument].
> boolean ifTrue:
> [ (self canBeImmutable: rcvr) ifFalse: [ ^ self
> primitiveFailFor: PrimErrInappropriate ] ].
> wasImmutable := (objectMemory isOopImmutable: rcvr)
> ifTrue: [ TrueObject ]
> ifFalse: [ FalseObject ].
> objectMemory setIsImmutableOf: rcvr to: boolean.
> + self pop: argumentCount + 1 thenPush: (self splObj: wasImmutable)!
> - self pop: argumentCount thenPush: (self splObj: wasImmutable)!
>
> Item was changed:
> ----- Method: StackInterpreter>>doubleExtendedDoAnythingBytecode (in
> category 'send bytecodes') -----
> doubleExtendedDoAnythingBytecode
> "Replaces the Blue Book double-extended send [132], in which the
> first byte was wasted on 8 bits of argument count.
> Here we use 3 bits for the operation sub-type (opType), and the
> remaining 5 bits for argument count where needed.
> The last byte give access to 256 instVars or literals.
> See also secondExtendedSendBytecode"
> | byte2 byte3 opType top |
> byte2 := self fetchByte.
> byte3 := self fetchByte.
> opType := byte2 >> 5.
> opType = 0 ifTrue:
> [messageSelector := self literal: byte3.
> argumentCount := byte2 bitAnd: 31.
> ^self normalSend].
> opType = 1 ifTrue:
> [messageSelector := self literal: byte3.
> argumentCount := byte2 bitAnd: 31.
> ^self superclassSend].
> + opType = 2 ifTrue: [self fetchNextBytecode. ^self
> pushMaybeContextReceiverVariable: byte3].
> + opType = 3 ifTrue: [self fetchNextBytecode. ^self
> pushLiteralConstant: byte3].
> + opType = 4 ifTrue: [self fetchNextBytecode. ^self
> pushLiteralVariable: byte3].
> - self fetchNextBytecode.
> - opType = 2 ifTrue: [^self pushMaybeContextReceiverVariable: byte3].
> - opType = 3 ifTrue: [^self pushLiteralConstant: byte3].
> - opType = 4 ifTrue: [^self pushLiteralVariable: byte3].
> top := self internalStackTop.
> opType = 7 ifTrue:
> [self storeLiteralVariable: byte3 withValue: top.
> + ^self fetchNextBytecode].
> - ^self].
> "opType = 5 is store; opType = 6 is storePop"
> opType = 6 ifTrue:
> [self internalPop: 1].
> + self storeMaybeContextReceiverVariable: byte3 withValue: top.
> + self fetchNextBytecode!
> - self storeMaybeContextReceiverVariable: byte3 withValue: top!
>
> Item was changed:
> ----- Method: StackInterpreter>>extStoreAndPopLiteralVariableBytecode
> (in category 'stack bytecodes') -----
> extStoreAndPopLiteralVariableBytecode
> "236 11101100 i i i i i i i i Pop and Store
> Literal Variable #iiiiiiii (+ Extend A * 256)"
> | variableIndex value |
> variableIndex := self fetchByte + (extA << 8).
> - self fetchNextBytecode.
> value := self internalStackTop.
> self internalPop: 1.
> extA := 0.
> + self storeLiteralVariable: variableIndex withValue: value.
> + self fetchNextBytecode.!
> - self storeLiteralVariable: variableIndex withValue: value!
>
> Item was changed:
> ----- Method: StackInterpreter>>extStoreAndPopReceiverVariableBytecode
> (in category 'stack bytecodes') -----
> extStoreAndPopReceiverVariableBytecode
> "235 11101011 i i i i i i i i Pop and Store
> Receiver Variable #iiiiiii (+ Extend A * 256)"
> | variableIndex value |
> variableIndex := self fetchByte + (extA << 8).
> - self fetchNextBytecode.
> extA := 0.
> value := self internalStackTop.
> self internalPop: 1.
> + self storeMaybeContextReceiverVariable: variableIndex withValue:
> value.
> + self fetchNextBytecode.!
> - self storeMaybeContextReceiverVariable: variableIndex withValue:
> value!
>
> Item was changed:
> ----- Method: StackInterpreter>>extStoreLiteralVariableBytecode (in
> category 'stack bytecodes') -----
> extStoreLiteralVariableBytecode
> "233 11101001 i i i i i i i i Store Literal
> Variable #iiiiiiii (+ Extend A * 256)"
> | variableIndex |
> variableIndex := self fetchByte + (extA << 8).
> - self fetchNextBytecode.
> extA := 0.
> + self storeLiteralVariable: variableIndex withValue: self
> internalStackTop.
> + self fetchNextBytecode.!
> - self storeLiteralVariable: variableIndex withValue: self
> internalStackTop!
>
> Item was changed:
> ----- Method: StackInterpreter>>extStoreReceiverVariableBytecode (in
> category 'stack bytecodes') -----
> extStoreReceiverVariableBytecode
> "232 11101000 i i i i i i i i Store Receiver
> Variable #iiiiiii (+ Extend A * 256)"
> | variableIndex |
> variableIndex := self fetchByte + (extA << 8).
> - self fetchNextBytecode.
> extA := 0.
> + self storeMaybeContextReceiverVariable: variableIndex withValue:
> self internalStackTop.
> + self fetchNextBytecode.!
> - self storeMaybeContextReceiverVariable: variableIndex withValue:
> self internalStackTop!
>
> Item was changed:
> ----- Method: StackInterpreter>>extendedStoreBytecodePop: (in category
> 'stack bytecodes') -----
> extendedStoreBytecodePop: popBoolean
> | descriptor variableType variableIndex value |
> <inline: true>
> descriptor := self fetchByte.
> - self fetchNextBytecode.
> variableType := descriptor >> 6 bitAnd: 3.
> variableIndex := descriptor bitAnd: 63.
> value := self internalStackTop.
> popBoolean ifTrue: [ self internalPop: 1 ].
> variableType = 0 ifTrue:
> + [objectMemory storePointerImmutabilityCheck: variableIndex
> ofObject: self receiver withValue: value.
> + ^ self fetchNextBytecode].
> - [^objectMemory storePointerImmutabilityCheck:
> variableIndex ofObject: self receiver withValue: value].
> variableType = 1 ifTrue:
> + [ self fetchNextBytecode.
> + ^self temporary: variableIndex in: localFP put: value].
> - [^self temporary: variableIndex in: localFP put: value].
> variableType = 3 ifTrue:
> + [self storeLiteralVariable: variableIndex withValue: value.
> + ^ self fetchNextBytecode].
> - [^self storeLiteralVariable: variableIndex withValue:
> value].
> self error: 'illegal store'
> !
>
> Item was changed:
> ----- Method: StackInterpreter>>storeAndPopReceiverVariableBytecode (in
> category 'stack bytecodes') -----
> storeAndPopReceiverVariableBytecode
> | rcvr top instVarIndex |
> rcvr := self receiver.
> top := self internalStackTop.
> instVarIndex := currentBytecode bitAnd: 7.
> self internalPop: 1.
> - self fetchNextBytecode.
> objectMemory
> storePointerImmutabilityCheck: instVarIndex
> ofObject: rcvr
> + withValue: top.
> + self fetchNextBytecode.!
> - withValue: top!
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20160118/d62c3baf/attachment-0001.htm
More information about the Vm-dev
mailing list