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!
vm-dev@lists.squeakfoundation.org