[Vm-dev] VM Maker: VMMaker.oscog-eem.152.mcz

commits at source.squeak.org commits at source.squeak.org
Sat Mar 3 20:48:39 UTC 2012


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)!



More information about the Vm-dev mailing list