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

commits at source.squeak.org commits at source.squeak.org
Fri Oct 24 22:50:58 UTC 2014


Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.913.mcz

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

Name: VMMaker.oscog-eem.913
Author: eem
Time: 24 October 2014, 3:48:03.341 pm
UUID: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
Ancestors: VMMaker.oscog-eem.912

Fix baaaad bug in checking for still-married contexts in
Spur.  One *cannot* simply follow what is assumed to
be the frameContext field of what is presumed to be
a context.  On Spur we need to *know* whether we
have a valid frameContext field, and for that we have
to know there is a valid frame.  So refactor, moving
isFrame:onPage: from StackInterpreterPrimitives to
StackInterpreter, and use it to validate the frame
pointer of a maybe married context before testing
the context for being forwarded.

=============== Diff against VMMaker.oscog-eem.912 ===============

Item was changed:
  ----- Method: StackInterpreter>>checkIsStillMarriedContext:currentFP: (in category 'frame access') -----
  checkIsStillMarriedContext: aContext currentFP: currentFP
  	"Another version of isWidowedContext: for debugging.
  	 This will not bereave a widowed context."
+ 	| thePage maybeFP limitFP maybeFrameCtxt |
- 	| thePage theFP limitFP frameCtxt |
  	<inline: false>
  	<var: #currentFP type: #'char *'>
  	<var: #thePage type: #'StackPage *'>
+ 	<var: #maybeFP type: #'char *'>
- 	<var: #theFP type: #'char *'>
  	<var: #limitFP type: #'char *'>
  	((objectMemory isContext: aContext)
  	 and: [self isMarriedOrWidowedContext: aContext]) ifFalse:
  		[^false].
+ 	maybeFP := self frameOfMarriedContext: aContext.
+ 	thePage := stackPages stackPageFor: maybeFP.
- 	theFP := self frameOfMarriedContext: aContext.
- 	thePage := stackPages stackPageFor: theFP.
  	limitFP := (thePage = stackPage and: [currentFP notNil])
  				ifTrue: [currentFP]
  				ifFalse: [thePage headFP].
+ 	(maybeFP >= limitFP
+ 	 and: [(objectMemory isNonImmediate: (self frameCallerFP: maybeFP) asInteger)
+ 	 and: [(self withSmallIntegerTags: (self frameCallerFP: maybeFP))
- 	(theFP >= limitFP
- 	 and: [(objectMemory isNonImmediate: (self frameCallerFP: theFP) asInteger)
- 	 and: [(self withSmallIntegerTags: (self frameCallerFP: theFP))
  			= (objectMemory fetchPointer: InstructionPointerIndex ofObject: aContext)
+ 	 and: [self frameHasContext: maybeFP]]]) ifFalse:
- 	 and: [self frameHasContext: theFP]]]) ifFalse:
  		[^false].
+ 	maybeFrameCtxt := self frameContext: maybeFP.
+ 	"On Spur we need to follow the context to check for a match, but since the VM is
+ 	 only speculating about maybeFrame being a frame, and only speculating about
+ 	 maybeContext being a context, we need to be sure before we can safely follow."
+ 	(objectMemory hasSpurMemoryManagerAPI
+ 	 and: [(self isFrame: maybeFP onPage: thePage)
+ 	 and: [objectMemory isForwarded: maybeFrameCtxt]]) ifTrue:
+ 		[maybeFrameCtxt := objectMemory followForwarded: maybeFrameCtxt].
+ 	^maybeFrameCtxt = aContext!
- 	frameCtxt := self frameContext: theFP.
- 	(objectMemory isForwarded: frameCtxt) ifTrue:
- 		[frameCtxt := objectMemory followForwarded: frameCtxt].
- 	^frameCtxt = aContext!

Item was added:
+ ----- Method: StackInterpreter>>isFrame:onPage: (in category 'frame access') -----
+ isFrame: aFrame onPage: aPage
+ 	<var: #aFrame type: #'char *'>
+ 	<var: #aPage type: #'StackPage *'>
+ 	| theFP prevFP |
+ 	<var: #theFP type: #'char *'>
+ 	<var: #prevFP type: #'char *'>
+ 	self deny: (stackPages isFree: aPage).
+ 	"Walk the static chain making sure progress is being made,
+ 	 and in the right direction, looking for a match with aFrame."
+ 	theFP := aPage headFP.
+ 	prevFP := theFP - objectMemory wordSize.
+ 	[theFP = aFrame ifTrue: [^true].
+ 	 theFP > prevFP
+ 	 and: [theFP < aPage baseFP]] whileTrue:
+ 		[prevFP := theFP.
+ 		 theFP := self frameCallerFP: theFP].
+ 	^false!

Item was changed:
  ----- Method: StackInterpreter>>isWidowedContext: (in category 'frame access') -----
  isWidowedContext: aOnceMarriedContext
  	"See if the argument is married to a live frame or not.
  	 If it is not, turn it into a bereaved single context."
+ 	| maybeFrame thePage shouldBeFrameCallerField maybeFrameCtxt |
+ 	<var: #maybeFrame type: #'char *'>
- 	| theFrame thePage shouldBeFrameCallerField frameCtxt |
- 	<var: #theFrame type: #'char *'>
  	<var: #thePage type: #'StackPage *'>
  	<var: #shouldBeFrameCallerField type: #'char *'>
  	self assert: ((objectMemory isContext: aOnceMarriedContext)
  				  and: [self isMarriedOrWidowedContext: aOnceMarriedContext]).
+ 	maybeFrame := self frameOfMarriedContext: aOnceMarriedContext.
+ 	thePage := stackPages stackPageFor: maybeFrame.
- 	theFrame := self frameOfMarriedContext: aOnceMarriedContext.
- 	thePage := stackPages stackPageFor: theFrame.
  	((stackPages isFree: thePage)
+ 	 or: [maybeFrame < thePage headFP]) ifFalse:
- 	 or: [theFrame < thePage headFP]) ifFalse:
  		["The frame pointer is within the bounds of a live page.
  		   Now check if it matches a frame."
  		 shouldBeFrameCallerField := self withoutSmallIntegerTags:
  											(objectMemory
  												fetchPointer: InstructionPointerIndex
  												ofObject: aOnceMarriedContext).
+ 		 ((self frameCallerFP: maybeFrame) = shouldBeFrameCallerField
+ 		  and: [self frameHasContext: maybeFrame]) ifTrue:
+ 			[maybeFrameCtxt := self frameContext: maybeFrame.
+ 			 "On Spur we need to follow the context to check for a match, but since the VM is
+ 			  only speculating about maybeFrame being a frame, and only speculating about
+ 			  maybeContext being a context, we need to be sure before we can safely follow."
+ 			 (objectMemory hasSpurMemoryManagerAPI
+ 			  and: [(self isFrame: maybeFrame onPage: thePage)
+ 			  and: [objectMemory isForwarded: maybeFrameCtxt]]) ifTrue:
+ 				[maybeFrameCtxt := objectMemory followForwarded: maybeFrameCtxt.
+ 				 self setFrameContext: maybeFrame to: maybeFrameCtxt].
+ 			 maybeFrameCtxt = aOnceMarriedContext ifTrue: "It is still married!!"
- 		 ((self frameCallerFP: theFrame) = shouldBeFrameCallerField
- 		  and: [self frameHasContext: theFrame]) ifTrue:
- 			[frameCtxt := self frameContext: theFrame.
- 			 (objectMemory isForwarded: frameCtxt) ifTrue:
- 				[frameCtxt := objectMemory followForwarded: frameCtxt.
- 				 self setFrameContext: theFrame to: frameCtxt].
- 			 frameCtxt = aOnceMarriedContext ifTrue: "It is still married!!"
  				[^false]]].
  	"It is out of range or doesn't match the frame's context.
  	 It is widowed. Time to wear black."
  	self markContextAsDead: aOnceMarriedContext.
  	^true!

Item was removed:
- ----- Method: StackInterpreterPrimitives>>isFrame:onPage: (in category 'object access primitives') -----
- isFrame: aFrame onPage: aPage
- 	<var: #aFrame type: #'char *'>
- 	<var: #aPage type: #'StackPage *'>
- 	| theFP |
- 	<var: #theFP type: #'char *'>
- 	theFP := aPage headFP.
- 	[theFP = aFrame ifTrue: [^true].
- 	 theFP ~= aPage baseFP
- 	 and: [(stackPages stackPageFor: theFP) = aPage]] whileTrue:
- 		[theFP := self frameCallerFP: theFP].
- 	^false!



More information about the Vm-dev mailing list