[Vm-dev] [commit][3111] CogVM source as per VMMaker.oscog-eem.913

commits at squeakvm.org commits at squeakvm.org
Fri Oct 24 22:52:58 UTC 2014


Revision: 3111
Author:   eliot
Date:     2014-10-24 15:52:56 -0700 (Fri, 24 Oct 2014)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.913

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.

Modified Paths:
--------------
    branches/Cog/nscogsrc/vm/cointerp.c
    branches/Cog/nscogsrc/vm/cointerp.h
    branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
    branches/Cog/nsspursrc/vm/cointerp.c
    branches/Cog/nsspursrc/vm/cointerp.h
    branches/Cog/nsspursrc/vm/gcc3x-cointerp.c
    branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c
    branches/Cog/nsspurstacksrc/vm/interp.c
    branches/Cog/sistasrc/vm/cointerp.c
    branches/Cog/sistasrc/vm/cointerp.h
    branches/Cog/sistasrc/vm/gcc3x-cointerp.c
    branches/Cog/spursistasrc/vm/cointerp.c
    branches/Cog/spursistasrc/vm/cointerp.h
    branches/Cog/spursistasrc/vm/gcc3x-cointerp.c
    branches/Cog/spursrc/vm/cointerp.c
    branches/Cog/spursrc/vm/cointerp.h
    branches/Cog/spursrc/vm/gcc3x-cointerp.c
    branches/Cog/spurstacksrc/vm/gcc3x-interp.c
    branches/Cog/spurstacksrc/vm/interp.c
    branches/Cog/src/vm/cointerp.c
    branches/Cog/src/vm/cointerp.h
    branches/Cog/src/vm/cointerpmt.c
    branches/Cog/src/vm/cointerpmt.h
    branches/Cog/src/vm/gcc3x-cointerp.c
    branches/Cog/src/vm/gcc3x-cointerpmt.c
    branches/Cog/stacksrc/vm/gcc3x-interp.c
    branches/Cog/stacksrc/vm/interp.c

Property Changed:
----------------
    branches/Cog/platforms/Cross/vm/sqSCCSVersion.h

Modified: branches/Cog/nscogsrc/vm/cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.c	2014-10-24 20:43:48 UTC (rev 3110)
+++ branches/Cog/nscogsrc/vm/cointerp.c	2014-10-24 22:52:56 UTC (rev 3111)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
    from
-	CoInterpreter VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c
+	CoInterpreter VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -1113,6 +1113,7 @@
 static sqInt isBaseFrame(char *theFP) NoDbgRegParms;
 static sqInt isEmptyList(sqInt aLinkedList) NoDbgRegParms;
 sqInt isFloatObject(sqInt oop);
+static sqInt isFrameonPage(char *aFrame, StackPage *aPage) NoDbgRegParms;
 static sqInt isLiveContext(sqInt oop) NoDbgRegParms;
 static sqInt isMarriedOrWidowedContext(sqInt aContext) NoDbgRegParms;
 static sqInt isNullExternalPrimitiveCall(sqInt aMethodObj) NoDbgRegParms;
@@ -1277,7 +1278,6 @@
 static sqInt writeImageFileIO(void);
 static sqInt fieldOrSenderFPofContext(sqInt index, sqInt contextObj) NoDbgRegParms;
 static sqInt fieldofFrame(sqInt index, char *theFP) NoDbgRegParms;
-static sqInt isFrameonPage(char *aFrame, StackPage *aPage) NoDbgRegParms;
 static void primitiveClone(void);
 static void primitiveContextAt(void);
 static void primitiveContextAtPut(void);
@@ -2085,7 +2085,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.912";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.913";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -43875,11 +43875,11 @@
 static sqInt
 checkIsStillMarriedContextcurrentFP(sqInt aContext, char *currentFP)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt frameCtxt;
     sqInt index;
     char *limitFP;
+    char *maybeFP;
+    sqInt maybeFrameCtxt;
     sqInt senderOop;
-    char *theFP;
     StackPage *thePage;
 
 	if (!((((aContext & 1) == 0)
@@ -43891,28 +43891,33 @@
 	senderOop = longAt((aContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
 	/* begin withoutSmallIntegerTags: */
 	assert((senderOop & 1));
-	theFP = pointerForOop(senderOop - 1);
+	maybeFP = pointerForOop(senderOop - 1);
 	/* begin stackPageFor: */
 	/* begin stackPageAt: */
 	/* begin pageIndexFor: */
-	assert((((((char *) theFP)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFP)) <= (((char *) GIV(pages))))));
-	index = pageIndexForstackBasePlus1bytesPerPage(theFP, GIV(stackBasePlus1), GIV(bytesPerPage));
+	assert((((((char *) maybeFP)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) maybeFP)) <= (((char *) GIV(pages))))));
+	index = pageIndexForstackBasePlus1bytesPerPage(maybeFP, GIV(stackBasePlus1), GIV(bytesPerPage));
 	thePage = stackPageAtpages(index, GIV(pages));
 	limitFP = ((thePage == GIV(stackPage))
 	 && (currentFP != null)
 		? currentFP
 		: (thePage->headFP));
-	if (!((theFP >= limitFP)
-		 && ((isNonImmediate(((sqInt)(frameCallerFP(theFP)))))
-		 && (((withSmallIntegerTags(frameCallerFP(theFP))) == (longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord))))
-		 && (((((usqInt)(longAt(theFP + FoxMethod)))) < (startOfMemory())
-			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
-			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)))))) {
+	if (!((maybeFP >= limitFP)
+		 && ((isNonImmediate(((sqInt)(frameCallerFP(maybeFP)))))
+		 && (((withSmallIntegerTags(frameCallerFP(maybeFP))) == (longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord))))
+		 && (((((usqInt)(longAt(maybeFP + FoxMethod)))) < (startOfMemory())
+			? ((longAt(maybeFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((maybeFP + FoxIFrameFlags) + 2)) != 0)))))) {
 		return 0;
 	}
-	frameCtxt = longAt(theFP + FoxThisContext);
+
+	/* 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. */
+
+	maybeFrameCtxt = longAt(maybeFP + FoxThisContext);
 	
-	return frameCtxt == aContext;
+	return maybeFrameCtxt == aContext;
 }
 
 sqInt
@@ -46465,7 +46470,29 @@
 	 && (ClassFloatCompactIndex == ((((usqInt) (longAt(oop))) >> (compactClassFieldLSB())) & 0x1F));
 }
 
+static sqInt
+isFrameonPage(char *aFrame, StackPage *aPage)
+{
+    char *prevFP;
+    char *theFP;
 
+	assert(!((isFree(aPage))));
+	theFP = (aPage->headFP);
+	prevFP = theFP - 4;
+	while (1) {
+		if (theFP == aFrame) {
+			return 1;
+		}
+		if (!((theFP > prevFP)
+		 && (theFP < ((aPage->baseFP))))) break;
+		prevFP = theFP;
+		/* begin frameCallerFP: */
+		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
+	}
+	return 0;
+}
+
+
 /*	Answer if the argument, which can be any object, is a live context. */
 
 static sqInt
@@ -46566,11 +46593,11 @@
 static sqInt
 isWidowedContext(sqInt aOnceMarriedContext)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt frameCtxt;
     sqInt index;
+    char *maybeFrame;
+    sqInt maybeFrameCtxt;
     sqInt senderOop;
     char *shouldBeFrameCallerField;
-    char *theFrame;
     StackPage *thePage;
 
 	assert((isContext(aOnceMarriedContext))
@@ -46579,15 +46606,15 @@
 	senderOop = longAt((aOnceMarriedContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
 	/* begin withoutSmallIntegerTags: */
 	assert((senderOop & 1));
-	theFrame = pointerForOop(senderOop - 1);
+	maybeFrame = pointerForOop(senderOop - 1);
 	/* begin stackPageFor: */
 	/* begin stackPageAt: */
 	/* begin pageIndexFor: */
-	assert((((((char *) theFrame)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFrame)) <= (((char *) GIV(pages))))));
-	index = pageIndexForstackBasePlus1bytesPerPage(theFrame, GIV(stackBasePlus1), GIV(bytesPerPage));
+	assert((((((char *) maybeFrame)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) maybeFrame)) <= (((char *) GIV(pages))))));
+	index = pageIndexForstackBasePlus1bytesPerPage(maybeFrame, GIV(stackBasePlus1), GIV(bytesPerPage));
 	thePage = stackPageAtpages(index, GIV(pages));
 	if (!((isFree(thePage))
-		 || (theFrame < ((thePage->headFP))))) {
+		 || (maybeFrame < ((thePage->headFP))))) {
 
 		/* The frame pointer is within the bounds of a live page.
 		   Now check if it matches a frame. */
@@ -46595,13 +46622,18 @@
 		/* begin withoutSmallIntegerTags: */
 		assert(((longAt((aOnceMarriedContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord))) & 1));
 		shouldBeFrameCallerField = pointerForOop((longAt((aOnceMarriedContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord))) - 1);
-		if (((frameCallerFP(theFrame)) == shouldBeFrameCallerField)
-		 && (((((usqInt)(longAt(theFrame + FoxMethod)))) < (startOfMemory())
-			? ((longAt(theFrame + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
-			: (byteAt((theFrame + FoxIFrameFlags) + 2)) != 0))) {
-			frameCtxt = longAt(theFrame + FoxThisContext);
+		if (((frameCallerFP(maybeFrame)) == shouldBeFrameCallerField)
+		 && (((((usqInt)(longAt(maybeFrame + FoxMethod)))) < (startOfMemory())
+			? ((longAt(maybeFrame + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((maybeFrame + FoxIFrameFlags) + 2)) != 0))) {
+
+			/* 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. */
+
+			maybeFrameCtxt = longAt(maybeFrame + FoxThisContext);
 			
-			if (frameCtxt == aOnceMarriedContext) {
+			if (maybeFrameCtxt == aOnceMarriedContext) {
 
 				/* It is still married! */
 
@@ -52537,25 +52569,7 @@
 	}
 }
 
-static sqInt
-isFrameonPage(char *aFrame, StackPage *aPage)
-{
-    char *theFP;
 
-	theFP = (aPage->headFP);
-	while (1) {
-		if (theFP == aFrame) {
-			return 1;
-		}
-		if (!((theFP != ((aPage->baseFP)))
-		 && ((stackPageFor(theFP)) == aPage))) break;
-		/* begin frameCallerFP: */
-		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
-	}
-	return 0;
-}
-
-
 /*	Return a shallow copy of the receiver.
 	Special-case non-single contexts (because of context-to-stack mapping).
 	Can't fail for contexts cuz of image context instantiation code (sigh). */

Modified: branches/Cog/nscogsrc/vm/cointerp.h
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.h	2014-10-24 20:43:48 UTC (rev 3110)
+++ branches/Cog/nscogsrc/vm/cointerp.h	2014-10-24 22:52:56 UTC (rev 3111)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
  */
 
 

Modified: branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2014-10-24 20:43:48 UTC (rev 3110)
+++ branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2014-10-24 22:52:56 UTC (rev 3111)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
    from
-	CoInterpreter VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c
+	CoInterpreter VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -1116,6 +1116,7 @@
 static sqInt isBaseFrame(char *theFP) NoDbgRegParms;
 static sqInt isEmptyList(sqInt aLinkedList) NoDbgRegParms;
 sqInt isFloatObject(sqInt oop);
+static sqInt isFrameonPage(char *aFrame, StackPage *aPage) NoDbgRegParms;
 static sqInt isLiveContext(sqInt oop) NoDbgRegParms;
 static sqInt isMarriedOrWidowedContext(sqInt aContext) NoDbgRegParms;
 static sqInt isNullExternalPrimitiveCall(sqInt aMethodObj) NoDbgRegParms;
@@ -1280,7 +1281,6 @@
 static sqInt writeImageFileIO(void);
 static sqInt fieldOrSenderFPofContext(sqInt index, sqInt contextObj) NoDbgRegParms;
 static sqInt fieldofFrame(sqInt index, char *theFP) NoDbgRegParms;
-static sqInt isFrameonPage(char *aFrame, StackPage *aPage) NoDbgRegParms;
 static void primitiveClone(void);
 static void primitiveContextAt(void);
 static void primitiveContextAtPut(void);
@@ -2088,7 +2088,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.912";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.913";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -43884,11 +43884,11 @@
 static sqInt
 checkIsStillMarriedContextcurrentFP(sqInt aContext, char *currentFP)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt frameCtxt;
     sqInt index;
     char *limitFP;
+    char *maybeFP;
+    sqInt maybeFrameCtxt;
     sqInt senderOop;
-    char *theFP;
     StackPage *thePage;
 
 	if (!((((aContext & 1) == 0)
@@ -43900,28 +43900,33 @@
 	senderOop = longAt((aContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
 	/* begin withoutSmallIntegerTags: */
 	assert((senderOop & 1));
-	theFP = pointerForOop(senderOop - 1);
+	maybeFP = pointerForOop(senderOop - 1);
 	/* begin stackPageFor: */
 	/* begin stackPageAt: */
 	/* begin pageIndexFor: */
-	assert((((((char *) theFP)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFP)) <= (((char *) GIV(pages))))));
-	index = pageIndexForstackBasePlus1bytesPerPage(theFP, GIV(stackBasePlus1), GIV(bytesPerPage));
+	assert((((((char *) maybeFP)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) maybeFP)) <= (((char *) GIV(pages))))));
+	index = pageIndexForstackBasePlus1bytesPerPage(maybeFP, GIV(stackBasePlus1), GIV(bytesPerPage));
 	thePage = stackPageAtpages(index, GIV(pages));
 	limitFP = ((thePage == GIV(stackPage))
 	 && (currentFP != null)
 		? currentFP
 		: (thePage->headFP));
-	if (!((theFP >= limitFP)
-		 && ((isNonImmediate(((sqInt)(frameCallerFP(theFP)))))
-		 && (((withSmallIntegerTags(frameCallerFP(theFP))) == (longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord))))
-		 && (((((usqInt)(longAt(theFP + FoxMethod)))) < (startOfMemory())
-			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
-			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)))))) {
+	if (!((maybeFP >= limitFP)
+		 && ((isNonImmediate(((sqInt)(frameCallerFP(maybeFP)))))
+		 && (((withSmallIntegerTags(frameCallerFP(maybeFP))) == (longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord))))
+		 && (((((usqInt)(longAt(maybeFP + FoxMethod)))) < (startOfMemory())
+			? ((longAt(maybeFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((maybeFP + FoxIFrameFlags) + 2)) != 0)))))) {
 		return 0;
 	}
-	frameCtxt = longAt(theFP + FoxThisContext);
+
+	/* 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. */
+
+	maybeFrameCtxt = longAt(maybeFP + FoxThisContext);
 	
-	return frameCtxt == aContext;
+	return maybeFrameCtxt == aContext;
 }
 
 sqInt
@@ -46474,7 +46479,29 @@
 	 && (ClassFloatCompactIndex == ((((usqInt) (longAt(oop))) >> (compactClassFieldLSB())) & 0x1F));
 }
 
+static sqInt
+isFrameonPage(char *aFrame, StackPage *aPage)
+{
+    char *prevFP;
+    char *theFP;
 
+	assert(!((isFree(aPage))));
+	theFP = (aPage->headFP);
+	prevFP = theFP - 4;
+	while (1) {
+		if (theFP == aFrame) {
+			return 1;
+		}
+		if (!((theFP > prevFP)
+		 && (theFP < ((aPage->baseFP))))) break;
+		prevFP = theFP;
+		/* begin frameCallerFP: */
+		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
+	}
+	return 0;
+}
+
+
 /*	Answer if the argument, which can be any object, is a live context. */
 
 static sqInt
@@ -46575,11 +46602,11 @@
 static sqInt
 isWidowedContext(sqInt aOnceMarriedContext)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt frameCtxt;
     sqInt index;
+    char *maybeFrame;
+    sqInt maybeFrameCtxt;
     sqInt senderOop;
     char *shouldBeFrameCallerField;
-    char *theFrame;
     StackPage *thePage;
 
 	assert((isContext(aOnceMarriedContext))
@@ -46588,15 +46615,15 @@
 	senderOop = longAt((aOnceMarriedContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
 	/* begin withoutSmallIntegerTags: */
 	assert((senderOop & 1));
-	theFrame = pointerForOop(senderOop - 1);
+	maybeFrame = pointerForOop(senderOop - 1);
 	/* begin stackPageFor: */
 	/* begin stackPageAt: */
 	/* begin pageIndexFor: */
-	assert((((((char *) theFrame)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFrame)) <= (((char *) GIV(pages))))));
-	index = pageIndexForstackBasePlus1bytesPerPage(theFrame, GIV(stackBasePlus1), GIV(bytesPerPage));
+	assert((((((char *) maybeFrame)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) maybeFrame)) <= (((char *) GIV(pages))))));
+	index = pageIndexForstackBasePlus1bytesPerPage(maybeFrame, GIV(stackBasePlus1), GIV(bytesPerPage));
 	thePage = stackPageAtpages(index, GIV(pages));
 	if (!((isFree(thePage))
-		 || (theFrame < ((thePage->headFP))))) {
+		 || (maybeFrame < ((thePage->headFP))))) {
 
 		/* The frame pointer is within the bounds of a live page.
 		   Now check if it matches a frame. */
@@ -46604,13 +46631,18 @@
 		/* begin withoutSmallIntegerTags: */
 		assert(((longAt((aOnceMarriedContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord))) & 1));
 		shouldBeFrameCallerField = pointerForOop((longAt((aOnceMarriedContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord))) - 1);
-		if (((frameCallerFP(theFrame)) == shouldBeFrameCallerField)
-		 && (((((usqInt)(longAt(theFrame + FoxMethod)))) < (startOfMemory())
-			? ((longAt(theFrame + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
-			: (byteAt((theFrame + FoxIFrameFlags) + 2)) != 0))) {
-			frameCtxt = longAt(theFrame + FoxThisContext);
+		if (((frameCallerFP(maybeFrame)) == shouldBeFrameCallerField)
+		 && (((((usqInt)(longAt(maybeFrame + FoxMethod)))) < (startOfMemory())
+			? ((longAt(maybeFrame + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((maybeFrame + FoxIFrameFlags) + 2)) != 0))) {
+
+			/* 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. */
+
+			maybeFrameCtxt = longAt(maybeFrame + FoxThisContext);
 			
-			if (frameCtxt == aOnceMarriedContext) {
+			if (maybeFrameCtxt == aOnceMarriedContext) {
 
 				/* It is still married! */
 
@@ -52546,25 +52578,7 @@
 	}
 }
 
-static sqInt
-isFrameonPage(char *aFrame, StackPage *aPage)
-{
-    char *theFP;
 
-	theFP = (aPage->headFP);
-	while (1) {
-		if (theFP == aFrame) {
-			return 1;
-		}
-		if (!((theFP != ((aPage->baseFP)))
-		 && ((stackPageFor(theFP)) == aPage))) break;
-		/* begin frameCallerFP: */
-		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
-	}
-	return 0;
-}
-
-
 /*	Return a shallow copy of the receiver.
 	Special-case non-single contexts (because of context-to-stack mapping).
 	Can't fail for contexts cuz of image context instantiation code (sigh). */

Modified: branches/Cog/nsspursrc/vm/cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.c	2014-10-24 20:43:48 UTC (rev 3110)
+++ branches/Cog/nsspursrc/vm/cointerp.c	2014-10-24 22:52:56 UTC (rev 3111)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
    from
-	CoInterpreter VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c
+	CoInterpreter VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -1304,6 +1304,7 @@
 static sqInt isBaseFrame(char *theFP) NoDbgRegParms;
 static sqInt isEmptyList(sqInt aLinkedList) NoDbgRegParms;
 sqInt isFloatObject(sqInt oop);
+static sqInt isFrameonPage(char *aFrame, StackPage *aPage) NoDbgRegParms;
 static sqInt isLiveContext(sqInt oop) NoDbgRegParms;
 static sqInt isMarriedOrWidowedContext(sqInt aContext) NoDbgRegParms;
 static sqInt isNullExternalPrimitiveCall(sqInt aMethodObj) NoDbgRegParms;
@@ -1465,7 +1466,6 @@
 static sqInt cloneContext(sqInt aContext) NoDbgRegParms;
 static sqInt fieldOrSenderFPofContext(sqInt index, sqInt contextObj) NoDbgRegParms;
 static sqInt fieldofFrame(sqInt index, char *theFP) NoDbgRegParms;
-static sqInt isFrameonPage(char *aFrame, StackPage *aPage) NoDbgRegParms;
 static void primitiveClone(void);
 static void primitiveContextAt(void);
 static void primitiveContextAtPut(void);
@@ -2335,7 +2335,7 @@
 /*540*/	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
 /*560*/	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0,-1,-1
 	};
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.912";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.913";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -63476,12 +63476,12 @@
 static sqInt
 checkIsStillMarriedContextcurrentFP(sqInt aContext, char *currentFP)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt frameCtxt;
     sqInt index;
     char *limitFP;
+    char *maybeFP;
+    sqInt maybeFrameCtxt;
     sqInt referent;
     sqInt senderOop;
-    char *theFP;
     StackPage *thePage;
 
 	if (!((((aContext & 3) == 0)
@@ -63493,37 +63493,44 @@
 	senderOop = longAt((aContext + BaseHeaderSize) + (SenderIndex << 2));
 	/* begin withoutSmallIntegerTags: */
 	assert((senderOop & 1));
-	theFP = pointerForOop(senderOop - 1);
+	maybeFP = pointerForOop(senderOop - 1);
 	/* begin stackPageFor: */
 	/* begin stackPageAt: */
 	/* begin pageIndexFor: */
-	assert((((((char *) theFP)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFP)) <= (((char *) GIV(pages))))));
-	index = pageIndexForstackBasePlus1bytesPerPage(theFP, GIV(stackBasePlus1), GIV(bytesPerPage));
+	assert((((((char *) maybeFP)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) maybeFP)) <= (((char *) GIV(pages))))));
+	index = pageIndexForstackBasePlus1bytesPerPage(maybeFP, GIV(stackBasePlus1), GIV(bytesPerPage));
 	thePage = stackPageAtpages(index, GIV(pages));
 	limitFP = ((thePage == GIV(stackPage))
 	 && (currentFP != null)
 		? currentFP
 		: (thePage->headFP));
-	if (!((theFP >= limitFP)
-		 && ((isNonImmediate(((sqInt)(frameCallerFP(theFP)))))
-		 && (((withSmallIntegerTags(frameCallerFP(theFP))) == (longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << 2))))
-		 && (((((usqInt)(longAt(theFP + FoxMethod)))) < (startOfMemory())
-			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
-			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)))))) {
+	if (!((maybeFP >= limitFP)
+		 && ((isNonImmediate(((sqInt)(frameCallerFP(maybeFP)))))
+		 && (((withSmallIntegerTags(frameCallerFP(maybeFP))) == (longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << 2))))
+		 && (((((usqInt)(longAt(maybeFP + FoxMethod)))) < (startOfMemory())
+			? ((longAt(maybeFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((maybeFP + FoxIFrameFlags) + 2)) != 0)))))) {
 		return 0;
 	}
-	frameCtxt = longAt(theFP + FoxThisContext);
-	if (((longAt(frameCtxt)) & (0x3FFFFF - 8)) == 0) {
+
+	/* 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. */
+
+	maybeFrameCtxt = longAt(maybeFP + FoxThisContext);
+	if (1
+	 && ((isFrameonPage(maybeFP, thePage))
+	 && (((longAt(maybeFrameCtxt)) & (0x3FFFFF - 8)) == 0))) {
 		/* begin followForwarded: */
-		assert(isUnambiguouslyForwarder(frameCtxt));
-		referent = longAt((frameCtxt + BaseHeaderSize) + (0 << 2));
+		assert(isUnambiguouslyForwarder(maybeFrameCtxt));
+		referent = longAt((maybeFrameCtxt + BaseHeaderSize) + (0 << 2));
 		while (((referent & 3) == 0)
 		 && (((longAt(referent)) & 0x3FFFFF) == 8)) {
 			referent = longAt((referent + BaseHeaderSize) + (0 << 2));
 		}
-		frameCtxt = referent;
+		maybeFrameCtxt = referent;
 	}
-	return frameCtxt == aContext;
+	return maybeFrameCtxt == aContext;
 }
 
 sqInt
@@ -66612,7 +66619,29 @@
 	 && (ClassFloatCompactIndex == ((longAt(oop)) & 0x3FFFFF));
 }
 
+static sqInt
+isFrameonPage(char *aFrame, StackPage *aPage)
+{
+    char *prevFP;
+    char *theFP;
 
+	assert(!((isFree(aPage))));
+	theFP = (aPage->headFP);
+	prevFP = theFP - (wordSize());
+	while (1) {
+		if (theFP == aFrame) {
+			return 1;
+		}
+		if (!((theFP > prevFP)
+		 && (theFP < ((aPage->baseFP))))) break;
+		prevFP = theFP;
+		/* begin frameCallerFP: */
+		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
+	}
+	return 0;
+}
+
+
 /*	Answer if the argument, which can be any object, is a live context. */
 
 static sqInt
@@ -66702,12 +66731,12 @@
 static sqInt
 isWidowedContext(sqInt aOnceMarriedContext)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt frameCtxt;
     sqInt index;
+    char *maybeFrame;
+    sqInt maybeFrameCtxt;
     sqInt referent;
     sqInt senderOop;
     char *shouldBeFrameCallerField;
-    char *theFrame;
     StackPage *thePage;
 
 	assert((isContext(aOnceMarriedContext))
@@ -66716,15 +66745,15 @@
 	senderOop = longAt((aOnceMarriedContext + BaseHeaderSize) + (SenderIndex << 2));
 	/* begin withoutSmallIntegerTags: */
 	assert((senderOop & 1));
-	theFrame = pointerForOop(senderOop - 1);
+	maybeFrame = pointerForOop(senderOop - 1);
 	/* begin stackPageFor: */
 	/* begin stackPageAt: */
 	/* begin pageIndexFor: */
-	assert((((((char *) theFrame)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFrame)) <= (((char *) GIV(pages))))));
-	index = pageIndexForstackBasePlus1bytesPerPage(theFrame, GIV(stackBasePlus1), GIV(bytesPerPage));
+	assert((((((char *) maybeFrame)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) maybeFrame)) <= (((char *) GIV(pages))))));
+	index = pageIndexForstackBasePlus1bytesPerPage(maybeFrame, GIV(stackBasePlus1), GIV(bytesPerPage));
 	thePage = stackPageAtpages(index, GIV(pages));
 	if (!((isFree(thePage))
-		 || (theFrame < ((thePage->headFP))))) {
+		 || (maybeFrame < ((thePage->headFP))))) {
 
 		/* The frame pointer is within the bounds of a live page.
 		   Now check if it matches a frame. */
@@ -66732,24 +66761,31 @@
 		/* begin withoutSmallIntegerTags: */
 		assert(((longAt((aOnceMarriedContext + BaseHeaderSize) + (InstructionPointerIndex << 2))) & 1));
 		shouldBeFrameCallerField = pointerForOop((longAt((aOnceMarriedContext + BaseHeaderSize) + (InstructionPointerIndex << 2))) - 1);
-		if (((frameCallerFP(theFrame)) == shouldBeFrameCallerField)
-		 && (((((usqInt)(longAt(theFrame + FoxMethod)))) < (startOfMemory())
-			? ((longAt(theFrame + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
-			: (byteAt((theFrame + FoxIFrameFlags) + 2)) != 0))) {
-			frameCtxt = longAt(theFrame + FoxThisContext);
-			if (((longAt(frameCtxt)) & (0x3FFFFF - 8)) == 0) {
+		if (((frameCallerFP(maybeFrame)) == shouldBeFrameCallerField)
+		 && (((((usqInt)(longAt(maybeFrame + FoxMethod)))) < (startOfMemory())
+			? ((longAt(maybeFrame + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((maybeFrame + FoxIFrameFlags) + 2)) != 0))) {
+
+			/* 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. */
+
+			maybeFrameCtxt = longAt(maybeFrame + FoxThisContext);
+			if (1
+			 && ((isFrameonPage(maybeFrame, thePage))
+			 && (((longAt(maybeFrameCtxt)) & (0x3FFFFF - 8)) == 0))) {
 				/* begin followForwarded: */
-				assert(isUnambiguouslyForwarder(frameCtxt));
-				referent = longAt((frameCtxt + BaseHeaderSize) + (0 << 2));
+				assert(isUnambiguouslyForwarder(maybeFrameCtxt));
+				referent = longAt((maybeFrameCtxt + BaseHeaderSize) + (0 << 2));
 				while (((referent & 3) == 0)
 				 && (((longAt(referent)) & 0x3FFFFF) == 8)) {
 					referent = longAt((referent + BaseHeaderSize) + (0 << 2));
 				}
-				frameCtxt = referent;
+				maybeFrameCtxt = referent;
 				/* begin setFrameContext:to: */
-				longAtput(theFrame + FoxThisContext, frameCtxt);
+				longAtput(maybeFrame + FoxThisContext, maybeFrameCtxt);
 			}
-			if (frameCtxt == aOnceMarriedContext) {
+			if (maybeFrameCtxt == aOnceMarriedContext) {
 
 				/* It is still married! */
 
@@ -74069,25 +74105,7 @@
 	}
 }
 
-static sqInt
-isFrameonPage(char *aFrame, StackPage *aPage)
-{
-    char *theFP;
 
-	theFP = (aPage->headFP);
-	while (1) {
-		if (theFP == aFrame) {
-			return 1;
-		}
-		if (!((theFP != ((aPage->baseFP)))
-		 && ((stackPageFor(theFP)) == aPage))) break;
-		/* begin frameCallerFP: */
-		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
-	}
-	return 0;
-}
-
-
 /*	Return a shallow copy of the receiver.
 	Special-case non-single contexts (because of context-to-stack mapping).
 	Can't fail for contexts cuz of image context instantiation code (sigh). */

Modified: branches/Cog/nsspursrc/vm/cointerp.h
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.h	2014-10-24 20:43:48 UTC (rev 3110)
+++ branches/Cog/nsspursrc/vm/cointerp.h	2014-10-24 22:52:56 UTC (rev 3111)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
  */
 
 

Modified: branches/Cog/nsspursrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/gcc3x-cointerp.c	2014-10-24 20:43:48 UTC (rev 3110)
+++ branches/Cog/nsspursrc/vm/gcc3x-cointerp.c	2014-10-24 22:52:56 UTC (rev 3111)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
    from
-	CoInterpreter VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c
+	CoInterpreter VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.912 uuid: d8b9d04a-adc6-44f8-b460-225d5ab73f6c " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -1307,6 +1307,7 @@
 static sqInt isBaseFrame(char *theFP) NoDbgRegParms;
 static sqInt isEmptyList(sqInt aLinkedList) NoDbgRegParms;
 sqInt isFloatObject(sqInt oop);
+static sqInt isFrameonPage(char *aFrame, StackPage *aPage) NoDbgRegParms;
 static sqInt isLiveContext(sqInt oop) NoDbgRegParms;
 static sqInt isMarriedOrWidowedContext(sqInt aContext) NoDbgRegParms;
 static sqInt isNullExternalPrimitiveCall(sqInt aMethodObj) NoDbgRegParms;
@@ -1468,7 +1469,6 @@
 static sqInt cloneContext(sqInt aContext) NoDbgRegParms;
 static sqInt fieldOrSenderFPofContext(sqInt index, sqInt contextObj) NoDbgRegParms;
 static sqInt fieldofFrame(sqInt index, char *theFP) NoDbgRegParms;
-static sqInt isFrameonPage(char *aFrame, StackPage *aPage) NoDbgRegParms;
 static void primitiveClone(void);
 static void primitiveContextAt(void);
 static void primitiveContextAtPut(void);
@@ -2338,7 +2338,7 @@
 /*540*/	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
 /*560*/	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0,-1,-1
 	};
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.912";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.913";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -63485,12 +63485,12 @@
 static sqInt
 checkIsStillMarriedContextcurrentFP(sqInt aContext, char *currentFP)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt frameCtxt;
     sqInt index;
     char *limitFP;
+    char *maybeFP;
+    sqInt maybeFrameCtxt;
     sqInt referent;
     sqInt senderOop;
-    char *theFP;
     StackPage *thePage;
 
 	if (!((((aContext & 3) == 0)
@@ -63502,37 +63502,44 @@
 	senderOop = longAt((aContext + BaseHeaderSize) + (SenderIndex << 2));
 	/* begin withoutSmallIntegerTags: */
 	assert((senderOop & 1));
-	theFP = pointerForOop(senderOop - 1);
+	maybeFP = pointerForOop(senderOop - 1);
 	/* begin stackPageFor: */
 	/* begin stackPageAt: */
 	/* begin pageIndexFor: */
-	assert((((((char *) theFP)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFP)) <= (((char *) GIV(pages))))));
-	index = pageIndexForstackBasePlus1bytesPerPage(theFP, GIV(stackBasePlus1), GIV(bytesPerPage));
+	assert((((((char *) maybeFP)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) maybeFP)) <= (((char *) GIV(pages))))));
+	index = pageIndexForstackBasePlus1bytesPerPage(maybeFP, GIV(stackBasePlus1), GIV(bytesPerPage));
 	thePage = stackPageAtpages(index, GIV(pages));
 	limitFP = ((thePage == GIV(stackPage))
 	 && (currentFP != null)
 		? currentFP
 		: (thePage->headFP));
-	if (!((theFP >= limitFP)
-		 && ((isNonImmediate(((sqInt)(frameCallerFP(theFP)))))
-		 && (((withSmallIntegerTags(frameCallerFP(theFP))) == (longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << 2))))
-		 && (((((usqInt)(longAt(theFP + FoxMethod)))) < (startOfMemory())
-			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
-			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)))))) {
+	if (!((maybeFP >= limitFP)
+		 && ((isNonImmediate(((sqInt)(frameCallerFP(maybeFP)))))
+		 && (((withSmallIntegerTags(frameCallerFP(maybeFP))) == (longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << 2))))
+		 && (((((usqInt)(longAt(maybeFP + FoxMethod)))) < (startOfMemory())
+			? ((longAt(maybeFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((maybeFP + FoxIFrameFlags) + 2)) != 0)))))) {
 		return 0;
 	}
-	frameCtxt = longAt(theFP + FoxThisContext);
-	if (((longAt(frameCtxt)) & (0x3FFFFF - 8)) == 0) {
+
+	/* 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. */
+
+	maybeFrameCtxt = longAt(maybeFP + FoxThisContext);
+	if (1
+	 && ((isFrameonPage(maybeFP, thePage))
+	 && (((longAt(maybeFrameCtxt)) & (0x3FFFFF - 8)) == 0))) {
 		/* begin followForwarded: */
-		assert(isUnambiguouslyForwarder(frameCtxt));
-		referent = longAt((frameCtxt + BaseHeaderSize) + (0 << 2));
+		assert(isUnambiguouslyForwarder(maybeFrameCtxt));
+		referent = longAt((maybeFrameCtxt + BaseHeaderSize) + (0 << 2));
 		while (((referent & 3) == 0)
 		 && (((longAt(referent)) & 0x3FFFFF) == 8)) {
 			referent = longAt((referent + BaseHeaderSize) + (0 << 2));
 		}
-		frameCtxt = referent;
+		maybeFrameCtxt = referent;
 	}
-	return frameCtxt == aContext;
+	return maybeFrameCtxt == aContext;
 }
 
 sqInt
@@ -66621,7 +66628,29 @@
 	 && (ClassFloatCompactIndex == ((longAt(oop)) & 0x3FFFFF));
 }
 
+static sqInt
+isFrameonPage(char *aFrame, StackPage *aPage)
+{
+    char *prevFP;
+    char *theFP;
 
+	assert(!((isFree(aPage))));
+	theFP = (aPage->headFP);
+	prevFP = theFP - (wordSize());
+	while (1) {
+		if (theFP == aFrame) {
+			return 1;
+		}
+		if (!((theFP > prevFP)
+		 && (theFP < ((aPage->baseFP))))) break;
+		prevFP = theFP;
+		/* begin frameCallerFP: */
+		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
+	}
+	return 0;
+}
+
+
 /*	Answer if the argument, which can be any object, is a live context. */
 
 static sqInt
@@ -66711,12 +66740,12 @@
 static sqInt
 isWidowedContext(sqInt aOnceMarriedContext)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt frameCtxt;
     sqInt index;
+    char *maybeFrame;
+    sqInt maybeFrameCtxt;
     sqInt referent;
     sqInt senderOop;
     char *shouldBeFrameCallerField;
-    char *theFrame;
     StackPage *thePage;
 
 	assert((isContext(aOnceMarriedContext))
@@ -66725,15 +66754,15 @@
 	senderOop = longAt((aOnceMarriedContext + BaseHeaderSize) + (SenderIndex << 2));
 	/* begin withoutSmallIntegerTags: */
 	assert((senderOop & 1));
-	theFrame = pointerForOop(senderOop - 1);
+	maybeFrame = pointerForOop(senderOop - 1);
 	/* begin stackPageFor: */
 	/* begin stackPageAt: */
 	/* begin pageIndexFor: */
-	assert((((((char *) theFrame)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFrame)) <= (((char *) GIV(pages))))));
-	index = pageIndexForstackBasePlus1bytesPerPage(theFrame, GIV(stackBasePlus1), GIV(bytesPerPage));
+	assert((((((char *) maybeFrame)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) maybeFrame)) <= (((char *) GIV(pages))))));
+	index = pageIndexForstackBasePlus1bytesPerPage(maybeFrame, GIV(stackBasePlus1), GIV(bytesPerPage));
 	thePage = stackPageAtpages(index, GIV(pages));
 	if (!((isFree(thePage))
-		 || (theFrame < ((thePage->headFP))))) {
+		 || (maybeFrame < ((thePage->headFP))))) {
 
 		/* The frame pointer is within the bounds of a live page.
 		   Now check if it matches a frame. */
@@ -66741,24 +66770,31 @@
 		/* begin withoutSmallIntegerTags: */
 		assert(((longAt((aOnceMarriedContext + BaseHeaderSize) + (InstructionPointerIndex << 2))) & 1));
 		shouldBeFrameCallerField = pointerForOop((longAt((aOnceMarriedContext + BaseHeaderSize) + (InstructionPointerIndex << 2))) - 1);
-		if (((frameCallerFP(theFrame)) == shouldBeFrameCallerField)
-		 && (((((usqInt)(longAt(theFrame + FoxMethod)))) < (startOfMemory())
-			? ((longAt(theFrame + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
-			: (byteAt((theFrame + FoxIFrameFlags) + 2)) != 0))) {
-			frameCtxt = longAt(theFrame + FoxThisContext);
-			if (((longAt(frameCtxt)) & (0x3FFFFF - 8)) == 0) {
+		if (((frameCallerFP(maybeFrame)) == shouldBeFrameCallerField)
+		 && (((((usqInt)(longAt(maybeFrame + FoxMethod)))) < (startOfMemory())
+			? ((longAt(maybeFrame + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((maybeFrame + FoxIFrameFlags) + 2)) != 0))) {
+
+			/* 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. */
+
+			maybeFrameCtxt = longAt(maybeFrame + FoxThisContext);
+			if (1
+			 && ((isFrameonPage(maybeFrame, thePage))
+			 && (((longAt(maybeFrameCtxt)) & (0x3FFFFF - 8)) == 0))) {
 				/* begin followForwarded: */
-				assert(isUnambiguouslyForwarder(frameCtxt));
-				referent = longAt((frameCtxt + BaseHeaderSize) + (0 << 2));
+				assert(isUnambiguouslyForwarder(maybeFrameCtxt));
+				referent = longAt((maybeFrameCtxt + BaseHeaderSize) + (0 << 2));
 				while (((referent & 3) == 0)
 				 && (((longAt(referent)) & 0x3FFFFF) == 8)) {
 					referent = longAt((referent + BaseHeaderSize) + (0 << 2));
 				}
-				frameCtxt = referent;
+				maybeFrameCtxt = referent;
 				/* begin setFrameContext:to: */
-				longAtput(theFrame + FoxThisContext, frameCtxt);
+				longAtput(maybeFrame + FoxThisContext, maybeFrameCtxt);
 			}
-			if (frameCtxt == aOnceMarriedContext) {
+			if (maybeFrameCtxt == aOnceMarriedContext) {
 
 				/* It is still married! */
 
@@ -74078,25 +74114,7 @@
 	}
 }
 
-static sqInt
-isFrameonPage(char *aFrame, StackPage *aPage)
-{
-    char *theFP;
 
-	theFP = (aPage->headFP);
-	while (1) {
-		if (theFP == aFrame) {
-			return 1;
-		}
-		if (!((theFP != ((aPage->baseFP)))
-		 && ((stackPageFor(theFP)) == aPage))) break;
-		/* begin frameCallerFP: */
-		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
-	}
-	return 0;
-}
-
-
 /*	Return a shallow copy of the receiver.
 	Special-case non-single contexts (because of context-to-stack mapping).
 	Can't fail for contexts cuz of image context instantiation code (sigh). */

Modified: branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c
===================================================================
--- branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c	2014-10-24 20:43:48 UTC (rev 3110)
+++ branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c	2014-10-24 22:52:56 UTC (rev 3111)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.909 uuid: 0d4fb242-44a2-408b-bc90-a737cfdd364d
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
    from
-	StackInterpreter VMMaker.oscog-eem.909 uuid: 0d4fb242-44a2-408b-bc90-a737cfdd364d
+	StackInterpreter VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
  */
-static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.909 uuid: 0d4fb242-44a2-408b-bc90-a737cfdd364d " __DATE__ ;
+static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -1074,6 +1074,7 @@
 static sqInt isBaseFrame(char *theFP) NoDbgRegParms;
 static sqInt isEmptyList(sqInt aLinkedList) NoDbgRegParms;
 sqInt isFloatObject(sqInt oop);
+static sqInt isFrameonPage(char *aFrame, StackPage *aPage) NoDbgRegParms;
 static sqInt isLiveContext(sqInt oop) NoDbgRegParms;
 static sqInt isMachineCodeFrame(char *theFP) NoDbgRegParms;
 static sqInt isMarriedOrWidowedContext(sqInt aContext) NoDbgRegParms;
@@ -1257,7 +1258,6 @@
 static sqInt cloneContext(sqInt aContext) NoDbgRegParms;
 static sqInt fieldOrSenderFPofContext(sqInt index, sqInt contextObj) NoDbgRegParms;
 static sqInt fieldofFrame(sqInt index, char *theFP) NoDbgRegParms;
-static sqInt isFrameonPage(char *aFrame, StackPage *aPage) NoDbgRegParms;
 static void primitiveClone(void);
 static void primitiveClosureCopyWithCopiedValues(void);
 static void primitiveContextAt(void);
@@ -2083,7 +2083,7 @@
  0 };
 char * breakSelector;
 sqInt breakSelectorLength = -1;
-const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.909";
+const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.913";
 volatile int sendTrace;
 sqInt suppressHeartbeatFlag;
 
@@ -49571,12 +49571,12 @@
 static sqInt
 checkIsStillMarriedContextcurrentFP(sqInt aContext, char *currentFP)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt frameCtxt;
     sqInt index;
     char *limitFP;
+    char *maybeFP;
+    sqInt maybeFrameCtxt;
     sqInt referent;
     sqInt senderOop;
-    char *theFP;
     StackPage *thePage;
 
 	if (!((((aContext & 3) == 0)
@@ -49588,33 +49588,40 @@
 	senderOop = longAt((aContext + BaseHeaderSize) + (SenderIndex << 2));
 	/* begin withoutSmallIntegerTags: */
 	assert((senderOop & 1));
-	theFP = pointerForOop(senderOop - 1);
+	maybeFP = pointerForOop(senderOop - 1);
 	/* begin stackPageFor: */
 	/* begin stackPageAt: */
-	index = pageIndexForstackMemorybytesPerPage(theFP, GIV(stackMemory), GIV(bytesPerPage));
+	index = pageIndexForstackMemorybytesPerPage(maybeFP, GIV(stackMemory), GIV(bytesPerPage));
 	thePage = stackPageAtpages(index, GIV(pages));
 	limitFP = ((thePage == GIV(stackPage))
 	 && (currentFP != null)
 		? currentFP
 		: (thePage->headFP));
-	if (!((theFP >= limitFP)
-		 && ((isNonImmediate(((sqInt)(frameCallerFP(theFP)))))
-		 && (((withSmallIntegerTags(frameCallerFP(theFP))) == (longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << 2))))
-		 && ((byteAt((theFP + FoxFrameFlags) + 2)) != 0))))) {
+	if (!((maybeFP >= limitFP)
+		 && ((isNonImmediate(((sqInt)(frameCallerFP(maybeFP)))))
+		 && (((withSmallIntegerTags(frameCallerFP(maybeFP))) == (longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << 2))))
+		 && ((byteAt((maybeFP + FoxFrameFlags) + 2)) != 0))))) {
 		return 0;
 	}
-	frameCtxt = longAt(theFP + FoxThisContext);
-	if (((longAt(frameCtxt)) & (0x3FFFFF - 8)) == 0) {
+
+	/* 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. */
+
+	maybeFrameCtxt = longAt(maybeFP + FoxThisContext);
+	if (1
+	 && ((isFrameonPage(maybeFP, thePage))
+	 && (((longAt(maybeFrameCtxt)) & (0x3FFFFF - 8)) == 0))) {
 		/* begin followForwarded: */
-		assert(isUnambiguouslyForwarder(frameCtxt));
-		referent = longAt((frameCtxt + BaseHeaderSize) + (0 << 2));
+		assert(isUnambiguouslyForwarder(maybeFrameCtxt));
+		referent = longAt((maybeFrameCtxt + BaseHeaderSize) + (0 << 2));
 		while (((referent & 3) == 0)
 		 && (((longAt(referent)) & 0x3FFFFF) == 8)) {
 			referent = longAt((referent + BaseHeaderSize) + (0 << 2));
 		}
-		frameCtxt = referent;
+		maybeFrameCtxt = referent;
 	}
-	return frameCtxt == aContext;
+	return maybeFrameCtxt == aContext;
 }
 
 
@@ -53410,7 +53417,29 @@
 	 && (ClassFloatCompactIndex == ((longAt(oop)) & 0x3FFFFF));
 }
 
+static sqInt
+isFrameonPage(char *aFrame, StackPage *aPage)
+{
+    char *prevFP;
+    char *theFP;
 
+	assert(!((isFree(aPage))));
+	theFP = (aPage->headFP);
+	prevFP = theFP - (wordSize());
+	while (1) {
+		if (theFP == aFrame) {
+			return 1;
+		}
+		if (!((theFP > prevFP)
+		 && (theFP < ((aPage->baseFP))))) break;
+		prevFP = theFP;
+		/* begin frameCallerFP: */
+		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
+	}
+	return 0;
+}
+
+
 /*	Answer if the argument, which can be any object, is a live context. */
 
 static sqInt
@@ -53489,12 +53518,12 @@
 static sqInt
 isWidowedContext(sqInt aOnceMarriedContext)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt frameCtxt;
     sqInt index;
+    char *maybeFrame;
+    sqInt maybeFrameCtxt;
     sqInt referent;
     sqInt senderOop;
     char *shouldBeFrameCallerField;
-    char *theFrame;
     StackPage *thePage;
 
 	assert((isContext(aOnceMarriedContext))
@@ -53503,13 +53532,13 @@
 	senderOop = longAt((aOnceMarriedContext + BaseHeaderSize) + (SenderIndex << 2));
 	/* begin withoutSmallIntegerTags: */
 	assert((senderOop & 1));
-	theFrame = pointerForOop(senderOop - 1);
+	maybeFrame = pointerForOop(senderOop - 1);
 	/* begin stackPageFor: */
 	/* begin stackPageAt: */
-	index = pageIndexForstackMemorybytesPerPage(theFrame, GIV(stackMemory), GIV(bytesPerPage));
+	index = pageIndexForstackMemorybytesPerPage(maybeFrame, GIV(stackMemory), GIV(bytesPerPage));
 	thePage = stackPageAtpages(index, GIV(pages));
 	if (!((isFree(thePage))
-		 || (theFrame < ((thePage->headFP))))) {
+		 || (maybeFrame < ((thePage->headFP))))) {
 
 		/* The frame pointer is within the bounds of a live page.
 		   Now check if it matches a frame. */
@@ -53517,22 +53546,29 @@
 		/* begin withoutSmallIntegerTags: */
 		assert(((longAt((aOnceMarriedContext + BaseHeaderSize) + (InstructionPointerIndex << 2))) & 1));
 		shouldBeFrameCallerField = pointerForOop((longAt((aOnceMarriedContext + BaseHeaderSize) + (InstructionPointerIndex << 2))) - 1);
-		if (((frameCallerFP(theFrame)) == shouldBeFrameCallerField)
-		 && ((byteAt((theFrame + FoxFrameFlags) + 2)) != 0)) {
-			frameCtxt = longAt(theFrame + FoxThisContext);
-			if (((longAt(frameCtxt)) & (0x3FFFFF - 8)) == 0) {
+		if (((frameCallerFP(maybeFrame)) == shouldBeFrameCallerField)
+		 && ((byteAt((maybeFrame + FoxFrameFlags) + 2)) != 0)) {
+
+			/* 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. */
+
+			maybeFrameCtxt = longAt(maybeFrame + FoxThisContext);
+			if (1
+			 && ((isFrameonPage(maybeFrame, thePage))
+			 && (((longAt(maybeFrameCtxt)) & (0x3FFFFF - 8)) == 0))) {
 				/* begin followForwarded: */
-				assert(isUnambiguouslyForwarder(frameCtxt));
-				referent = longAt((frameCtxt + BaseHeaderSize) + (0 << 2));
+				assert(isUnambiguouslyForwarder(maybeFrameCtxt));
+				referent = longAt((maybeFrameCtxt + BaseHeaderSize) + (0 << 2));
 				while (((referent & 3) == 0)
 				 && (((longAt(referent)) & 0x3FFFFF) == 8)) {
 					referent = longAt((referent + BaseHeaderSize) + (0 << 2));
 				}
-				frameCtxt = referent;
+				maybeFrameCtxt = referent;
 				/* begin setFrameContext:to: */
-				longAtput(theFrame + FoxThisContext, frameCtxt);
+				longAtput(maybeFrame + FoxThisContext, maybeFrameCtxt);
 			}
-			if (frameCtxt == aOnceMarriedContext) {
+			if (maybeFrameCtxt == aOnceMarriedContext) {
 
 				/* It is still married! */
 
@@ -63874,25 +63910,7 @@
 	}
 }
 
-static sqInt
-isFrameonPage(char *aFrame, StackPage *aPage)
-{
-    char *theFP;
 
-	theFP = (aPage->headFP);
-	while (1) {
-		if (theFP == aFrame) {
-			return 1;
-		}
-		if (!((theFP != ((aPage->baseFP)))
-		 && ((stackPageFor(theFP)) == aPage))) break;
-		/* begin frameCallerFP: */
-		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
-	}
-	return 0;
-}
-
-
 /*	Return a shallow copy of the receiver.
 	Special-case non-single contexts (because of context-to-stack mapping).
 	Can't fail for contexts cuz of image context instantiation code (sigh). */

Modified: branches/Cog/nsspurstacksrc/vm/interp.c
===================================================================
--- branches/Cog/nsspurstacksrc/vm/interp.c	2014-10-24 20:43:48 UTC (rev 3110)
+++ branches/Cog/nsspurstacksrc/vm/interp.c	2014-10-24 22:52:56 UTC (rev 3111)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.909 uuid: 0d4fb242-44a2-408b-bc90-a737cfdd364d
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
    from
-	StackInterpreter VMMaker.oscog-eem.909 uuid: 0d4fb242-44a2-408b-bc90-a737cfdd364d
+	StackInterpreter VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7
  */
-static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.909 uuid: 0d4fb242-44a2-408b-bc90-a737cfdd364d " __DATE__ ;
+static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.913 uuid: 236b8f3e-0ff4-4a68-baf9-e3fc62b97da7 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -1071,6 +1071,7 @@
 static sqInt isBaseFrame(char *theFP) NoDbgRegParms;
 static sqInt isEmptyList(sqInt aLinkedList) NoDbgRegParms;
 sqInt isFloatObject(sqInt oop);
+static sqInt isFrameonPage(char *aFrame, StackPage *aPage) NoDbgRegParms;
 static sqInt isLiveContext(sqInt oop) NoDbgRegParms;
 static sqInt isMachineCodeFrame(char *theFP) NoDbgRegParms;
 static sqInt isMarriedOrWidowedContext(sqInt aContext) NoDbgRegParms;
@@ -1254,7 +1255,6 @@
 static sqInt cloneContext(sqInt aContext) NoDbgRegParms;
 static sqInt fieldOrSenderFPofContext(sqInt index, sqInt contextObj) NoDbgRegParms;
 static sqInt fieldofFrame(sqInt index, char *theFP) NoDbgRegParms;
-static sqInt isFrameonPage(char *aFrame, StackPage *aPage) NoDbgRegParms;
 static void primitiveClone(void);
 static void primitiveClosureCopyWithCopiedValues(void);
 static void primitiveContextAt(void);
@@ -2080,7 +2080,7 @@
  0 };
 char * breakSelector;
 sqInt breakSelectorLength = -1;
-const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.909";
+const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.913";
 volatile int sendTrace;
 sqInt suppressHeartbeatFlag;
 
@@ -49562,12 +49562,12 @@
 static sqInt
 checkIsStillMarriedContextcurrentFP(sqInt aContext, char *currentFP)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt frameCtxt;
     sqInt index;
     char *limitFP;
+    char *maybeFP;
+    sqInt maybeFrameCtxt;
     sqInt referent;
     sqInt senderOop;
-    char *theFP;
     StackPage *thePage;
 
 	if (!((((aContext & 3) == 0)
@@ -49579,33 +49579,40 @@

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list