[Vm-dev] [commit] r2548 - CogVM source as per VMMaker.oscog-eem.156

commits at squeakvm.org commits at squeakvm.org
Fri Apr 13 17:44:19 UTC 2012


Author: eliot
Date: 2012-04-13 10:44:17 -0700 (Fri, 13 Apr 2012)
New Revision: 2548

Modified:
   branches/Cog/macbuild/
   branches/Cog/macbuild/Mpeg3Plugin/
   branches/Cog/macbuild/Mpeg3Plugin/Mpeg3Plugin.xcodeproj/
   branches/Cog/macbuild/SqueakFFIPrims/SqueakFFI.xcodeproj/
   branches/Cog/macbuild/SqueakMTFFIPrims/
   branches/Cog/nscogbuild/macbuild/CoreVM.xcodeproj/
   branches/Cog/nscogsrc/vm/cogit.c
   branches/Cog/nscogsrc/vm/cogit.h
   branches/Cog/nscogsrc/vm/cogmethod.h
   branches/Cog/nscogsrc/vm/cointerp.c
   branches/Cog/nscogsrc/vm/cointerp.h
   branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
   branches/Cog/nscogsrc/vm/interp.h
   branches/Cog/nscogsrc/vm/vmCallback.h
   branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
   branches/Cog/platforms/Mac OS/vm/sqMacUIEventsUniversal.c
   branches/Cog/src/vm/cogit.c
   branches/Cog/src/vm/cogit.h
   branches/Cog/src/vm/cogmethod.h
   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/src/vm/interp.h
   branches/Cog/src/vm/vmCallback.h
   branches/Cog/stackbuild/macbuild/
   branches/Cog/stackbuild/macbuild/Mpeg3Plugin/
Log:
CogVM source as per VMMaker.oscog-eem.156

CoInterpreter:
Provide a thorough flush primitive for CompiledMethods that discards all
machine code and makes sure that any contexts using the method have bytecode
pcs.  Primitive #215 (same as 116 in the Stack VM).  This is much slower than
116 (flushCache) since it has to enumerate over all heap contexts.

Provide an xray primitive for CompiledMethod that answers if a method has
machine code, and if so if it's machine code is frameless, and/or refers
to a young object.  No primitive number.  Used to test the above.

Make printOopShort: print Association keys.  Useful for
longPrintOop:, and hence printReferencesTo: etc.

Mac OS: add fflush to debug printing in sqMacUIEventsUniversal.c so output
appears promptly.

Build: a few more svn:ignore properties.



Property changes on: branches/Cog/macbuild
___________________________________________________________________
Modified: svn:ignore
   - build
*.app
*.bundle
LOG*
*.sources

   + build
*.app
*.bundle
LOG*
*.sources
sqNamedPrims.h



Property changes on: branches/Cog/macbuild/Mpeg3Plugin
___________________________________________________________________
Added: svn:ignore
   + build



Property changes on: branches/Cog/macbuild/Mpeg3Plugin/Mpeg3Plugin.xcodeproj
___________________________________________________________________
Added: svn:ignore
   + *.pbxuser
*.mode*



Property changes on: branches/Cog/macbuild/SqueakFFIPrims/SqueakFFI.xcodeproj
___________________________________________________________________
Modified: svn:ignore
   - eliot.*

   + *.pbxuser
*.mode*



Property changes on: branches/Cog/macbuild/SqueakMTFFIPrims
___________________________________________________________________
Added: svn:ignore
   + build



Property changes on: branches/Cog/nscogbuild/macbuild/CoreVM.xcodeproj
___________________________________________________________________
Added: svn:ignore
   + *.pbxuser
*.mode*


Modified: branches/Cog/nscogsrc/vm/cogit.c
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.c	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/nscogsrc/vm/cogit.c	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,9 +1,15 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGenerator eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	StackToRegisterMappingCogit eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01 " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -996,7 +1002,7 @@
 static sqInt unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod);
 void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector);
 void unlinkSendsToFree(void);
-void unlinkSendsTo(sqInt targetMethodObject);
+void unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue);
 static sqInt unsignedShortAt(AbstractInstruction * self_in_unsignedShortAt, sqInt byteAddress);
 static void updateLabel(AbstractInstruction * self_in_updateLabel, AbstractInstruction *labelInstruction);
 static sqInt updateMaybeObjRefAt(sqInt mcpc);
@@ -17411,7 +17417,7 @@
 	could be affected. */
 
 void
-unlinkSendsTo(sqInt targetMethodObject)
+unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue)
 {
     CogMethod *cogMethod;
     sqInt freedPIC;
@@ -17440,6 +17446,9 @@
 		}
 		cogMethod = methodAfter(cogMethod);
 	}
+	if (freeIfTrue) {
+		freeMethod(targetMethod);
+	}
 	if (freedPIC) {
 		unlinkSendsToFree();
 	}

Modified: branches/Cog/nscogsrc/vm/cogit.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.h	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/nscogsrc/vm/cogit.h	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,5 +1,7 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGenerator eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
 
 
@@ -71,7 +73,7 @@
 void unlinkAllSends(void);
 void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector);
 void unlinkSendsToFree(void);
-void unlinkSendsTo(sqInt targetMethodObject);
+void unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue);
 void voidCogCompiledCode(void);
 
 

Modified: branches/Cog/nscogsrc/vm/cogmethod.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogmethod.h	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/nscogsrc/vm/cogmethod.h	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,5 +1,7 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGenerator eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
 
 typedef struct {

Modified: branches/Cog/nscogsrc/vm/cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.c	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/nscogsrc/vm/cointerp.c	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,9 +1,15 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGeneratorGlobalStructure eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
    from
-	CoInterpreter VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CoInterpreter eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -211,6 +217,7 @@
 #define ImmutabilityBit 0x20000000
 #define InstanceSpecificationIndex 2
 #define InstructionPointerIndex 1
+#define KeyIndex 0
 #define LargeContextBit 0x40000
 #define LargeContextBytes 252
 #define LargeContextSize 252
@@ -463,6 +470,7 @@
 static void displayBitsOfLeftTopRightBottom(sqInt aForm, sqInt l, sqInt t, sqInt r, sqInt b);
 sqInt displayObject(void);
 static sqInt divorceAllFrames(void);
+static sqInt divorceAMachineCodeFrameWithCogMethodin(CogMethod *cogMethod, StackPage *aStackPage);
 static void divorceFramesIn(StackPage *aStackPage);
 static sqInt doPrimitiveDivby(sqInt rcvr, sqInt arg);
 static sqInt doPrimitiveModby(sqInt rcvr, sqInt arg);
@@ -675,6 +683,7 @@
 static void markStackPageMostRecentlyUsed(StackPage *page);
 static void markStackPageNextMostRecentlyUsed(StackPage *page);
 static sqInt marriedContextpointsTostackDeltaForCurrentFrame(sqInt spouseContext, sqInt anOop, sqInt stackDeltaForCurrentFrame);
+static void marryContextInNewStackPageAndInitializeInterpreterRegisters(sqInt aContext);
 static sqInt marryFrameSP(char *theFP, char *theSP);
 static void maybeFlagMethodAsInterpreted(sqInt aMethod);
 sqInt maybeSplObj(sqInt index);
@@ -881,6 +890,7 @@
 static void primitiveMarkUnwindMethod(void);
 static void primitiveMaxIdentityHash(void);
 sqInt primitiveMethod(void);
+EXPORT(void) primitiveMethodXray(void);
 static void primitiveMillisecondClock(void);
 EXPORT(sqInt) primitiveMillisecondClockMask(void);
 static void primitiveMod(void);
@@ -972,6 +982,7 @@
 static void primitiveVMProfileSamplesInto(void);
 EXPORT(void) primitiveVoidReceiver(void);
 static void primitiveVoidVMState(void);
+static void primitiveVoidVMStateForMethod(void);
 static void primitiveWait(void);
 static void primitiveYield(void);
 void * primTraceLogAddress(void);
@@ -1142,6 +1153,7 @@
 static void verifyCleanHeaders(void);
 sqInt vmEndianness(void);
 static void voidLongRunningPrimitive(char *reason);
+static sqInt voidVMStateForSnapshot(void);
 static sqInt wakeHighestPriority(void);
 static sqInt withSmallIntegerTags(char *value);
 static sqInt wordSwapped(sqInt w);
@@ -1164,12 +1176,12 @@
 _iss sqInt nilObj;
 _iss usqInt method;
 _iss usqInt instructionPointer;
+_iss sqInt argumentCount;
 _iss usqInt freeStart;
-_iss sqInt argumentCount;
 _iss usqInt newMethod;
 _iss sqInt messageSelector;
+_iss StackPage * pages;
 _iss usqInt youngStart;
-_iss StackPage * pages;
 _iss char * stackBasePlus1;
 _iss usqInt endOfMemory;
 _iss sqInt rootTableCount;
@@ -1179,15 +1191,15 @@
 _iss sqInt falseObj;
 _iss sqInt bytesPerPage;
 _iss sqInt traceLogIndex;
+_iss usqInt reserveStart;
 _iss char * stackLimit;
-_iss usqInt reserveStart;
 _iss usqInt memoryLimit;
 _iss StackPage * mostRecentlyUsedPage;
 _iss sqInt needGCFlag;
 _iss usqInt scavengeThreshold;
+_iss sqInt numStackPages;
 _iss unsigned char primTraceLogIndex;
 _iss sqLong nextProfileTick;
-_iss sqInt numStackPages;
 _iss sqInt jmpDepth;
 _iss usqInt fwdTableNext;
 _iss sqInt longRunningPrimitiveCheckSemaphore;
@@ -1547,7 +1559,7 @@
 	/* 212 */ primitiveContextSize,
 	/* 213 */ primitiveContextXray,
 	/* 214 */ primitiveVoidVMState,
-	/* 215 */ (void (*)(void))0,
+	/* 215 */ primitiveVoidVMStateForMethod,
 	/* 216 */ (void (*)(void))0,
 	/* 217 */ (void (*)(void))0,
 	/* 218 */ primitiveDoNamedPrimitiveWithArgs,
@@ -1910,7 +1922,9 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.154";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_eneraiton.
+
+VMMaker.oscog-eem.156";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -13806,6 +13820,55 @@
 	return activeContext;
 }
 
+
+/*	Divorce at most one frame in the current page (since the divorce may cause
+	the page to be split)
+	and answer whether a frame was divorced. */
+
+static sqInt
+divorceAMachineCodeFrameWithCogMethodin(CogMethod *cogMethod, StackPage *aStackPage)
+{
+    char *calleeFP;
+    sqInt theContext;
+    char *theFP;
+    char *theSP;
+
+	theFP = (aStackPage->headFP);
+	theSP = (aStackPage->headSP);
+
+	/* theSP points at hottest item on frame's stack */
+
+	theSP += BytesPerWord;
+	while (1) {
+		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase)
+		 && (cogMethod == (mframeHomeMethod(theFP)))) {
+			/* begin ensureFrameIsMarried:SP: */
+			VM_LABEL(11ensureFrameIsMarriedSP);
+			if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
+				? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+				: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
+				assert(isContext(frameContext(theFP)));
+				theContext = longAt(theFP + FoxThisContext);
+				goto l1;
+			}
+			theContext = marryFrameSP(theFP, theSP);
+		l1:	/* end ensureFrameIsMarried:SP: */;
+			externalDivorceFrameandContext(theFP, theContext);
+			return 1;
+		}
+		calleeFP = theFP;
+		/* begin frameCallerFP: */
+		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
+		if (!(theFP != 0)) break;
+		/* begin frameCallerSP: */
+		assert(!(isBaseFrame(calleeFP)));
+		theSP = (calleeFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(calleeFP + FoxMethod)))) < heapBase
+	? (mframeCogMethod(calleeFP)->cmNumArgs)
+	: byteAt((calleeFP + FoxIFrameFlags) + 1))))) + BytesPerWord;
+	}
+	return 0;
+}
+
 static void
 divorceFramesIn(StackPage *aStackPage)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
@@ -13832,7 +13895,7 @@
 	calleeContext = null;
 	while (1) {
 		/* begin ensureFrameIsMarried:SP: */
-		VM_LABEL(11ensureFrameIsMarriedSP);
+		VM_LABEL(12ensureFrameIsMarriedSP);
 		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
 			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
@@ -14745,7 +14808,7 @@
 		return callerContextOrNil;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(12ensureFrameIsMarriedSP);
+	VM_LABEL(13ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -14791,6 +14854,7 @@
 {
     sqInt pc;
 
+	/* begin ensureContextHasBytecodePC: */
 	assert(!(isMarriedOrWidowedContext(aContext)));
 	pc = longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
 	if (((pc & 1))
@@ -15338,7 +15402,6 @@
     char *theSP1;
     sqInt valuePointer;
 
-	assert(theFP != GIV(framePointer));
 	assert((GIV(stackPage) == 0)
 	 || (GIV(stackPage) == (mostRecentlyUsedPage())));
 	/* begin stackPageFor: */
@@ -15372,7 +15435,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(13ensureFrameIsMarriedSP);
+	VM_LABEL(14ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP1 = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -15569,7 +15632,7 @@
 			return callerContextOrNil;
 		}
 		/* begin ensureFrameIsMarried:SP: */
-		VM_LABEL(14ensureFrameIsMarriedSP);
+		VM_LABEL(15ensureFrameIsMarriedSP);
 		/* begin frameCallerStackPointer: */
 		assert(!(isBaseFrame(spouseFP)));
 		theSP = (spouseFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(spouseFP + FoxMethod)))) < heapBase
@@ -16266,7 +16329,7 @@
 	: byteAt((theFPAbove + FoxIFrameFlags) + 1))))) + BytesPerWord;
 				}
 				/* begin ensureFrameIsMarried:SP: */
-				VM_LABEL(15ensureFrameIsMarriedSP);
+				VM_LABEL(16ensureFrameIsMarriedSP);
 				if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 					? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
 					: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
@@ -17681,7 +17744,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(16ensureFrameIsMarriedSP);
+	VM_LABEL(17ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -18977,13 +19040,9 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
     sqInt activeProc;
-    sqInt aMethodObj;
-    StackPage *newPage;
     sqInt stackPageBytes;
     sqInt stackPagesBytes;
-    char *theFP;
     char *theStackMemory;
-    sqInt top;
 
 	stackPageBytes = stackPageByteSize();
 	stackPagesBytes = (GIV(numStackPages) * ((sizeof(CogStackPage)) + (stackPageByteSize()))) + BytesPerWord;
@@ -18999,37 +19058,7 @@
 	}
 	activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	activeContext = longAt((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord));
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(0marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	ioInitHeartbeat();
 	initialEnterSmalltalkExecutive();
 	return null;
@@ -19836,7 +19865,8 @@
     StackPage *thePage;
     sqInt value;
 
-	assert(isContext(aOnceMarriedContext));
+	assert((isContext(aOnceMarriedContext))
+	 && (isMarriedOrWidowedContext(aOnceMarriedContext)));
 	/* begin frameOfMarriedContext: */
 	value = longAt((aOnceMarriedContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
 	/* begin withoutSmallIntegerTags: */
@@ -20619,13 +20649,9 @@
 
 void
 loadInitialContext(void)
-{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+{
     sqInt activeContext;
     sqInt activeProc;
-    sqInt aMethodObj;
-    StackPage *newPage;
-    char *theFP;
-    sqInt top;
 
 	if ((checkForLeaks & 1) != 0) {
 		clearLeakMapAndMapAccessibleObjects();
@@ -20633,37 +20659,7 @@
 	}
 	activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	activeContext = longAt((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord));
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(1marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 }
 
 void
@@ -22580,6 +22576,50 @@
 }
 
 
+/*	Establish aContext at the base of a new stackPage, make the stackPage the
+	active one and set-up the interreter registers. This is used to boot the
+	system and bring it back after a snapshot. */
+
+static void
+marryContextInNewStackPageAndInitializeInterpreterRegisters(sqInt aContext)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt aMethodObj;
+    StackPage *newPage;
+    char *theFP;
+    sqInt top;
+
+	assert(GIV(stackPage) == 0);
+	newPage = makeBaseFrameFor(aContext);
+	/* begin setStackPageAndLimit: */
+	GIV(stackPage) = newPage;
+	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
+		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
+	}
+	markStackPageMostRecentlyUsed(newPage);
+	GIV(framePointer) = (GIV(stackPage)->headFP);
+	GIV(stackPointer) = (GIV(stackPage)->headSP);
+	/* begin setMethod: */
+	/* begin iframeMethod: */
+	theFP = (GIV(stackPage)->headFP);
+	aMethodObj = longAt(theFP + FoxMethod);
+	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
+	GIV(method) = aMethodObj;
+	assert(isOopCompiledMethod(GIV(method)));
+	
+#  if MULTIPLEBYTECODESETS
+	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
+		? 256
+		: 0);
+
+#  endif /* MULTIPLEBYTECODESETS */
+
+	/* begin popStack */
+	top = longAt(GIV(stackPointer));
+	GIV(stackPointer) += BytesPerWord;
+	GIV(instructionPointer) = ((sqInt) top);
+}
+
+
 /*	Marry an unmarried frame. This means creating a spouse context initialized
 	with a subset of the frame's state (state through the last argument) that
 	references the
@@ -23083,7 +23123,7 @@
 	assert(frameHasContext(callerFP));
 	assert(isContext(frameContext(callerFP)));
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(17ensureFrameIsMarriedSP);
+	VM_LABEL(18ensureFrameIsMarriedSP);
 	theSP = theFP + (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 	? FoxMFReceiver
 	: FoxIFReceiver));
@@ -30169,7 +30209,7 @@
 	for (i1 = 1; i1 <= AtCacheTotalSize; i1 += 1) {
 		GIV(atCache)[i1] = 0;
 	}
-	unlinkSendsTo(longAt(GIV(stackPointer)));
+	unlinkSendsToandFreeIf(longAt(GIV(stackPointer)), 0);
 }
 
 
@@ -32429,18 +32469,9 @@
 primitiveLongRunningPrimitiveSemaphore(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
     sqInt flushState;
-    sqInt header;
-    StackPage *newPage;
-    sqInt oop;
     sqInt sema;
     char *sp;
-    sqInt sz;
-    char *theFP;
-    sqInt top;
 
 	sema = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	if (((sema & 1))
@@ -32470,84 +32501,8 @@
 		/* begin push: */
 		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp;
-		/* begin voidVMStateForSnapshot */
-
-		/* in case of code compactions. */
-
-		GIV(instructionPointer) = 0;
-		activeContext1 = divorceAllFrames();
-		/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-		VM_LABEL(0ensureAllContextsHaveBytecodePCsOrAreBereaved);
-		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-		while (oop < GIV(freeStart)) {
-			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-			 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-					/* begin markContextAsDead: */
-					assert(isContext(oop));
-					longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-				}
-				else {
-					decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-					if (((decodedIP & 1))
-					 && ((((sqInt) decodedIP)) < 0)) {
-						decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-					}
-				}
-			}
-			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
-			}
-			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-				sz = (longAt(oop)) & AllButTypeMask;
-			}
-			else {
-				/* begin sizeBitsOf: */
-				header = longAt(oop);
-				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-					: header & SizeMask);
-			}
-			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
-		}
-		voidCogCompiledCode();
-		activeContext = activeContext1;
-		/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-		VM_LABEL(2marryContextInNewStackPageAndInitializeInterpreterRegisters);
-		assert(GIV(stackPage) == 0);
-		newPage = makeBaseFrameFor(activeContext);
-		/* begin setStackPageAndLimit: */
-		GIV(stackPage) = newPage;
-		if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-			GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-		}
-		markStackPageMostRecentlyUsed(newPage);
-		GIV(framePointer) = (GIV(stackPage)->headFP);
-		GIV(stackPointer) = (GIV(stackPage)->headSP);
-		/* begin setMethod: */
-		/* begin iframeMethod: */
-		theFP = (GIV(stackPage)->headFP);
-		aMethodObj = longAt(theFP + FoxMethod);
-		assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-		GIV(method) = aMethodObj;
-		assert(isOopCompiledMethod(GIV(method)));
-		
-#    if MULTIPLEBYTECODESETS
-		bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-			? 256
-			: 0);
-
-#    endif /* MULTIPLEBYTECODESETS */
-
-		/* begin popStack */
-		top = longAt(GIV(stackPointer));
-		GIV(stackPointer) += BytesPerWord;
-		GIV(instructionPointer) = ((sqInt) top);
+		activeContext = voidVMStateForSnapshot();
+		marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 		assert((((stackValue(0)) == (nilObject()))
  && (GIV(longRunningPrimitiveCheckSemaphore) == null))
 		 || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore))
@@ -32714,6 +32669,49 @@
 }
 
 
+/*	Lift the veil from a method and answer an integer describing the interior
+	state of its machine code.
+	Used for e.g. VM tests so they can verify they're testing what they think
+	they're testing.
+	0 implies a vanilla method.
+	Bit 0 = method is currently compiled to machine code
+	Bit 1 = is compiled frameless.
+	Bit 2 = method refers to young object */
+
+EXPORT(void)
+primitiveMethodXray(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt aMethodOop;
+    CogMethod *cogMethod;
+    sqInt flags;
+    sqInt methodHeader;
+    char *sp;
+
+	if ((((longAt(GIV(stackPointer))) & 1) == 0)
+	 && ((((((usqInt) (longAt(longAt(GIV(stackPointer))))) >> 8) & 15) >= 12)
+	 && (isCogMethodReference(longAt(((longAt(GIV(stackPointer))) + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
+		/* begin cogMethodOf: */
+		aMethodOop = longAt(GIV(stackPointer));
+		methodHeader = longAt((aMethodOop + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+		assert((isNonIntegerObject(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		flags = (((cogMethod->stackCheckOffset)) == 0
+			? 3
+			: 1);
+		if ((cogMethod->cmRefersToYoung)) {
+			flags += 4;
+		}
+	}
+	else {
+		flags = 0;
+	}
+	/* begin pop:thenPush: */
+	longAtput((sp = GIV(stackPointer) + ((1 - 1) * BytesPerWord)), ((flags << 1) | 1));
+	GIV(stackPointer) = sp;
+}
+
+
 /*	Return the value of the millisecond clock as an integer. Note that the
 	millisecond clock wraps around periodically. On some platforms it can wrap
 	daily. The range is limited to SmallInteger maxVal / 2 to allow delays of
@@ -33989,18 +33987,9 @@
 primitiveProfileSemaphore(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
     sqInt flushState;
-    sqInt header;
-    StackPage *newPage;
-    sqInt oop;
     sqInt sema;
     char *sp;
-    sqInt sz;
-    char *theFP;
-    sqInt top;
 
 	sema = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	if (((sema & 1))
@@ -34035,84 +34024,8 @@
 		/* begin push: */
 		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp;
-		/* begin voidVMStateForSnapshot */
-
-		/* in case of code compactions. */
-
-		GIV(instructionPointer) = 0;
-		activeContext1 = divorceAllFrames();
-		/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-		VM_LABEL(1ensureAllContextsHaveBytecodePCsOrAreBereaved);
-		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-		while (oop < GIV(freeStart)) {
-			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-			 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-					/* begin markContextAsDead: */
-					assert(isContext(oop));
-					longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-				}
-				else {
-					decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-					if (((decodedIP & 1))
-					 && ((((sqInt) decodedIP)) < 0)) {
-						decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-					}
-				}
-			}
-			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
-			}
-			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-				sz = (longAt(oop)) & AllButTypeMask;
-			}
-			else {
-				/* begin sizeBitsOf: */
-				header = longAt(oop);
-				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-					: header & SizeMask);
-			}
-			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
-		}
-		voidCogCompiledCode();
-		activeContext = activeContext1;
-		/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-		VM_LABEL(3marryContextInNewStackPageAndInitializeInterpreterRegisters);
-		assert(GIV(stackPage) == 0);
-		newPage = makeBaseFrameFor(activeContext);
-		/* begin setStackPageAndLimit: */
-		GIV(stackPage) = newPage;
-		if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-			GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-		}
-		markStackPageMostRecentlyUsed(newPage);
-		GIV(framePointer) = (GIV(stackPage)->headFP);
-		GIV(stackPointer) = (GIV(stackPage)->headSP);
-		/* begin setMethod: */
-		/* begin iframeMethod: */
-		theFP = (GIV(stackPage)->headFP);
-		aMethodObj = longAt(theFP + FoxMethod);
-		assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-		GIV(method) = aMethodObj;
-		assert(isOopCompiledMethod(GIV(method)));
-		
-#    if MULTIPLEBYTECODESETS
-		bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-			? 256
-			: 0);
-
-#    endif /* MULTIPLEBYTECODESETS */
-
-		/* begin popStack */
-		top = longAt(GIV(stackPointer));
-		GIV(stackPointer) += BytesPerWord;
-		GIV(instructionPointer) = ((sqInt) top);
+		activeContext = voidVMStateForSnapshot();
+		marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 		assert((((stackValue(0)) == (nilObject()))
  && (GIV(profileSemaphore) == (nilObject())))
 		 || (((stackValue(0)) == GIV(profileSemaphore))
@@ -38137,98 +38050,211 @@
 primitiveVoidVMState(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
+    char *sp;
+
+	/* begin push: */
+	longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+	GIV(stackPointer) = sp;
+	activeContext = voidVMStateForSnapshot();
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
+	siglongjmp(reenterInterpreter, ReturnToInterpreter);
+}
+
+
+/*	The receiver is a compiledMethod. Clear all entries in the method lookup
+	cache that refer to this method, presumably because it has been redefined,
+	overridden or removed.
+ */
+/*	The receiver is a compiledMethod. Clear all VM state associated with the
+	method, including any machine code, or machine code pcs in context
+	objects.  */
+
+static void
+primitiveVoidVMStateForMethod(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt activeContext;
+    StackPage *aPage;
+    CogMethod *cogMethod;
+    sqInt divorcedSome;
+    sqInt divorcedSome1;
     sqInt header;
-    StackPage *newPage;
+    sqInt i;
+    sqInt i1;
+    sqInt i2;
+    sqInt index;
+    sqInt methodHeader;
+    sqInt methodObj;
+    sqInt oldMethod;
     sqInt oop;
+    sqInt pc;
+    sqInt primBits;
+    sqInt primIdx;
+    sqInt probe;
     char *sp;
     sqInt sz;
     char *theFP;
+    char *theFrame;
+    StackPage *thePage;
+    char *theSP;
     sqInt top;
+    sqInt top1;
+    sqInt value;
 
-	/* begin push: */
-	longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
-	GIV(stackPointer) = sp;
-	/* begin voidVMStateForSnapshot */
-
-	/* in case of code compactions. */
-
-	GIV(instructionPointer) = 0;
-	activeContext1 = divorceAllFrames();
-	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-	VM_LABEL(2ensureAllContextsHaveBytecodePCsOrAreBereaved);
-	oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-	while (oop < GIV(freeStart)) {
-		if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-		 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-			if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-				/* begin markContextAsDead: */
-				assert(isContext(oop));
-				longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-				longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
+	oldMethod = longAt(GIV(stackPointer));
+	probe = 0;
+	for (i = 1; i <= MethodCacheEntries; i += 1) {
+		if ((GIV(methodCache)[probe + MethodCacheMethod]) == oldMethod) {
+			GIV(methodCache)[probe + MethodCacheSelector] = 0;
+		}
+		probe += MethodCacheEntrySize;
+	}
+	/* begin primitiveIndexOf: */
+	primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
+	primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
+	if (primIdx == PrimitiveExternalCallIndex) {
+		flushExternalPrimitiveOf(oldMethod);
+	}
+	/* begin flushAtCache */
+	for (i2 = 1; i2 <= AtCacheTotalSize; i2 += 1) {
+		GIV(atCache)[i2] = 0;
+	}
+	if (methodHasCogMethod(longAt(GIV(stackPointer)))) {
+		methodObj = longAt(GIV(stackPointer));
+		/* begin push: */
+		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+		GIV(stackPointer) = sp;
+		/* begin externalWriteBackHeadFramePointers */
+		assert((GIV(framePointer) - GIV(stackPointer)) < LargeContextSize);
+		assert(GIV(stackPage) == (mostRecentlyUsedPage()));
+		/* begin setHeadFP:andSP:inPage: */
+		assert(GIV(stackPointer) < GIV(framePointer));
+		assert((GIV(stackPointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(stackPointer) > (((GIV(stackPage)->realStackLimit)) - LargeContextSize)));
+		assert((GIV(framePointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(framePointer) > (((GIV(stackPage)->realStackLimit)) - (((sqInt) LargeContextSize >> 1)))));
+		(GIV(stackPage)->headFP = GIV(framePointer));
+		(GIV(stackPage)->headSP = GIV(stackPointer));
+		assert(pageListIsWellFormed());
+		/* begin ensureFrameIsMarried:SP: */
+		VM_LABEL(19ensureFrameIsMarriedSP);
+		theFP = GIV(framePointer);
+		theSP = GIV(stackPointer);
+		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
+			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
+			assert(isContext(frameContext(theFP)));
+			activeContext = longAt(theFP + FoxThisContext);
+			goto l1;
+		}
+		activeContext = marryFrameSP(theFP, theSP);
+	l1:	/* end ensureFrameIsMarried:SP: */;
+		/* begin divorceMachineCodeFramesWithMethod: */
+		/* begin cogMethodOf: */
+		methodHeader = longAt((methodObj + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+		assert((isNonIntegerObject(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		do {
+			if (GIV(stackPage) != 0) {
+				markStackPageMostRecentlyUsed(GIV(stackPage));
 			}
-			else {
-				decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-				if (((decodedIP & 1))
-				 && ((((sqInt) decodedIP)) < 0)) {
-					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
+			/* begin divorceSomeMachineCodeFramesWithMethod: */
+			divorcedSome1 = 0;
+			for (i1 = 0; i1 <= (GIV(numStackPages) - 1); i1 += 1) {
+				/* begin stackPageAt: */
+				aPage = stackPageAtpages(i1, GIV(pages));
+				if (!(isFree(aPage))) {
+					markStackPageMostRecentlyUsed(GIV(stackPage));
+					if (divorceAMachineCodeFrameWithCogMethodin(cogMethod, aPage)) {
+						divorcedSome1 = 1;
+					}
 				}
 			}
+			divorcedSome = divorcedSome1;
+		} while(divorcedSome);
+		/* begin ensureAllContextsWithMethodHaveBytecodePCs: */
+		VM_LABEL(0ensureAllContextsWithMethodHaveBytecodePCs);
+		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
+		while (oop < GIV(freeStart)) {
+			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
+			 && ((((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)
+			 && ((longAt((oop + BaseHeaderSize) + (MethodIndex << ShiftForWord))) == methodObj))) {
+				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
+					if (checkIsStillMarriedContextcurrentFP(oop, (GIV(stackPage)->headFP))) {
+						assert(!(isMachineCodeFrame(frameOfMarriedContext(oop))));
+					}
+				}
+				else {
+					/* begin ensureContextHasBytecodePC: */
+					assert(!(isMarriedOrWidowedContext(oop)));
+					pc = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
+					if (((pc & 1))
+					 && (((pc = (pc >> 1))) < 0)) {
+						pc = mustMapMachineCodePCcontext(pc, oop);
+						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), pc);
+					}
+				}
+			}
+			/* begin objectAfter: */
+			if (DoAssertionChecks) {
+				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
+					error("no objects after the end of memory");
+				}
+			}
+			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+				sz = (longAt(oop)) & AllButTypeMask;
+			}
+			else {
+				/* begin sizeBitsOf: */
+				header = longAt(oop);
+				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+					: header & SizeMask);
+			}
+			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
 		}
-		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
+		unlinkSendsToandFreeIf(methodObj, 1);
+		if ((((longAt((activeContext + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1))
+		 && (!(isWidowedContext(activeContext)))) {
+			/* begin frameOfMarriedContext: */
+			value = longAt((activeContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
+			/* begin withoutSmallIntegerTags: */
+			assert((value & 1));
+			theFrame = pointerForOop(value - 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));
+			thePage = stackPageAtpages(index, GIV(pages));
+			assert(((thePage->headFP)) == theFrame);
+			/* begin setStackPageAndLimit: */
+			GIV(stackPage) = thePage;
+			if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
+				GIV(stackLimit) = (GIV(stackPage)->stackLimit);
 			}
+			markStackPageMostRecentlyUsed(thePage);
+			GIV(stackPointer) = (thePage->headSP);
+			GIV(framePointer) = (thePage->headFP);
+			/* begin popStack */
+			top = longAt(GIV(stackPointer));
+			GIV(stackPointer) += BytesPerWord;
+			GIV(instructionPointer) = ((sqInt) top);
+			assert(methodObj == (stackTop()));
 		}
-		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-			sz = (longAt(oop)) & AllButTypeMask;
-		}
 		else {
-			/* begin sizeBitsOf: */
-			header = longAt(oop);
-			sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-				? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-				: header & SizeMask);
+
+			/* to avoid assert in marryContextInNewStackPageAndInitializeInterpreterRegisters: */
+
+			GIV(stackPage) = 0;
+			marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
+			/* begin popStack */
+			top1 = longAt(GIV(stackPointer));
+			GIV(stackPointer) += BytesPerWord;
+			assert(methodObj == (stackTop()));
+			siglongjmp(reenterInterpreter, ReturnToInterpreter);
 		}
-		oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
 	}
-	voidCogCompiledCode();
-	activeContext = activeContext1;
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
-	siglongjmp(reenterInterpreter, ReturnToInterpreter);
 }
 
 static void
@@ -38816,7 +38842,7 @@
 			printf("\n");
 		}
 		else {
-			print("widdowed (assuming framePointer valid)");
+			print("widowed (assuming framePointer valid)");
 			/* begin cr */
 			printf("\n");
 		}
@@ -40064,6 +40090,17 @@
 		goto l2;
 	}
 	printf("a(n) %.*s", nameLen, name);
+	if (((instanceSizeOf(classOop)) == (ValueIndex + 1))
+	 && (((longAt((classOop + BaseHeaderSize) + (SuperclassIndex << ShiftForWord))) == (superclassOf(fetchClassOfNonInt(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))))))
+	 && ((((longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord))) & 1) == 0)
+	 && (((((usqInt) (longAt(longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord))))) >> 8) & 15) >= 8)))) {
+		/* begin space */
+		/* begin printChar: */
+		putchar(' ');
+		printOopShort(longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord)));
+		print(" -> ");
+		printHex(longAt((oop + BaseHeaderSize) + (ValueIndex << ShiftForWord)));
+	}
 l2:	/* end printOopShortInner: */;
 	flush();
 }
@@ -43231,26 +43268,20 @@
 snapshot(sqInt embedded)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
     sqInt activeProc;
-    sqInt aMethodObj;
     sqInt dataSize;
-    sqInt decodedIP;
     sqInt fmt;
     sqInt header;
     sqInt header1;
     sqInt header2;
-    sqInt header3;
     sqInt i;
     sqInt i1;
-    StackPage *newPage;
     sqInt object;
     sqInt object1;
     sqInt oop;
     sqInt oop1;
     sqInt oop2;
     sqInt oop3;
-    sqInt oop4;
     sqInt rcvr;
     void *setMacType;
     char *sp;
@@ -43259,61 +43290,12 @@
     sqInt stackIndex;
     sqInt sz;
     sqInt sz1;
-    sqInt sz2;
-    char *theFP;
-    sqInt top;
 
 	/* begin push: */
 	object1 = GIV(instructionPointer);
 	longAtput((sp2 = GIV(stackPointer) - BytesPerWord), object1);
 	GIV(stackPointer) = sp2;
-	/* begin voidVMStateForSnapshot */
-
-	/* in case of code compactions. */
-
-	GIV(instructionPointer) = 0;
-	activeContext1 = divorceAllFrames();
-	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-	VM_LABEL(3ensureAllContextsHaveBytecodePCsOrAreBereaved);
-	oop4 = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-	while (oop4 < GIV(freeStart)) {
-		if ((!(((longAt(oop4)) & TypeMask) == HeaderTypeFree))
-		 && (((((usqInt) (longAt(oop4))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-			if (((longAt((oop4 + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-				/* begin markContextAsDead: */
-				assert(isContext(oop4));
-				longAtput((oop4 + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-				longAtput((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-			}
-			else {
-				decodedIP = longAt((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-				if (((decodedIP & 1))
-				 && ((((sqInt) decodedIP)) < 0)) {
-					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop4);
-					longAtput((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-				}
-			}
-		}
-		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop4)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
-			}
-		}
-		if (((longAt(oop4)) & TypeMask) == HeaderTypeFree) {
-			sz2 = (longAt(oop4)) & AllButTypeMask;
-		}
-		else {
-			/* begin sizeBitsOf: */
-			header3 = longAt(oop4);
-			sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
-				? (longAt(oop4 - (BytesPerWord * 2))) & LongSizeMask
-				: header3 & SizeMask);
-		}
-		oop4 = (oop4 + sz2) + (headerTypeBytes[(longAt(oop4 + sz2)) & TypeMask]);
-	}
-	voidCogCompiledCode();
-	activeContext = activeContext1;
+	activeContext = voidVMStateForSnapshot();
 	/* begin pushRemappableOop: */
 	assert(addressCouldBeOop(activeContext));
 	GIV(remapBuffer)[(GIV(remapBufferCount) += 1)] = activeContext;
@@ -43416,37 +43398,7 @@
 		}
 		longAtput((activeContext + BaseHeaderSize) + (StackPointerIndex << ShiftForWord), (((stackIndex - 1) << 1) | 1));
 	}
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(4marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	if (!GIV(primFailCode)) {
 		/* begin push: */
 		object = GIV(falseObj);
@@ -44586,7 +44538,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(18ensureFrameIsMarriedSP);
+	VM_LABEL(20ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -45211,7 +45163,7 @@
 	sched = longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord));
 	oldProc = longAt((sched + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(19ensureFrameIsMarriedSP);
+	VM_LABEL(21ensureFrameIsMarriedSP);
 	theFP = GIV(framePointer);
 	theSP = GIV(stackPointer);
 	if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -46084,6 +46036,70 @@
 }
 
 
+/*	Make sure that all VM state that affects the heap contents is voided so
+	that the heap is ready
+	to be snapshotted. Answer the activeContext object that should be stored
+	in the snapshot.
+ */
+
+static sqInt
+voidVMStateForSnapshot(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt activeContext;
+    sqInt decodedIP;
+    sqInt header;
+    sqInt oop;
+    sqInt sz;
+
+
+	/* in case of code compactions. */
+
+	GIV(instructionPointer) = 0;
+	activeContext = divorceAllFrames();
+	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
+	VM_LABEL(0ensureAllContextsHaveBytecodePCsOrAreBereaved);
+	oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
+	while (oop < GIV(freeStart)) {
+		if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
+		 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
+			if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
+				/* begin markContextAsDead: */
+				assert(isContext(oop));
+				longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
+				longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
+			}
+			else {
+				decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
+				if (((decodedIP & 1))
+				 && ((((sqInt) decodedIP)) < 0)) {
+					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
+					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
+				}
+			}
+		}
+		/* begin objectAfter: */
+		if (DoAssertionChecks) {
+			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
+				error("no objects after the end of memory");
+			}
+		}
+		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+			sz = (longAt(oop)) & AllButTypeMask;
+		}
+		else {
+			/* begin sizeBitsOf: */
+			header = longAt(oop);
+			sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+				? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+				: header & SizeMask);
+		}
+		oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
+	}
+	voidCogCompiledCode();
+	return activeContext;
+}
+
+
 /*	Return the highest priority process that is ready to run.
 	To save time looking at many empty lists before finding a
 	runnable process the VM maintains a variable holding the
@@ -46293,6 +46309,7 @@
 	{"", "primitiveLessThanLargeIntegers", (void*)primitiveLessThanLargeIntegers},
 	{"", "primitiveLongRunningPrimitive", (void*)primitiveLongRunningPrimitive},
 	{"", "primitiveLongRunningPrimitiveSemaphore", (void*)primitiveLongRunningPrimitiveSemaphore},
+	{"", "primitiveMethodXray", (void*)primitiveMethodXray},
 	{"", "primitiveMillisecondClockMask", (void*)primitiveMillisecondClockMask},
 	{"", "primitiveModLargeIntegers", (void*)primitiveModLargeIntegers},
 	{"", "primitiveMultiplyLargeIntegers", (void*)primitiveMultiplyLargeIntegers},

Modified: branches/Cog/nscogsrc/vm/cointerp.h
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.h	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/nscogsrc/vm/cointerp.h	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,5 +1,7 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGeneratorGlobalStructure eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
 
 

Modified: branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2012-04-13 17:44:17 UTC (rev 2548)
@@ -2,11 +2,17 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGeneratorGlobalStructure eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
    from
-	CoInterpreter VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CoInterpreter eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -214,6 +220,7 @@
 #define ImmutabilityBit 0x20000000
 #define InstanceSpecificationIndex 2
 #define InstructionPointerIndex 1
+#define KeyIndex 0
 #define LargeContextBit 0x40000
 #define LargeContextBytes 252
 #define LargeContextSize 252
@@ -466,6 +473,7 @@
 static void displayBitsOfLeftTopRightBottom(sqInt aForm, sqInt l, sqInt t, sqInt r, sqInt b);
 sqInt displayObject(void);
 static sqInt divorceAllFrames(void);
+static sqInt divorceAMachineCodeFrameWithCogMethodin(CogMethod *cogMethod, StackPage *aStackPage);
 static void divorceFramesIn(StackPage *aStackPage);
 static sqInt doPrimitiveDivby(sqInt rcvr, sqInt arg);
 static sqInt doPrimitiveModby(sqInt rcvr, sqInt arg);
@@ -678,6 +686,7 @@
 static void markStackPageMostRecentlyUsed(StackPage *page);
 static void markStackPageNextMostRecentlyUsed(StackPage *page);
 static sqInt marriedContextpointsTostackDeltaForCurrentFrame(sqInt spouseContext, sqInt anOop, sqInt stackDeltaForCurrentFrame);
+static void marryContextInNewStackPageAndInitializeInterpreterRegisters(sqInt aContext);
 static sqInt marryFrameSP(char *theFP, char *theSP);
 static void maybeFlagMethodAsInterpreted(sqInt aMethod);
 sqInt maybeSplObj(sqInt index);
@@ -884,6 +893,7 @@
 static void primitiveMarkUnwindMethod(void);
 static void primitiveMaxIdentityHash(void);
 sqInt primitiveMethod(void);
+EXPORT(void) primitiveMethodXray(void);
 static void primitiveMillisecondClock(void);
 EXPORT(sqInt) primitiveMillisecondClockMask(void);
 static void primitiveMod(void);
@@ -975,6 +985,7 @@
 static void primitiveVMProfileSamplesInto(void);
 EXPORT(void) primitiveVoidReceiver(void);
 static void primitiveVoidVMState(void);
+static void primitiveVoidVMStateForMethod(void);
 static void primitiveWait(void);
 static void primitiveYield(void);
 void * primTraceLogAddress(void);
@@ -1145,6 +1156,7 @@
 static void verifyCleanHeaders(void);
 sqInt vmEndianness(void);
 static void voidLongRunningPrimitive(char *reason);
+static sqInt voidVMStateForSnapshot(void);
 static sqInt wakeHighestPriority(void);
 static sqInt withSmallIntegerTags(char *value);
 static sqInt wordSwapped(sqInt w);
@@ -1167,12 +1179,12 @@
 _iss sqInt nilObj;
 _iss usqInt method;
 _iss usqInt instructionPointer;
+_iss sqInt argumentCount;
 _iss usqInt freeStart;
-_iss sqInt argumentCount;
 _iss usqInt newMethod;
 _iss sqInt messageSelector;
+_iss StackPage * pages;
 _iss usqInt youngStart;
-_iss StackPage * pages;
 _iss char * stackBasePlus1;
 _iss usqInt endOfMemory;
 _iss sqInt rootTableCount;
@@ -1182,15 +1194,15 @@
 _iss sqInt falseObj;
 _iss sqInt bytesPerPage;
 _iss sqInt traceLogIndex;
+_iss usqInt reserveStart;
 _iss char * stackLimit;
-_iss usqInt reserveStart;
 _iss usqInt memoryLimit;
 _iss StackPage * mostRecentlyUsedPage;
 _iss sqInt needGCFlag;
 _iss usqInt scavengeThreshold;
+_iss sqInt numStackPages;
 _iss unsigned char primTraceLogIndex;
 _iss sqLong nextProfileTick;
-_iss sqInt numStackPages;
 _iss sqInt jmpDepth;
 _iss usqInt fwdTableNext;
 _iss sqInt longRunningPrimitiveCheckSemaphore;
@@ -1550,7 +1562,7 @@
 	/* 212 */ primitiveContextSize,
 	/* 213 */ primitiveContextXray,
 	/* 214 */ primitiveVoidVMState,
-	/* 215 */ (void (*)(void))0,
+	/* 215 */ primitiveVoidVMStateForMethod,
 	/* 216 */ (void (*)(void))0,
 	/* 217 */ (void (*)(void))0,
 	/* 218 */ primitiveDoNamedPrimitiveWithArgs,
@@ -1913,7 +1925,9 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.154";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_eneraiton.
+
+VMMaker.oscog-eem.156";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -13810,6 +13824,55 @@
 	return activeContext;
 }
 
+
+/*	Divorce at most one frame in the current page (since the divorce may cause
+	the page to be split)
+	and answer whether a frame was divorced. */
+
+static sqInt
+divorceAMachineCodeFrameWithCogMethodin(CogMethod *cogMethod, StackPage *aStackPage)
+{
+    char *calleeFP;
+    sqInt theContext;
+    char *theFP;
+    char *theSP;
+
+	theFP = (aStackPage->headFP);
+	theSP = (aStackPage->headSP);
+
+	/* theSP points at hottest item on frame's stack */
+
+	theSP += BytesPerWord;
+	while (1) {
+		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase)
+		 && (cogMethod == (mframeHomeMethod(theFP)))) {
+			/* begin ensureFrameIsMarried:SP: */
+			VM_LABEL(11ensureFrameIsMarriedSP);
+			if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
+				? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+				: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
+				assert(isContext(frameContext(theFP)));
+				theContext = longAt(theFP + FoxThisContext);
+				goto l1;
+			}
+			theContext = marryFrameSP(theFP, theSP);
+		l1:	/* end ensureFrameIsMarried:SP: */;
+			externalDivorceFrameandContext(theFP, theContext);
+			return 1;
+		}
+		calleeFP = theFP;
+		/* begin frameCallerFP: */
+		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
+		if (!(theFP != 0)) break;
+		/* begin frameCallerSP: */
+		assert(!(isBaseFrame(calleeFP)));
+		theSP = (calleeFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(calleeFP + FoxMethod)))) < heapBase
+	? (mframeCogMethod(calleeFP)->cmNumArgs)
+	: byteAt((calleeFP + FoxIFrameFlags) + 1))))) + BytesPerWord;
+	}
+	return 0;
+}
+
 static void
 divorceFramesIn(StackPage *aStackPage)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
@@ -13836,7 +13899,7 @@
 	calleeContext = null;
 	while (1) {
 		/* begin ensureFrameIsMarried:SP: */
-		VM_LABEL(11ensureFrameIsMarriedSP);
+		VM_LABEL(12ensureFrameIsMarriedSP);
 		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
 			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
@@ -14749,7 +14812,7 @@
 		return callerContextOrNil;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(12ensureFrameIsMarriedSP);
+	VM_LABEL(13ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -14795,6 +14858,7 @@
 {
     sqInt pc;
 
+	/* begin ensureContextHasBytecodePC: */
 	assert(!(isMarriedOrWidowedContext(aContext)));
 	pc = longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
 	if (((pc & 1))
@@ -15342,7 +15406,6 @@
     char *theSP1;
     sqInt valuePointer;
 
-	assert(theFP != GIV(framePointer));
 	assert((GIV(stackPage) == 0)
 	 || (GIV(stackPage) == (mostRecentlyUsedPage())));
 	/* begin stackPageFor: */
@@ -15376,7 +15439,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(13ensureFrameIsMarriedSP);
+	VM_LABEL(14ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP1 = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -15573,7 +15636,7 @@
 			return callerContextOrNil;
 		}
 		/* begin ensureFrameIsMarried:SP: */
-		VM_LABEL(14ensureFrameIsMarriedSP);
+		VM_LABEL(15ensureFrameIsMarriedSP);
 		/* begin frameCallerStackPointer: */
 		assert(!(isBaseFrame(spouseFP)));
 		theSP = (spouseFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(spouseFP + FoxMethod)))) < heapBase
@@ -16270,7 +16333,7 @@
 	: byteAt((theFPAbove + FoxIFrameFlags) + 1))))) + BytesPerWord;
 				}
 				/* begin ensureFrameIsMarried:SP: */
-				VM_LABEL(15ensureFrameIsMarriedSP);
+				VM_LABEL(16ensureFrameIsMarriedSP);
 				if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 					? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
 					: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
@@ -17685,7 +17748,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(16ensureFrameIsMarriedSP);
+	VM_LABEL(17ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -18981,13 +19044,9 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
     sqInt activeProc;
-    sqInt aMethodObj;
-    StackPage *newPage;
     sqInt stackPageBytes;
     sqInt stackPagesBytes;
-    char *theFP;
     char *theStackMemory;
-    sqInt top;
 
 	stackPageBytes = stackPageByteSize();
 	stackPagesBytes = (GIV(numStackPages) * ((sizeof(CogStackPage)) + (stackPageByteSize()))) + BytesPerWord;
@@ -19003,37 +19062,7 @@
 	}
 	activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	activeContext = longAt((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord));
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(0marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	ioInitHeartbeat();
 	initialEnterSmalltalkExecutive();
 	return null;
@@ -19840,7 +19869,8 @@
     StackPage *thePage;
     sqInt value;
 
-	assert(isContext(aOnceMarriedContext));
+	assert((isContext(aOnceMarriedContext))
+	 && (isMarriedOrWidowedContext(aOnceMarriedContext)));
 	/* begin frameOfMarriedContext: */
 	value = longAt((aOnceMarriedContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
 	/* begin withoutSmallIntegerTags: */
@@ -20623,13 +20653,9 @@
 
 void
 loadInitialContext(void)
-{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+{
     sqInt activeContext;
     sqInt activeProc;
-    sqInt aMethodObj;
-    StackPage *newPage;
-    char *theFP;
-    sqInt top;
 
 	if ((checkForLeaks & 1) != 0) {
 		clearLeakMapAndMapAccessibleObjects();
@@ -20637,37 +20663,7 @@
 	}
 	activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	activeContext = longAt((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord));
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(1marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 }
 
 void
@@ -22584,6 +22580,50 @@
 }
 
 
+/*	Establish aContext at the base of a new stackPage, make the stackPage the
+	active one and set-up the interreter registers. This is used to boot the
+	system and bring it back after a snapshot. */
+
+static void
+marryContextInNewStackPageAndInitializeInterpreterRegisters(sqInt aContext)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt aMethodObj;
+    StackPage *newPage;
+    char *theFP;
+    sqInt top;
+
+	assert(GIV(stackPage) == 0);
+	newPage = makeBaseFrameFor(aContext);
+	/* begin setStackPageAndLimit: */
+	GIV(stackPage) = newPage;
+	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
+		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
+	}
+	markStackPageMostRecentlyUsed(newPage);
+	GIV(framePointer) = (GIV(stackPage)->headFP);
+	GIV(stackPointer) = (GIV(stackPage)->headSP);
+	/* begin setMethod: */
+	/* begin iframeMethod: */
+	theFP = (GIV(stackPage)->headFP);
+	aMethodObj = longAt(theFP + FoxMethod);
+	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
+	GIV(method) = aMethodObj;
+	assert(isOopCompiledMethod(GIV(method)));
+	
+#  if MULTIPLEBYTECODESETS
+	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
+		? 256
+		: 0);
+
+#  endif /* MULTIPLEBYTECODESETS */
+
+	/* begin popStack */
+	top = longAt(GIV(stackPointer));
+	GIV(stackPointer) += BytesPerWord;
+	GIV(instructionPointer) = ((sqInt) top);
+}
+
+
 /*	Marry an unmarried frame. This means creating a spouse context initialized
 	with a subset of the frame's state (state through the last argument) that
 	references the
@@ -23087,7 +23127,7 @@
 	assert(frameHasContext(callerFP));
 	assert(isContext(frameContext(callerFP)));
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(17ensureFrameIsMarriedSP);
+	VM_LABEL(18ensureFrameIsMarriedSP);
 	theSP = theFP + (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 	? FoxMFReceiver
 	: FoxIFReceiver));
@@ -30173,7 +30213,7 @@
 	for (i1 = 1; i1 <= AtCacheTotalSize; i1 += 1) {
 		GIV(atCache)[i1] = 0;
 	}
-	unlinkSendsTo(longAt(GIV(stackPointer)));
+	unlinkSendsToandFreeIf(longAt(GIV(stackPointer)), 0);
 }
 
 
@@ -32433,18 +32473,9 @@
 primitiveLongRunningPrimitiveSemaphore(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
     sqInt flushState;
-    sqInt header;
-    StackPage *newPage;
-    sqInt oop;
     sqInt sema;
     char *sp;
-    sqInt sz;
-    char *theFP;
-    sqInt top;
 
 	sema = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	if (((sema & 1))
@@ -32474,84 +32505,8 @@
 		/* begin push: */
 		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp;
-		/* begin voidVMStateForSnapshot */
-
-		/* in case of code compactions. */
-
-		GIV(instructionPointer) = 0;
-		activeContext1 = divorceAllFrames();
-		/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-		VM_LABEL(0ensureAllContextsHaveBytecodePCsOrAreBereaved);
-		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-		while (oop < GIV(freeStart)) {
-			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-			 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-					/* begin markContextAsDead: */
-					assert(isContext(oop));
-					longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-				}
-				else {
-					decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-					if (((decodedIP & 1))
-					 && ((((sqInt) decodedIP)) < 0)) {
-						decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-					}
-				}
-			}
-			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
-			}
-			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-				sz = (longAt(oop)) & AllButTypeMask;
-			}
-			else {
-				/* begin sizeBitsOf: */
-				header = longAt(oop);
-				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-					: header & SizeMask);
-			}
-			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
-		}
-		voidCogCompiledCode();
-		activeContext = activeContext1;
-		/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-		VM_LABEL(2marryContextInNewStackPageAndInitializeInterpreterRegisters);
-		assert(GIV(stackPage) == 0);
-		newPage = makeBaseFrameFor(activeContext);
-		/* begin setStackPageAndLimit: */
-		GIV(stackPage) = newPage;
-		if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-			GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-		}
-		markStackPageMostRecentlyUsed(newPage);
-		GIV(framePointer) = (GIV(stackPage)->headFP);
-		GIV(stackPointer) = (GIV(stackPage)->headSP);
-		/* begin setMethod: */
-		/* begin iframeMethod: */
-		theFP = (GIV(stackPage)->headFP);
-		aMethodObj = longAt(theFP + FoxMethod);
-		assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-		GIV(method) = aMethodObj;
-		assert(isOopCompiledMethod(GIV(method)));
-		
-#    if MULTIPLEBYTECODESETS
-		bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-			? 256
-			: 0);
-
-#    endif /* MULTIPLEBYTECODESETS */
-
-		/* begin popStack */
-		top = longAt(GIV(stackPointer));
-		GIV(stackPointer) += BytesPerWord;
-		GIV(instructionPointer) = ((sqInt) top);
+		activeContext = voidVMStateForSnapshot();
+		marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 		assert((((stackValue(0)) == (nilObject()))
  && (GIV(longRunningPrimitiveCheckSemaphore) == null))
 		 || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore))
@@ -32718,6 +32673,49 @@
 }
 
 
+/*	Lift the veil from a method and answer an integer describing the interior
+	state of its machine code.
+	Used for e.g. VM tests so they can verify they're testing what they think
+	they're testing.
+	0 implies a vanilla method.
+	Bit 0 = method is currently compiled to machine code
+	Bit 1 = is compiled frameless.
+	Bit 2 = method refers to young object */
+
+EXPORT(void)
+primitiveMethodXray(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt aMethodOop;
+    CogMethod *cogMethod;
+    sqInt flags;
+    sqInt methodHeader;
+    char *sp;
+
+	if ((((longAt(GIV(stackPointer))) & 1) == 0)
+	 && ((((((usqInt) (longAt(longAt(GIV(stackPointer))))) >> 8) & 15) >= 12)
+	 && (isCogMethodReference(longAt(((longAt(GIV(stackPointer))) + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
+		/* begin cogMethodOf: */
+		aMethodOop = longAt(GIV(stackPointer));
+		methodHeader = longAt((aMethodOop + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+		assert((isNonIntegerObject(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		flags = (((cogMethod->stackCheckOffset)) == 0
+			? 3
+			: 1);
+		if ((cogMethod->cmRefersToYoung)) {
+			flags += 4;
+		}
+	}
+	else {
+		flags = 0;
+	}
+	/* begin pop:thenPush: */
+	longAtput((sp = GIV(stackPointer) + ((1 - 1) * BytesPerWord)), ((flags << 1) | 1));
+	GIV(stackPointer) = sp;
+}
+
+
 /*	Return the value of the millisecond clock as an integer. Note that the
 	millisecond clock wraps around periodically. On some platforms it can wrap
 	daily. The range is limited to SmallInteger maxVal / 2 to allow delays of
@@ -33993,18 +33991,9 @@
 primitiveProfileSemaphore(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
     sqInt flushState;
-    sqInt header;
-    StackPage *newPage;
-    sqInt oop;
     sqInt sema;
     char *sp;
-    sqInt sz;
-    char *theFP;
-    sqInt top;
 
 	sema = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	if (((sema & 1))
@@ -34039,84 +34028,8 @@
 		/* begin push: */
 		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp;
-		/* begin voidVMStateForSnapshot */
-
-		/* in case of code compactions. */
-
-		GIV(instructionPointer) = 0;
-		activeContext1 = divorceAllFrames();
-		/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-		VM_LABEL(1ensureAllContextsHaveBytecodePCsOrAreBereaved);
-		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-		while (oop < GIV(freeStart)) {
-			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-			 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-					/* begin markContextAsDead: */
-					assert(isContext(oop));
-					longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-				}
-				else {
-					decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-					if (((decodedIP & 1))
-					 && ((((sqInt) decodedIP)) < 0)) {
-						decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-					}
-				}
-			}
-			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
-			}
-			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-				sz = (longAt(oop)) & AllButTypeMask;
-			}
-			else {
-				/* begin sizeBitsOf: */
-				header = longAt(oop);
-				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-					: header & SizeMask);
-			}
-			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
-		}
-		voidCogCompiledCode();
-		activeContext = activeContext1;
-		/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-		VM_LABEL(3marryContextInNewStackPageAndInitializeInterpreterRegisters);
-		assert(GIV(stackPage) == 0);
-		newPage = makeBaseFrameFor(activeContext);
-		/* begin setStackPageAndLimit: */
-		GIV(stackPage) = newPage;
-		if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-			GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-		}
-		markStackPageMostRecentlyUsed(newPage);
-		GIV(framePointer) = (GIV(stackPage)->headFP);
-		GIV(stackPointer) = (GIV(stackPage)->headSP);
-		/* begin setMethod: */
-		/* begin iframeMethod: */
-		theFP = (GIV(stackPage)->headFP);
-		aMethodObj = longAt(theFP + FoxMethod);
-		assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-		GIV(method) = aMethodObj;
-		assert(isOopCompiledMethod(GIV(method)));
-		
-#    if MULTIPLEBYTECODESETS
-		bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-			? 256
-			: 0);
-
-#    endif /* MULTIPLEBYTECODESETS */
-
-		/* begin popStack */
-		top = longAt(GIV(stackPointer));
-		GIV(stackPointer) += BytesPerWord;
-		GIV(instructionPointer) = ((sqInt) top);
+		activeContext = voidVMStateForSnapshot();
+		marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 		assert((((stackValue(0)) == (nilObject()))
  && (GIV(profileSemaphore) == (nilObject())))
 		 || (((stackValue(0)) == GIV(profileSemaphore))
@@ -38141,98 +38054,211 @@
 primitiveVoidVMState(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
+    char *sp;
+
+	/* begin push: */
+	longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+	GIV(stackPointer) = sp;
+	activeContext = voidVMStateForSnapshot();
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
+	siglongjmp(reenterInterpreter, ReturnToInterpreter);
+}
+
+
+/*	The receiver is a compiledMethod. Clear all entries in the method lookup
+	cache that refer to this method, presumably because it has been redefined,
+	overridden or removed.
+ */
+/*	The receiver is a compiledMethod. Clear all VM state associated with the
+	method, including any machine code, or machine code pcs in context
+	objects.  */
+
+static void
+primitiveVoidVMStateForMethod(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt activeContext;
+    StackPage *aPage;
+    CogMethod *cogMethod;
+    sqInt divorcedSome;
+    sqInt divorcedSome1;
     sqInt header;
-    StackPage *newPage;
+    sqInt i;
+    sqInt i1;
+    sqInt i2;
+    sqInt index;
+    sqInt methodHeader;
+    sqInt methodObj;
+    sqInt oldMethod;
     sqInt oop;
+    sqInt pc;
+    sqInt primBits;
+    sqInt primIdx;
+    sqInt probe;
     char *sp;
     sqInt sz;
     char *theFP;
+    char *theFrame;
+    StackPage *thePage;
+    char *theSP;
     sqInt top;
+    sqInt top1;
+    sqInt value;
 
-	/* begin push: */
-	longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
-	GIV(stackPointer) = sp;
-	/* begin voidVMStateForSnapshot */
-
-	/* in case of code compactions. */
-
-	GIV(instructionPointer) = 0;
-	activeContext1 = divorceAllFrames();
-	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-	VM_LABEL(2ensureAllContextsHaveBytecodePCsOrAreBereaved);
-	oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-	while (oop < GIV(freeStart)) {
-		if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-		 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-			if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-				/* begin markContextAsDead: */
-				assert(isContext(oop));
-				longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-				longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
+	oldMethod = longAt(GIV(stackPointer));
+	probe = 0;
+	for (i = 1; i <= MethodCacheEntries; i += 1) {
+		if ((GIV(methodCache)[probe + MethodCacheMethod]) == oldMethod) {
+			GIV(methodCache)[probe + MethodCacheSelector] = 0;
+		}
+		probe += MethodCacheEntrySize;
+	}
+	/* begin primitiveIndexOf: */
+	primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
+	primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
+	if (primIdx == PrimitiveExternalCallIndex) {
+		flushExternalPrimitiveOf(oldMethod);
+	}
+	/* begin flushAtCache */
+	for (i2 = 1; i2 <= AtCacheTotalSize; i2 += 1) {
+		GIV(atCache)[i2] = 0;
+	}
+	if (methodHasCogMethod(longAt(GIV(stackPointer)))) {
+		methodObj = longAt(GIV(stackPointer));
+		/* begin push: */
+		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+		GIV(stackPointer) = sp;
+		/* begin externalWriteBackHeadFramePointers */
+		assert((GIV(framePointer) - GIV(stackPointer)) < LargeContextSize);
+		assert(GIV(stackPage) == (mostRecentlyUsedPage()));
+		/* begin setHeadFP:andSP:inPage: */
+		assert(GIV(stackPointer) < GIV(framePointer));
+		assert((GIV(stackPointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(stackPointer) > (((GIV(stackPage)->realStackLimit)) - LargeContextSize)));
+		assert((GIV(framePointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(framePointer) > (((GIV(stackPage)->realStackLimit)) - (((sqInt) LargeContextSize >> 1)))));
+		(GIV(stackPage)->headFP = GIV(framePointer));
+		(GIV(stackPage)->headSP = GIV(stackPointer));
+		assert(pageListIsWellFormed());
+		/* begin ensureFrameIsMarried:SP: */
+		VM_LABEL(19ensureFrameIsMarriedSP);
+		theFP = GIV(framePointer);
+		theSP = GIV(stackPointer);
+		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
+			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
+			assert(isContext(frameContext(theFP)));
+			activeContext = longAt(theFP + FoxThisContext);
+			goto l1;
+		}
+		activeContext = marryFrameSP(theFP, theSP);
+	l1:	/* end ensureFrameIsMarried:SP: */;
+		/* begin divorceMachineCodeFramesWithMethod: */
+		/* begin cogMethodOf: */
+		methodHeader = longAt((methodObj + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+		assert((isNonIntegerObject(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		do {
+			if (GIV(stackPage) != 0) {
+				markStackPageMostRecentlyUsed(GIV(stackPage));
 			}
-			else {
-				decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-				if (((decodedIP & 1))
-				 && ((((sqInt) decodedIP)) < 0)) {
-					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
+			/* begin divorceSomeMachineCodeFramesWithMethod: */
+			divorcedSome1 = 0;
+			for (i1 = 0; i1 <= (GIV(numStackPages) - 1); i1 += 1) {
+				/* begin stackPageAt: */
+				aPage = stackPageAtpages(i1, GIV(pages));
+				if (!(isFree(aPage))) {
+					markStackPageMostRecentlyUsed(GIV(stackPage));
+					if (divorceAMachineCodeFrameWithCogMethodin(cogMethod, aPage)) {
+						divorcedSome1 = 1;
+					}
 				}
 			}
+			divorcedSome = divorcedSome1;
+		} while(divorcedSome);
+		/* begin ensureAllContextsWithMethodHaveBytecodePCs: */
+		VM_LABEL(0ensureAllContextsWithMethodHaveBytecodePCs);
+		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
+		while (oop < GIV(freeStart)) {
+			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
+			 && ((((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)
+			 && ((longAt((oop + BaseHeaderSize) + (MethodIndex << ShiftForWord))) == methodObj))) {
+				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
+					if (checkIsStillMarriedContextcurrentFP(oop, (GIV(stackPage)->headFP))) {
+						assert(!(isMachineCodeFrame(frameOfMarriedContext(oop))));
+					}
+				}
+				else {
+					/* begin ensureContextHasBytecodePC: */
+					assert(!(isMarriedOrWidowedContext(oop)));
+					pc = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
+					if (((pc & 1))
+					 && (((pc = (pc >> 1))) < 0)) {
+						pc = mustMapMachineCodePCcontext(pc, oop);
+						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), pc);
+					}
+				}
+			}
+			/* begin objectAfter: */
+			if (DoAssertionChecks) {
+				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
+					error("no objects after the end of memory");
+				}
+			}
+			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+				sz = (longAt(oop)) & AllButTypeMask;
+			}
+			else {
+				/* begin sizeBitsOf: */
+				header = longAt(oop);
+				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+					: header & SizeMask);
+			}
+			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
 		}
-		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
+		unlinkSendsToandFreeIf(methodObj, 1);
+		if ((((longAt((activeContext + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1))
+		 && (!(isWidowedContext(activeContext)))) {
+			/* begin frameOfMarriedContext: */
+			value = longAt((activeContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
+			/* begin withoutSmallIntegerTags: */
+			assert((value & 1));
+			theFrame = pointerForOop(value - 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));
+			thePage = stackPageAtpages(index, GIV(pages));
+			assert(((thePage->headFP)) == theFrame);
+			/* begin setStackPageAndLimit: */
+			GIV(stackPage) = thePage;
+			if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
+				GIV(stackLimit) = (GIV(stackPage)->stackLimit);
 			}
+			markStackPageMostRecentlyUsed(thePage);
+			GIV(stackPointer) = (thePage->headSP);
+			GIV(framePointer) = (thePage->headFP);
+			/* begin popStack */
+			top = longAt(GIV(stackPointer));
+			GIV(stackPointer) += BytesPerWord;
+			GIV(instructionPointer) = ((sqInt) top);
+			assert(methodObj == (stackTop()));
 		}
-		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-			sz = (longAt(oop)) & AllButTypeMask;
-		}
 		else {
-			/* begin sizeBitsOf: */
-			header = longAt(oop);
-			sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-				? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-				: header & SizeMask);
+
+			/* to avoid assert in marryContextInNewStackPageAndInitializeInterpreterRegisters: */
+
+			GIV(stackPage) = 0;
+			marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
+			/* begin popStack */
+			top1 = longAt(GIV(stackPointer));
+			GIV(stackPointer) += BytesPerWord;
+			assert(methodObj == (stackTop()));
+			siglongjmp(reenterInterpreter, ReturnToInterpreter);
 		}
-		oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
 	}
-	voidCogCompiledCode();
-	activeContext = activeContext1;
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
-	siglongjmp(reenterInterpreter, ReturnToInterpreter);
 }
 
 static void
@@ -38820,7 +38846,7 @@
 			printf("\n");
 		}
 		else {
-			print("widdowed (assuming framePointer valid)");
+			print("widowed (assuming framePointer valid)");
 			/* begin cr */
 			printf("\n");
 		}
@@ -40068,6 +40094,17 @@
 		goto l2;
 	}
 	printf("a(n) %.*s", nameLen, name);
+	if (((instanceSizeOf(classOop)) == (ValueIndex + 1))
+	 && (((longAt((classOop + BaseHeaderSize) + (SuperclassIndex << ShiftForWord))) == (superclassOf(fetchClassOfNonInt(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))))))
+	 && ((((longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord))) & 1) == 0)
+	 && (((((usqInt) (longAt(longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord))))) >> 8) & 15) >= 8)))) {
+		/* begin space */
+		/* begin printChar: */
+		putchar(' ');
+		printOopShort(longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord)));
+		print(" -> ");
+		printHex(longAt((oop + BaseHeaderSize) + (ValueIndex << ShiftForWord)));
+	}
 l2:	/* end printOopShortInner: */;
 	flush();
 }
@@ -43235,26 +43272,20 @@
 snapshot(sqInt embedded)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
     sqInt activeProc;
-    sqInt aMethodObj;
     sqInt dataSize;
-    sqInt decodedIP;
     sqInt fmt;
     sqInt header;
     sqInt header1;
     sqInt header2;
-    sqInt header3;
     sqInt i;
     sqInt i1;
-    StackPage *newPage;
     sqInt object;
     sqInt object1;
     sqInt oop;
     sqInt oop1;
     sqInt oop2;
     sqInt oop3;
-    sqInt oop4;
     sqInt rcvr;
     void *setMacType;
     char *sp;
@@ -43263,61 +43294,12 @@
     sqInt stackIndex;
     sqInt sz;
     sqInt sz1;
-    sqInt sz2;
-    char *theFP;
-    sqInt top;
 
 	/* begin push: */
 	object1 = GIV(instructionPointer);
 	longAtput((sp2 = GIV(stackPointer) - BytesPerWord), object1);
 	GIV(stackPointer) = sp2;
-	/* begin voidVMStateForSnapshot */
-
-	/* in case of code compactions. */
-
-	GIV(instructionPointer) = 0;
-	activeContext1 = divorceAllFrames();
-	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-	VM_LABEL(3ensureAllContextsHaveBytecodePCsOrAreBereaved);
-	oop4 = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-	while (oop4 < GIV(freeStart)) {
-		if ((!(((longAt(oop4)) & TypeMask) == HeaderTypeFree))
-		 && (((((usqInt) (longAt(oop4))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-			if (((longAt((oop4 + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-				/* begin markContextAsDead: */
-				assert(isContext(oop4));
-				longAtput((oop4 + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-				longAtput((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-			}
-			else {
-				decodedIP = longAt((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-				if (((decodedIP & 1))
-				 && ((((sqInt) decodedIP)) < 0)) {
-					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop4);
-					longAtput((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-				}
-			}
-		}
-		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop4)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
-			}
-		}
-		if (((longAt(oop4)) & TypeMask) == HeaderTypeFree) {
-			sz2 = (longAt(oop4)) & AllButTypeMask;
-		}
-		else {
-			/* begin sizeBitsOf: */
-			header3 = longAt(oop4);
-			sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
-				? (longAt(oop4 - (BytesPerWord * 2))) & LongSizeMask
-				: header3 & SizeMask);
-		}
-		oop4 = (oop4 + sz2) + (headerTypeBytes[(longAt(oop4 + sz2)) & TypeMask]);
-	}
-	voidCogCompiledCode();
-	activeContext = activeContext1;
+	activeContext = voidVMStateForSnapshot();
 	/* begin pushRemappableOop: */
 	assert(addressCouldBeOop(activeContext));
 	GIV(remapBuffer)[(GIV(remapBufferCount) += 1)] = activeContext;
@@ -43420,37 +43402,7 @@
 		}
 		longAtput((activeContext + BaseHeaderSize) + (StackPointerIndex << ShiftForWord), (((stackIndex - 1) << 1) | 1));
 	}
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(4marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	if (!GIV(primFailCode)) {
 		/* begin push: */
 		object = GIV(falseObj);
@@ -44590,7 +44542,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(18ensureFrameIsMarriedSP);
+	VM_LABEL(20ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -45215,7 +45167,7 @@
 	sched = longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord));
 	oldProc = longAt((sched + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(19ensureFrameIsMarriedSP);
+	VM_LABEL(21ensureFrameIsMarriedSP);
 	theFP = GIV(framePointer);
 	theSP = GIV(stackPointer);
 	if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -46088,6 +46040,70 @@
 }
 
 
+/*	Make sure that all VM state that affects the heap contents is voided so
+	that the heap is ready
+	to be snapshotted. Answer the activeContext object that should be stored
+	in the snapshot.
+ */
+
+static sqInt
+voidVMStateForSnapshot(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt activeContext;
+    sqInt decodedIP;
+    sqInt header;
+    sqInt oop;
+    sqInt sz;
+
+
+	/* in case of code compactions. */
+
+	GIV(instructionPointer) = 0;
+	activeContext = divorceAllFrames();
+	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
+	VM_LABEL(0ensureAllContextsHaveBytecodePCsOrAreBereaved);
+	oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
+	while (oop < GIV(freeStart)) {
+		if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
+		 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
+			if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
+				/* begin markContextAsDead: */
+				assert(isContext(oop));
+				longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
+				longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
+			}
+			else {
+				decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
+				if (((decodedIP & 1))
+				 && ((((sqInt) decodedIP)) < 0)) {
+					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
+					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
+				}
+			}
+		}
+		/* begin objectAfter: */
+		if (DoAssertionChecks) {
+			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
+				error("no objects after the end of memory");
+			}
+		}
+		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+			sz = (longAt(oop)) & AllButTypeMask;
+		}
+		else {
+			/* begin sizeBitsOf: */
+			header = longAt(oop);
+			sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+				? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+				: header & SizeMask);
+		}
+		oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
+	}
+	voidCogCompiledCode();
+	return activeContext;
+}
+
+
 /*	Return the highest priority process that is ready to run.
 	To save time looking at many empty lists before finding a
 	runnable process the VM maintains a variable holding the
@@ -46297,6 +46313,7 @@
 	{"", "primitiveLessThanLargeIntegers", (void*)primitiveLessThanLargeIntegers},
 	{"", "primitiveLongRunningPrimitive", (void*)primitiveLongRunningPrimitive},
 	{"", "primitiveLongRunningPrimitiveSemaphore", (void*)primitiveLongRunningPrimitiveSemaphore},
+	{"", "primitiveMethodXray", (void*)primitiveMethodXray},
 	{"", "primitiveMillisecondClockMask", (void*)primitiveMillisecondClockMask},
 	{"", "primitiveModLargeIntegers", (void*)primitiveModLargeIntegers},
 	{"", "primitiveMultiplyLargeIntegers", (void*)primitiveMultiplyLargeIntegers},

Modified: branches/Cog/nscogsrc/vm/interp.h
===================================================================
--- branches/Cog/nscogsrc/vm/interp.h	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/nscogsrc/vm/interp.h	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,5 +1,7 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGeneratorGlobalStructure eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
 
 #define VM_PROXY_MAJOR 1

Modified: branches/Cog/nscogsrc/vm/vmCallback.h
===================================================================
--- branches/Cog/nscogsrc/vm/vmCallback.h	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/nscogsrc/vm/vmCallback.h	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,5 +1,7 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGeneratorGlobalStructure eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
 
 #define VM_CALLBACK_INC 1


Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Sun Apr  8 15:41:40 PDT 2012
   + Fri Apr 13 10:40:28 PDT 2012

Modified: branches/Cog/platforms/Mac OS/vm/sqMacUIEventsUniversal.c
===================================================================
--- branches/Cog/platforms/Mac OS/vm/sqMacUIEventsUniversal.c	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/platforms/Mac OS/vm/sqMacUIEventsUniversal.c	2012-04-13 17:44:17 UTC (rev 2548)
@@ -469,7 +469,7 @@
 
     whatHappened = GetEventKind(event);
 
-	//fprintf(stderr,"\nAppEvent %i",whatHappened);
+	//fprintf(stderr,"\nAppEvent %i",whatHappened); fflush(stdout);
     switch (whatHappened)
     {
         case kEventAppActivated: {
@@ -558,7 +558,7 @@
         return result;
     GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL,sizeof(window), NULL, &window);
     whatHappened = GetEventKind(event);
-	//fprintf(stderr,"\nWindowEvent %i %i %i",whatHappened,IsWindowActive(window),windowIndexFromHandle((int)window));
+	//fprintf(stderr,"\nWindowEvent %i %i %i",whatHappened,IsWindowActive(window),windowIndexFromHandle((int)window)); fflush(stdout);
 	if (windowIndexFromHandle(window) == 0) 
 		return result;
     switch (whatHappened)
@@ -652,7 +652,7 @@
 	
 
 //	if (whatHappened != 5) 
-//		fprintf(stderr,"\nMouseEvent %i-%i ",whatHappened,windowActive);
+//		fprintf(stderr,"\nMouseEvent %i-%i ",whatHappened,windowActive); fflush(stdout);
 
 	if (!windowActive) {
 		if (whatHappened == kEventMouseDown)
@@ -766,7 +766,7 @@
             EventRef event, void* userData)
 {
 #pragma unused(myHandler,userData)
-    UInt32 whatHappened,keyCode;
+    UInt32 whatHappened,keyCode,keyChar;
 	SInt32 key;
     OSStatus result = eventNotHandledErr; /* report failure by default */
 	 
@@ -778,20 +778,22 @@
 		
     whatHappened = GetEventKind(event);
 	GetEventParameter (event, kEventParamKeyCode, typeUInt32,NULL, sizeof(typeUInt32), NULL, &keyCode);
-    switch (whatHappened)
-    {
+	/* See UCKeyTranslate in https://developer.apple.com/library/mac/#documentation/Carbon/reference/Unicode_Utilities_Ref/Reference/reference.html
+	 * for how to convert an event to one or more Unicode characters.
+	 */
+    switch (whatHappened) {
         case kEventRawKeyDown:
-			//fprintf(stdout,"\nrawkey down %i",ioMSecs());
+			//fprintf(stdout,"\nrawkey down %i",ioMSecs()); fflush(stdout);
 			addToKeyMap(keyCode, 0);	
             result = eventNotHandledErr;
             break;
         case kEventRawKeyRepeat:
-			//fprintf(stdout,"\nrawkey repeat %i",ioMSecs());
+			//fprintf(stdout,"\nrawkey repeat %i",ioMSecs()); fflush(stdout);
 			setRepeatInKeyMap(keyCode);
             result = eventNotHandledErr;
             break;
         case kEventRawKeyUp:
-			//fprintf(stdout,"\nrawkey up %i",ioMSecs());
+			//fprintf(stdout,"\nrawkey up %i",ioMSecs()); fflush(stdout);
 			key = findInKeyMap(keyCode);
 			if (key != -1) {
 				enterKeystroke ( EventTypeKeyboard,keyCode, EventKeyUp, 0, ModifierStateCarbon(event));
@@ -1458,7 +1460,7 @@
 	evt = (sqKeyboardEvent*) nextEventPut();
 
 	/* first the basics */
-	//fprintf(stdout,"\nKeyStroke time %i Type %i Value %i",ioMSecs(),pc,cc);
+	//fprintf(stdout,"\nKeyStroke time %i Type %i Value %i",ioMSecs(),pc,cc); fflush(stdout);
 	evt->type = type;
 	evt->timeStamp = ioMSecs() & MillisecondClockMask;
 	/* now the key code */
@@ -1495,7 +1497,7 @@
 
 static int addToKeyMap(int keyCode, int keyChar)
 {
-  //fprintf(stdout, "\nAddToKeyMap T %i c %i i %i",ioMSecs(),keyCode,keyMapSize);
+  // fprintf(stdout, "\nAddToKeyMap T %i code %i char %i i %i",ioMSecs(),keyCode,keyChar,keyMapSize); fflush(stdout);
   if (keyMapSize > KeyMapSize) { fprintf(stderr, "keymap overflow\n");  return -1; }
   keyMap[keyMapSize++]= (KeyMapping){ keyCode, keyChar, 0};
   return keyChar;
@@ -1532,7 +1534,7 @@
 {
   int idx= indexInKeyMap(keyCode);
   int keyChar= -1;
-  //fprintf(stdout, "\nremoveFromKeyMap T %i c %i i %i",ioMSecs(),keyCode,keyMapSize-1);
+  //fprintf(stdout, "\nremoveFromKeyMap T %i c %i i %i",ioMSecs(),keyCode,keyMapSize-1); fflush(stdout);
   if (idx == -1) { //fprintf(stderr, "keymap underflow\n");  
 		return -1; }
   keyChar= keyMap[idx].keyChar;

Modified: branches/Cog/src/vm/cogit.c
===================================================================
--- branches/Cog/src/vm/cogit.c	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/src/vm/cogit.c	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,9 +1,15 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGenerator eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	StackToRegisterMappingCogit eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01 " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -985,7 +991,7 @@
 static sqInt unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod);
 void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector);
 void unlinkSendsToFree(void);
-void unlinkSendsTo(sqInt targetMethodObject);
+void unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue);
 static sqInt unsignedShortAt(AbstractInstruction * self_in_unsignedShortAt, sqInt byteAddress);
 static void updateLabel(AbstractInstruction * self_in_updateLabel, AbstractInstruction *labelInstruction);
 static sqInt updateMaybeObjRefAt(sqInt mcpc);
@@ -16932,7 +16938,7 @@
 	could be affected. */
 
 void
-unlinkSendsTo(sqInt targetMethodObject)
+unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue)
 {
     CogMethod *cogMethod;
     sqInt freedPIC;
@@ -16961,6 +16967,9 @@
 		}
 		cogMethod = methodAfter(cogMethod);
 	}
+	if (freeIfTrue) {
+		freeMethod(targetMethod);
+	}
 	if (freedPIC) {
 		unlinkSendsToFree();
 	}

Modified: branches/Cog/src/vm/cogit.h
===================================================================
--- branches/Cog/src/vm/cogit.h	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/src/vm/cogit.h	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,5 +1,7 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGenerator eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
 
 
@@ -71,7 +73,7 @@
 void unlinkAllSends(void);
 void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector);
 void unlinkSendsToFree(void);
-void unlinkSendsTo(sqInt targetMethodObject);
+void unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue);
 void voidCogCompiledCode(void);
 
 

Modified: branches/Cog/src/vm/cogmethod.h
===================================================================
--- branches/Cog/src/vm/cogmethod.h	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/src/vm/cogmethod.h	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,5 +1,7 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGenerator eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
 
 typedef struct {

Modified: branches/Cog/src/vm/cointerp.c
===================================================================
--- branches/Cog/src/vm/cointerp.c	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/src/vm/cointerp.c	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,9 +1,15 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGeneratorGlobalStructure eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
    from
-	CoInterpreter VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CoInterpreter eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -209,6 +215,7 @@
 #define ImmutabilityBit 0x20000000
 #define InstanceSpecificationIndex 2
 #define InstructionPointerIndex 1
+#define KeyIndex 0
 #define LargeContextBit 0x40000
 #define LargeContextBytes 252
 #define LargeContextSize 252
@@ -458,6 +465,7 @@
 static void displayBitsOfLeftTopRightBottom(sqInt aForm, sqInt l, sqInt t, sqInt r, sqInt b);
 sqInt displayObject(void);
 static sqInt divorceAllFrames(void);
+static sqInt divorceAMachineCodeFrameWithCogMethodin(CogMethod *cogMethod, StackPage *aStackPage);
 static void divorceFramesIn(StackPage *aStackPage);
 static sqInt doPrimitiveDivby(sqInt rcvr, sqInt arg);
 static sqInt doPrimitiveModby(sqInt rcvr, sqInt arg);
@@ -666,6 +674,7 @@
 static void markStackPageMostRecentlyUsed(StackPage *page);
 static void markStackPageNextMostRecentlyUsed(StackPage *page);
 static sqInt marriedContextpointsTostackDeltaForCurrentFrame(sqInt spouseContext, sqInt anOop, sqInt stackDeltaForCurrentFrame);
+static void marryContextInNewStackPageAndInitializeInterpreterRegisters(sqInt aContext);
 static sqInt marryFrameSP(char *theFP, char *theSP);
 static void maybeFlagMethodAsInterpreted(sqInt aMethod);
 sqInt maybeSplObj(sqInt index);
@@ -871,6 +880,7 @@
 static void primitiveMarkUnwindMethod(void);
 static void primitiveMaxIdentityHash(void);
 sqInt primitiveMethod(void);
+EXPORT(void) primitiveMethodXray(void);
 static void primitiveMillisecondClock(void);
 EXPORT(sqInt) primitiveMillisecondClockMask(void);
 static void primitiveMod(void);
@@ -962,6 +972,7 @@
 static void primitiveVMProfileSamplesInto(void);
 EXPORT(void) primitiveVoidReceiver(void);
 static void primitiveVoidVMState(void);
+static void primitiveVoidVMStateForMethod(void);
 static void primitiveWait(void);
 static void primitiveYield(void);
 void * primTraceLogAddress(void);
@@ -1132,6 +1143,7 @@
 static void verifyCleanHeaders(void);
 sqInt vmEndianness(void);
 static void voidLongRunningPrimitive(char *reason);
+static sqInt voidVMStateForSnapshot(void);
 static sqInt wakeHighestPriority(void);
 static sqInt withSmallIntegerTags(char *value);
 static sqInt wordSwapped(sqInt w);
@@ -1151,8 +1163,8 @@
 _iss char * framePointer;
 _iss sqInt specialObjectsOop;
 _iss StackPage * stackPage;
+_iss sqInt nilObj;
 _iss usqInt method;
-_iss sqInt nilObj;
 _iss usqInt instructionPointer;
 _iss usqInt freeStart;
 _iss sqInt argumentCount;
@@ -1169,15 +1181,15 @@
 _iss sqInt lkupClass;
 _iss sqInt bytesPerPage;
 _iss sqInt traceLogIndex;
+_iss usqInt reserveStart;
 _iss char * stackLimit;
-_iss usqInt reserveStart;
 _iss usqInt memoryLimit;
 _iss StackPage * mostRecentlyUsedPage;
 _iss sqInt needGCFlag;
 _iss usqInt scavengeThreshold;
+_iss sqInt numStackPages;
 _iss unsigned char primTraceLogIndex;
 _iss sqLong nextProfileTick;
-_iss sqInt numStackPages;
 _iss sqInt jmpDepth;
 _iss usqInt fwdTableNext;
 _iss sqInt longRunningPrimitiveCheckSemaphore;
@@ -1537,7 +1549,7 @@
 	/* 212 */ primitiveContextSize,
 	/* 213 */ primitiveContextXray,
 	/* 214 */ primitiveVoidVMState,
-	/* 215 */ (void (*)(void))0,
+	/* 215 */ primitiveVoidVMStateForMethod,
 	/* 216 */ (void (*)(void))0,
 	/* 217 */ (void (*)(void))0,
 	/* 218 */ primitiveDoNamedPrimitiveWithArgs,
@@ -1900,7 +1912,9 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.154]";
+const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter eneraiton.
+
+VMMaker.oscog-eem.156]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -13426,6 +13440,55 @@
 	return activeContext;
 }
 
+
+/*	Divorce at most one frame in the current page (since the divorce may cause
+	the page to be split)
+	and answer whether a frame was divorced. */
+
+static sqInt
+divorceAMachineCodeFrameWithCogMethodin(CogMethod *cogMethod, StackPage *aStackPage)
+{
+    char *calleeFP;
+    sqInt theContext;
+    char *theFP;
+    char *theSP;
+
+	theFP = (aStackPage->headFP);
+	theSP = (aStackPage->headSP);
+
+	/* theSP points at hottest item on frame's stack */
+
+	theSP += BytesPerWord;
+	while (1) {
+		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase)
+		 && (cogMethod == (mframeHomeMethod(theFP)))) {
+			/* begin ensureFrameIsMarried:SP: */
+			VM_LABEL(11ensureFrameIsMarriedSP);
+			if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
+				? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+				: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
+				assert(isContext(frameContext(theFP)));
+				theContext = longAt(theFP + FoxThisContext);
+				goto l1;
+			}
+			theContext = marryFrameSP(theFP, theSP);
+		l1:	/* end ensureFrameIsMarried:SP: */;
+			externalDivorceFrameandContext(theFP, theContext);
+			return 1;
+		}
+		calleeFP = theFP;
+		/* begin frameCallerFP: */
+		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
+		if (!(theFP != 0)) break;
+		/* begin frameCallerSP: */
+		assert(!(isBaseFrame(calleeFP)));
+		theSP = (calleeFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(calleeFP + FoxMethod)))) < heapBase
+	? (mframeCogMethod(calleeFP)->cmNumArgs)
+	: byteAt((calleeFP + FoxIFrameFlags) + 1))))) + BytesPerWord;
+	}
+	return 0;
+}
+
 static void
 divorceFramesIn(StackPage *aStackPage)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
@@ -13452,7 +13515,7 @@
 	calleeContext = null;
 	while (1) {
 		/* begin ensureFrameIsMarried:SP: */
-		VM_LABEL(11ensureFrameIsMarriedSP);
+		VM_LABEL(12ensureFrameIsMarriedSP);
 		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
 			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
@@ -14365,7 +14428,7 @@
 		return callerContextOrNil;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(12ensureFrameIsMarriedSP);
+	VM_LABEL(13ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -14411,6 +14474,7 @@
 {
     sqInt pc;
 
+	/* begin ensureContextHasBytecodePC: */
 	assert(!(isMarriedOrWidowedContext(aContext)));
 	pc = longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
 	if (((pc & 1))
@@ -14902,7 +14966,6 @@
     char *theSP1;
     sqInt valuePointer;
 
-	assert(theFP != GIV(framePointer));
 	assert((GIV(stackPage) == 0)
 	 || (GIV(stackPage) == (mostRecentlyUsedPage())));
 	/* begin stackPageFor: */
@@ -14936,7 +14999,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(13ensureFrameIsMarriedSP);
+	VM_LABEL(14ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP1 = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -15133,7 +15196,7 @@
 			return callerContextOrNil;
 		}
 		/* begin ensureFrameIsMarried:SP: */
-		VM_LABEL(14ensureFrameIsMarriedSP);
+		VM_LABEL(15ensureFrameIsMarriedSP);
 		/* begin frameCallerStackPointer: */
 		assert(!(isBaseFrame(spouseFP)));
 		theSP = (spouseFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(spouseFP + FoxMethod)))) < heapBase
@@ -15804,7 +15867,7 @@
 	: byteAt((theFPAbove + FoxIFrameFlags) + 1))))) + BytesPerWord;
 				}
 				/* begin ensureFrameIsMarried:SP: */
-				VM_LABEL(15ensureFrameIsMarriedSP);
+				VM_LABEL(16ensureFrameIsMarriedSP);
 				if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 					? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
 					: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
@@ -17219,7 +17282,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(16ensureFrameIsMarriedSP);
+	VM_LABEL(17ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -18307,13 +18370,9 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
     sqInt activeProc;
-    sqInt aMethodObj;
-    StackPage *newPage;
     sqInt stackPageBytes;
     sqInt stackPagesBytes;
-    char *theFP;
     char *theStackMemory;
-    sqInt top;
 
 	stackPageBytes = stackPageByteSize();
 	stackPagesBytes = (GIV(numStackPages) * ((sizeof(CogStackPage)) + (stackPageByteSize()))) + BytesPerWord;
@@ -18329,37 +18388,7 @@
 	}
 	activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	activeContext = longAt((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord));
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(0marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	ioInitHeartbeat();
 	initialEnterSmalltalkExecutive();
 	return null;
@@ -19160,7 +19189,8 @@
     StackPage *thePage;
     sqInt value;
 
-	assert(isContext(aOnceMarriedContext));
+	assert((isContext(aOnceMarriedContext))
+	 && (isMarriedOrWidowedContext(aOnceMarriedContext)));
 	/* begin frameOfMarriedContext: */
 	value = longAt((aOnceMarriedContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
 	/* begin withoutSmallIntegerTags: */
@@ -19943,13 +19973,9 @@
 
 void
 loadInitialContext(void)
-{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+{
     sqInt activeContext;
     sqInt activeProc;
-    sqInt aMethodObj;
-    StackPage *newPage;
-    char *theFP;
-    sqInt top;
 
 	if ((checkForLeaks & 1) != 0) {
 		clearLeakMapAndMapAccessibleObjects();
@@ -19957,37 +19983,7 @@
 	}
 	activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	activeContext = longAt((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord));
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(1marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 }
 
 void
@@ -21904,6 +21900,50 @@
 }
 
 
+/*	Establish aContext at the base of a new stackPage, make the stackPage the
+	active one and set-up the interreter registers. This is used to boot the
+	system and bring it back after a snapshot. */
+
+static void
+marryContextInNewStackPageAndInitializeInterpreterRegisters(sqInt aContext)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt aMethodObj;
+    StackPage *newPage;
+    char *theFP;
+    sqInt top;
+
+	assert(GIV(stackPage) == 0);
+	newPage = makeBaseFrameFor(aContext);
+	/* begin setStackPageAndLimit: */
+	GIV(stackPage) = newPage;
+	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
+		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
+	}
+	markStackPageMostRecentlyUsed(newPage);
+	GIV(framePointer) = (GIV(stackPage)->headFP);
+	GIV(stackPointer) = (GIV(stackPage)->headSP);
+	/* begin setMethod: */
+	/* begin iframeMethod: */
+	theFP = (GIV(stackPage)->headFP);
+	aMethodObj = longAt(theFP + FoxMethod);
+	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
+	GIV(method) = aMethodObj;
+	assert(isOopCompiledMethod(GIV(method)));
+	
+#  if MULTIPLEBYTECODESETS
+	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
+		? 256
+		: 0);
+
+#  endif /* MULTIPLEBYTECODESETS */
+
+	/* begin popStack */
+	top = longAt(GIV(stackPointer));
+	GIV(stackPointer) += BytesPerWord;
+	GIV(instructionPointer) = ((sqInt) top);
+}
+
+
 /*	Marry an unmarried frame. This means creating a spouse context initialized
 	with a subset of the frame's state (state through the last argument) that
 	references the
@@ -22394,7 +22434,7 @@
 	assert(frameHasContext(callerFP));
 	assert(isContext(frameContext(callerFP)));
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(17ensureFrameIsMarriedSP);
+	VM_LABEL(18ensureFrameIsMarriedSP);
 	theSP = theFP + (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 	? FoxMFReceiver
 	: FoxIFReceiver));
@@ -29480,7 +29520,7 @@
 	for (i1 = 1; i1 <= AtCacheTotalSize; i1 += 1) {
 		GIV(atCache)[i1] = 0;
 	}
-	unlinkSendsTo(longAt(GIV(stackPointer)));
+	unlinkSendsToandFreeIf(longAt(GIV(stackPointer)), 0);
 }
 
 
@@ -31740,18 +31780,9 @@
 primitiveLongRunningPrimitiveSemaphore(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
     sqInt flushState;
-    sqInt header;
-    StackPage *newPage;
-    sqInt oop;
     sqInt sema;
     char *sp;
-    sqInt sz;
-    char *theFP;
-    sqInt top;
 
 	sema = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	if (((sema & 1))
@@ -31781,84 +31812,8 @@
 		/* begin push: */
 		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp;
-		/* begin voidVMStateForSnapshot */
-
-		/* in case of code compactions. */
-
-		GIV(instructionPointer) = 0;
-		activeContext1 = divorceAllFrames();
-		/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-		VM_LABEL(0ensureAllContextsHaveBytecodePCsOrAreBereaved);
-		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-		while (oop < GIV(freeStart)) {
-			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-			 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-					/* begin markContextAsDead: */
-					assert(isContext(oop));
-					longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-				}
-				else {
-					decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-					if (((decodedIP & 1))
-					 && ((((sqInt) decodedIP)) < 0)) {
-						decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-					}
-				}
-			}
-			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
-			}
-			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-				sz = (longAt(oop)) & AllButTypeMask;
-			}
-			else {
-				/* begin sizeBitsOf: */
-				header = longAt(oop);
-				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-					: header & SizeMask);
-			}
-			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
-		}
-		voidCogCompiledCode();
-		activeContext = activeContext1;
-		/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-		VM_LABEL(2marryContextInNewStackPageAndInitializeInterpreterRegisters);
-		assert(GIV(stackPage) == 0);
-		newPage = makeBaseFrameFor(activeContext);
-		/* begin setStackPageAndLimit: */
-		GIV(stackPage) = newPage;
-		if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-			GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-		}
-		markStackPageMostRecentlyUsed(newPage);
-		GIV(framePointer) = (GIV(stackPage)->headFP);
-		GIV(stackPointer) = (GIV(stackPage)->headSP);
-		/* begin setMethod: */
-		/* begin iframeMethod: */
-		theFP = (GIV(stackPage)->headFP);
-		aMethodObj = longAt(theFP + FoxMethod);
-		assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-		GIV(method) = aMethodObj;
-		assert(isOopCompiledMethod(GIV(method)));
-		
-#    if MULTIPLEBYTECODESETS
-		bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-			? 256
-			: 0);
-
-#    endif /* MULTIPLEBYTECODESETS */
-
-		/* begin popStack */
-		top = longAt(GIV(stackPointer));
-		GIV(stackPointer) += BytesPerWord;
-		GIV(instructionPointer) = ((sqInt) top);
+		activeContext = voidVMStateForSnapshot();
+		marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 		assert((((stackValue(0)) == (nilObject()))
  && (GIV(longRunningPrimitiveCheckSemaphore) == null))
 		 || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore))
@@ -32025,6 +31980,49 @@
 }
 
 
+/*	Lift the veil from a method and answer an integer describing the interior
+	state of its machine code.
+	Used for e.g. VM tests so they can verify they're testing what they think
+	they're testing.
+	0 implies a vanilla method.
+	Bit 0 = method is currently compiled to machine code
+	Bit 1 = is compiled frameless.
+	Bit 2 = method refers to young object */
+
+EXPORT(void)
+primitiveMethodXray(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt aMethodOop;
+    CogMethod *cogMethod;
+    sqInt flags;
+    sqInt methodHeader;
+    char *sp;
+
+	if ((((longAt(GIV(stackPointer))) & 1) == 0)
+	 && ((((((usqInt) (longAt(longAt(GIV(stackPointer))))) >> 8) & 15) >= 12)
+	 && (isCogMethodReference(longAt(((longAt(GIV(stackPointer))) + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
+		/* begin cogMethodOf: */
+		aMethodOop = longAt(GIV(stackPointer));
+		methodHeader = longAt((aMethodOop + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+		assert((isNonIntegerObject(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		flags = (((cogMethod->stackCheckOffset)) == 0
+			? 3
+			: 1);
+		if ((cogMethod->cmRefersToYoung)) {
+			flags += 4;
+		}
+	}
+	else {
+		flags = 0;
+	}
+	/* begin pop:thenPush: */
+	longAtput((sp = GIV(stackPointer) + ((1 - 1) * BytesPerWord)), ((flags << 1) | 1));
+	GIV(stackPointer) = sp;
+}
+
+
 /*	Return the value of the millisecond clock as an integer. Note that the
 	millisecond clock wraps around periodically. On some platforms it can wrap
 	daily. The range is limited to SmallInteger maxVal / 2 to allow delays of
@@ -33300,18 +33298,9 @@
 primitiveProfileSemaphore(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
     sqInt flushState;
-    sqInt header;
-    StackPage *newPage;
-    sqInt oop;
     sqInt sema;
     char *sp;
-    sqInt sz;
-    char *theFP;
-    sqInt top;
 
 	sema = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	if (((sema & 1))
@@ -33346,84 +33335,8 @@
 		/* begin push: */
 		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp;
-		/* begin voidVMStateForSnapshot */
-
-		/* in case of code compactions. */
-
-		GIV(instructionPointer) = 0;
-		activeContext1 = divorceAllFrames();
-		/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-		VM_LABEL(1ensureAllContextsHaveBytecodePCsOrAreBereaved);
-		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-		while (oop < GIV(freeStart)) {
-			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-			 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-					/* begin markContextAsDead: */
-					assert(isContext(oop));
-					longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-				}
-				else {
-					decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-					if (((decodedIP & 1))
-					 && ((((sqInt) decodedIP)) < 0)) {
-						decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-					}
-				}
-			}
-			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
-			}
-			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-				sz = (longAt(oop)) & AllButTypeMask;
-			}
-			else {
-				/* begin sizeBitsOf: */
-				header = longAt(oop);
-				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-					: header & SizeMask);
-			}
-			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
-		}
-		voidCogCompiledCode();
-		activeContext = activeContext1;
-		/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-		VM_LABEL(3marryContextInNewStackPageAndInitializeInterpreterRegisters);
-		assert(GIV(stackPage) == 0);
-		newPage = makeBaseFrameFor(activeContext);
-		/* begin setStackPageAndLimit: */
-		GIV(stackPage) = newPage;
-		if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-			GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-		}
-		markStackPageMostRecentlyUsed(newPage);
-		GIV(framePointer) = (GIV(stackPage)->headFP);
-		GIV(stackPointer) = (GIV(stackPage)->headSP);
-		/* begin setMethod: */
-		/* begin iframeMethod: */
-		theFP = (GIV(stackPage)->headFP);
-		aMethodObj = longAt(theFP + FoxMethod);
-		assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-		GIV(method) = aMethodObj;
-		assert(isOopCompiledMethod(GIV(method)));
-		
-#    if MULTIPLEBYTECODESETS
-		bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-			? 256
-			: 0);
-
-#    endif /* MULTIPLEBYTECODESETS */
-
-		/* begin popStack */
-		top = longAt(GIV(stackPointer));
-		GIV(stackPointer) += BytesPerWord;
-		GIV(instructionPointer) = ((sqInt) top);
+		activeContext = voidVMStateForSnapshot();
+		marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 		assert((((stackValue(0)) == (nilObject()))
  && (GIV(profileSemaphore) == (nilObject())))
 		 || (((stackValue(0)) == GIV(profileSemaphore))
@@ -37448,98 +37361,211 @@
 primitiveVoidVMState(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
+    char *sp;
+
+	/* begin push: */
+	longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+	GIV(stackPointer) = sp;
+	activeContext = voidVMStateForSnapshot();
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
+	siglongjmp(reenterInterpreter, ReturnToInterpreter);
+}
+
+
+/*	The receiver is a compiledMethod. Clear all entries in the method lookup
+	cache that refer to this method, presumably because it has been redefined,
+	overridden or removed.
+ */
+/*	The receiver is a compiledMethod. Clear all VM state associated with the
+	method, including any machine code, or machine code pcs in context
+	objects.  */
+
+static void
+primitiveVoidVMStateForMethod(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt activeContext;
+    StackPage *aPage;
+    CogMethod *cogMethod;
+    sqInt divorcedSome;
+    sqInt divorcedSome1;
     sqInt header;
-    StackPage *newPage;
+    sqInt i;
+    sqInt i1;
+    sqInt i2;
+    sqInt index;
+    sqInt methodHeader;
+    sqInt methodObj;
+    sqInt oldMethod;
     sqInt oop;
+    sqInt pc;
+    sqInt primBits;
+    sqInt primIdx;
+    sqInt probe;
     char *sp;
     sqInt sz;
     char *theFP;
+    char *theFrame;
+    StackPage *thePage;
+    char *theSP;
     sqInt top;
+    sqInt top1;
+    sqInt value;
 
-	/* begin push: */
-	longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
-	GIV(stackPointer) = sp;
-	/* begin voidVMStateForSnapshot */
-
-	/* in case of code compactions. */
-
-	GIV(instructionPointer) = 0;
-	activeContext1 = divorceAllFrames();
-	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-	VM_LABEL(2ensureAllContextsHaveBytecodePCsOrAreBereaved);
-	oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-	while (oop < GIV(freeStart)) {
-		if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-		 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-			if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-				/* begin markContextAsDead: */
-				assert(isContext(oop));
-				longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-				longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
+	oldMethod = longAt(GIV(stackPointer));
+	probe = 0;
+	for (i = 1; i <= MethodCacheEntries; i += 1) {
+		if ((GIV(methodCache)[probe + MethodCacheMethod]) == oldMethod) {
+			GIV(methodCache)[probe + MethodCacheSelector] = 0;
+		}
+		probe += MethodCacheEntrySize;
+	}
+	/* begin primitiveIndexOf: */
+	primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
+	primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
+	if (primIdx == PrimitiveExternalCallIndex) {
+		flushExternalPrimitiveOf(oldMethod);
+	}
+	/* begin flushAtCache */
+	for (i2 = 1; i2 <= AtCacheTotalSize; i2 += 1) {
+		GIV(atCache)[i2] = 0;
+	}
+	if (methodHasCogMethod(longAt(GIV(stackPointer)))) {
+		methodObj = longAt(GIV(stackPointer));
+		/* begin push: */
+		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+		GIV(stackPointer) = sp;
+		/* begin externalWriteBackHeadFramePointers */
+		assert((GIV(framePointer) - GIV(stackPointer)) < LargeContextSize);
+		assert(GIV(stackPage) == (mostRecentlyUsedPage()));
+		/* begin setHeadFP:andSP:inPage: */
+		assert(GIV(stackPointer) < GIV(framePointer));
+		assert((GIV(stackPointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(stackPointer) > (((GIV(stackPage)->realStackLimit)) - LargeContextSize)));
+		assert((GIV(framePointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(framePointer) > (((GIV(stackPage)->realStackLimit)) - (((sqInt) LargeContextSize >> 1)))));
+		(GIV(stackPage)->headFP = GIV(framePointer));
+		(GIV(stackPage)->headSP = GIV(stackPointer));
+		assert(pageListIsWellFormed());
+		/* begin ensureFrameIsMarried:SP: */
+		VM_LABEL(19ensureFrameIsMarriedSP);
+		theFP = GIV(framePointer);
+		theSP = GIV(stackPointer);
+		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
+			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
+			assert(isContext(frameContext(theFP)));
+			activeContext = longAt(theFP + FoxThisContext);
+			goto l1;
+		}
+		activeContext = marryFrameSP(theFP, theSP);
+	l1:	/* end ensureFrameIsMarried:SP: */;
+		/* begin divorceMachineCodeFramesWithMethod: */
+		/* begin cogMethodOf: */
+		methodHeader = longAt((methodObj + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+		assert((isNonIntegerObject(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		do {
+			if (GIV(stackPage) != 0) {
+				markStackPageMostRecentlyUsed(GIV(stackPage));
 			}
-			else {
-				decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-				if (((decodedIP & 1))
-				 && ((((sqInt) decodedIP)) < 0)) {
-					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
+			/* begin divorceSomeMachineCodeFramesWithMethod: */
+			divorcedSome1 = 0;
+			for (i1 = 0; i1 <= (GIV(numStackPages) - 1); i1 += 1) {
+				/* begin stackPageAt: */
+				aPage = stackPageAtpages(i1, GIV(pages));
+				if (!(isFree(aPage))) {
+					markStackPageMostRecentlyUsed(GIV(stackPage));
+					if (divorceAMachineCodeFrameWithCogMethodin(cogMethod, aPage)) {
+						divorcedSome1 = 1;
+					}
 				}
 			}
+			divorcedSome = divorcedSome1;
+		} while(divorcedSome);
+		/* begin ensureAllContextsWithMethodHaveBytecodePCs: */
+		VM_LABEL(0ensureAllContextsWithMethodHaveBytecodePCs);
+		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
+		while (oop < GIV(freeStart)) {
+			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
+			 && ((((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)
+			 && ((longAt((oop + BaseHeaderSize) + (MethodIndex << ShiftForWord))) == methodObj))) {
+				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
+					if (checkIsStillMarriedContextcurrentFP(oop, (GIV(stackPage)->headFP))) {
+						assert(!(isMachineCodeFrame(frameOfMarriedContext(oop))));
+					}
+				}
+				else {
+					/* begin ensureContextHasBytecodePC: */
+					assert(!(isMarriedOrWidowedContext(oop)));
+					pc = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
+					if (((pc & 1))
+					 && (((pc = (pc >> 1))) < 0)) {
+						pc = mustMapMachineCodePCcontext(pc, oop);
+						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), pc);
+					}
+				}
+			}
+			/* begin objectAfter: */
+			if (DoAssertionChecks) {
+				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
+					error("no objects after the end of memory");
+				}
+			}
+			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+				sz = (longAt(oop)) & AllButTypeMask;
+			}
+			else {
+				/* begin sizeBitsOf: */
+				header = longAt(oop);
+				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+					: header & SizeMask);
+			}
+			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
 		}
-		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
+		unlinkSendsToandFreeIf(methodObj, 1);
+		if ((((longAt((activeContext + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1))
+		 && (!(isWidowedContext(activeContext)))) {
+			/* begin frameOfMarriedContext: */
+			value = longAt((activeContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
+			/* begin withoutSmallIntegerTags: */
+			assert((value & 1));
+			theFrame = pointerForOop(value - 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));
+			thePage = stackPageAtpages(index, GIV(pages));
+			assert(((thePage->headFP)) == theFrame);
+			/* begin setStackPageAndLimit: */
+			GIV(stackPage) = thePage;
+			if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
+				GIV(stackLimit) = (GIV(stackPage)->stackLimit);
 			}
+			markStackPageMostRecentlyUsed(thePage);
+			GIV(stackPointer) = (thePage->headSP);
+			GIV(framePointer) = (thePage->headFP);
+			/* begin popStack */
+			top = longAt(GIV(stackPointer));
+			GIV(stackPointer) += BytesPerWord;
+			GIV(instructionPointer) = ((sqInt) top);
+			assert(methodObj == (stackTop()));
 		}
-		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-			sz = (longAt(oop)) & AllButTypeMask;
-		}
 		else {
-			/* begin sizeBitsOf: */
-			header = longAt(oop);
-			sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-				? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-				: header & SizeMask);
+
+			/* to avoid assert in marryContextInNewStackPageAndInitializeInterpreterRegisters: */
+
+			GIV(stackPage) = 0;
+			marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
+			/* begin popStack */
+			top1 = longAt(GIV(stackPointer));
+			GIV(stackPointer) += BytesPerWord;
+			assert(methodObj == (stackTop()));
+			siglongjmp(reenterInterpreter, ReturnToInterpreter);
 		}
-		oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
 	}
-	voidCogCompiledCode();
-	activeContext = activeContext1;
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
-	siglongjmp(reenterInterpreter, ReturnToInterpreter);
 }
 
 static void
@@ -38127,7 +38153,7 @@
 			printf("\n");
 		}
 		else {
-			print("widdowed (assuming framePointer valid)");
+			print("widowed (assuming framePointer valid)");
 			/* begin cr */
 			printf("\n");
 		}
@@ -39375,6 +39401,17 @@
 		goto l2;
 	}
 	printf("a(n) %.*s", nameLen, name);
+	if (((instanceSizeOf(classOop)) == (ValueIndex + 1))
+	 && (((longAt((classOop + BaseHeaderSize) + (SuperclassIndex << ShiftForWord))) == (superclassOf(fetchClassOfNonInt(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))))))
+	 && ((((longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord))) & 1) == 0)
+	 && (((((usqInt) (longAt(longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord))))) >> 8) & 15) >= 8)))) {
+		/* begin space */
+		/* begin printChar: */
+		putchar(' ');
+		printOopShort(longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord)));
+		print(" -> ");
+		printHex(longAt((oop + BaseHeaderSize) + (ValueIndex << ShiftForWord)));
+	}
 l2:	/* end printOopShortInner: */;
 	flush();
 }
@@ -42542,26 +42579,20 @@
 snapshot(sqInt embedded)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
     sqInt activeProc;
-    sqInt aMethodObj;
     sqInt dataSize;
-    sqInt decodedIP;
     sqInt fmt;
     sqInt header;
     sqInt header1;
     sqInt header2;
-    sqInt header3;
     sqInt i;
     sqInt i1;
-    StackPage *newPage;
     sqInt object;
     sqInt object1;
     sqInt oop;
     sqInt oop1;
     sqInt oop2;
     sqInt oop3;
-    sqInt oop4;
     sqInt rcvr;
     void *setMacType;
     char *sp;
@@ -42570,61 +42601,12 @@
     sqInt stackIndex;
     sqInt sz;
     sqInt sz1;
-    sqInt sz2;
-    char *theFP;
-    sqInt top;
 
 	/* begin push: */
 	object1 = GIV(instructionPointer);
 	longAtput((sp2 = GIV(stackPointer) - BytesPerWord), object1);
 	GIV(stackPointer) = sp2;
-	/* begin voidVMStateForSnapshot */
-
-	/* in case of code compactions. */
-
-	GIV(instructionPointer) = 0;
-	activeContext1 = divorceAllFrames();
-	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-	VM_LABEL(3ensureAllContextsHaveBytecodePCsOrAreBereaved);
-	oop4 = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-	while (oop4 < GIV(freeStart)) {
-		if ((!(((longAt(oop4)) & TypeMask) == HeaderTypeFree))
-		 && (((((usqInt) (longAt(oop4))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-			if (((longAt((oop4 + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-				/* begin markContextAsDead: */
-				assert(isContext(oop4));
-				longAtput((oop4 + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-				longAtput((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-			}
-			else {
-				decodedIP = longAt((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-				if (((decodedIP & 1))
-				 && ((((sqInt) decodedIP)) < 0)) {
-					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop4);
-					longAtput((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-				}
-			}
-		}
-		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop4)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
-			}
-		}
-		if (((longAt(oop4)) & TypeMask) == HeaderTypeFree) {
-			sz2 = (longAt(oop4)) & AllButTypeMask;
-		}
-		else {
-			/* begin sizeBitsOf: */
-			header3 = longAt(oop4);
-			sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
-				? (longAt(oop4 - (BytesPerWord * 2))) & LongSizeMask
-				: header3 & SizeMask);
-		}
-		oop4 = (oop4 + sz2) + (headerTypeBytes[(longAt(oop4 + sz2)) & TypeMask]);
-	}
-	voidCogCompiledCode();
-	activeContext = activeContext1;
+	activeContext = voidVMStateForSnapshot();
 	/* begin pushRemappableOop: */
 	assert(addressCouldBeOop(activeContext));
 	GIV(remapBuffer)[(GIV(remapBufferCount) += 1)] = activeContext;
@@ -42727,37 +42709,7 @@
 		}
 		longAtput((activeContext + BaseHeaderSize) + (StackPointerIndex << ShiftForWord), (((stackIndex - 1) << 1) | 1));
 	}
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(4marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	if (!GIV(primFailCode)) {
 		/* begin push: */
 		object = GIV(falseObj);
@@ -43897,7 +43849,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(18ensureFrameIsMarriedSP);
+	VM_LABEL(20ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -44522,7 +44474,7 @@
 	sched = longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord));
 	oldProc = longAt((sched + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(19ensureFrameIsMarriedSP);
+	VM_LABEL(21ensureFrameIsMarriedSP);
 	theFP = GIV(framePointer);
 	theSP = GIV(stackPointer);
 	if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -45395,6 +45347,70 @@
 }
 
 
+/*	Make sure that all VM state that affects the heap contents is voided so
+	that the heap is ready
+	to be snapshotted. Answer the activeContext object that should be stored
+	in the snapshot.
+ */
+
+static sqInt
+voidVMStateForSnapshot(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt activeContext;
+    sqInt decodedIP;
+    sqInt header;
+    sqInt oop;
+    sqInt sz;
+
+
+	/* in case of code compactions. */
+
+	GIV(instructionPointer) = 0;
+	activeContext = divorceAllFrames();
+	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
+	VM_LABEL(0ensureAllContextsHaveBytecodePCsOrAreBereaved);
+	oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
+	while (oop < GIV(freeStart)) {
+		if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
+		 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
+			if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
+				/* begin markContextAsDead: */
+				assert(isContext(oop));
+				longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
+				longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
+			}
+			else {
+				decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
+				if (((decodedIP & 1))
+				 && ((((sqInt) decodedIP)) < 0)) {
+					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
+					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
+				}
+			}
+		}
+		/* begin objectAfter: */
+		if (DoAssertionChecks) {
+			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
+				error("no objects after the end of memory");
+			}
+		}
+		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+			sz = (longAt(oop)) & AllButTypeMask;
+		}
+		else {
+			/* begin sizeBitsOf: */
+			header = longAt(oop);
+			sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+				? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+				: header & SizeMask);
+		}
+		oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
+	}
+	voidCogCompiledCode();
+	return activeContext;
+}
+
+
 /*	Return the highest priority process that is ready to run.
 	To save time looking at many empty lists before finding a
 	runnable process the VM maintains a variable holding the
@@ -45603,6 +45619,7 @@
 	{"", "primitiveLessThanLargeIntegers", (void*)primitiveLessThanLargeIntegers},
 	{"", "primitiveLongRunningPrimitive", (void*)primitiveLongRunningPrimitive},
 	{"", "primitiveLongRunningPrimitiveSemaphore", (void*)primitiveLongRunningPrimitiveSemaphore},
+	{"", "primitiveMethodXray", (void*)primitiveMethodXray},
 	{"", "primitiveMillisecondClockMask", (void*)primitiveMillisecondClockMask},
 	{"", "primitiveModLargeIntegers", (void*)primitiveModLargeIntegers},
 	{"", "primitiveMultiplyLargeIntegers", (void*)primitiveMultiplyLargeIntegers},

Modified: branches/Cog/src/vm/cointerp.h
===================================================================
--- branches/Cog/src/vm/cointerp.h	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/src/vm/cointerp.h	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,5 +1,7 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGeneratorGlobalStructure eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
 
 

Modified: branches/Cog/src/vm/cointerpmt.c
===================================================================
--- branches/Cog/src/vm/cointerpmt.c	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/src/vm/cointerpmt.c	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,9 +1,15 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGeneratorGlobalStructure eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
    from
-	CoInterpreterMT VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CoInterpreterMT eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
-static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa " __DATE__ ;
+static char __buildInfo[] = "CoInterpreterMT eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -239,6 +245,7 @@
 #define ImmutabilityBit 0x20000000
 #define InstanceSpecificationIndex 2
 #define InstructionPointerIndex 1
+#define KeyIndex 0
 #define LargeContextBit 0x40000
 #define LargeContextBytes 252
 #define LargeContextSize 252
@@ -506,6 +513,7 @@
 static void displayBitsOfLeftTopRightBottom(sqInt aForm, sqInt l, sqInt t, sqInt r, sqInt b);
 sqInt displayObject(void);
 static sqInt divorceAllFrames(void);
+static sqInt divorceAMachineCodeFrameWithCogMethodin(CogMethod *cogMethod, StackPage *aStackPage);
 static void divorceFramesIn(StackPage *aStackPage);
 static sqInt doPrimitiveDivby(sqInt rcvr, sqInt arg);
 static sqInt doPrimitiveModby(sqInt rcvr, sqInt arg);
@@ -722,6 +730,7 @@
 static void markStackPageMostRecentlyUsed(StackPage *page);
 static void markStackPageNextMostRecentlyUsed(StackPage *page);
 static sqInt marriedContextpointsTostackDeltaForCurrentFrame(sqInt spouseContext, sqInt anOop, sqInt stackDeltaForCurrentFrame);
+static void marryContextInNewStackPageAndInitializeInterpreterRegisters(sqInt aContext);
 static sqInt marryFrameSP(char *theFP, char *theSP);
 static void maybeFlagMethodAsInterpreted(sqInt aMethod);
 sqInt maybeSplObj(sqInt index);
@@ -933,6 +942,7 @@
 static void primitiveMarkUnwindMethod(void);
 static void primitiveMaxIdentityHash(void);
 sqInt primitiveMethod(void);
+EXPORT(void) primitiveMethodXray(void);
 static void primitiveMillisecondClock(void);
 EXPORT(sqInt) primitiveMillisecondClockMask(void);
 static void primitiveMod(void);
@@ -1027,6 +1037,7 @@
 static void primitiveVMProfileSamplesInto(void);
 EXPORT(void) primitiveVoidReceiver(void);
 static void primitiveVoidVMState(void);
+static void primitiveVoidVMStateForMethod(void);
 static void primitiveWait(void);
 static void primitiveYield(void);
 void * primTraceLogAddress(void);
@@ -1212,6 +1223,7 @@
 usqInt vmOwnerLockAddress(void);
 static CogVMThread * vmThreadAt(sqInt index);
 static void voidLongRunningPrimitive(char *reason);
+static sqInt voidVMStateForSnapshot(void);
 static sqInt wakeHighestPriority(void);
 static void wakeVMThreadFor(sqInt index);
 static CogVMThread * willingVMThread(void);
@@ -1234,8 +1246,8 @@
 _iss sqInt specialObjectsOop;
 _iss StackPage * stackPage;
 _iss sqInt nilObj;
+_iss usqInt instructionPointer;
 _iss usqInt method;
-_iss usqInt instructionPointer;
 _iss sqInt argumentCount;
 _iss usqInt freeStart;
 _iss usqInt newMethod;
@@ -1252,18 +1264,18 @@
 _iss sqInt lkupClass;
 _iss sqInt bytesPerPage;
 _iss sqInt cogThreadManager;
+_iss usqInt reserveStart;
 _iss char * stackLimit;
-_iss usqInt reserveStart;
 _iss usqInt memoryLimit;
 _iss StackPage * mostRecentlyUsedPage;
 _iss sqInt needGCFlag;
 _iss usqInt scavengeThreshold;
 _iss sqInt numThreads;
+_iss sqInt numStackPages;
 _iss unsigned char primTraceLogIndex;
 _iss sqInt processHasThreadId;
 _iss CogVMThread ** threads;
 _iss sqLong nextProfileTick;
-_iss sqInt numStackPages;
 _iss CogVMThread * disowningVMThread;
 _iss sqInt jmpDepth;
 _iss usqInt fwdTableNext;
@@ -1368,8 +1380,8 @@
 _iss sqInt imageHeaderFlags;
 _iss usqLong longRunningPrimitiveGCUsecs;
 _iss sqInt overflowLimit;
+_iss long methodCache[MethodCacheSize + 1 /* 4097 */];
 _iss sqInt traceLog[TraceBufferSize /* 768 */];
-_iss long methodCache[MethodCacheSize + 1 /* 4097 */];
 _iss sqInt remapBuffer[RemapBufferSize + 1 /* 26 */];
 _iss sqInt atCache[AtCacheTotalSize + 1 /* 65 */];
 _iss sqInt rootTable[RootTableSize + 1 /* 2501 */];
@@ -1400,8 +1412,8 @@
 #endif
 static usqInt heapBase;
 static void (*primitiveFunctionPointer)();
+jmp_buf reenterInterpreter; /* private export */;
 #define bytecodeSetSelector 0
-jmp_buf reenterInterpreter; /* private export */;
 sqInt maxLiteralCountForCompile = MaxLiteralCountForCompile /* 60 */;
 sqInt inIOProcessEvents;
 sqInt checkForLeaks;
@@ -1636,7 +1648,7 @@
 	/* 212 */ primitiveContextSize,
 	/* 213 */ primitiveContextXray,
 	/* 214 */ primitiveVoidVMState,
-	/* 215 */ (void (*)(void))0,
+	/* 215 */ primitiveVoidVMStateForMethod,
 	/* 216 */ (void (*)(void))0,
 	/* 217 */ (void (*)(void))0,
 	/* 218 */ primitiveDoNamedPrimitiveWithArgs,
@@ -1999,7 +2011,9 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Croquet Closure Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.154]";
+const char *interpreterVersion = "Croquet Closure Cog MT VM [CoInterpreterMT eneraiton.
+
+VMMaker.oscog-eem.156]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 sqInt willNotThreadWarnCount;
@@ -13965,6 +13979,55 @@
 	return activeContext;
 }
 
+
+/*	Divorce at most one frame in the current page (since the divorce may cause
+	the page to be split)
+	and answer whether a frame was divorced. */
+
+static sqInt
+divorceAMachineCodeFrameWithCogMethodin(CogMethod *cogMethod, StackPage *aStackPage)
+{
+    char *calleeFP;
+    sqInt theContext;
+    char *theFP;
+    char *theSP;
+
+	theFP = (aStackPage->headFP);
+	theSP = (aStackPage->headSP);
+
+	/* theSP points at hottest item on frame's stack */
+
+	theSP += BytesPerWord;
+	while (1) {
+		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase)
+		 && (cogMethod == (mframeHomeMethod(theFP)))) {
+			/* begin ensureFrameIsMarried:SP: */
+			VM_LABEL(12ensureFrameIsMarriedSP);
+			if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
+				? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+				: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
+				assert(isContext(frameContext(theFP)));
+				theContext = longAt(theFP + FoxThisContext);
+				goto l1;
+			}
+			theContext = marryFrameSP(theFP, theSP);
+		l1:	/* end ensureFrameIsMarried:SP: */;
+			externalDivorceFrameandContext(theFP, theContext);
+			return 1;
+		}
+		calleeFP = theFP;
+		/* begin frameCallerFP: */
+		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
+		if (!(theFP != 0)) break;
+		/* begin frameCallerSP: */
+		assert(!(isBaseFrame(calleeFP)));
+		theSP = (calleeFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(calleeFP + FoxMethod)))) < heapBase
+	? (mframeCogMethod(calleeFP)->cmNumArgs)
+	: byteAt((calleeFP + FoxIFrameFlags) + 1))))) + BytesPerWord;
+	}
+	return 0;
+}
+
 static void
 divorceFramesIn(StackPage *aStackPage)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
@@ -13991,7 +14054,7 @@
 	calleeContext = null;
 	while (1) {
 		/* begin ensureFrameIsMarried:SP: */
-		VM_LABEL(12ensureFrameIsMarriedSP);
+		VM_LABEL(13ensureFrameIsMarriedSP);
 		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
 			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
@@ -14904,7 +14967,7 @@
 		return callerContextOrNil;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(13ensureFrameIsMarriedSP);
+	VM_LABEL(14ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -14950,6 +15013,7 @@
 {
     sqInt pc;
 
+	/* begin ensureContextHasBytecodePC: */
 	assert(!(isMarriedOrWidowedContext(aContext)));
 	pc = longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
 	if (((pc & 1))
@@ -15451,7 +15515,6 @@
     char *theSP1;
     sqInt valuePointer;
 
-	assert(theFP != GIV(framePointer));
 	assert((GIV(stackPage) == 0)
 	 || (GIV(stackPage) == (mostRecentlyUsedPage())));
 	/* begin stackPageFor: */
@@ -15485,7 +15548,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(14ensureFrameIsMarriedSP);
+	VM_LABEL(15ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP1 = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -15682,7 +15745,7 @@
 			return callerContextOrNil;
 		}
 		/* begin ensureFrameIsMarried:SP: */
-		VM_LABEL(15ensureFrameIsMarriedSP);
+		VM_LABEL(16ensureFrameIsMarriedSP);
 		/* begin frameCallerStackPointer: */
 		assert(!(isBaseFrame(spouseFP)));
 		theSP = (spouseFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(spouseFP + FoxMethod)))) < heapBase
@@ -16420,7 +16483,7 @@
 	: byteAt((theFPAbove + FoxIFrameFlags) + 1))))) + BytesPerWord;
 				}
 				/* begin ensureFrameIsMarried:SP: */
-				VM_LABEL(16ensureFrameIsMarriedSP);
+				VM_LABEL(17ensureFrameIsMarriedSP);
 				if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 					? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
 					: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
@@ -17882,7 +17945,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(17ensureFrameIsMarriedSP);
+	VM_LABEL(18ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -19003,13 +19066,9 @@
     sqInt activeContext;
     sqInt activeProc;
     sqInt activeProc1;
-    sqInt aMethodObj;
-    StackPage *newPage;
     sqInt stackPageBytes;
     sqInt stackPagesBytes;
-    char *theFP;
     char *theStackMemory;
-    sqInt top;
 
 	stackPageBytes = stackPageByteSize();
 	stackPagesBytes = (GIV(numStackPages) * ((sizeof(CogStackPage)) + (stackPageByteSize()))) + BytesPerWord;
@@ -19025,37 +19084,7 @@
 	}
 	activeProc1 = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	activeContext = longAt((activeProc1 + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord));
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(0marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	assert((ownerIndexOfProcess(activeProc)) == 0);
 	GIV(activeProcessAffined) = (ownerIndexOfThreadId((GIV(processHasThreadId)
@@ -19886,7 +19915,8 @@
     StackPage *thePage;
     sqInt value;
 
-	assert(isContext(aOnceMarriedContext));
+	assert((isContext(aOnceMarriedContext))
+	 && (isMarriedOrWidowedContext(aOnceMarriedContext)));
 	/* begin frameOfMarriedContext: */
 	value = longAt((aOnceMarriedContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
 	/* begin withoutSmallIntegerTags: */
@@ -20673,10 +20703,6 @@
     sqInt activeContext;
     sqInt activeProc;
     sqInt activeProc1;
-    sqInt aMethodObj;
-    StackPage *newPage;
-    char *theFP;
-    sqInt top;
 
 	if ((checkForLeaks & 1) != 0) {
 		clearLeakMapAndMapAccessibleObjects();
@@ -20684,37 +20710,7 @@
 	}
 	activeProc1 = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	activeContext = longAt((activeProc1 + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord));
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(1marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	assert((ownerIndexOfProcess(activeProc)) == 0);
 	GIV(activeProcessAffined) = (ownerIndexOfThreadId((GIV(processHasThreadId)
@@ -22664,6 +22660,50 @@
 }
 
 
+/*	Establish aContext at the base of a new stackPage, make the stackPage the
+	active one and set-up the interreter registers. This is used to boot the
+	system and bring it back after a snapshot. */
+
+static void
+marryContextInNewStackPageAndInitializeInterpreterRegisters(sqInt aContext)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt aMethodObj;
+    StackPage *newPage;
+    char *theFP;
+    sqInt top;
+
+	assert(GIV(stackPage) == 0);
+	newPage = makeBaseFrameFor(aContext);
+	/* begin setStackPageAndLimit: */
+	GIV(stackPage) = newPage;
+	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
+		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
+	}
+	markStackPageMostRecentlyUsed(newPage);
+	GIV(framePointer) = (GIV(stackPage)->headFP);
+	GIV(stackPointer) = (GIV(stackPage)->headSP);
+	/* begin setMethod: */
+	/* begin iframeMethod: */
+	theFP = (GIV(stackPage)->headFP);
+	aMethodObj = longAt(theFP + FoxMethod);
+	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
+	GIV(method) = aMethodObj;
+	assert(isOopCompiledMethod(GIV(method)));
+	
+#  if MULTIPLEBYTECODESETS
+	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
+		? 256
+		: 0);
+
+#  endif /* MULTIPLEBYTECODESETS */
+
+	/* begin popStack */
+	top = longAt(GIV(stackPointer));
+	GIV(stackPointer) += BytesPerWord;
+	GIV(instructionPointer) = ((sqInt) top);
+}
+
+
 /*	Marry an unmarried frame. This means creating a spouse context initialized
 	with a subset of the frame's state (state through the last argument) that
 	references the
@@ -23154,7 +23194,7 @@
 	assert(frameHasContext(callerFP));
 	assert(isContext(frameContext(callerFP)));
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(18ensureFrameIsMarriedSP);
+	VM_LABEL(19ensureFrameIsMarriedSP);
 	theSP = theFP + (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 	? FoxMFReceiver
 	: FoxIFReceiver));
@@ -24749,7 +24789,7 @@
 	(GIV(stackPage)->headSP = GIV(stackPointer));
 	assert(pageListIsWellFormed());
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(19ensureFrameIsMarriedSP);
+	VM_LABEL(20ensureFrameIsMarriedSP);
 	theFP = GIV(framePointer);
 	theSP = GIV(stackPointer);
 	if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -30688,7 +30728,7 @@
 	for (i1 = 1; i1 <= AtCacheTotalSize; i1 += 1) {
 		GIV(atCache)[i1] = 0;
 	}
-	unlinkSendsTo(longAt(GIV(stackPointer)));
+	unlinkSendsToandFreeIf(longAt(GIV(stackPointer)), 0);
 }
 
 
@@ -32948,18 +32988,9 @@
 primitiveLongRunningPrimitiveSemaphore(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
     sqInt flushState;
-    sqInt header;
-    StackPage *newPage;
-    sqInt oop;
     sqInt sema;
     char *sp;
-    sqInt sz;
-    char *theFP;
-    sqInt top;
 
 	sema = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	if (((sema & 1))
@@ -32989,84 +33020,8 @@
 		/* begin push: */
 		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp;
-		/* begin voidVMStateForSnapshot */
-
-		/* in case of code compactions. */
-
-		GIV(instructionPointer) = 0;
-		activeContext1 = divorceAllFrames();
-		/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-		VM_LABEL(0ensureAllContextsHaveBytecodePCsOrAreBereaved);
-		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-		while (oop < GIV(freeStart)) {
-			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-			 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-					/* begin markContextAsDead: */
-					assert(isContext(oop));
-					longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-				}
-				else {
-					decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-					if (((decodedIP & 1))
-					 && ((((sqInt) decodedIP)) < 0)) {
-						decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-					}
-				}
-			}
-			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
-			}
-			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-				sz = (longAt(oop)) & AllButTypeMask;
-			}
-			else {
-				/* begin sizeBitsOf: */
-				header = longAt(oop);
-				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-					: header & SizeMask);
-			}
-			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
-		}
-		voidCogCompiledCode();
-		activeContext = activeContext1;
-		/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-		VM_LABEL(2marryContextInNewStackPageAndInitializeInterpreterRegisters);
-		assert(GIV(stackPage) == 0);
-		newPage = makeBaseFrameFor(activeContext);
-		/* begin setStackPageAndLimit: */
-		GIV(stackPage) = newPage;
-		if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-			GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-		}
-		markStackPageMostRecentlyUsed(newPage);
-		GIV(framePointer) = (GIV(stackPage)->headFP);
-		GIV(stackPointer) = (GIV(stackPage)->headSP);
-		/* begin setMethod: */
-		/* begin iframeMethod: */
-		theFP = (GIV(stackPage)->headFP);
-		aMethodObj = longAt(theFP + FoxMethod);
-		assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-		GIV(method) = aMethodObj;
-		assert(isOopCompiledMethod(GIV(method)));
-		
-#    if MULTIPLEBYTECODESETS
-		bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-			? 256
-			: 0);
-
-#    endif /* MULTIPLEBYTECODESETS */
-
-		/* begin popStack */
-		top = longAt(GIV(stackPointer));
-		GIV(stackPointer) += BytesPerWord;
-		GIV(instructionPointer) = ((sqInt) top);
+		activeContext = voidVMStateForSnapshot();
+		marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 		assert((((stackValue(0)) == (nilObject()))
  && (GIV(longRunningPrimitiveCheckSemaphore) == null))
 		 || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore))
@@ -33233,6 +33188,49 @@
 }
 
 
+/*	Lift the veil from a method and answer an integer describing the interior
+	state of its machine code.
+	Used for e.g. VM tests so they can verify they're testing what they think
+	they're testing.
+	0 implies a vanilla method.
+	Bit 0 = method is currently compiled to machine code
+	Bit 1 = is compiled frameless.
+	Bit 2 = method refers to young object */
+
+EXPORT(void)
+primitiveMethodXray(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt aMethodOop;
+    CogMethod *cogMethod;
+    sqInt flags;
+    sqInt methodHeader;
+    char *sp;
+
+	if ((((longAt(GIV(stackPointer))) & 1) == 0)
+	 && ((((((usqInt) (longAt(longAt(GIV(stackPointer))))) >> 8) & 15) >= 12)
+	 && (isCogMethodReference(longAt(((longAt(GIV(stackPointer))) + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
+		/* begin cogMethodOf: */
+		aMethodOop = longAt(GIV(stackPointer));
+		methodHeader = longAt((aMethodOop + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+		assert((isNonIntegerObject(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		flags = (((cogMethod->stackCheckOffset)) == 0
+			? 3
+			: 1);
+		if ((cogMethod->cmRefersToYoung)) {
+			flags += 4;
+		}
+	}
+	else {
+		flags = 0;
+	}
+	/* begin pop:thenPush: */
+	longAtput((sp = GIV(stackPointer) + ((1 - 1) * BytesPerWord)), ((flags << 1) | 1));
+	GIV(stackPointer) = sp;
+}
+
+
 /*	Return the value of the millisecond clock as an integer. Note that the
 	millisecond clock wraps around periodically. On some platforms it can wrap
 	daily. The range is limited to SmallInteger maxVal / 2 to allow delays of
@@ -34590,18 +34588,9 @@
 primitiveProfileSemaphore(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
     sqInt flushState;
-    sqInt header;
-    StackPage *newPage;
-    sqInt oop;
     sqInt sema;
     char *sp;
-    sqInt sz;
-    char *theFP;
-    sqInt top;
 
 	sema = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	if (((sema & 1))
@@ -34636,84 +34625,8 @@
 		/* begin push: */
 		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp;
-		/* begin voidVMStateForSnapshot */
-
-		/* in case of code compactions. */
-
-		GIV(instructionPointer) = 0;
-		activeContext1 = divorceAllFrames();
-		/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-		VM_LABEL(1ensureAllContextsHaveBytecodePCsOrAreBereaved);
-		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-		while (oop < GIV(freeStart)) {
-			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-			 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-					/* begin markContextAsDead: */
-					assert(isContext(oop));
-					longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-				}
-				else {
-					decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-					if (((decodedIP & 1))
-					 && ((((sqInt) decodedIP)) < 0)) {
-						decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-					}
-				}
-			}
-			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
-			}
-			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-				sz = (longAt(oop)) & AllButTypeMask;
-			}
-			else {
-				/* begin sizeBitsOf: */
-				header = longAt(oop);
-				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-					: header & SizeMask);
-			}
-			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
-		}
-		voidCogCompiledCode();
-		activeContext = activeContext1;
-		/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-		VM_LABEL(3marryContextInNewStackPageAndInitializeInterpreterRegisters);
-		assert(GIV(stackPage) == 0);
-		newPage = makeBaseFrameFor(activeContext);
-		/* begin setStackPageAndLimit: */
-		GIV(stackPage) = newPage;
-		if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-			GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-		}
-		markStackPageMostRecentlyUsed(newPage);
-		GIV(framePointer) = (GIV(stackPage)->headFP);
-		GIV(stackPointer) = (GIV(stackPage)->headSP);
-		/* begin setMethod: */
-		/* begin iframeMethod: */
-		theFP = (GIV(stackPage)->headFP);
-		aMethodObj = longAt(theFP + FoxMethod);
-		assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-		GIV(method) = aMethodObj;
-		assert(isOopCompiledMethod(GIV(method)));
-		
-#    if MULTIPLEBYTECODESETS
-		bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-			? 256
-			: 0);
-
-#    endif /* MULTIPLEBYTECODESETS */
-
-		/* begin popStack */
-		top = longAt(GIV(stackPointer));
-		GIV(stackPointer) += BytesPerWord;
-		GIV(instructionPointer) = ((sqInt) top);
+		activeContext = voidVMStateForSnapshot();
+		marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 		assert((((stackValue(0)) == (nilObject()))
  && (GIV(profileSemaphore) == (nilObject())))
 		 || (((stackValue(0)) == GIV(profileSemaphore))
@@ -38774,98 +38687,211 @@
 primitiveVoidVMState(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
+    char *sp;
+
+	/* begin push: */
+	longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+	GIV(stackPointer) = sp;
+	activeContext = voidVMStateForSnapshot();
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
+	siglongjmp(reenterInterpreter, ReturnToInterpreter);
+}
+
+
+/*	The receiver is a compiledMethod. Clear all entries in the method lookup
+	cache that refer to this method, presumably because it has been redefined,
+	overridden or removed.
+ */
+/*	The receiver is a compiledMethod. Clear all VM state associated with the
+	method, including any machine code, or machine code pcs in context
+	objects.  */
+
+static void
+primitiveVoidVMStateForMethod(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt activeContext;
+    StackPage *aPage;
+    CogMethod *cogMethod;
+    sqInt divorcedSome;
+    sqInt divorcedSome1;
     sqInt header;
-    StackPage *newPage;
+    sqInt i;
+    sqInt i1;
+    sqInt i2;
+    sqInt index;
+    sqInt methodHeader;
+    sqInt methodObj;
+    sqInt oldMethod;
     sqInt oop;
+    sqInt pc;
+    sqInt primBits;
+    sqInt primIdx;
+    sqInt probe;
     char *sp;
     sqInt sz;
     char *theFP;
+    char *theFrame;
+    StackPage *thePage;
+    char *theSP;
     sqInt top;
+    sqInt top1;
+    sqInt value;
 
-	/* begin push: */
-	longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
-	GIV(stackPointer) = sp;
-	/* begin voidVMStateForSnapshot */
-
-	/* in case of code compactions. */
-
-	GIV(instructionPointer) = 0;
-	activeContext1 = divorceAllFrames();
-	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-	VM_LABEL(2ensureAllContextsHaveBytecodePCsOrAreBereaved);
-	oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-	while (oop < GIV(freeStart)) {
-		if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-		 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-			if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-				/* begin markContextAsDead: */
-				assert(isContext(oop));
-				longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-				longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
+	oldMethod = longAt(GIV(stackPointer));
+	probe = 0;
+	for (i = 1; i <= MethodCacheEntries; i += 1) {
+		if ((GIV(methodCache)[probe + MethodCacheMethod]) == oldMethod) {
+			GIV(methodCache)[probe + MethodCacheSelector] = 0;
+		}
+		probe += MethodCacheEntrySize;
+	}
+	/* begin primitiveIndexOf: */
+	primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
+	primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
+	if (primIdx == PrimitiveExternalCallIndex) {
+		flushExternalPrimitiveOf(oldMethod);
+	}
+	/* begin flushAtCache */
+	for (i2 = 1; i2 <= AtCacheTotalSize; i2 += 1) {
+		GIV(atCache)[i2] = 0;
+	}
+	if (methodHasCogMethod(longAt(GIV(stackPointer)))) {
+		methodObj = longAt(GIV(stackPointer));
+		/* begin push: */
+		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+		GIV(stackPointer) = sp;
+		/* begin externalWriteBackHeadFramePointers */
+		assert((GIV(framePointer) - GIV(stackPointer)) < LargeContextSize);
+		assert(GIV(stackPage) == (mostRecentlyUsedPage()));
+		/* begin setHeadFP:andSP:inPage: */
+		assert(GIV(stackPointer) < GIV(framePointer));
+		assert((GIV(stackPointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(stackPointer) > (((GIV(stackPage)->realStackLimit)) - LargeContextSize)));
+		assert((GIV(framePointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(framePointer) > (((GIV(stackPage)->realStackLimit)) - (((sqInt) LargeContextSize >> 1)))));
+		(GIV(stackPage)->headFP = GIV(framePointer));
+		(GIV(stackPage)->headSP = GIV(stackPointer));
+		assert(pageListIsWellFormed());
+		/* begin ensureFrameIsMarried:SP: */
+		VM_LABEL(21ensureFrameIsMarriedSP);
+		theFP = GIV(framePointer);
+		theSP = GIV(stackPointer);
+		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
+			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
+			assert(isContext(frameContext(theFP)));
+			activeContext = longAt(theFP + FoxThisContext);
+			goto l1;
+		}
+		activeContext = marryFrameSP(theFP, theSP);
+	l1:	/* end ensureFrameIsMarried:SP: */;
+		/* begin divorceMachineCodeFramesWithMethod: */
+		/* begin cogMethodOf: */
+		methodHeader = longAt((methodObj + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+		assert((isNonIntegerObject(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		do {
+			if (GIV(stackPage) != 0) {
+				markStackPageMostRecentlyUsed(GIV(stackPage));
 			}
-			else {
-				decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-				if (((decodedIP & 1))
-				 && ((((sqInt) decodedIP)) < 0)) {
-					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
+			/* begin divorceSomeMachineCodeFramesWithMethod: */
+			divorcedSome1 = 0;
+			for (i1 = 0; i1 <= (GIV(numStackPages) - 1); i1 += 1) {
+				/* begin stackPageAt: */
+				aPage = stackPageAtpages(i1, GIV(pages));
+				if (!(isFree(aPage))) {
+					markStackPageMostRecentlyUsed(GIV(stackPage));
+					if (divorceAMachineCodeFrameWithCogMethodin(cogMethod, aPage)) {
+						divorcedSome1 = 1;
+					}
 				}
 			}
+			divorcedSome = divorcedSome1;
+		} while(divorcedSome);
+		/* begin ensureAllContextsWithMethodHaveBytecodePCs: */
+		VM_LABEL(0ensureAllContextsWithMethodHaveBytecodePCs);
+		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
+		while (oop < GIV(freeStart)) {
+			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
+			 && ((((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)
+			 && ((longAt((oop + BaseHeaderSize) + (MethodIndex << ShiftForWord))) == methodObj))) {
+				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
+					if (checkIsStillMarriedContextcurrentFP(oop, (GIV(stackPage)->headFP))) {
+						assert(!(isMachineCodeFrame(frameOfMarriedContext(oop))));
+					}
+				}
+				else {
+					/* begin ensureContextHasBytecodePC: */
+					assert(!(isMarriedOrWidowedContext(oop)));
+					pc = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
+					if (((pc & 1))
+					 && (((pc = (pc >> 1))) < 0)) {
+						pc = mustMapMachineCodePCcontext(pc, oop);
+						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), pc);
+					}
+				}
+			}
+			/* begin objectAfter: */
+			if (DoAssertionChecks) {
+				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
+					error("no objects after the end of memory");
+				}
+			}
+			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+				sz = (longAt(oop)) & AllButTypeMask;
+			}
+			else {
+				/* begin sizeBitsOf: */
+				header = longAt(oop);
+				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+					: header & SizeMask);
+			}
+			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
 		}
-		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
+		unlinkSendsToandFreeIf(methodObj, 1);
+		if ((((longAt((activeContext + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1))
+		 && (!(isWidowedContext(activeContext)))) {
+			/* begin frameOfMarriedContext: */
+			value = longAt((activeContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
+			/* begin withoutSmallIntegerTags: */
+			assert((value & 1));
+			theFrame = pointerForOop(value - 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));
+			thePage = stackPageAtpages(index, GIV(pages));
+			assert(((thePage->headFP)) == theFrame);
+			/* begin setStackPageAndLimit: */
+			GIV(stackPage) = thePage;
+			if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
+				GIV(stackLimit) = (GIV(stackPage)->stackLimit);
 			}
+			markStackPageMostRecentlyUsed(thePage);
+			GIV(stackPointer) = (thePage->headSP);
+			GIV(framePointer) = (thePage->headFP);
+			/* begin popStack */
+			top = longAt(GIV(stackPointer));
+			GIV(stackPointer) += BytesPerWord;
+			GIV(instructionPointer) = ((sqInt) top);
+			assert(methodObj == (stackTop()));
 		}
-		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-			sz = (longAt(oop)) & AllButTypeMask;
-		}
 		else {
-			/* begin sizeBitsOf: */
-			header = longAt(oop);
-			sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-				? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-				: header & SizeMask);
+
+			/* to avoid assert in marryContextInNewStackPageAndInitializeInterpreterRegisters: */
+
+			GIV(stackPage) = 0;
+			marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
+			/* begin popStack */
+			top1 = longAt(GIV(stackPointer));
+			GIV(stackPointer) += BytesPerWord;
+			assert(methodObj == (stackTop()));
+			siglongjmp(reenterInterpreter, ReturnToInterpreter);
 		}
-		oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
 	}
-	voidCogCompiledCode();
-	activeContext = activeContext1;
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
-	siglongjmp(reenterInterpreter, ReturnToInterpreter);
 }
 
 static void
@@ -39453,7 +39479,7 @@
 			printf("\n");
 		}
 		else {
-			print("widdowed (assuming framePointer valid)");
+			print("widowed (assuming framePointer valid)");
 			/* begin cr */
 			printf("\n");
 		}
@@ -40725,6 +40751,17 @@
 		goto l2;
 	}
 	printf("a(n) %.*s", nameLen, name);
+	if (((instanceSizeOf(classOop)) == (ValueIndex + 1))
+	 && (((longAt((classOop + BaseHeaderSize) + (SuperclassIndex << ShiftForWord))) == (superclassOf(fetchClassOfNonInt(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))))))
+	 && ((((longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord))) & 1) == 0)
+	 && (((((usqInt) (longAt(longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord))))) >> 8) & 15) >= 8)))) {
+		/* begin space */
+		/* begin printChar: */
+		putchar(' ');
+		printOopShort(longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord)));
+		print(" -> ");
+		printHex(longAt((oop + BaseHeaderSize) + (ValueIndex << ShiftForWord)));
+	}
 l2:	/* end printOopShortInner: */;
 	flush();
 }
@@ -43969,26 +44006,20 @@
 snapshot(sqInt embedded)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
     sqInt activeProc;
-    sqInt aMethodObj;
     sqInt dataSize;
-    sqInt decodedIP;
     sqInt fmt;
     sqInt header;
     sqInt header1;
     sqInt header2;
-    sqInt header3;
     sqInt i;
     sqInt i1;
-    StackPage *newPage;
     sqInt object;
     sqInt object1;
     sqInt oop;
     sqInt oop1;
     sqInt oop2;
     sqInt oop3;
-    sqInt oop4;
     sqInt rcvr;
     void *setMacType;
     char *sp;
@@ -43997,61 +44028,12 @@
     sqInt stackIndex;
     sqInt sz;
     sqInt sz1;
-    sqInt sz2;
-    char *theFP;
-    sqInt top;
 
 	/* begin push: */
 	object1 = GIV(instructionPointer);
 	longAtput((sp2 = GIV(stackPointer) - BytesPerWord), object1);
 	GIV(stackPointer) = sp2;
-	/* begin voidVMStateForSnapshot */
-
-	/* in case of code compactions. */
-
-	GIV(instructionPointer) = 0;
-	activeContext1 = divorceAllFrames();
-	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-	VM_LABEL(3ensureAllContextsHaveBytecodePCsOrAreBereaved);
-	oop4 = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-	while (oop4 < GIV(freeStart)) {
-		if ((!(((longAt(oop4)) & TypeMask) == HeaderTypeFree))
-		 && (((((usqInt) (longAt(oop4))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-			if (((longAt((oop4 + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-				/* begin markContextAsDead: */
-				assert(isContext(oop4));
-				longAtput((oop4 + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-				longAtput((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-			}
-			else {
-				decodedIP = longAt((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-				if (((decodedIP & 1))
-				 && ((((sqInt) decodedIP)) < 0)) {
-					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop4);
-					longAtput((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-				}
-			}
-		}
-		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop4)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
-			}
-		}
-		if (((longAt(oop4)) & TypeMask) == HeaderTypeFree) {
-			sz2 = (longAt(oop4)) & AllButTypeMask;
-		}
-		else {
-			/* begin sizeBitsOf: */
-			header3 = longAt(oop4);
-			sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
-				? (longAt(oop4 - (BytesPerWord * 2))) & LongSizeMask
-				: header3 & SizeMask);
-		}
-		oop4 = (oop4 + sz2) + (headerTypeBytes[(longAt(oop4 + sz2)) & TypeMask]);
-	}
-	voidCogCompiledCode();
-	activeContext = activeContext1;
+	activeContext = voidVMStateForSnapshot();
 	/* begin pushRemappableOop: */
 	assert(addressCouldBeOop(activeContext));
 	GIV(remapBuffer)[(GIV(remapBufferCount) += 1)] = activeContext;
@@ -44154,37 +44136,7 @@
 		}
 		longAtput((activeContext + BaseHeaderSize) + (StackPointerIndex << ShiftForWord), (((stackIndex - 1) << 1) | 1));
 	}
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(4marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	if (!GIV(primFailCode)) {
 		/* begin push: */
 		object = GIV(falseObj);
@@ -45394,7 +45346,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(20ensureFrameIsMarriedSP);
+	VM_LABEL(22ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -46152,7 +46104,7 @@
 			(GIV(stackPage)->headSP = GIV(stackPointer));
 			assert(pageListIsWellFormed());
 			/* begin ensureFrameIsMarried:SP: */
-			VM_LABEL(21ensureFrameIsMarriedSP);
+			VM_LABEL(23ensureFrameIsMarriedSP);
 			theFP = GIV(framePointer);
 			theSP = GIV(stackPointer);
 			if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -46235,7 +46187,7 @@
 	sched = longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord));
 	oldProc = longAt((sched + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(22ensureFrameIsMarriedSP);
+	VM_LABEL(24ensureFrameIsMarriedSP);
 	theFP = GIV(framePointer);
 	theSP = GIV(stackPointer);
 	if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -47152,6 +47104,70 @@
 }
 
 
+/*	Make sure that all VM state that affects the heap contents is voided so
+	that the heap is ready
+	to be snapshotted. Answer the activeContext object that should be stored
+	in the snapshot.
+ */
+
+static sqInt
+voidVMStateForSnapshot(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt activeContext;
+    sqInt decodedIP;
+    sqInt header;
+    sqInt oop;
+    sqInt sz;
+
+
+	/* in case of code compactions. */
+
+	GIV(instructionPointer) = 0;
+	activeContext = divorceAllFrames();
+	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
+	VM_LABEL(0ensureAllContextsHaveBytecodePCsOrAreBereaved);
+	oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
+	while (oop < GIV(freeStart)) {
+		if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
+		 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
+			if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
+				/* begin markContextAsDead: */
+				assert(isContext(oop));
+				longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
+				longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
+			}
+			else {
+				decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
+				if (((decodedIP & 1))
+				 && ((((sqInt) decodedIP)) < 0)) {
+					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
+					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
+				}
+			}
+		}
+		/* begin objectAfter: */
+		if (DoAssertionChecks) {
+			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
+				error("no objects after the end of memory");
+			}
+		}
+		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+			sz = (longAt(oop)) & AllButTypeMask;
+		}
+		else {
+			/* begin sizeBitsOf: */
+			header = longAt(oop);
+			sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+				? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+				: header & SizeMask);
+		}
+		oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
+	}
+	voidCogCompiledCode();
+	return activeContext;
+}
+
+
 /*	Return the highest priority process that is ready to run.
 	To save time looking at many empty lists before finding a
 	runnable process the VM maintains a variable holding the
@@ -47438,6 +47454,7 @@
 	{"", "primitiveLessThanLargeIntegers", (void*)primitiveLessThanLargeIntegers},
 	{"", "primitiveLongRunningPrimitive", (void*)primitiveLongRunningPrimitive},
 	{"", "primitiveLongRunningPrimitiveSemaphore", (void*)primitiveLongRunningPrimitiveSemaphore},
+	{"", "primitiveMethodXray", (void*)primitiveMethodXray},
 	{"", "primitiveMillisecondClockMask", (void*)primitiveMillisecondClockMask},
 	{"", "primitiveModLargeIntegers", (void*)primitiveModLargeIntegers},
 	{"", "primitiveMultiplyLargeIntegers", (void*)primitiveMultiplyLargeIntegers},

Modified: branches/Cog/src/vm/cointerpmt.h
===================================================================
--- branches/Cog/src/vm/cointerpmt.h	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/src/vm/cointerpmt.h	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,5 +1,7 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGeneratorGlobalStructure eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
 
 

Modified: branches/Cog/src/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/src/vm/gcc3x-cointerp.c	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/src/vm/gcc3x-cointerp.c	2012-04-13 17:44:17 UTC (rev 2548)
@@ -2,11 +2,17 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGeneratorGlobalStructure eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
    from
-	CoInterpreter VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CoInterpreter eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -212,6 +218,7 @@
 #define ImmutabilityBit 0x20000000
 #define InstanceSpecificationIndex 2
 #define InstructionPointerIndex 1
+#define KeyIndex 0
 #define LargeContextBit 0x40000
 #define LargeContextBytes 252
 #define LargeContextSize 252
@@ -461,6 +468,7 @@
 static void displayBitsOfLeftTopRightBottom(sqInt aForm, sqInt l, sqInt t, sqInt r, sqInt b);
 sqInt displayObject(void);
 static sqInt divorceAllFrames(void);
+static sqInt divorceAMachineCodeFrameWithCogMethodin(CogMethod *cogMethod, StackPage *aStackPage);
 static void divorceFramesIn(StackPage *aStackPage);
 static sqInt doPrimitiveDivby(sqInt rcvr, sqInt arg);
 static sqInt doPrimitiveModby(sqInt rcvr, sqInt arg);
@@ -669,6 +677,7 @@
 static void markStackPageMostRecentlyUsed(StackPage *page);
 static void markStackPageNextMostRecentlyUsed(StackPage *page);
 static sqInt marriedContextpointsTostackDeltaForCurrentFrame(sqInt spouseContext, sqInt anOop, sqInt stackDeltaForCurrentFrame);
+static void marryContextInNewStackPageAndInitializeInterpreterRegisters(sqInt aContext);
 static sqInt marryFrameSP(char *theFP, char *theSP);
 static void maybeFlagMethodAsInterpreted(sqInt aMethod);
 sqInt maybeSplObj(sqInt index);
@@ -874,6 +883,7 @@
 static void primitiveMarkUnwindMethod(void);
 static void primitiveMaxIdentityHash(void);
 sqInt primitiveMethod(void);
+EXPORT(void) primitiveMethodXray(void);
 static void primitiveMillisecondClock(void);
 EXPORT(sqInt) primitiveMillisecondClockMask(void);
 static void primitiveMod(void);
@@ -965,6 +975,7 @@
 static void primitiveVMProfileSamplesInto(void);
 EXPORT(void) primitiveVoidReceiver(void);
 static void primitiveVoidVMState(void);
+static void primitiveVoidVMStateForMethod(void);
 static void primitiveWait(void);
 static void primitiveYield(void);
 void * primTraceLogAddress(void);
@@ -1135,6 +1146,7 @@
 static void verifyCleanHeaders(void);
 sqInt vmEndianness(void);
 static void voidLongRunningPrimitive(char *reason);
+static sqInt voidVMStateForSnapshot(void);
 static sqInt wakeHighestPriority(void);
 static sqInt withSmallIntegerTags(char *value);
 static sqInt wordSwapped(sqInt w);
@@ -1154,8 +1166,8 @@
 _iss char * framePointer;
 _iss sqInt specialObjectsOop;
 _iss StackPage * stackPage;
+_iss sqInt nilObj;
 _iss usqInt method;
-_iss sqInt nilObj;
 _iss usqInt instructionPointer;
 _iss usqInt freeStart;
 _iss sqInt argumentCount;
@@ -1172,15 +1184,15 @@
 _iss sqInt lkupClass;
 _iss sqInt bytesPerPage;
 _iss sqInt traceLogIndex;
+_iss usqInt reserveStart;
 _iss char * stackLimit;
-_iss usqInt reserveStart;
 _iss usqInt memoryLimit;
 _iss StackPage * mostRecentlyUsedPage;
 _iss sqInt needGCFlag;
 _iss usqInt scavengeThreshold;
+_iss sqInt numStackPages;
 _iss unsigned char primTraceLogIndex;
 _iss sqLong nextProfileTick;
-_iss sqInt numStackPages;
 _iss sqInt jmpDepth;
 _iss usqInt fwdTableNext;
 _iss sqInt longRunningPrimitiveCheckSemaphore;
@@ -1540,7 +1552,7 @@
 	/* 212 */ primitiveContextSize,
 	/* 213 */ primitiveContextXray,
 	/* 214 */ primitiveVoidVMState,
-	/* 215 */ (void (*)(void))0,
+	/* 215 */ primitiveVoidVMStateForMethod,
 	/* 216 */ (void (*)(void))0,
 	/* 217 */ (void (*)(void))0,
 	/* 218 */ primitiveDoNamedPrimitiveWithArgs,
@@ -1903,7 +1915,9 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.154]";
+const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter eneraiton.
+
+VMMaker.oscog-eem.156]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -13430,6 +13444,55 @@
 	return activeContext;
 }
 
+
+/*	Divorce at most one frame in the current page (since the divorce may cause
+	the page to be split)
+	and answer whether a frame was divorced. */
+
+static sqInt
+divorceAMachineCodeFrameWithCogMethodin(CogMethod *cogMethod, StackPage *aStackPage)
+{
+    char *calleeFP;
+    sqInt theContext;
+    char *theFP;
+    char *theSP;
+
+	theFP = (aStackPage->headFP);
+	theSP = (aStackPage->headSP);
+
+	/* theSP points at hottest item on frame's stack */
+
+	theSP += BytesPerWord;
+	while (1) {
+		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase)
+		 && (cogMethod == (mframeHomeMethod(theFP)))) {
+			/* begin ensureFrameIsMarried:SP: */
+			VM_LABEL(11ensureFrameIsMarriedSP);
+			if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
+				? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+				: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
+				assert(isContext(frameContext(theFP)));
+				theContext = longAt(theFP + FoxThisContext);
+				goto l1;
+			}
+			theContext = marryFrameSP(theFP, theSP);
+		l1:	/* end ensureFrameIsMarried:SP: */;
+			externalDivorceFrameandContext(theFP, theContext);
+			return 1;
+		}
+		calleeFP = theFP;
+		/* begin frameCallerFP: */
+		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
+		if (!(theFP != 0)) break;
+		/* begin frameCallerSP: */
+		assert(!(isBaseFrame(calleeFP)));
+		theSP = (calleeFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(calleeFP + FoxMethod)))) < heapBase
+	? (mframeCogMethod(calleeFP)->cmNumArgs)
+	: byteAt((calleeFP + FoxIFrameFlags) + 1))))) + BytesPerWord;
+	}
+	return 0;
+}
+
 static void
 divorceFramesIn(StackPage *aStackPage)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
@@ -13456,7 +13519,7 @@
 	calleeContext = null;
 	while (1) {
 		/* begin ensureFrameIsMarried:SP: */
-		VM_LABEL(11ensureFrameIsMarriedSP);
+		VM_LABEL(12ensureFrameIsMarriedSP);
 		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
 			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
@@ -14369,7 +14432,7 @@
 		return callerContextOrNil;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(12ensureFrameIsMarriedSP);
+	VM_LABEL(13ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -14415,6 +14478,7 @@
 {
     sqInt pc;
 
+	/* begin ensureContextHasBytecodePC: */
 	assert(!(isMarriedOrWidowedContext(aContext)));
 	pc = longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
 	if (((pc & 1))
@@ -14906,7 +14970,6 @@
     char *theSP1;
     sqInt valuePointer;
 
-	assert(theFP != GIV(framePointer));
 	assert((GIV(stackPage) == 0)
 	 || (GIV(stackPage) == (mostRecentlyUsedPage())));
 	/* begin stackPageFor: */
@@ -14940,7 +15003,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(13ensureFrameIsMarriedSP);
+	VM_LABEL(14ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP1 = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -15137,7 +15200,7 @@
 			return callerContextOrNil;
 		}
 		/* begin ensureFrameIsMarried:SP: */
-		VM_LABEL(14ensureFrameIsMarriedSP);
+		VM_LABEL(15ensureFrameIsMarriedSP);
 		/* begin frameCallerStackPointer: */
 		assert(!(isBaseFrame(spouseFP)));
 		theSP = (spouseFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(spouseFP + FoxMethod)))) < heapBase
@@ -15808,7 +15871,7 @@
 	: byteAt((theFPAbove + FoxIFrameFlags) + 1))))) + BytesPerWord;
 				}
 				/* begin ensureFrameIsMarried:SP: */
-				VM_LABEL(15ensureFrameIsMarriedSP);
+				VM_LABEL(16ensureFrameIsMarriedSP);
 				if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 					? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
 					: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
@@ -17223,7 +17286,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(16ensureFrameIsMarriedSP);
+	VM_LABEL(17ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -18311,13 +18374,9 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
     sqInt activeProc;
-    sqInt aMethodObj;
-    StackPage *newPage;
     sqInt stackPageBytes;
     sqInt stackPagesBytes;
-    char *theFP;
     char *theStackMemory;
-    sqInt top;
 
 	stackPageBytes = stackPageByteSize();
 	stackPagesBytes = (GIV(numStackPages) * ((sizeof(CogStackPage)) + (stackPageByteSize()))) + BytesPerWord;
@@ -18333,37 +18392,7 @@
 	}
 	activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	activeContext = longAt((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord));
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(0marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	ioInitHeartbeat();
 	initialEnterSmalltalkExecutive();
 	return null;
@@ -19164,7 +19193,8 @@
     StackPage *thePage;
     sqInt value;
 
-	assert(isContext(aOnceMarriedContext));
+	assert((isContext(aOnceMarriedContext))
+	 && (isMarriedOrWidowedContext(aOnceMarriedContext)));
 	/* begin frameOfMarriedContext: */
 	value = longAt((aOnceMarriedContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
 	/* begin withoutSmallIntegerTags: */
@@ -19947,13 +19977,9 @@
 
 void
 loadInitialContext(void)
-{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+{
     sqInt activeContext;
     sqInt activeProc;
-    sqInt aMethodObj;
-    StackPage *newPage;
-    char *theFP;
-    sqInt top;
 
 	if ((checkForLeaks & 1) != 0) {
 		clearLeakMapAndMapAccessibleObjects();
@@ -19961,37 +19987,7 @@
 	}
 	activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	activeContext = longAt((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord));
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(1marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 }
 
 void
@@ -21908,6 +21904,50 @@
 }
 
 
+/*	Establish aContext at the base of a new stackPage, make the stackPage the
+	active one and set-up the interreter registers. This is used to boot the
+	system and bring it back after a snapshot. */
+
+static void
+marryContextInNewStackPageAndInitializeInterpreterRegisters(sqInt aContext)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt aMethodObj;
+    StackPage *newPage;
+    char *theFP;
+    sqInt top;
+
+	assert(GIV(stackPage) == 0);
+	newPage = makeBaseFrameFor(aContext);
+	/* begin setStackPageAndLimit: */
+	GIV(stackPage) = newPage;
+	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
+		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
+	}
+	markStackPageMostRecentlyUsed(newPage);
+	GIV(framePointer) = (GIV(stackPage)->headFP);
+	GIV(stackPointer) = (GIV(stackPage)->headSP);
+	/* begin setMethod: */
+	/* begin iframeMethod: */
+	theFP = (GIV(stackPage)->headFP);
+	aMethodObj = longAt(theFP + FoxMethod);
+	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
+	GIV(method) = aMethodObj;
+	assert(isOopCompiledMethod(GIV(method)));
+	
+#  if MULTIPLEBYTECODESETS
+	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
+		? 256
+		: 0);
+
+#  endif /* MULTIPLEBYTECODESETS */
+
+	/* begin popStack */
+	top = longAt(GIV(stackPointer));
+	GIV(stackPointer) += BytesPerWord;
+	GIV(instructionPointer) = ((sqInt) top);
+}
+
+
 /*	Marry an unmarried frame. This means creating a spouse context initialized
 	with a subset of the frame's state (state through the last argument) that
 	references the
@@ -22398,7 +22438,7 @@
 	assert(frameHasContext(callerFP));
 	assert(isContext(frameContext(callerFP)));
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(17ensureFrameIsMarriedSP);
+	VM_LABEL(18ensureFrameIsMarriedSP);
 	theSP = theFP + (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 	? FoxMFReceiver
 	: FoxIFReceiver));
@@ -29484,7 +29524,7 @@
 	for (i1 = 1; i1 <= AtCacheTotalSize; i1 += 1) {
 		GIV(atCache)[i1] = 0;
 	}
-	unlinkSendsTo(longAt(GIV(stackPointer)));
+	unlinkSendsToandFreeIf(longAt(GIV(stackPointer)), 0);
 }
 
 
@@ -31744,18 +31784,9 @@
 primitiveLongRunningPrimitiveSemaphore(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
     sqInt flushState;
-    sqInt header;
-    StackPage *newPage;
-    sqInt oop;
     sqInt sema;
     char *sp;
-    sqInt sz;
-    char *theFP;
-    sqInt top;
 
 	sema = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	if (((sema & 1))
@@ -31785,84 +31816,8 @@
 		/* begin push: */
 		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp;
-		/* begin voidVMStateForSnapshot */
-
-		/* in case of code compactions. */
-
-		GIV(instructionPointer) = 0;
-		activeContext1 = divorceAllFrames();
-		/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-		VM_LABEL(0ensureAllContextsHaveBytecodePCsOrAreBereaved);
-		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-		while (oop < GIV(freeStart)) {
-			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-			 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-					/* begin markContextAsDead: */
-					assert(isContext(oop));
-					longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-				}
-				else {
-					decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-					if (((decodedIP & 1))
-					 && ((((sqInt) decodedIP)) < 0)) {
-						decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-					}
-				}
-			}
-			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
-			}
-			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-				sz = (longAt(oop)) & AllButTypeMask;
-			}
-			else {
-				/* begin sizeBitsOf: */
-				header = longAt(oop);
-				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-					: header & SizeMask);
-			}
-			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
-		}
-		voidCogCompiledCode();
-		activeContext = activeContext1;
-		/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-		VM_LABEL(2marryContextInNewStackPageAndInitializeInterpreterRegisters);
-		assert(GIV(stackPage) == 0);
-		newPage = makeBaseFrameFor(activeContext);
-		/* begin setStackPageAndLimit: */
-		GIV(stackPage) = newPage;
-		if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-			GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-		}
-		markStackPageMostRecentlyUsed(newPage);
-		GIV(framePointer) = (GIV(stackPage)->headFP);
-		GIV(stackPointer) = (GIV(stackPage)->headSP);
-		/* begin setMethod: */
-		/* begin iframeMethod: */
-		theFP = (GIV(stackPage)->headFP);
-		aMethodObj = longAt(theFP + FoxMethod);
-		assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-		GIV(method) = aMethodObj;
-		assert(isOopCompiledMethod(GIV(method)));
-		
-#    if MULTIPLEBYTECODESETS
-		bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-			? 256
-			: 0);
-
-#    endif /* MULTIPLEBYTECODESETS */
-
-		/* begin popStack */
-		top = longAt(GIV(stackPointer));
-		GIV(stackPointer) += BytesPerWord;
-		GIV(instructionPointer) = ((sqInt) top);
+		activeContext = voidVMStateForSnapshot();
+		marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 		assert((((stackValue(0)) == (nilObject()))
  && (GIV(longRunningPrimitiveCheckSemaphore) == null))
 		 || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore))
@@ -32029,6 +31984,49 @@
 }
 
 
+/*	Lift the veil from a method and answer an integer describing the interior
+	state of its machine code.
+	Used for e.g. VM tests so they can verify they're testing what they think
+	they're testing.
+	0 implies a vanilla method.
+	Bit 0 = method is currently compiled to machine code
+	Bit 1 = is compiled frameless.
+	Bit 2 = method refers to young object */
+
+EXPORT(void)
+primitiveMethodXray(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt aMethodOop;
+    CogMethod *cogMethod;
+    sqInt flags;
+    sqInt methodHeader;
+    char *sp;
+
+	if ((((longAt(GIV(stackPointer))) & 1) == 0)
+	 && ((((((usqInt) (longAt(longAt(GIV(stackPointer))))) >> 8) & 15) >= 12)
+	 && (isCogMethodReference(longAt(((longAt(GIV(stackPointer))) + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
+		/* begin cogMethodOf: */
+		aMethodOop = longAt(GIV(stackPointer));
+		methodHeader = longAt((aMethodOop + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+		assert((isNonIntegerObject(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		flags = (((cogMethod->stackCheckOffset)) == 0
+			? 3
+			: 1);
+		if ((cogMethod->cmRefersToYoung)) {
+			flags += 4;
+		}
+	}
+	else {
+		flags = 0;
+	}
+	/* begin pop:thenPush: */
+	longAtput((sp = GIV(stackPointer) + ((1 - 1) * BytesPerWord)), ((flags << 1) | 1));
+	GIV(stackPointer) = sp;
+}
+
+
 /*	Return the value of the millisecond clock as an integer. Note that the
 	millisecond clock wraps around periodically. On some platforms it can wrap
 	daily. The range is limited to SmallInteger maxVal / 2 to allow delays of
@@ -33304,18 +33302,9 @@
 primitiveProfileSemaphore(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
     sqInt flushState;
-    sqInt header;
-    StackPage *newPage;
-    sqInt oop;
     sqInt sema;
     char *sp;
-    sqInt sz;
-    char *theFP;
-    sqInt top;
 
 	sema = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	if (((sema & 1))
@@ -33350,84 +33339,8 @@
 		/* begin push: */
 		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp;
-		/* begin voidVMStateForSnapshot */
-
-		/* in case of code compactions. */
-
-		GIV(instructionPointer) = 0;
-		activeContext1 = divorceAllFrames();
-		/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-		VM_LABEL(1ensureAllContextsHaveBytecodePCsOrAreBereaved);
-		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-		while (oop < GIV(freeStart)) {
-			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-			 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-					/* begin markContextAsDead: */
-					assert(isContext(oop));
-					longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-				}
-				else {
-					decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-					if (((decodedIP & 1))
-					 && ((((sqInt) decodedIP)) < 0)) {
-						decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-					}
-				}
-			}
-			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
-			}
-			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-				sz = (longAt(oop)) & AllButTypeMask;
-			}
-			else {
-				/* begin sizeBitsOf: */
-				header = longAt(oop);
-				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-					: header & SizeMask);
-			}
-			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
-		}
-		voidCogCompiledCode();
-		activeContext = activeContext1;
-		/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-		VM_LABEL(3marryContextInNewStackPageAndInitializeInterpreterRegisters);
-		assert(GIV(stackPage) == 0);
-		newPage = makeBaseFrameFor(activeContext);
-		/* begin setStackPageAndLimit: */
-		GIV(stackPage) = newPage;
-		if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-			GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-		}
-		markStackPageMostRecentlyUsed(newPage);
-		GIV(framePointer) = (GIV(stackPage)->headFP);
-		GIV(stackPointer) = (GIV(stackPage)->headSP);
-		/* begin setMethod: */
-		/* begin iframeMethod: */
-		theFP = (GIV(stackPage)->headFP);
-		aMethodObj = longAt(theFP + FoxMethod);
-		assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-		GIV(method) = aMethodObj;
-		assert(isOopCompiledMethod(GIV(method)));
-		
-#    if MULTIPLEBYTECODESETS
-		bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-			? 256
-			: 0);
-
-#    endif /* MULTIPLEBYTECODESETS */
-
-		/* begin popStack */
-		top = longAt(GIV(stackPointer));
-		GIV(stackPointer) += BytesPerWord;
-		GIV(instructionPointer) = ((sqInt) top);
+		activeContext = voidVMStateForSnapshot();
+		marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 		assert((((stackValue(0)) == (nilObject()))
  && (GIV(profileSemaphore) == (nilObject())))
 		 || (((stackValue(0)) == GIV(profileSemaphore))
@@ -37452,98 +37365,211 @@
 primitiveVoidVMState(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
+    char *sp;
+
+	/* begin push: */
+	longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+	GIV(stackPointer) = sp;
+	activeContext = voidVMStateForSnapshot();
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
+	siglongjmp(reenterInterpreter, ReturnToInterpreter);
+}
+
+
+/*	The receiver is a compiledMethod. Clear all entries in the method lookup
+	cache that refer to this method, presumably because it has been redefined,
+	overridden or removed.
+ */
+/*	The receiver is a compiledMethod. Clear all VM state associated with the
+	method, including any machine code, or machine code pcs in context
+	objects.  */
+
+static void
+primitiveVoidVMStateForMethod(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt activeContext;
+    StackPage *aPage;
+    CogMethod *cogMethod;
+    sqInt divorcedSome;
+    sqInt divorcedSome1;
     sqInt header;
-    StackPage *newPage;
+    sqInt i;
+    sqInt i1;
+    sqInt i2;
+    sqInt index;
+    sqInt methodHeader;
+    sqInt methodObj;
+    sqInt oldMethod;
     sqInt oop;
+    sqInt pc;
+    sqInt primBits;
+    sqInt primIdx;
+    sqInt probe;
     char *sp;
     sqInt sz;
     char *theFP;
+    char *theFrame;
+    StackPage *thePage;
+    char *theSP;
     sqInt top;
+    sqInt top1;
+    sqInt value;
 
-	/* begin push: */
-	longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
-	GIV(stackPointer) = sp;
-	/* begin voidVMStateForSnapshot */
-
-	/* in case of code compactions. */
-
-	GIV(instructionPointer) = 0;
-	activeContext1 = divorceAllFrames();
-	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-	VM_LABEL(2ensureAllContextsHaveBytecodePCsOrAreBereaved);
-	oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-	while (oop < GIV(freeStart)) {
-		if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-		 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-			if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-				/* begin markContextAsDead: */
-				assert(isContext(oop));
-				longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-				longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
+	oldMethod = longAt(GIV(stackPointer));
+	probe = 0;
+	for (i = 1; i <= MethodCacheEntries; i += 1) {
+		if ((GIV(methodCache)[probe + MethodCacheMethod]) == oldMethod) {
+			GIV(methodCache)[probe + MethodCacheSelector] = 0;
+		}
+		probe += MethodCacheEntrySize;
+	}
+	/* begin primitiveIndexOf: */
+	primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
+	primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
+	if (primIdx == PrimitiveExternalCallIndex) {
+		flushExternalPrimitiveOf(oldMethod);
+	}
+	/* begin flushAtCache */
+	for (i2 = 1; i2 <= AtCacheTotalSize; i2 += 1) {
+		GIV(atCache)[i2] = 0;
+	}
+	if (methodHasCogMethod(longAt(GIV(stackPointer)))) {
+		methodObj = longAt(GIV(stackPointer));
+		/* begin push: */
+		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+		GIV(stackPointer) = sp;
+		/* begin externalWriteBackHeadFramePointers */
+		assert((GIV(framePointer) - GIV(stackPointer)) < LargeContextSize);
+		assert(GIV(stackPage) == (mostRecentlyUsedPage()));
+		/* begin setHeadFP:andSP:inPage: */
+		assert(GIV(stackPointer) < GIV(framePointer));
+		assert((GIV(stackPointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(stackPointer) > (((GIV(stackPage)->realStackLimit)) - LargeContextSize)));
+		assert((GIV(framePointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(framePointer) > (((GIV(stackPage)->realStackLimit)) - (((sqInt) LargeContextSize >> 1)))));
+		(GIV(stackPage)->headFP = GIV(framePointer));
+		(GIV(stackPage)->headSP = GIV(stackPointer));
+		assert(pageListIsWellFormed());
+		/* begin ensureFrameIsMarried:SP: */
+		VM_LABEL(19ensureFrameIsMarriedSP);
+		theFP = GIV(framePointer);
+		theSP = GIV(stackPointer);
+		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
+			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
+			assert(isContext(frameContext(theFP)));
+			activeContext = longAt(theFP + FoxThisContext);
+			goto l1;
+		}
+		activeContext = marryFrameSP(theFP, theSP);
+	l1:	/* end ensureFrameIsMarried:SP: */;
+		/* begin divorceMachineCodeFramesWithMethod: */
+		/* begin cogMethodOf: */
+		methodHeader = longAt((methodObj + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+		assert((isNonIntegerObject(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		do {
+			if (GIV(stackPage) != 0) {
+				markStackPageMostRecentlyUsed(GIV(stackPage));
 			}
-			else {
-				decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-				if (((decodedIP & 1))
-				 && ((((sqInt) decodedIP)) < 0)) {
-					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
+			/* begin divorceSomeMachineCodeFramesWithMethod: */
+			divorcedSome1 = 0;
+			for (i1 = 0; i1 <= (GIV(numStackPages) - 1); i1 += 1) {
+				/* begin stackPageAt: */
+				aPage = stackPageAtpages(i1, GIV(pages));
+				if (!(isFree(aPage))) {
+					markStackPageMostRecentlyUsed(GIV(stackPage));
+					if (divorceAMachineCodeFrameWithCogMethodin(cogMethod, aPage)) {
+						divorcedSome1 = 1;
+					}
 				}
 			}
+			divorcedSome = divorcedSome1;
+		} while(divorcedSome);
+		/* begin ensureAllContextsWithMethodHaveBytecodePCs: */
+		VM_LABEL(0ensureAllContextsWithMethodHaveBytecodePCs);
+		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
+		while (oop < GIV(freeStart)) {
+			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
+			 && ((((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)
+			 && ((longAt((oop + BaseHeaderSize) + (MethodIndex << ShiftForWord))) == methodObj))) {
+				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
+					if (checkIsStillMarriedContextcurrentFP(oop, (GIV(stackPage)->headFP))) {
+						assert(!(isMachineCodeFrame(frameOfMarriedContext(oop))));
+					}
+				}
+				else {
+					/* begin ensureContextHasBytecodePC: */
+					assert(!(isMarriedOrWidowedContext(oop)));
+					pc = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
+					if (((pc & 1))
+					 && (((pc = (pc >> 1))) < 0)) {
+						pc = mustMapMachineCodePCcontext(pc, oop);
+						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), pc);
+					}
+				}
+			}
+			/* begin objectAfter: */
+			if (DoAssertionChecks) {
+				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
+					error("no objects after the end of memory");
+				}
+			}
+			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+				sz = (longAt(oop)) & AllButTypeMask;
+			}
+			else {
+				/* begin sizeBitsOf: */
+				header = longAt(oop);
+				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+					: header & SizeMask);
+			}
+			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
 		}
-		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
+		unlinkSendsToandFreeIf(methodObj, 1);
+		if ((((longAt((activeContext + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1))
+		 && (!(isWidowedContext(activeContext)))) {
+			/* begin frameOfMarriedContext: */
+			value = longAt((activeContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
+			/* begin withoutSmallIntegerTags: */
+			assert((value & 1));
+			theFrame = pointerForOop(value - 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));
+			thePage = stackPageAtpages(index, GIV(pages));
+			assert(((thePage->headFP)) == theFrame);
+			/* begin setStackPageAndLimit: */
+			GIV(stackPage) = thePage;
+			if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
+				GIV(stackLimit) = (GIV(stackPage)->stackLimit);
 			}
+			markStackPageMostRecentlyUsed(thePage);
+			GIV(stackPointer) = (thePage->headSP);
+			GIV(framePointer) = (thePage->headFP);
+			/* begin popStack */
+			top = longAt(GIV(stackPointer));
+			GIV(stackPointer) += BytesPerWord;
+			GIV(instructionPointer) = ((sqInt) top);
+			assert(methodObj == (stackTop()));
 		}
-		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-			sz = (longAt(oop)) & AllButTypeMask;
-		}
 		else {
-			/* begin sizeBitsOf: */
-			header = longAt(oop);
-			sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-				? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-				: header & SizeMask);
+
+			/* to avoid assert in marryContextInNewStackPageAndInitializeInterpreterRegisters: */
+
+			GIV(stackPage) = 0;
+			marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
+			/* begin popStack */
+			top1 = longAt(GIV(stackPointer));
+			GIV(stackPointer) += BytesPerWord;
+			assert(methodObj == (stackTop()));
+			siglongjmp(reenterInterpreter, ReturnToInterpreter);
 		}
-		oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
 	}
-	voidCogCompiledCode();
-	activeContext = activeContext1;
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
-	siglongjmp(reenterInterpreter, ReturnToInterpreter);
 }
 
 static void
@@ -38131,7 +38157,7 @@
 			printf("\n");
 		}
 		else {
-			print("widdowed (assuming framePointer valid)");
+			print("widowed (assuming framePointer valid)");
 			/* begin cr */
 			printf("\n");
 		}
@@ -39379,6 +39405,17 @@
 		goto l2;
 	}
 	printf("a(n) %.*s", nameLen, name);
+	if (((instanceSizeOf(classOop)) == (ValueIndex + 1))
+	 && (((longAt((classOop + BaseHeaderSize) + (SuperclassIndex << ShiftForWord))) == (superclassOf(fetchClassOfNonInt(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))))))
+	 && ((((longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord))) & 1) == 0)
+	 && (((((usqInt) (longAt(longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord))))) >> 8) & 15) >= 8)))) {
+		/* begin space */
+		/* begin printChar: */
+		putchar(' ');
+		printOopShort(longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord)));
+		print(" -> ");
+		printHex(longAt((oop + BaseHeaderSize) + (ValueIndex << ShiftForWord)));
+	}
 l2:	/* end printOopShortInner: */;
 	flush();
 }
@@ -42546,26 +42583,20 @@
 snapshot(sqInt embedded)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
     sqInt activeProc;
-    sqInt aMethodObj;
     sqInt dataSize;
-    sqInt decodedIP;
     sqInt fmt;
     sqInt header;
     sqInt header1;
     sqInt header2;
-    sqInt header3;
     sqInt i;
     sqInt i1;
-    StackPage *newPage;
     sqInt object;
     sqInt object1;
     sqInt oop;
     sqInt oop1;
     sqInt oop2;
     sqInt oop3;
-    sqInt oop4;
     sqInt rcvr;
     void *setMacType;
     char *sp;
@@ -42574,61 +42605,12 @@
     sqInt stackIndex;
     sqInt sz;
     sqInt sz1;
-    sqInt sz2;
-    char *theFP;
-    sqInt top;
 
 	/* begin push: */
 	object1 = GIV(instructionPointer);
 	longAtput((sp2 = GIV(stackPointer) - BytesPerWord), object1);
 	GIV(stackPointer) = sp2;
-	/* begin voidVMStateForSnapshot */
-
-	/* in case of code compactions. */
-
-	GIV(instructionPointer) = 0;
-	activeContext1 = divorceAllFrames();
-	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-	VM_LABEL(3ensureAllContextsHaveBytecodePCsOrAreBereaved);
-	oop4 = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-	while (oop4 < GIV(freeStart)) {
-		if ((!(((longAt(oop4)) & TypeMask) == HeaderTypeFree))
-		 && (((((usqInt) (longAt(oop4))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-			if (((longAt((oop4 + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-				/* begin markContextAsDead: */
-				assert(isContext(oop4));
-				longAtput((oop4 + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-				longAtput((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-			}
-			else {
-				decodedIP = longAt((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-				if (((decodedIP & 1))
-				 && ((((sqInt) decodedIP)) < 0)) {
-					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop4);
-					longAtput((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-				}
-			}
-		}
-		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop4)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
-			}
-		}
-		if (((longAt(oop4)) & TypeMask) == HeaderTypeFree) {
-			sz2 = (longAt(oop4)) & AllButTypeMask;
-		}
-		else {
-			/* begin sizeBitsOf: */
-			header3 = longAt(oop4);
-			sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
-				? (longAt(oop4 - (BytesPerWord * 2))) & LongSizeMask
-				: header3 & SizeMask);
-		}
-		oop4 = (oop4 + sz2) + (headerTypeBytes[(longAt(oop4 + sz2)) & TypeMask]);
-	}
-	voidCogCompiledCode();
-	activeContext = activeContext1;
+	activeContext = voidVMStateForSnapshot();
 	/* begin pushRemappableOop: */
 	assert(addressCouldBeOop(activeContext));
 	GIV(remapBuffer)[(GIV(remapBufferCount) += 1)] = activeContext;
@@ -42731,37 +42713,7 @@
 		}
 		longAtput((activeContext + BaseHeaderSize) + (StackPointerIndex << ShiftForWord), (((stackIndex - 1) << 1) | 1));
 	}
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(4marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	if (!GIV(primFailCode)) {
 		/* begin push: */
 		object = GIV(falseObj);
@@ -43901,7 +43853,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(18ensureFrameIsMarriedSP);
+	VM_LABEL(20ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -44526,7 +44478,7 @@
 	sched = longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord));
 	oldProc = longAt((sched + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(19ensureFrameIsMarriedSP);
+	VM_LABEL(21ensureFrameIsMarriedSP);
 	theFP = GIV(framePointer);
 	theSP = GIV(stackPointer);
 	if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -45399,6 +45351,70 @@
 }
 
 
+/*	Make sure that all VM state that affects the heap contents is voided so
+	that the heap is ready
+	to be snapshotted. Answer the activeContext object that should be stored
+	in the snapshot.
+ */
+
+static sqInt
+voidVMStateForSnapshot(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt activeContext;
+    sqInt decodedIP;
+    sqInt header;
+    sqInt oop;
+    sqInt sz;
+
+
+	/* in case of code compactions. */
+
+	GIV(instructionPointer) = 0;
+	activeContext = divorceAllFrames();
+	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
+	VM_LABEL(0ensureAllContextsHaveBytecodePCsOrAreBereaved);
+	oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
+	while (oop < GIV(freeStart)) {
+		if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
+		 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
+			if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
+				/* begin markContextAsDead: */
+				assert(isContext(oop));
+				longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
+				longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
+			}
+			else {
+				decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
+				if (((decodedIP & 1))
+				 && ((((sqInt) decodedIP)) < 0)) {
+					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
+					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
+				}
+			}
+		}
+		/* begin objectAfter: */
+		if (DoAssertionChecks) {
+			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
+				error("no objects after the end of memory");
+			}
+		}
+		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+			sz = (longAt(oop)) & AllButTypeMask;
+		}
+		else {
+			/* begin sizeBitsOf: */
+			header = longAt(oop);
+			sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+				? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+				: header & SizeMask);
+		}
+		oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
+	}
+	voidCogCompiledCode();
+	return activeContext;
+}
+
+
 /*	Return the highest priority process that is ready to run.
 	To save time looking at many empty lists before finding a
 	runnable process the VM maintains a variable holding the
@@ -45607,6 +45623,7 @@
 	{"", "primitiveLessThanLargeIntegers", (void*)primitiveLessThanLargeIntegers},
 	{"", "primitiveLongRunningPrimitive", (void*)primitiveLongRunningPrimitive},
 	{"", "primitiveLongRunningPrimitiveSemaphore", (void*)primitiveLongRunningPrimitiveSemaphore},
+	{"", "primitiveMethodXray", (void*)primitiveMethodXray},
 	{"", "primitiveMillisecondClockMask", (void*)primitiveMillisecondClockMask},
 	{"", "primitiveModLargeIntegers", (void*)primitiveModLargeIntegers},
 	{"", "primitiveMultiplyLargeIntegers", (void*)primitiveMultiplyLargeIntegers},

Modified: branches/Cog/src/vm/gcc3x-cointerpmt.c
===================================================================
--- branches/Cog/src/vm/gcc3x-cointerpmt.c	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/src/vm/gcc3x-cointerpmt.c	2012-04-13 17:44:17 UTC (rev 2548)
@@ -2,11 +2,17 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGeneratorGlobalStructure eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
    from
-	CoInterpreterMT VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CoInterpreterMT eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
-static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa " __DATE__ ;
+static char __buildInfo[] = "CoInterpreterMT eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -242,6 +248,7 @@
 #define ImmutabilityBit 0x20000000
 #define InstanceSpecificationIndex 2
 #define InstructionPointerIndex 1
+#define KeyIndex 0
 #define LargeContextBit 0x40000
 #define LargeContextBytes 252
 #define LargeContextSize 252
@@ -509,6 +516,7 @@
 static void displayBitsOfLeftTopRightBottom(sqInt aForm, sqInt l, sqInt t, sqInt r, sqInt b);
 sqInt displayObject(void);
 static sqInt divorceAllFrames(void);
+static sqInt divorceAMachineCodeFrameWithCogMethodin(CogMethod *cogMethod, StackPage *aStackPage);
 static void divorceFramesIn(StackPage *aStackPage);
 static sqInt doPrimitiveDivby(sqInt rcvr, sqInt arg);
 static sqInt doPrimitiveModby(sqInt rcvr, sqInt arg);
@@ -725,6 +733,7 @@
 static void markStackPageMostRecentlyUsed(StackPage *page);
 static void markStackPageNextMostRecentlyUsed(StackPage *page);
 static sqInt marriedContextpointsTostackDeltaForCurrentFrame(sqInt spouseContext, sqInt anOop, sqInt stackDeltaForCurrentFrame);
+static void marryContextInNewStackPageAndInitializeInterpreterRegisters(sqInt aContext);
 static sqInt marryFrameSP(char *theFP, char *theSP);
 static void maybeFlagMethodAsInterpreted(sqInt aMethod);
 sqInt maybeSplObj(sqInt index);
@@ -936,6 +945,7 @@
 static void primitiveMarkUnwindMethod(void);
 static void primitiveMaxIdentityHash(void);
 sqInt primitiveMethod(void);
+EXPORT(void) primitiveMethodXray(void);
 static void primitiveMillisecondClock(void);
 EXPORT(sqInt) primitiveMillisecondClockMask(void);
 static void primitiveMod(void);
@@ -1030,6 +1040,7 @@
 static void primitiveVMProfileSamplesInto(void);
 EXPORT(void) primitiveVoidReceiver(void);
 static void primitiveVoidVMState(void);
+static void primitiveVoidVMStateForMethod(void);
 static void primitiveWait(void);
 static void primitiveYield(void);
 void * primTraceLogAddress(void);
@@ -1215,6 +1226,7 @@
 usqInt vmOwnerLockAddress(void);
 static CogVMThread * vmThreadAt(sqInt index);
 static void voidLongRunningPrimitive(char *reason);
+static sqInt voidVMStateForSnapshot(void);
 static sqInt wakeHighestPriority(void);
 static void wakeVMThreadFor(sqInt index);
 static CogVMThread * willingVMThread(void);
@@ -1237,8 +1249,8 @@
 _iss sqInt specialObjectsOop;
 _iss StackPage * stackPage;
 _iss sqInt nilObj;
+_iss usqInt instructionPointer;
 _iss usqInt method;
-_iss usqInt instructionPointer;
 _iss sqInt argumentCount;
 _iss usqInt freeStart;
 _iss usqInt newMethod;
@@ -1255,18 +1267,18 @@
 _iss sqInt lkupClass;
 _iss sqInt bytesPerPage;
 _iss sqInt cogThreadManager;
+_iss usqInt reserveStart;
 _iss char * stackLimit;
-_iss usqInt reserveStart;
 _iss usqInt memoryLimit;
 _iss StackPage * mostRecentlyUsedPage;
 _iss sqInt needGCFlag;
 _iss usqInt scavengeThreshold;
 _iss sqInt numThreads;
+_iss sqInt numStackPages;
 _iss unsigned char primTraceLogIndex;
 _iss sqInt processHasThreadId;
 _iss CogVMThread ** threads;
 _iss sqLong nextProfileTick;
-_iss sqInt numStackPages;
 _iss CogVMThread * disowningVMThread;
 _iss sqInt jmpDepth;
 _iss usqInt fwdTableNext;
@@ -1371,8 +1383,8 @@
 _iss sqInt imageHeaderFlags;
 _iss usqLong longRunningPrimitiveGCUsecs;
 _iss sqInt overflowLimit;
+_iss long methodCache[MethodCacheSize + 1 /* 4097 */];
 _iss sqInt traceLog[TraceBufferSize /* 768 */];
-_iss long methodCache[MethodCacheSize + 1 /* 4097 */];
 _iss sqInt remapBuffer[RemapBufferSize + 1 /* 26 */];
 _iss sqInt atCache[AtCacheTotalSize + 1 /* 65 */];
 _iss sqInt rootTable[RootTableSize + 1 /* 2501 */];
@@ -1403,8 +1415,8 @@
 #endif
 static usqInt heapBase;
 static void (*primitiveFunctionPointer)();
+jmp_buf reenterInterpreter; /* private export */;
 #define bytecodeSetSelector 0
-jmp_buf reenterInterpreter; /* private export */;
 sqInt maxLiteralCountForCompile = MaxLiteralCountForCompile /* 60 */;
 sqInt inIOProcessEvents;
 sqInt checkForLeaks;
@@ -1639,7 +1651,7 @@
 	/* 212 */ primitiveContextSize,
 	/* 213 */ primitiveContextXray,
 	/* 214 */ primitiveVoidVMState,
-	/* 215 */ (void (*)(void))0,
+	/* 215 */ primitiveVoidVMStateForMethod,
 	/* 216 */ (void (*)(void))0,
 	/* 217 */ (void (*)(void))0,
 	/* 218 */ primitiveDoNamedPrimitiveWithArgs,
@@ -2002,7 +2014,9 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Croquet Closure Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.154]";
+const char *interpreterVersion = "Croquet Closure Cog MT VM [CoInterpreterMT eneraiton.
+
+VMMaker.oscog-eem.156]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 sqInt willNotThreadWarnCount;
@@ -13969,6 +13983,55 @@
 	return activeContext;
 }
 
+
+/*	Divorce at most one frame in the current page (since the divorce may cause
+	the page to be split)
+	and answer whether a frame was divorced. */
+
+static sqInt
+divorceAMachineCodeFrameWithCogMethodin(CogMethod *cogMethod, StackPage *aStackPage)
+{
+    char *calleeFP;
+    sqInt theContext;
+    char *theFP;
+    char *theSP;
+
+	theFP = (aStackPage->headFP);
+	theSP = (aStackPage->headSP);
+
+	/* theSP points at hottest item on frame's stack */
+
+	theSP += BytesPerWord;
+	while (1) {
+		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase)
+		 && (cogMethod == (mframeHomeMethod(theFP)))) {
+			/* begin ensureFrameIsMarried:SP: */
+			VM_LABEL(12ensureFrameIsMarriedSP);
+			if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
+				? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+				: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
+				assert(isContext(frameContext(theFP)));
+				theContext = longAt(theFP + FoxThisContext);
+				goto l1;
+			}
+			theContext = marryFrameSP(theFP, theSP);
+		l1:	/* end ensureFrameIsMarried:SP: */;
+			externalDivorceFrameandContext(theFP, theContext);
+			return 1;
+		}
+		calleeFP = theFP;
+		/* begin frameCallerFP: */
+		theFP = pointerForOop(longAt(theFP + FoxSavedFP));
+		if (!(theFP != 0)) break;
+		/* begin frameCallerSP: */
+		assert(!(isBaseFrame(calleeFP)));
+		theSP = (calleeFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(calleeFP + FoxMethod)))) < heapBase
+	? (mframeCogMethod(calleeFP)->cmNumArgs)
+	: byteAt((calleeFP + FoxIFrameFlags) + 1))))) + BytesPerWord;
+	}
+	return 0;
+}
+
 static void
 divorceFramesIn(StackPage *aStackPage)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
@@ -13995,7 +14058,7 @@
 	calleeContext = null;
 	while (1) {
 		/* begin ensureFrameIsMarried:SP: */
-		VM_LABEL(12ensureFrameIsMarriedSP);
+		VM_LABEL(13ensureFrameIsMarriedSP);
 		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
 			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
@@ -14908,7 +14971,7 @@
 		return callerContextOrNil;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(13ensureFrameIsMarriedSP);
+	VM_LABEL(14ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -14954,6 +15017,7 @@
 {
     sqInt pc;
 
+	/* begin ensureContextHasBytecodePC: */
 	assert(!(isMarriedOrWidowedContext(aContext)));
 	pc = longAt((aContext + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
 	if (((pc & 1))
@@ -15455,7 +15519,6 @@
     char *theSP1;
     sqInt valuePointer;
 
-	assert(theFP != GIV(framePointer));
 	assert((GIV(stackPage) == 0)
 	 || (GIV(stackPage) == (mostRecentlyUsedPage())));
 	/* begin stackPageFor: */
@@ -15489,7 +15552,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(14ensureFrameIsMarriedSP);
+	VM_LABEL(15ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP1 = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -15686,7 +15749,7 @@
 			return callerContextOrNil;
 		}
 		/* begin ensureFrameIsMarried:SP: */
-		VM_LABEL(15ensureFrameIsMarriedSP);
+		VM_LABEL(16ensureFrameIsMarriedSP);
 		/* begin frameCallerStackPointer: */
 		assert(!(isBaseFrame(spouseFP)));
 		theSP = (spouseFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(spouseFP + FoxMethod)))) < heapBase
@@ -16424,7 +16487,7 @@
 	: byteAt((theFPAbove + FoxIFrameFlags) + 1))))) + BytesPerWord;
 				}
 				/* begin ensureFrameIsMarried:SP: */
-				VM_LABEL(16ensureFrameIsMarriedSP);
+				VM_LABEL(17ensureFrameIsMarriedSP);
 				if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 					? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
 					: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
@@ -17886,7 +17949,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(17ensureFrameIsMarriedSP);
+	VM_LABEL(18ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -19007,13 +19070,9 @@
     sqInt activeContext;
     sqInt activeProc;
     sqInt activeProc1;
-    sqInt aMethodObj;
-    StackPage *newPage;
     sqInt stackPageBytes;
     sqInt stackPagesBytes;
-    char *theFP;
     char *theStackMemory;
-    sqInt top;
 
 	stackPageBytes = stackPageByteSize();
 	stackPagesBytes = (GIV(numStackPages) * ((sizeof(CogStackPage)) + (stackPageByteSize()))) + BytesPerWord;
@@ -19029,37 +19088,7 @@
 	}
 	activeProc1 = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	activeContext = longAt((activeProc1 + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord));
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(0marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	assert((ownerIndexOfProcess(activeProc)) == 0);
 	GIV(activeProcessAffined) = (ownerIndexOfThreadId((GIV(processHasThreadId)
@@ -19890,7 +19919,8 @@
     StackPage *thePage;
     sqInt value;
 
-	assert(isContext(aOnceMarriedContext));
+	assert((isContext(aOnceMarriedContext))
+	 && (isMarriedOrWidowedContext(aOnceMarriedContext)));
 	/* begin frameOfMarriedContext: */
 	value = longAt((aOnceMarriedContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
 	/* begin withoutSmallIntegerTags: */
@@ -20677,10 +20707,6 @@
     sqInt activeContext;
     sqInt activeProc;
     sqInt activeProc1;
-    sqInt aMethodObj;
-    StackPage *newPage;
-    char *theFP;
-    sqInt top;
 
 	if ((checkForLeaks & 1) != 0) {
 		clearLeakMapAndMapAccessibleObjects();
@@ -20688,37 +20714,7 @@
 	}
 	activeProc1 = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	activeContext = longAt((activeProc1 + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord));
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(1marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	assert((ownerIndexOfProcess(activeProc)) == 0);
 	GIV(activeProcessAffined) = (ownerIndexOfThreadId((GIV(processHasThreadId)
@@ -22668,6 +22664,50 @@
 }
 
 
+/*	Establish aContext at the base of a new stackPage, make the stackPage the
+	active one and set-up the interreter registers. This is used to boot the
+	system and bring it back after a snapshot. */
+
+static void
+marryContextInNewStackPageAndInitializeInterpreterRegisters(sqInt aContext)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt aMethodObj;
+    StackPage *newPage;
+    char *theFP;
+    sqInt top;
+
+	assert(GIV(stackPage) == 0);
+	newPage = makeBaseFrameFor(aContext);
+	/* begin setStackPageAndLimit: */
+	GIV(stackPage) = newPage;
+	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
+		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
+	}
+	markStackPageMostRecentlyUsed(newPage);
+	GIV(framePointer) = (GIV(stackPage)->headFP);
+	GIV(stackPointer) = (GIV(stackPage)->headSP);
+	/* begin setMethod: */
+	/* begin iframeMethod: */
+	theFP = (GIV(stackPage)->headFP);
+	aMethodObj = longAt(theFP + FoxMethod);
+	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
+	GIV(method) = aMethodObj;
+	assert(isOopCompiledMethod(GIV(method)));
+	
+#  if MULTIPLEBYTECODESETS
+	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
+		? 256
+		: 0);
+
+#  endif /* MULTIPLEBYTECODESETS */
+
+	/* begin popStack */
+	top = longAt(GIV(stackPointer));
+	GIV(stackPointer) += BytesPerWord;
+	GIV(instructionPointer) = ((sqInt) top);
+}
+
+
 /*	Marry an unmarried frame. This means creating a spouse context initialized
 	with a subset of the frame's state (state through the last argument) that
 	references the
@@ -23158,7 +23198,7 @@
 	assert(frameHasContext(callerFP));
 	assert(isContext(frameContext(callerFP)));
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(18ensureFrameIsMarriedSP);
+	VM_LABEL(19ensureFrameIsMarriedSP);
 	theSP = theFP + (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
 	? FoxMFReceiver
 	: FoxIFReceiver));
@@ -24753,7 +24793,7 @@
 	(GIV(stackPage)->headSP = GIV(stackPointer));
 	assert(pageListIsWellFormed());
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(19ensureFrameIsMarriedSP);
+	VM_LABEL(20ensureFrameIsMarriedSP);
 	theFP = GIV(framePointer);
 	theSP = GIV(stackPointer);
 	if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -30692,7 +30732,7 @@
 	for (i1 = 1; i1 <= AtCacheTotalSize; i1 += 1) {
 		GIV(atCache)[i1] = 0;
 	}
-	unlinkSendsTo(longAt(GIV(stackPointer)));
+	unlinkSendsToandFreeIf(longAt(GIV(stackPointer)), 0);
 }
 
 
@@ -32952,18 +32992,9 @@
 primitiveLongRunningPrimitiveSemaphore(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
     sqInt flushState;
-    sqInt header;
-    StackPage *newPage;
-    sqInt oop;
     sqInt sema;
     char *sp;
-    sqInt sz;
-    char *theFP;
-    sqInt top;
 
 	sema = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	if (((sema & 1))
@@ -32993,84 +33024,8 @@
 		/* begin push: */
 		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp;
-		/* begin voidVMStateForSnapshot */
-
-		/* in case of code compactions. */
-
-		GIV(instructionPointer) = 0;
-		activeContext1 = divorceAllFrames();
-		/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-		VM_LABEL(0ensureAllContextsHaveBytecodePCsOrAreBereaved);
-		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-		while (oop < GIV(freeStart)) {
-			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-			 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-					/* begin markContextAsDead: */
-					assert(isContext(oop));
-					longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-				}
-				else {
-					decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-					if (((decodedIP & 1))
-					 && ((((sqInt) decodedIP)) < 0)) {
-						decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-					}
-				}
-			}
-			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
-			}
-			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-				sz = (longAt(oop)) & AllButTypeMask;
-			}
-			else {
-				/* begin sizeBitsOf: */
-				header = longAt(oop);
-				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-					: header & SizeMask);
-			}
-			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
-		}
-		voidCogCompiledCode();
-		activeContext = activeContext1;
-		/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-		VM_LABEL(2marryContextInNewStackPageAndInitializeInterpreterRegisters);
-		assert(GIV(stackPage) == 0);
-		newPage = makeBaseFrameFor(activeContext);
-		/* begin setStackPageAndLimit: */
-		GIV(stackPage) = newPage;
-		if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-			GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-		}
-		markStackPageMostRecentlyUsed(newPage);
-		GIV(framePointer) = (GIV(stackPage)->headFP);
-		GIV(stackPointer) = (GIV(stackPage)->headSP);
-		/* begin setMethod: */
-		/* begin iframeMethod: */
-		theFP = (GIV(stackPage)->headFP);
-		aMethodObj = longAt(theFP + FoxMethod);
-		assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-		GIV(method) = aMethodObj;
-		assert(isOopCompiledMethod(GIV(method)));
-		
-#    if MULTIPLEBYTECODESETS
-		bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-			? 256
-			: 0);
-
-#    endif /* MULTIPLEBYTECODESETS */
-
-		/* begin popStack */
-		top = longAt(GIV(stackPointer));
-		GIV(stackPointer) += BytesPerWord;
-		GIV(instructionPointer) = ((sqInt) top);
+		activeContext = voidVMStateForSnapshot();
+		marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 		assert((((stackValue(0)) == (nilObject()))
  && (GIV(longRunningPrimitiveCheckSemaphore) == null))
 		 || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore))
@@ -33237,6 +33192,49 @@
 }
 
 
+/*	Lift the veil from a method and answer an integer describing the interior
+	state of its machine code.
+	Used for e.g. VM tests so they can verify they're testing what they think
+	they're testing.
+	0 implies a vanilla method.
+	Bit 0 = method is currently compiled to machine code
+	Bit 1 = is compiled frameless.
+	Bit 2 = method refers to young object */
+
+EXPORT(void)
+primitiveMethodXray(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt aMethodOop;
+    CogMethod *cogMethod;
+    sqInt flags;
+    sqInt methodHeader;
+    char *sp;
+
+	if ((((longAt(GIV(stackPointer))) & 1) == 0)
+	 && ((((((usqInt) (longAt(longAt(GIV(stackPointer))))) >> 8) & 15) >= 12)
+	 && (isCogMethodReference(longAt(((longAt(GIV(stackPointer))) + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
+		/* begin cogMethodOf: */
+		aMethodOop = longAt(GIV(stackPointer));
+		methodHeader = longAt((aMethodOop + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+		assert((isNonIntegerObject(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		flags = (((cogMethod->stackCheckOffset)) == 0
+			? 3
+			: 1);
+		if ((cogMethod->cmRefersToYoung)) {
+			flags += 4;
+		}
+	}
+	else {
+		flags = 0;
+	}
+	/* begin pop:thenPush: */
+	longAtput((sp = GIV(stackPointer) + ((1 - 1) * BytesPerWord)), ((flags << 1) | 1));
+	GIV(stackPointer) = sp;
+}
+
+
 /*	Return the value of the millisecond clock as an integer. Note that the
 	millisecond clock wraps around periodically. On some platforms it can wrap
 	daily. The range is limited to SmallInteger maxVal / 2 to allow delays of
@@ -34594,18 +34592,9 @@
 primitiveProfileSemaphore(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
     sqInt flushState;
-    sqInt header;
-    StackPage *newPage;
-    sqInt oop;
     sqInt sema;
     char *sp;
-    sqInt sz;
-    char *theFP;
-    sqInt top;
 
 	sema = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	if (((sema & 1))
@@ -34640,84 +34629,8 @@
 		/* begin push: */
 		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp;
-		/* begin voidVMStateForSnapshot */
-
-		/* in case of code compactions. */
-
-		GIV(instructionPointer) = 0;
-		activeContext1 = divorceAllFrames();
-		/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-		VM_LABEL(1ensureAllContextsHaveBytecodePCsOrAreBereaved);
-		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-		while (oop < GIV(freeStart)) {
-			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-			 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-					/* begin markContextAsDead: */
-					assert(isContext(oop));
-					longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-				}
-				else {
-					decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-					if (((decodedIP & 1))
-					 && ((((sqInt) decodedIP)) < 0)) {
-						decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-					}
-				}
-			}
-			/* begin objectAfter: */
-			if (DoAssertionChecks) {
-				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-					error("no objects after the end of memory");
-				}
-			}
-			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-				sz = (longAt(oop)) & AllButTypeMask;
-			}
-			else {
-				/* begin sizeBitsOf: */
-				header = longAt(oop);
-				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-					: header & SizeMask);
-			}
-			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
-		}
-		voidCogCompiledCode();
-		activeContext = activeContext1;
-		/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-		VM_LABEL(3marryContextInNewStackPageAndInitializeInterpreterRegisters);
-		assert(GIV(stackPage) == 0);
-		newPage = makeBaseFrameFor(activeContext);
-		/* begin setStackPageAndLimit: */
-		GIV(stackPage) = newPage;
-		if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-			GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-		}
-		markStackPageMostRecentlyUsed(newPage);
-		GIV(framePointer) = (GIV(stackPage)->headFP);
-		GIV(stackPointer) = (GIV(stackPage)->headSP);
-		/* begin setMethod: */
-		/* begin iframeMethod: */
-		theFP = (GIV(stackPage)->headFP);
-		aMethodObj = longAt(theFP + FoxMethod);
-		assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-		GIV(method) = aMethodObj;
-		assert(isOopCompiledMethod(GIV(method)));
-		
-#    if MULTIPLEBYTECODESETS
-		bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-			? 256
-			: 0);
-
-#    endif /* MULTIPLEBYTECODESETS */
-
-		/* begin popStack */
-		top = longAt(GIV(stackPointer));
-		GIV(stackPointer) += BytesPerWord;
-		GIV(instructionPointer) = ((sqInt) top);
+		activeContext = voidVMStateForSnapshot();
+		marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 		assert((((stackValue(0)) == (nilObject()))
  && (GIV(profileSemaphore) == (nilObject())))
 		 || (((stackValue(0)) == GIV(profileSemaphore))
@@ -38778,98 +38691,211 @@
 primitiveVoidVMState(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
-    sqInt aMethodObj;
-    sqInt decodedIP;
+    char *sp;
+
+	/* begin push: */
+	longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+	GIV(stackPointer) = sp;
+	activeContext = voidVMStateForSnapshot();
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
+	siglongjmp(reenterInterpreter, ReturnToInterpreter);
+}
+
+
+/*	The receiver is a compiledMethod. Clear all entries in the method lookup
+	cache that refer to this method, presumably because it has been redefined,
+	overridden or removed.
+ */
+/*	The receiver is a compiledMethod. Clear all VM state associated with the
+	method, including any machine code, or machine code pcs in context
+	objects.  */
+
+static void
+primitiveVoidVMStateForMethod(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt activeContext;
+    StackPage *aPage;
+    CogMethod *cogMethod;
+    sqInt divorcedSome;
+    sqInt divorcedSome1;
     sqInt header;
-    StackPage *newPage;
+    sqInt i;
+    sqInt i1;
+    sqInt i2;
+    sqInt index;
+    sqInt methodHeader;
+    sqInt methodObj;
+    sqInt oldMethod;
     sqInt oop;
+    sqInt pc;
+    sqInt primBits;
+    sqInt primIdx;
+    sqInt probe;
     char *sp;
     sqInt sz;
     char *theFP;
+    char *theFrame;
+    StackPage *thePage;
+    char *theSP;
     sqInt top;
+    sqInt top1;
+    sqInt value;
 
-	/* begin push: */
-	longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
-	GIV(stackPointer) = sp;
-	/* begin voidVMStateForSnapshot */
-
-	/* in case of code compactions. */
-
-	GIV(instructionPointer) = 0;
-	activeContext1 = divorceAllFrames();
-	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-	VM_LABEL(2ensureAllContextsHaveBytecodePCsOrAreBereaved);
-	oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-	while (oop < GIV(freeStart)) {
-		if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
-		 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-			if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-				/* begin markContextAsDead: */
-				assert(isContext(oop));
-				longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-				longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
+	oldMethod = longAt(GIV(stackPointer));
+	probe = 0;
+	for (i = 1; i <= MethodCacheEntries; i += 1) {
+		if ((GIV(methodCache)[probe + MethodCacheMethod]) == oldMethod) {
+			GIV(methodCache)[probe + MethodCacheSelector] = 0;
+		}
+		probe += MethodCacheEntrySize;
+	}
+	/* begin primitiveIndexOf: */
+	primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
+	primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
+	if (primIdx == PrimitiveExternalCallIndex) {
+		flushExternalPrimitiveOf(oldMethod);
+	}
+	/* begin flushAtCache */
+	for (i2 = 1; i2 <= AtCacheTotalSize; i2 += 1) {
+		GIV(atCache)[i2] = 0;
+	}
+	if (methodHasCogMethod(longAt(GIV(stackPointer)))) {
+		methodObj = longAt(GIV(stackPointer));
+		/* begin push: */
+		longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+		GIV(stackPointer) = sp;
+		/* begin externalWriteBackHeadFramePointers */
+		assert((GIV(framePointer) - GIV(stackPointer)) < LargeContextSize);
+		assert(GIV(stackPage) == (mostRecentlyUsedPage()));
+		/* begin setHeadFP:andSP:inPage: */
+		assert(GIV(stackPointer) < GIV(framePointer));
+		assert((GIV(stackPointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(stackPointer) > (((GIV(stackPage)->realStackLimit)) - LargeContextSize)));
+		assert((GIV(framePointer) < ((GIV(stackPage)->baseAddress)))
+		 && (GIV(framePointer) > (((GIV(stackPage)->realStackLimit)) - (((sqInt) LargeContextSize >> 1)))));
+		(GIV(stackPage)->headFP = GIV(framePointer));
+		(GIV(stackPage)->headSP = GIV(stackPointer));
+		assert(pageListIsWellFormed());
+		/* begin ensureFrameIsMarried:SP: */
+		VM_LABEL(21ensureFrameIsMarriedSP);
+		theFP = GIV(framePointer);
+		theSP = GIV(stackPointer);
+		if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
+			? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
+			: (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) {
+			assert(isContext(frameContext(theFP)));
+			activeContext = longAt(theFP + FoxThisContext);
+			goto l1;
+		}
+		activeContext = marryFrameSP(theFP, theSP);
+	l1:	/* end ensureFrameIsMarried:SP: */;
+		/* begin divorceMachineCodeFramesWithMethod: */
+		/* begin cogMethodOf: */
+		methodHeader = longAt((methodObj + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+		assert((isNonIntegerObject(methodHeader))
+		 && ((((usqInt)methodHeader)) < (startOfMemory())));
+		cogMethod = ((CogMethod *) methodHeader);
+		do {
+			if (GIV(stackPage) != 0) {
+				markStackPageMostRecentlyUsed(GIV(stackPage));
 			}
-			else {
-				decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-				if (((decodedIP & 1))
-				 && ((((sqInt) decodedIP)) < 0)) {
-					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
-					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
+			/* begin divorceSomeMachineCodeFramesWithMethod: */
+			divorcedSome1 = 0;
+			for (i1 = 0; i1 <= (GIV(numStackPages) - 1); i1 += 1) {
+				/* begin stackPageAt: */
+				aPage = stackPageAtpages(i1, GIV(pages));
+				if (!(isFree(aPage))) {
+					markStackPageMostRecentlyUsed(GIV(stackPage));
+					if (divorceAMachineCodeFrameWithCogMethodin(cogMethod, aPage)) {
+						divorcedSome1 = 1;
+					}
 				}
 			}
+			divorcedSome = divorcedSome1;
+		} while(divorcedSome);
+		/* begin ensureAllContextsWithMethodHaveBytecodePCs: */
+		VM_LABEL(0ensureAllContextsWithMethodHaveBytecodePCs);
+		oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
+		while (oop < GIV(freeStart)) {
+			if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
+			 && ((((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)
+			 && ((longAt((oop + BaseHeaderSize) + (MethodIndex << ShiftForWord))) == methodObj))) {
+				if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
+					if (checkIsStillMarriedContextcurrentFP(oop, (GIV(stackPage)->headFP))) {
+						assert(!(isMachineCodeFrame(frameOfMarriedContext(oop))));
+					}
+				}
+				else {
+					/* begin ensureContextHasBytecodePC: */
+					assert(!(isMarriedOrWidowedContext(oop)));
+					pc = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
+					if (((pc & 1))
+					 && (((pc = (pc >> 1))) < 0)) {
+						pc = mustMapMachineCodePCcontext(pc, oop);
+						longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), pc);
+					}
+				}
+			}
+			/* begin objectAfter: */
+			if (DoAssertionChecks) {
+				if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
+					error("no objects after the end of memory");
+				}
+			}
+			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+				sz = (longAt(oop)) & AllButTypeMask;
+			}
+			else {
+				/* begin sizeBitsOf: */
+				header = longAt(oop);
+				sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+					: header & SizeMask);
+			}
+			oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
 		}
-		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
+		unlinkSendsToandFreeIf(methodObj, 1);
+		if ((((longAt((activeContext + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1))
+		 && (!(isWidowedContext(activeContext)))) {
+			/* begin frameOfMarriedContext: */
+			value = longAt((activeContext + BaseHeaderSize) + (SenderIndex << ShiftForWord));
+			/* begin withoutSmallIntegerTags: */
+			assert((value & 1));
+			theFrame = pointerForOop(value - 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));
+			thePage = stackPageAtpages(index, GIV(pages));
+			assert(((thePage->headFP)) == theFrame);
+			/* begin setStackPageAndLimit: */
+			GIV(stackPage) = thePage;
+			if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
+				GIV(stackLimit) = (GIV(stackPage)->stackLimit);
 			}
+			markStackPageMostRecentlyUsed(thePage);
+			GIV(stackPointer) = (thePage->headSP);
+			GIV(framePointer) = (thePage->headFP);
+			/* begin popStack */
+			top = longAt(GIV(stackPointer));
+			GIV(stackPointer) += BytesPerWord;
+			GIV(instructionPointer) = ((sqInt) top);
+			assert(methodObj == (stackTop()));
 		}
-		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
-			sz = (longAt(oop)) & AllButTypeMask;
-		}
 		else {
-			/* begin sizeBitsOf: */
-			header = longAt(oop);
-			sz = ((header & TypeMask) == HeaderTypeSizeAndClass
-				? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
-				: header & SizeMask);
+
+			/* to avoid assert in marryContextInNewStackPageAndInitializeInterpreterRegisters: */
+
+			GIV(stackPage) = 0;
+			marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
+			/* begin popStack */
+			top1 = longAt(GIV(stackPointer));
+			GIV(stackPointer) += BytesPerWord;
+			assert(methodObj == (stackTop()));
+			siglongjmp(reenterInterpreter, ReturnToInterpreter);
 		}
-		oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
 	}
-	voidCogCompiledCode();
-	activeContext = activeContext1;
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
-	siglongjmp(reenterInterpreter, ReturnToInterpreter);
 }
 
 static void
@@ -39457,7 +39483,7 @@
 			printf("\n");
 		}
 		else {
-			print("widdowed (assuming framePointer valid)");
+			print("widowed (assuming framePointer valid)");
 			/* begin cr */
 			printf("\n");
 		}
@@ -40729,6 +40755,17 @@
 		goto l2;
 	}
 	printf("a(n) %.*s", nameLen, name);
+	if (((instanceSizeOf(classOop)) == (ValueIndex + 1))
+	 && (((longAt((classOop + BaseHeaderSize) + (SuperclassIndex << ShiftForWord))) == (superclassOf(fetchClassOfNonInt(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))))))
+	 && ((((longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord))) & 1) == 0)
+	 && (((((usqInt) (longAt(longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord))))) >> 8) & 15) >= 8)))) {
+		/* begin space */
+		/* begin printChar: */
+		putchar(' ');
+		printOopShort(longAt((oop + BaseHeaderSize) + (KeyIndex << ShiftForWord)));
+		print(" -> ");
+		printHex(longAt((oop + BaseHeaderSize) + (ValueIndex << ShiftForWord)));
+	}
 l2:	/* end printOopShortInner: */;
 	flush();
 }
@@ -43973,26 +44010,20 @@
 snapshot(sqInt embedded)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt activeContext;
-    sqInt activeContext1;
     sqInt activeProc;
-    sqInt aMethodObj;
     sqInt dataSize;
-    sqInt decodedIP;
     sqInt fmt;
     sqInt header;
     sqInt header1;
     sqInt header2;
-    sqInt header3;
     sqInt i;
     sqInt i1;
-    StackPage *newPage;
     sqInt object;
     sqInt object1;
     sqInt oop;
     sqInt oop1;
     sqInt oop2;
     sqInt oop3;
-    sqInt oop4;
     sqInt rcvr;
     void *setMacType;
     char *sp;
@@ -44001,61 +44032,12 @@
     sqInt stackIndex;
     sqInt sz;
     sqInt sz1;
-    sqInt sz2;
-    char *theFP;
-    sqInt top;
 
 	/* begin push: */
 	object1 = GIV(instructionPointer);
 	longAtput((sp2 = GIV(stackPointer) - BytesPerWord), object1);
 	GIV(stackPointer) = sp2;
-	/* begin voidVMStateForSnapshot */
-
-	/* in case of code compactions. */
-
-	GIV(instructionPointer) = 0;
-	activeContext1 = divorceAllFrames();
-	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
-	VM_LABEL(3ensureAllContextsHaveBytecodePCsOrAreBereaved);
-	oop4 = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
-	while (oop4 < GIV(freeStart)) {
-		if ((!(((longAt(oop4)) & TypeMask) == HeaderTypeFree))
-		 && (((((usqInt) (longAt(oop4))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
-			if (((longAt((oop4 + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
-				/* begin markContextAsDead: */
-				assert(isContext(oop4));
-				longAtput((oop4 + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
-				longAtput((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
-			}
-			else {
-				decodedIP = longAt((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
-				if (((decodedIP & 1))
-				 && ((((sqInt) decodedIP)) < 0)) {
-					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop4);
-					longAtput((oop4 + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
-				}
-			}
-		}
-		/* begin objectAfter: */
-		if (DoAssertionChecks) {
-			if ((((usqInt) oop4)) >= (((usqInt) GIV(endOfMemory)))) {
-				error("no objects after the end of memory");
-			}
-		}
-		if (((longAt(oop4)) & TypeMask) == HeaderTypeFree) {
-			sz2 = (longAt(oop4)) & AllButTypeMask;
-		}
-		else {
-			/* begin sizeBitsOf: */
-			header3 = longAt(oop4);
-			sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
-				? (longAt(oop4 - (BytesPerWord * 2))) & LongSizeMask
-				: header3 & SizeMask);
-		}
-		oop4 = (oop4 + sz2) + (headerTypeBytes[(longAt(oop4 + sz2)) & TypeMask]);
-	}
-	voidCogCompiledCode();
-	activeContext = activeContext1;
+	activeContext = voidVMStateForSnapshot();
 	/* begin pushRemappableOop: */
 	assert(addressCouldBeOop(activeContext));
 	GIV(remapBuffer)[(GIV(remapBufferCount) += 1)] = activeContext;
@@ -44158,37 +44140,7 @@
 		}
 		longAtput((activeContext + BaseHeaderSize) + (StackPointerIndex << ShiftForWord), (((stackIndex - 1) << 1) | 1));
 	}
-	/* begin marryContextInNewStackPageAndInitializeInterpreterRegisters: */
-	VM_LABEL(4marryContextInNewStackPageAndInitializeInterpreterRegisters);
-	assert(GIV(stackPage) == 0);
-	newPage = makeBaseFrameFor(activeContext);
-	/* begin setStackPageAndLimit: */
-	GIV(stackPage) = newPage;
-	if (GIV(stackLimit) != (((char *) (((usqInt) -1))))) {
-		GIV(stackLimit) = (GIV(stackPage)->stackLimit);
-	}
-	markStackPageMostRecentlyUsed(newPage);
-	GIV(framePointer) = (GIV(stackPage)->headFP);
-	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	/* begin setMethod: */
-	/* begin iframeMethod: */
-	theFP = (GIV(stackPage)->headFP);
-	aMethodObj = longAt(theFP + FoxMethod);
-	assert((((usqInt)aMethodObj)) >= (startOfMemory()));
-	GIV(method) = aMethodObj;
-	assert(isOopCompiledMethod(GIV(method)));
-	
-#  if MULTIPLEBYTECODESETS
-	bytecodeSetSelector = ((((headerOf(GIV(method))) >> 1)) < 0
-		? 256
-		: 0);
-
-#  endif /* MULTIPLEBYTECODESETS */
-
-	/* begin popStack */
-	top = longAt(GIV(stackPointer));
-	GIV(stackPointer) += BytesPerWord;
-	GIV(instructionPointer) = ((sqInt) top);
+	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	if (!GIV(primFailCode)) {
 		/* begin push: */
 		object = GIV(falseObj);
@@ -45398,7 +45350,7 @@
 		goto l1;
 	}
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(20ensureFrameIsMarriedSP);
+	VM_LABEL(22ensureFrameIsMarriedSP);
 	/* begin frameCallerStackPointer: */
 	assert(!(isBaseFrame(theFP)));
 	theSP = (theFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -46156,7 +46108,7 @@
 			(GIV(stackPage)->headSP = GIV(stackPointer));
 			assert(pageListIsWellFormed());
 			/* begin ensureFrameIsMarried:SP: */
-			VM_LABEL(21ensureFrameIsMarriedSP);
+			VM_LABEL(23ensureFrameIsMarriedSP);
 			theFP = GIV(framePointer);
 			theSP = GIV(stackPointer);
 			if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -46239,7 +46191,7 @@
 	sched = longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord));
 	oldProc = longAt((sched + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord));
 	/* begin ensureFrameIsMarried:SP: */
-	VM_LABEL(22ensureFrameIsMarriedSP);
+	VM_LABEL(24ensureFrameIsMarriedSP);
 	theFP = GIV(framePointer);
 	theSP = GIV(stackPointer);
 	if (((((usqInt)(longAt(theFP + FoxMethod)))) < heapBase
@@ -47156,6 +47108,70 @@
 }
 
 
+/*	Make sure that all VM state that affects the heap contents is voided so
+	that the heap is ready
+	to be snapshotted. Answer the activeContext object that should be stored
+	in the snapshot.
+ */
+
+static sqInt
+voidVMStateForSnapshot(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt activeContext;
+    sqInt decodedIP;
+    sqInt header;
+    sqInt oop;
+    sqInt sz;
+
+
+	/* in case of code compactions. */
+
+	GIV(instructionPointer) = 0;
+	activeContext = divorceAllFrames();
+	/* begin ensureAllContextsHaveBytecodePCsOrAreBereaved */
+	VM_LABEL(0ensureAllContextsHaveBytecodePCsOrAreBereaved);
+	oop = heapBase + (headerTypeBytes[(longAt(heapBase)) & TypeMask]);
+	while (oop < GIV(freeStart)) {
+		if ((!(((longAt(oop)) & TypeMask) == HeaderTypeFree))
+		 && (((((usqInt) (longAt(oop))) >> 12) & 31) == ClassMethodContextCompactIndex)) {
+			if (((longAt((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord))) & 1)) {
+				/* begin markContextAsDead: */
+				assert(isContext(oop));
+				longAtput((oop + BaseHeaderSize) + (SenderIndex << ShiftForWord), GIV(nilObj));
+				longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), GIV(nilObj));
+			}
+			else {
+				decodedIP = longAt((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord));
+				if (((decodedIP & 1))
+				 && ((((sqInt) decodedIP)) < 0)) {
+					decodedIP = mustMapMachineCodePCcontext((decodedIP >> 1), oop);
+					longAtput((oop + BaseHeaderSize) + (InstructionPointerIndex << ShiftForWord), decodedIP);
+				}
+			}
+		}
+		/* begin objectAfter: */
+		if (DoAssertionChecks) {
+			if ((((usqInt) oop)) >= (((usqInt) GIV(endOfMemory)))) {
+				error("no objects after the end of memory");
+			}
+		}
+		if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+			sz = (longAt(oop)) & AllButTypeMask;
+		}
+		else {
+			/* begin sizeBitsOf: */
+			header = longAt(oop);
+			sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+				? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+				: header & SizeMask);
+		}
+		oop = (oop + sz) + (headerTypeBytes[(longAt(oop + sz)) & TypeMask]);
+	}
+	voidCogCompiledCode();
+	return activeContext;
+}
+
+
 /*	Return the highest priority process that is ready to run.
 	To save time looking at many empty lists before finding a
 	runnable process the VM maintains a variable holding the
@@ -47442,6 +47458,7 @@
 	{"", "primitiveLessThanLargeIntegers", (void*)primitiveLessThanLargeIntegers},
 	{"", "primitiveLongRunningPrimitive", (void*)primitiveLongRunningPrimitive},
 	{"", "primitiveLongRunningPrimitiveSemaphore", (void*)primitiveLongRunningPrimitiveSemaphore},
+	{"", "primitiveMethodXray", (void*)primitiveMethodXray},
 	{"", "primitiveMillisecondClockMask", (void*)primitiveMillisecondClockMask},
 	{"", "primitiveModLargeIntegers", (void*)primitiveModLargeIntegers},
 	{"", "primitiveMultiplyLargeIntegers", (void*)primitiveMultiplyLargeIntegers},

Modified: branches/Cog/src/vm/interp.h
===================================================================
--- branches/Cog/src/vm/interp.h	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/src/vm/interp.h	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,5 +1,7 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGeneratorGlobalStructure eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
 
 #define VM_PROXY_MAJOR 1

Modified: branches/Cog/src/vm/vmCallback.h
===================================================================
--- branches/Cog/src/vm/vmCallback.h	2012-04-08 22:43:27 UTC (rev 2547)
+++ branches/Cog/src/vm/vmCallback.h	2012-04-13 17:44:17 UTC (rev 2548)
@@ -1,5 +1,7 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.154 uuid: 5cbb57c7-0a54-4b7e-848c-1f292759f1fa
+	CCodeGeneratorGlobalStructure eneraiton.
+
+VMMaker.oscog-eem.156 uuid: f03602f8-cb8a-4ae7-9a2e-921b5b77cf01
  */
 
 #define VM_CALLBACK_INC 1


Property changes on: branches/Cog/stackbuild/macbuild
___________________________________________________________________
Modified: svn:ignore
   - build
*.app
*.bundle
LOG*
*.sources

   + build
*.app
*.bundle
LOG*
*.sources
sqNamedPrims.h



Property changes on: branches/Cog/stackbuild/macbuild/Mpeg3Plugin
___________________________________________________________________
Added: svn:ignore
   + build




More information about the Vm-dev mailing list