Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.152.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.152 Author: eem Time: 3 March 2012, 12:46:18 pm UUID: d39d62b0-45ca-4621-8f67-e3981bbe1875 Ancestors: VMMaker.oscog-eem.151
Fix tricky context state bug that can cause crashes in the GC. Contextpart>runUntilErrorOrReturnFrom: may pop the last argument. Hence if a frame is married in this state its spouse context won't have its last argument slot initialized. If later the frame is divorced and the arguments are not updated the last argument slot can be left with this uninitialized slot and ... bang. The sloution is to update arguments as well as stack contents when divorcing. This is good also becausde it removes the VM's assumption that method arguments are read-only, and that's only enforced by the Smalltalk bytecode compiler, not by the bytecode.
=============== Diff against VMMaker.oscog-eem.151 ===============
Item was changed: ----- Method: CoInterpreter>>updateStateOfSpouseContextForFrame:WithSP: (in category 'frame access') ----- updateStateOfSpouseContextForFrame: theFP WithSP: theSP "Update the frame's spouse context with the frame's current state except for the sender and instruction pointer, which are used to mark the context as married." + | theContext tempIndex pointer argsPointer | - | theContext tempIndex pointer | <inline: false> <var: #theFP type: #'char *'> <var: #theSP type: #'char *'> <var: #pointer type: #'char *'> + <var: #argsPointer type: #'char *'> self assert: (self frameHasContext: theFP). theContext := self frameContext: theFP. self assert: (self isContext: theContext). self assert: (self frameReceiver: theFP) = (objectMemory fetchPointer: ReceiverIndex ofObject: theContext). (self isMachineCodeFrame: theFP) ifTrue: [tempIndex := self mframeNumArgs: theFP. pointer := theFP + FoxMFReceiver - BytesPerWord] ifFalse: [tempIndex := self iframeNumArgs: theFP. pointer := theFP + FoxIFReceiver - BytesPerWord]. + "update the arguments. this would appear not to be strictly necessary, but is for two reasons. + First, the fact that arguments are read-only is only as convention in the Smalltalk compiler; + other languages may choose to modify arguments. + Second, the Squeak runUntilErrorOrReturnFrom: nightmare pops the stack top, which may, in + certain circumstances, be the last argument, and hence the last argument may not have been + stored into the context." + argsPointer := theFP + (self frameStackedReceiverOffsetNumArgs: tempIndex). + 1 to: tempIndex do: + [:i| + argsPointer := argsPointer - BytesPerWord. + self assert: (objectMemory addressCouldBeOop: (stackPages longAt: argsPointer)). + objectMemory storePointer: ReceiverIndex + i + ofObject: theContext + withValue: (stackPages longAt: argsPointer)]. + "now update the non-argument stack contents." [pointer >= theSP] whileTrue: [self assert: (objectMemory addressCouldBeOop: (stackPages longAt: pointer)). tempIndex := tempIndex + 1. objectMemory storePointer: ReceiverIndex + tempIndex ofObject: theContext withValue: (stackPages longAt: pointer). pointer := pointer - BytesPerWord]. self assert: ReceiverIndex + tempIndex < (objectMemory lengthOf: theContext). objectMemory storePointerUnchecked: StackPointerIndex ofObject: theContext withValue: (objectMemory integerObjectOf: tempIndex)!
Item was changed: ----- Method: StackInterpreter>>updateStateOfSpouseContextForFrame:WithSP: (in category 'frame access') ----- updateStateOfSpouseContextForFrame: theFP WithSP: theSP "Update the frame's spouse context with the frame's current state except for the sender and instruction pointer, which are used to mark the context as married." | theContext tempIndex pointer | <inline: false> <var: #theFP type: #'char *'> <var: #theSP type: #'char *'> <var: #pointer type: #'char *'> + <var: #argsPointer type: #'char *'> self assert: (self frameHasContext: theFP). theContext := self frameContext: theFP. self assert: (self frameReceiver: theFP) = (objectMemory fetchPointer: ReceiverIndex ofObject: theContext). tempIndex := self frameNumArgs: theFP. + "update the arguments. this would appear not to be strictly necessary, but is for two reasons. + First, the fact that arguments are read-only is only as convention in the Smalltalk compiler; + other languages may choose to modify arguments. + Second, the Squeak runUntilErrorOrReturnFrom: nightmare pops the stack top, which may, in + certain circumstances, be the last argument, and hence the last argument may not have been + stored into the context." + pointer := theFP + (self frameStackedReceiverOffsetNumArgs: tempIndex). + 1 to: tempIndex do: + [:i| + pointer := pointer - BytesPerWord. + self assert: (objectMemory addressCouldBeOop: (stackPages longAt: pointer)). + objectMemory storePointer: ReceiverIndex + i + ofObject: theContext + withValue: (stackPages longAt: pointer)]. + "now update the non-argument stack contents." pointer := theFP + FoxReceiver - BytesPerWord. [pointer >= theSP] whileTrue: [self assert: (objectMemory addressCouldBeOop: (stackPages longAt: pointer)). tempIndex := tempIndex + 1. objectMemory storePointer: ReceiverIndex + tempIndex ofObject: theContext withValue: (stackPages longAt: pointer). pointer := pointer - BytesPerWord]. self assert: ReceiverIndex + tempIndex < (objectMemory lengthOf: theContext). objectMemory storePointerUnchecked: StackPointerIndex ofObject: theContext withValue: (objectMemory integerObjectOf: tempIndex)!
vm-dev@lists.squeakfoundation.org