[Vm-dev] [commit][2874] CogVM source as per VMMaker.oscog-eem.635

commits at squeakvm.org commits at squeakvm.org
Sun Mar 9 19:17:18 UTC 2014


Revision: 2874
Author:   eliot
Date:     2014-03-09 12:17:15 -0700 (Sun, 09 Mar 2014)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.635

Spur:
Fix decoding the per-segment bridge span/seg size info on load
and successfully load a multi-segment Newspeak bootstrap image.
Finally!

Rename writeImageToFile: to writeImageSegmentsToFile:.

Don't write out empty segments on snapshot.

Make various of the segment snapshot i/o rouitnes not inline for
debugging Newspeak bootstrap load crash.

Make segmentContainingObj: available for debugging.

Fix assert in inClassTableBitmapSet:.

Make sure adjustAllOopsBy: only sets bits in the classTableBitmap
for classes, not class index puns. 

Provide a free tree printer.

Modified Paths:
--------------
    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/nsspursrc/vm/cointerp.c
    branches/Cog/nsspursrc/vm/cointerp.h
    branches/Cog/nsspursrc/vm/gcc3x-cointerp.c
    branches/Cog/nsspursrc/vm/interp.h
    branches/Cog/nsspursrc/vm/vmCallback.h
    branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c
    branches/Cog/nsspurstacksrc/vm/interp.c
    branches/Cog/nsspurstacksrc/vm/interp.h
    branches/Cog/nsspurstacksrc/vm/vmCallback.h
    branches/Cog/spursrc/vm/cointerp.c
    branches/Cog/spursrc/vm/cointerp.h
    branches/Cog/spursrc/vm/gcc3x-cointerp.c
    branches/Cog/spursrc/vm/interp.h
    branches/Cog/spursrc/vm/vmCallback.h
    branches/Cog/spurstacksrc/vm/gcc3x-interp.c
    branches/Cog/spurstacksrc/vm/interp.c
    branches/Cog/spurstacksrc/vm/interp.h
    branches/Cog/spurstacksrc/vm/vmCallback.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/stacksrc/vm/gcc3x-interp.c
    branches/Cog/stacksrc/vm/interp.c
    branches/Cog/stacksrc/vm/interp.h
    branches/Cog/stacksrc/vm/vmCallback.h

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

Modified: branches/Cog/nscogsrc/vm/cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.c	2014-03-06 23:26:55 UTC (rev 2873)
+++ branches/Cog/nscogsrc/vm/cointerp.c	2014-03-09 19:17:15 UTC (rev 2874)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743
    from
-	CoInterpreter VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900
+	CoInterpreter VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -1146,7 +1146,7 @@
 static void rewriteMethodCacheEntryForExternalPrimitiveToFunction(void (*localPrimAddress)(void));
 static sqInt roomToPushNArgs(sqInt n);
 static void runLeakCheckerForFullGC(sqInt fullGCFlag);
-static usqInt safeObjectAfter(sqInt oop);
+static sqInt safeObjectAfter(sqInt oop);
 static sqInt safePrintStringOf(sqInt oop);
 usqInt scavengeThresholdAddress(void);
 EXPORT(sqInt) sendInvokeCallbackContext(VMCallbackContext *vmCallbackContext);
@@ -1273,8 +1273,8 @@
 _iss usqInt method;
 _iss StackPage * stackPage;
 _iss sqInt bytecodeSetSelector;
+_iss usqInt instructionPointer;
 _iss usqInt freeStart;
-_iss usqInt instructionPointer;
 _iss sqInt argumentCount;
 _iss sqInt nilObj;
 _iss usqInt newMethod;
@@ -2033,7 +2033,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.630";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.635";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -4827,6 +4827,7 @@
 							GIV(framePointer) = localFP;
 							
 							ceEnterCogCodePopReceiverReg();
+							null;
 							goto l307;
 						}
 						localIP = pointerForOop(longAt(localFP + FoxIFSavedIP));
@@ -4844,7 +4845,7 @@
 					/* begin fetchNextBytecode */
 					currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
-					/* return self */
+					null;
 				l307:	/* end baseFrameReturn */;
 					goto l304;
 				}
@@ -23734,15 +23735,17 @@
     sqInt header1;
     sqInt header2;
     sqInt header3;
+    sqInt header4;
     usqInt lastWord;
     sqInt newFreeChunk;
     sqInt newOop;
-    usqInt next;
+    sqInt next;
     sqInt oop;
     sqInt realHeader;
     sqInt sz;
     sqInt sz1;
     sqInt sz2;
+    sqInt sz3;
     sqInt target;
     usqInt w;
 
@@ -23753,7 +23756,21 @@
 		/* begin objectAfterWhileForwarding: */
 		header2 = longAt(oop);
 		if ((header2 & MarkBit) == 0) {
-			next = ((sqInt) (objectAfter(oop)));
+			/* begin objectAfter: */
+			if (!(asserta(oopisLessThan(oop, GIV(freeStart))))) {
+				error("no objects after the end of memory");
+			}
+			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+				sz2 = (longAt(oop)) & AllButTypeMask;
+			}
+			else {
+				/* begin sizeBitsOf: */
+				header3 = longAt(oop);
+				sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
+					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+					: header3 & SizeMask);
+			}
+			next = (oop + sz2) + (headerTypeBytes[(longAt(oop + sz2)) & TypeMask]);
 			goto l1;
 		}
 		fwdBlock1 = (header2 & AllButMarkBitAndTypeMask) << 1;
@@ -23768,7 +23785,7 @@
 		else {
 			sz1 = realHeader & SizeMask;
 		}
-		next = ((sqInt) ((oop + sz1) + (headerTypeBytes[(longAt(oop + sz1)) & TypeMask])));
+		next = (oop + sz1) + (headerTypeBytes[(longAt(oop + sz1)) & TypeMask]);
 	l1:	/* end objectAfterWhileForwarding: */;
 		if (!(((longAt(oop)) & TypeMask) == HeaderTypeFree)) {
 
@@ -23822,18 +23839,18 @@
 	}
 	/* begin safeObjectAfter: */
 	if (((longAt(newFreeChunk)) & TypeMask) == HeaderTypeFree) {
-		sz2 = (longAt(newFreeChunk)) & AllButTypeMask;
+		sz3 = (longAt(newFreeChunk)) & AllButTypeMask;
 	}
 	else {
 		/* begin sizeBitsOf: */
-		header3 = longAt(newFreeChunk);
-		sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
+		header4 = longAt(newFreeChunk);
+		sz3 = ((header4 & TypeMask) == HeaderTypeSizeAndClass
 			? (longAt(newFreeChunk - (BytesPerWord * 2))) & LongSizeMask
-			: header3 & SizeMask);
+			: header4 & SizeMask);
 	}
-	next = ((newFreeChunk + sz2) >= GIV(freeStart)
+	next = ((newFreeChunk + sz3) >= GIV(freeStart)
 		? GIV(freeStart)
-		: (newFreeChunk + sz2) + (headerTypeBytes[(longAt(newFreeChunk + sz2)) & TypeMask]));
+		: (newFreeChunk + sz3) + (headerTypeBytes[(longAt(newFreeChunk + sz3)) & TypeMask]));
 	assert((next == GIV(freeStart))
 	 || (next == (oopFromChunk(GIV(compEnd)))));
 	if (next == GIV(freeStart)) {
@@ -50248,7 +50265,7 @@
 	given object or free chunk in memory. Return freeStart when
 	enumeration is complete. This is for assertion checking only. */
 
-static usqInt
+static sqInt
 safeObjectAfter(sqInt oop)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt header;
@@ -55013,23 +55030,23 @@
 	return ((((usqInt) w << 0)) & Bytes3to0Mask) + ((((usqInt) w << 0)) & Bytes7to4Mask);
 }
 
+
+/*	Write the image header and heap contents to imageFile for snapshot. */
+
 static sqInt
 writeImageFileIO(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt bytesWritten;
     sqImageFile f;
     sqInt headerSize;
-    squeakFileOffsetType  headerStart;
+    squeakFileOffsetType headerStart;
     sqInt i;
-    usqInt memStart;
+    usqInt imageBytes;
+    extern char imageName[];
     sqInt okToWrite;
     void *sCWIfn;
-    sqInt successBoolean;
 
-
-	/* If the security plugin can be loaded, use it to check for write permission.
-	   If not, assume it's ok */
-
+	null;
 	sCWIfn = ioLoadFunctionFrom("secCanWriteImage", "SecurityPlugin");
 	if (sCWIfn != 0) {
 		okToWrite = ((sqInt (*)(void))sCWIfn)();
@@ -55057,12 +55074,13 @@
 		}
 		return null;
 	}
-	headerStart = sqImageFileStartLocation(f,imageName,headerSize+imageBytes);
+	imageBytes = GIV(freeStart) - (startOfMemory());
+	headerStart = sqImageFileStartLocation(f, imageName, headerSize + imageBytes);
 	/* Note: on Unix systems one could put an exec command here, padded to 512 bytes */;
 	sqImageFileSeek(f, headerStart);
 	putLongtoFile(imageFormatVersion(), f);
 	putLongtoFile(headerSize, f);
-	putLongtoFile(GIV(freeStart) - (startOfMemory()), f);
+	putLongtoFile(imageBytes, f);
 	putLongtoFile(startOfMemory(), f);
 	putLongtoFile(GIV(specialObjectsOop), f);
 	putLongtoFile(((usqInt) GIV(freeStart)) >> ShiftForWord, f);
@@ -55088,6 +55106,7 @@
 		putLongtoFile(0, f);
 	}
 
+	sqImageFileSeek(f, headerStart + headerSize);
 	if (!(!GIV(primFailCode))) {
 
 		/* file write or seek failure */
@@ -55095,14 +55114,10 @@
 		sqImageFileClose(f);
 		return null;
 	}
-	sqImageFileSeek(f, headerStart + headerSize);
-	memStart = startOfMemory();
-	bytesWritten = sqImageFileWrite(pointerForOop(memStart), sizeof(char), GIV(freeStart) - (startOfMemory()), f);
-	
+	bytesWritten = sqImageFileWrite(pointerForOop(startOfMemory()), sizeof(char), imageBytes, f);
 
 	/* begin success: */
-	successBoolean = bytesWritten == (GIV(freeStart) - (startOfMemory()));
-	if (!successBoolean) {
+	if (!(bytesWritten == imageBytes)) {
 
 		/* Don't overwrite an error code that has already been set. */
 

Modified: branches/Cog/nscogsrc/vm/cointerp.h
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.h	2014-03-06 23:26:55 UTC (rev 2873)
+++ branches/Cog/nscogsrc/vm/cointerp.h	2014-03-09 19:17:15 UTC (rev 2874)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743
  */
 
 

Modified: branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2014-03-06 23:26:55 UTC (rev 2873)
+++ branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2014-03-09 19:17:15 UTC (rev 2874)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743
    from
-	CoInterpreter VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900
+	CoInterpreter VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -1149,7 +1149,7 @@
 static void rewriteMethodCacheEntryForExternalPrimitiveToFunction(void (*localPrimAddress)(void));
 static sqInt roomToPushNArgs(sqInt n);
 static void runLeakCheckerForFullGC(sqInt fullGCFlag);
-static usqInt safeObjectAfter(sqInt oop);
+static sqInt safeObjectAfter(sqInt oop);
 static sqInt safePrintStringOf(sqInt oop);
 usqInt scavengeThresholdAddress(void);
 EXPORT(sqInt) sendInvokeCallbackContext(VMCallbackContext *vmCallbackContext);
@@ -1276,8 +1276,8 @@
 _iss usqInt method;
 _iss StackPage * stackPage;
 _iss sqInt bytecodeSetSelector;
+_iss usqInt instructionPointer;
 _iss usqInt freeStart;
-_iss usqInt instructionPointer;
 _iss sqInt argumentCount;
 _iss sqInt nilObj;
 _iss usqInt newMethod;
@@ -2036,7 +2036,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.630";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.635";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -4836,6 +4836,7 @@
 							GIV(framePointer) = localFP;
 							
 							ceEnterCogCodePopReceiverReg();
+							null;
 							goto l307;
 						}
 						localIP = pointerForOop(longAt(localFP + FoxIFSavedIP));
@@ -4853,7 +4854,7 @@
 					/* begin fetchNextBytecode */
 					currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
-					/* return self */
+					null;
 				l307:	/* end baseFrameReturn */;
 					goto l304;
 				}
@@ -23743,15 +23744,17 @@
     sqInt header1;
     sqInt header2;
     sqInt header3;
+    sqInt header4;
     usqInt lastWord;
     sqInt newFreeChunk;
     sqInt newOop;
-    usqInt next;
+    sqInt next;
     sqInt oop;
     sqInt realHeader;
     sqInt sz;
     sqInt sz1;
     sqInt sz2;
+    sqInt sz3;
     sqInt target;
     usqInt w;
 
@@ -23762,7 +23765,21 @@
 		/* begin objectAfterWhileForwarding: */
 		header2 = longAt(oop);
 		if ((header2 & MarkBit) == 0) {
-			next = ((sqInt) (objectAfter(oop)));
+			/* begin objectAfter: */
+			if (!(asserta(oopisLessThan(oop, GIV(freeStart))))) {
+				error("no objects after the end of memory");
+			}
+			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+				sz2 = (longAt(oop)) & AllButTypeMask;
+			}
+			else {
+				/* begin sizeBitsOf: */
+				header3 = longAt(oop);
+				sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
+					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+					: header3 & SizeMask);
+			}
+			next = (oop + sz2) + (headerTypeBytes[(longAt(oop + sz2)) & TypeMask]);
 			goto l1;
 		}
 		fwdBlock1 = (header2 & AllButMarkBitAndTypeMask) << 1;
@@ -23777,7 +23794,7 @@
 		else {
 			sz1 = realHeader & SizeMask;
 		}
-		next = ((sqInt) ((oop + sz1) + (headerTypeBytes[(longAt(oop + sz1)) & TypeMask])));
+		next = (oop + sz1) + (headerTypeBytes[(longAt(oop + sz1)) & TypeMask]);
 	l1:	/* end objectAfterWhileForwarding: */;
 		if (!(((longAt(oop)) & TypeMask) == HeaderTypeFree)) {
 
@@ -23831,18 +23848,18 @@
 	}
 	/* begin safeObjectAfter: */
 	if (((longAt(newFreeChunk)) & TypeMask) == HeaderTypeFree) {
-		sz2 = (longAt(newFreeChunk)) & AllButTypeMask;
+		sz3 = (longAt(newFreeChunk)) & AllButTypeMask;
 	}
 	else {
 		/* begin sizeBitsOf: */
-		header3 = longAt(newFreeChunk);
-		sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
+		header4 = longAt(newFreeChunk);
+		sz3 = ((header4 & TypeMask) == HeaderTypeSizeAndClass
 			? (longAt(newFreeChunk - (BytesPerWord * 2))) & LongSizeMask
-			: header3 & SizeMask);
+			: header4 & SizeMask);
 	}
-	next = ((newFreeChunk + sz2) >= GIV(freeStart)
+	next = ((newFreeChunk + sz3) >= GIV(freeStart)
 		? GIV(freeStart)
-		: (newFreeChunk + sz2) + (headerTypeBytes[(longAt(newFreeChunk + sz2)) & TypeMask]));
+		: (newFreeChunk + sz3) + (headerTypeBytes[(longAt(newFreeChunk + sz3)) & TypeMask]));
 	assert((next == GIV(freeStart))
 	 || (next == (oopFromChunk(GIV(compEnd)))));
 	if (next == GIV(freeStart)) {
@@ -50257,7 +50274,7 @@
 	given object or free chunk in memory. Return freeStart when
 	enumeration is complete. This is for assertion checking only. */
 
-static usqInt
+static sqInt
 safeObjectAfter(sqInt oop)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt header;
@@ -55022,23 +55039,23 @@
 	return ((((usqInt) w << 0)) & Bytes3to0Mask) + ((((usqInt) w << 0)) & Bytes7to4Mask);
 }
 
+
+/*	Write the image header and heap contents to imageFile for snapshot. */
+
 static sqInt
 writeImageFileIO(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt bytesWritten;
     sqImageFile f;
     sqInt headerSize;
-    squeakFileOffsetType  headerStart;
+    squeakFileOffsetType headerStart;
     sqInt i;
-    usqInt memStart;
+    usqInt imageBytes;
+    extern char imageName[];
     sqInt okToWrite;
     void *sCWIfn;
-    sqInt successBoolean;
 
-
-	/* If the security plugin can be loaded, use it to check for write permission.
-	   If not, assume it's ok */
-
+	null;
 	sCWIfn = ioLoadFunctionFrom("secCanWriteImage", "SecurityPlugin");
 	if (sCWIfn != 0) {
 		okToWrite = ((sqInt (*)(void))sCWIfn)();
@@ -55066,12 +55083,13 @@
 		}
 		return null;
 	}
-	headerStart = sqImageFileStartLocation(f,imageName,headerSize+imageBytes);
+	imageBytes = GIV(freeStart) - (startOfMemory());
+	headerStart = sqImageFileStartLocation(f, imageName, headerSize + imageBytes);
 	/* Note: on Unix systems one could put an exec command here, padded to 512 bytes */;
 	sqImageFileSeek(f, headerStart);
 	putLongtoFile(imageFormatVersion(), f);
 	putLongtoFile(headerSize, f);
-	putLongtoFile(GIV(freeStart) - (startOfMemory()), f);
+	putLongtoFile(imageBytes, f);
 	putLongtoFile(startOfMemory(), f);
 	putLongtoFile(GIV(specialObjectsOop), f);
 	putLongtoFile(((usqInt) GIV(freeStart)) >> ShiftForWord, f);
@@ -55097,6 +55115,7 @@
 		putLongtoFile(0, f);
 	}
 
+	sqImageFileSeek(f, headerStart + headerSize);
 	if (!(!GIV(primFailCode))) {
 
 		/* file write or seek failure */
@@ -55104,14 +55123,10 @@
 		sqImageFileClose(f);
 		return null;
 	}
-	sqImageFileSeek(f, headerStart + headerSize);
-	memStart = startOfMemory();
-	bytesWritten = sqImageFileWrite(pointerForOop(memStart), sizeof(char), GIV(freeStart) - (startOfMemory()), f);
-	
+	bytesWritten = sqImageFileWrite(pointerForOop(startOfMemory()), sizeof(char), imageBytes, f);
 
 	/* begin success: */
-	successBoolean = bytesWritten == (GIV(freeStart) - (startOfMemory()));
-	if (!successBoolean) {
+	if (!(bytesWritten == imageBytes)) {
 
 		/* Don't overwrite an error code that has already been set. */
 

Modified: branches/Cog/nscogsrc/vm/interp.h
===================================================================
--- branches/Cog/nscogsrc/vm/interp.h	2014-03-06 23:26:55 UTC (rev 2873)
+++ branches/Cog/nscogsrc/vm/interp.h	2014-03-09 19:17:15 UTC (rev 2874)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743
  */
 
 #define VM_PROXY_MAJOR 1

Modified: branches/Cog/nscogsrc/vm/vmCallback.h
===================================================================
--- branches/Cog/nscogsrc/vm/vmCallback.h	2014-03-06 23:26:55 UTC (rev 2873)
+++ branches/Cog/nscogsrc/vm/vmCallback.h	2014-03-09 19:17:15 UTC (rev 2874)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743
  */
 
 #define VM_CALLBACK_INC 1

Modified: branches/Cog/nsspursrc/vm/cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.c	2014-03-06 23:26:55 UTC (rev 2873)
+++ branches/Cog/nsspursrc/vm/cointerp.c	2014-03-09 19:17:15 UTC (rev 2874)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743
    from
-	CoInterpreter VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900
+	CoInterpreter VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -604,6 +604,7 @@
 void findString(char *aCString);
 static sqInt firstAccessibleObject(void);
 sqInt firstByteFormat(void);
+static sqInt firstClassIndexPun(void);
 sqInt firstCompiledMethodFormat(void);
 static sqInt firstCorpse(sqInt headOfCorpseList);
 static void firstFitCompact(void);
@@ -699,7 +700,6 @@
 static sqInt iframeSavedIP(char *theFP);
 void ifValidWriteBackStackPointersSaveTo(void *theCFP, void *theCSP, char **savedFPP, char **savedSPP);
 static sqInt imageFormatVersion(void);
-static sqInt imageSizeToWrite(void);
 sqInt implicitReceiverFormixinimplementing(sqInt rcvr, sqInt mixin, sqInt selector);
 static sqInt inactiveOrFailedToDeferScan(sqInt anEphemeron);
 sqInt includesBehaviorThatOf(sqInt aClass, sqInt aSuperclass);
@@ -711,6 +711,7 @@
 static void initializeStacknumSlotspageSize(char *theStackPages, sqInt stackSlots, sqInt slotsPerPage);
 sqInt initialPCForHeadermethod(sqInt methodHeader, sqInt theMethod);
 static void initSegmentBridgeWithBytesat(usqLong numBytes, sqInt address);
+void inOrderPrintFreeTreeprintList(sqInt freeChunk, sqInt printNextList);
 sqInt instanceSizeOf(sqInt classObj);
 sqInt instantiateClassindexableSize(sqInt classObj, sqInt nElements);
 usqInt instructionPointerAddress(void);
@@ -881,6 +882,7 @@
 static sqInt newObjectHash(void);
 static sqInt newSpaceIsEmpty(void);
 static StackPage * newStackPage(void);
+static SpurSegmentInfo * nextNonEmptySegmentAfter(sqInt i);
 usqInt nextProfileTickAddress(void);
 sqInt nilObject(void);
 static void nilUnmarkedWeaklingSlots(void);
@@ -932,6 +934,7 @@
 unsigned long positiveMachineIntegerValueOf(sqInt oop);
 static void postBecomeOrCompactScanClassTable(sqInt effectsFlags);
 static void postGCAction(sqInt gcModeArg);
+static void prepareForSnapshot(void);
 sqInt primErrTable(void);
 usqInt primFailCodeAddress(void);
 static void primitiveAdd(void);
@@ -1196,6 +1199,7 @@
 sqInt printFrame(char *theFP);
 void printFrameWithSP(char *theFP, char *theSP);
 void printFreeChunk(sqInt freeChunk);
+static void printFreeChunkisNextChunk(sqInt freeChunk, sqInt isNextChunk);
 void printFreeList(sqInt chunkOrIndex);
 void printHex(sqInt n);
 void printInstancesOf(sqInt aClassOop);
@@ -1278,6 +1282,7 @@
 static sqInt scavengeUnfiredEphemeronsOnEphemeronList(void);
 static void scavengingGCTenuringIf(sqInt tenuringCriterion);
 static usqInt segLimit(SpurSegmentInfo * self_in_segLimit);
+EXPORT(SpurSegmentInfo *) segmentContainingObj(sqInt objOop);
 EXPORT(sqInt) sendInvokeCallbackContext(VMCallbackContext *vmCallbackContext);
 EXPORT(sqInt) sendInvokeCallbackStackRegistersJmpbuf(sqInt thunkPtr, sqInt stackPtr, sqInt regsPtr, sqInt jmpBufPtr);
 void setBreakSelector(char *aString);
@@ -1393,7 +1398,8 @@
 static sqInt withSmallIntegerTags(char *value);
 static sqInt wordIndexableFormat(void);
 static sqInt writeImageFileIO(void);
-static sqInt writeSegmentnextSegmentSizetoFile(SpurSegmentInfo *segment, sqInt nextSegSize, FILE *aBinaryStream);
+static sqInt writeImageSegmentsToFile(sqImageFile aBinaryStream);
+static sqInt writeSegmentnextSegmenttoFile(SpurSegmentInfo *segment, SpurSegmentInfo *nextSegment, sqImageFile aBinaryStream);
 
 /*** Variables ***/
 #if SQ_USE_GLOBAL_STRUCT
@@ -1423,9 +1429,9 @@
 _iss usqInt endOfMemory;
 _iss sqInt totalFreeOldSpace;
 _iss sqInt trueObj;
+_iss SpurSegmentInfo * segments;
 _iss sqInt falseObj;
 _iss sqInt remapBufferCount;
-_iss SpurSegmentInfo * segments;
 _iss sqInt needGCFlag;
 _iss sqInt traceLogIndex;
 _iss sqInt bytesPerPage;
@@ -2185,7 +2191,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 usqInt heapBase;
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.630";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.635";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -27382,6 +27388,19 @@
 	return 16;
 }
 
+
+/*	Class puns are class indices not used by any class. There is an entry
+	for the pun that refers to the notional class of objects with this class
+	index. But because the index doesn't match the class it won't show up
+	in allInstances, hence hiding the object with a pun as its class index.
+	The puns occupy indices 16 through 31. */
+
+static sqInt
+firstClassIndexPun(void)
+{
+	return 16;
+}
+
 sqInt
 firstCompiledMethodFormat(void)
 {
@@ -30387,24 +30406,6 @@
 }
 
 
-/*	when asked, newSpace should be empty. */
-
-static sqInt
-imageSizeToWrite(void)
-{   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt i;
-    sqInt total;
-
-	assert(newSpaceIsEmpty());
-	/* begin totalBytesInSegments */
-	total = 0;
-	for (i = 0; i < GIV(numSegments); i += 1) {
-		total += ((GIV(segments)[i]).segSize);
-	}
-	return total;
-}
-
-
 /*	This is used to implement the innards of the pushImplicitReceiverBytecode,
 	used for implicit receiver sends in NS2/NS3. Find the nearest
 	lexically-enclosing implementation of selector by searching up the static
@@ -30990,6 +30991,7 @@
     SpurNewSpaceSpace *aNewSpace;
     sqInt bit;
     sqInt bit1;
+    sqInt classIndex;
     sqInt classTableRoot;
     sqInt field;
     sqInt fieldAddr;
@@ -31065,32 +31067,16 @@
 			? GIV(oldSpaceStart) + (BaseHeaderSize)
 			: GIV(oldSpaceStart));
 		while ((((usqInt) obj)) < (((usqInt) GIV(freeOldSpaceStart)))) {
-			if (((longAt(obj)) & 0x3FFFFF) == 0) {
-				/* begin swizzleFieldsOfFreeChunk: */
-				field = longAt((obj + (BaseHeaderSize)) + (0 << 2));
-				if (field != 0) {
-					/* begin storePointerNoAssert:ofFreeChunk:withValue: */
-					valuePointer = swizzleObj(field);
-					longAtput((obj + (BaseHeaderSize)) + (0 << 2), valuePointer);
+			classIndex = (longAt(obj)) & 0x3FFFFF;
+			if (classIndex >= 8) {
+				if (classIndex > 0x1F) {
+					/* begin inClassTableBitmapSet: */
+					assert((classIndex >= (firstClassIndexPun()))
+					 && (classIndex <= (classIndexMask())));
+					majorIndex = ((sqInt) classIndex >> 3);
+					bit = 1 << (classIndex & (BitsPerByte - 1));
+					GIV(classTableBitmap)[majorIndex] = ((GIV(classTableBitmap)[majorIndex]) | bit);
 				}
-				if ((bytesInObject(obj)) >= (32 * 8)) {
-					for (index = 2, indexLimiT = 4; index <= indexLimiT; index += 1) {
-						field = longAt((obj + (BaseHeaderSize)) + (index << 2));
-						if (field != 0) {
-							/* begin storePointerNoAssert:ofFreeChunk:withValue: */
-							valuePointer1 = swizzleObj(field);
-							longAtput((obj + (BaseHeaderSize)) + (index << 2), valuePointer1);
-						}
-					}
-				}
-			}
-			else {
-				/* begin inClassTableBitmapSet: */
-				assert((((longAt(obj)) & 0x3FFFFF) >= 0)
-				 && (((longAt(obj)) & 0x3FFFFF) <= (classIndexMask())));
-				majorIndex = ((sqInt) ((longAt(obj)) & 0x3FFFFF) >> 3);
-				bit = 1 << (((longAt(obj)) & 0x3FFFFF) & (BitsPerByte - 1));
-				GIV(classTableBitmap)[majorIndex] = ((GIV(classTableBitmap)[majorIndex]) | bit);
 				/* begin swizzleFieldsOfObject: */
 				fieldAddr = obj + (lastPointerOfWhileSwizzling(obj));
 				while ((((usqInt) fieldAddr)) >= (((usqInt) (obj + (BaseHeaderSize))))) {
@@ -31101,6 +31087,27 @@
 					fieldAddr -= BytesPerOop;
 				}
 			}
+			else {
+				if (classIndex == 0) {
+					/* begin swizzleFieldsOfFreeChunk: */
+					field = longAt((obj + (BaseHeaderSize)) + (0 << 2));
+					if (field != 0) {
+						/* begin storePointerNoAssert:ofFreeChunk:withValue: */
+						valuePointer = swizzleObj(field);
+						longAtput((obj + (BaseHeaderSize)) + (0 << 2), valuePointer);
+					}
+					if ((bytesInObject(obj)) >= (32 * 8)) {
+						for (index = 2, indexLimiT = 4; index <= indexLimiT; index += 1) {
+							field = longAt((obj + (BaseHeaderSize)) + (index << 2));
+							if (field != 0) {
+								/* begin storePointerNoAssert:ofFreeChunk:withValue: */
+								valuePointer1 = swizzleObj(field);
+								longAtput((obj + (BaseHeaderSize)) + (index << 2), valuePointer1);
+							}
+						}
+					}
+				}
+			}
 			obj = objectAfter(obj);
 		}
 	}
@@ -31114,12 +31121,13 @@
 			? GIV(oldSpaceStart) + (BaseHeaderSize)
 			: GIV(oldSpaceStart));
 		while ((((usqInt) obj)) < (((usqInt) GIV(endOfMemory)))) {
-			if (!(((longAt(obj)) & 0x3FFFFF) == 0)) {
+			classIndex = (longAt(obj)) & 0x3FFFFF;
+			if (classIndex > 0x1F) {
 				/* begin inClassTableBitmapSet: */
-				assert((((longAt(obj)) & 0x3FFFFF) >= 0)
-				 && (((longAt(obj)) & 0x3FFFFF) <= (classIndexMask())));
-				majorIndex1 = ((sqInt) ((longAt(obj)) & 0x3FFFFF) >> 3);
-				bit1 = 1 << (((longAt(obj)) & 0x3FFFFF) & (BitsPerByte - 1));
+				assert((classIndex >= (firstClassIndexPun()))
+				 && (classIndex <= (classIndexMask())));
+				majorIndex1 = ((sqInt) classIndex >> 3);
+				bit1 = 1 << (classIndex & (BitsPerByte - 1));
 				GIV(classTableBitmap)[majorIndex1] = ((GIV(classTableBitmap)[majorIndex1]) | bit1);
 			}
 			obj = objectAfter(obj);
@@ -31348,6 +31356,32 @@
 }
 
 
+/*	print free chunks in freeTree in order. */
+
+void
+inOrderPrintFreeTreeprintList(sqInt freeChunk, sqInt printNextList)
+{
+    sqInt next;
+
+	if (((next = longAt((freeChunk + (BaseHeaderSize)) + (3 << 2)))) != 0) {
+		inOrderPrintFreeTreeprintList(next, printNextList);
+	}
+	printFreeChunkisNextChunk(freeChunk, 0);
+	if (printNextList) {
+		next = freeChunk;
+		while (((next = longAt((next + (BaseHeaderSize)) + (0 << 2)))) != 0) {
+			/* begin tab */
+			/* begin printChar: */
+			putchar('	');
+			printFreeChunkisNextChunk(next, 1);
+		}
+	}
+	if (((next = longAt((freeChunk + (BaseHeaderSize)) + (4 << 2)))) != 0) {
+		inOrderPrintFreeTreeprintList(next, printNextList);
+	}
+}
+
+
 /*	Answer the number of slots in a class. For example the instanceSizeOf: 
 	ClassPoint is 2, for the x & y slots. The instance size of non-pointer
 	classes is 0. */
@@ -34774,7 +34808,7 @@
 
 	classIndex = (longAt(objOop)) & 0x3FFFFF;
 	/* begin inClassTableBitmapSet: */
-	assert((classIndex >= 0)
+	assert((classIndex >= (firstClassIndexPun()))
 	 && (classIndex <= (classIndexMask())));
 	majorIndex = ((sqInt) classIndex >> 3);
 	bit = 1 << (classIndex & (BitsPerByte - 1));
@@ -36700,6 +36734,30 @@
 }
 
 
+/*	Answer the the next non-empty segment or nil. The size of a segment
+	includes that of its bridge. A segment containing just a free object and a
+	bridge will still
+	have a size of manager bridgeSize after shortening it in
+	prepareForSnapshot. 
+ */
+
+static SpurSegmentInfo *
+nextNonEmptySegmentAfter(sqInt i)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt nextx;
+
+	nextx = i;
+	while(1) {
+		if (((nextx += 1)) >= GIV(numSegments)) {
+			return null;
+		}
+		if ((((GIV(segments)[nextx]).segSize)) > (2 * (BaseHeaderSize))) {
+			return (&(GIV(segments)[nextx]));
+		}
+	}
+}
+
+
 /*	N.B. nextProfileTick is 64-bits */
 
 usqInt
@@ -38172,6 +38230,110 @@
 	GIV(gcMode) = 0;
 }
 
+
+/*	shorten all segments by any trailing free space. */
+
+static void
+prepareForSnapshot(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt cameFrom;
+    SpurSegmentInfo * cascade0;
+    usqInt freeChunk;
+    sqInt i;
+    sqInt i1;
+    sqInt largeChild;
+    sqInt newEndOfMemory;
+    sqInt next;
+    sqInt node;
+    SpurSegmentInfo *seg;
+    sqInt smallChild;
+    sqInt treeNode;
+
+	for (i = 0; i < GIV(numSegments); i += 1) {
+		cascade0 = (&(GIV(segments)[i]));
+		(cascade0->savedSegSize = ((GIV(segments)[i]).segSize));
+		(cascade0->lastFreeObject = null);
+	}
+	/* begin freeTreeNodesDo: */
+	treeNode = GIV(freeLists)[0];
+	if (treeNode == 0) {
+		goto l2;
+	}
+	cameFrom = -1;
+	do {
+		assert((bytesInObject(treeNode)) >= ((numFreeLists()) * (allocationUnit())));
+		smallChild = longAt((treeNode + (BaseHeaderSize)) + (3 << 2));
+		largeChild = longAt((treeNode + (BaseHeaderSize)) + (4 << 2));
+		assert((smallChild == 0)
+		 || (treeNode == (fetchPointerofFreeChunk(freeChunkParentIndex(), smallChild))));
+		assert((largeChild == 0)
+		 || (treeNode == (fetchPointerofFreeChunk(freeChunkParentIndex(), largeChild))));
+		if (((smallChild == 0)
+ && (largeChild == 0))
+		 || ((largeChild == 0
+			? cameFrom == smallChild
+			: cameFrom == largeChild))) {
+
+			/* and since we've applied we must move on up */
+
+			node = treeNode;
+			while (node != 0) {
+				next = objectAfterlimit(node, endOfMemory());
+				if (((longAt(next)) & 0x3FFFFF) == 3) {
+					/* begin segmentContainingObj: */
+					for (i1 = (GIV(numSegments) - 1); i1 >= 0; i1 += -1) {
+						if (node >= (((GIV(segments)[i1]).segStart))) {
+							seg = (&(GIV(segments)[i1]));
+							goto l3;
+						}
+					}
+					seg = null;
+				l3:	/* end segmentContainingObj: */;
+					(seg->lastFreeObject = node);
+					node = 0;
+				}
+				else {
+					node = longAt((node + (BaseHeaderSize)) + (0 << 2));
+				}
+			}
+			treeNode = treeNode;
+
+			cameFrom = treeNode;
+			treeNode = longAt((treeNode + (BaseHeaderSize)) + (2 << 2));
+		}
+		else {
+			if ((smallChild != 0)
+			 && (cameFrom != smallChild)) {
+				treeNode = smallChild;
+			}
+			else {
+				assert(largeChild != 0);
+				treeNode = largeChild;
+			}
+			cameFrom = -1;
+		}
+	} while(treeNode != 0);
+l2:	/* end freeTreeNodesDo: */;
+	for (i = 0; i < GIV(numSegments); i += 1) {
+		freeChunk = ((GIV(segments)[i]).lastFreeObject);
+		if (!(freeChunk == null)) {
+			detachFreeObject(freeChunk);
+			((GIV(segments)[i]).segSize = ((((rawNumSlotsOf(freeChunk)) == 0xFF
+	? freeChunk - (BaseHeaderSize)
+	: freeChunk)) + (2 * (BaseHeaderSize))) - (((GIV(segments)[i]).segStart)));
+			bridgeFromto((&(GIV(segments)[i])), (i < (GIV(numSegments) - 1)
+				? (&(GIV(segments)[i + 1]))
+				: 0));
+		}
+	}
+	/* begin setEndOfMemory: */
+	newEndOfMemory = ((((GIV(segments)[GIV(numSegments) - 1]).segSize)) + (((GIV(segments)[GIV(numSegments) - 1]).segStart))) - (2 * (BaseHeaderSize));
+	GIV(endOfMemory) = newEndOfMemory;
+	if (GIV(freeOldSpaceStart) > newEndOfMemory) {
+		GIV(freeOldSpaceStart) = newEndOfMemory;
+	}
+}
+
 sqInt
 primErrTable(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
@@ -56383,6 +56545,12 @@
 void
 printFreeChunk(sqInt freeChunk)
 {
+	printFreeChunkisNextChunk(freeChunk, 0);
+}
+
+static void
+printFreeChunkisNextChunk(sqInt freeChunk, sqInt isNextChunk)
+{
     usqLong numBytes;
 
 	numBytes = bytesInObject(freeChunk);
@@ -56396,7 +56564,8 @@
 	/* begin printHexPtrnp: */
 	/* begin printHexnp: */
 	printf("0x%x", oopForPointer(longAt((freeChunk + (BaseHeaderSize)) + (0 << 2))));
-	if (numBytes >= (32 * 8)) {
+	if ((numBytes >= (32 * 8))
+	 && (!isNextChunk)) {
 		print(" ^ ");
 		/* begin printHexPtrnp: */
 		/* begin printHexnp: */
@@ -56418,7 +56587,6 @@
 printFreeList(sqInt chunkOrIndex)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt freeChunk;
-    usqLong numBytes;
 
 	if ((chunkOrIndex >= 0)
 	 && (chunkOrIndex < 32)) {
@@ -56428,33 +56596,7 @@
 	freeChunk = chunkOrIndex;
 	while (freeChunk != 0) {
 		/* begin printFreeChunk: */
-		numBytes = bytesInObject(freeChunk);
-		print("freeChunk ");
-		/* begin printHexPtrnp: */
-		/* begin printHexnp: */
-		printf("0x%x", oopForPointer(freeChunk));
-		print(" bytes ");
-		printNum(numBytes);
-		print(" next ");
-		/* begin printHexPtrnp: */
-		/* begin printHexnp: */
-		printf("0x%x", oopForPointer(longAt((freeChunk + (BaseHeaderSize)) + (0 << 2))));
-		if (numBytes >= (32 * 8)) {
-			print(" ^ ");
-			/* begin printHexPtrnp: */
-			/* begin printHexnp: */
-			printf("0x%x", oopForPointer(longAt((freeChunk + (BaseHeaderSize)) + (2 << 2))));
-			print(" < ");
-			/* begin printHexPtrnp: */
-			/* begin printHexnp: */
-			printf("0x%x", oopForPointer(longAt((freeChunk + (BaseHeaderSize)) + (3 << 2))));
-			print(" > ");
-			/* begin printHexPtrnp: */
-			/* begin printHexnp: */
-			printf("0x%x", oopForPointer(longAt((freeChunk + (BaseHeaderSize)) + (4 << 2))));
-		}
-		/* begin cr */
-		printf("\n");
+		printFreeChunkisNextChunk(freeChunk, 0);
 		freeChunk = longAt((freeChunk + (BaseHeaderSize)) + (0 << 2));
 	}
 }
@@ -59368,13 +59510,16 @@
 /*	Read numBytes of image data from f into memory at memoryBaseForImageRead.
 	Answer the number of bytes written. In addition, read each segment, build
 	up the
-	segment info, while eliminating the bridge objects that end each segment
-	and give the size of the subsequent segment. */
+	segment info for swizzling, while eliminating the bridge objects at the
+	end of each
+	segment that specify the distance to and the size of the subsequent
+	segment.  */
 
 static sqInt
 readHeapFromImageFiledataBytes(sqImageFile f, sqInt numBytes)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt bridge;
+    sqInt bridgehead;
     sqInt bridgeSpan;
     sqInt bytesRead;
     usqInt newBase;
@@ -59391,7 +59536,7 @@
 	oldBase = 0;
 	newBase = oldSpaceStart();
 	nextSegmentSize = GIV(firstSegmentSize);
-	bridge = (GIV(firstSegmentSize) + (oldSpaceStart())) - (BaseHeaderSize);
+	bridgehead = (GIV(firstSegmentSize) + (oldSpaceStart())) - (2 * (BaseHeaderSize));
 	while (1) {
 		segInfo = (&(GIV(segments)[GIV(numSegments)]));
 		(segInfo->segStart = oldBase);
@@ -59405,12 +59550,15 @@
 			return totalBytesRead;
 		}
 		GIV(numSegments) += 1;
-		bridgeSpan = 4 * (rawOverflowSlotsOf(bridge));
+		bridge = bridgehead + (BaseHeaderSize);
+		bridgeSpan = ((rawNumSlotsOf(bridgehead)) == 0
+			? 0
+			: 4 * (rawOverflowSlotsOf(bridge)));
 		oldBase = (oldBase + nextSegmentSize) + bridgeSpan;
 		newBase = (newBase + nextSegmentSize) - (2 * (BaseHeaderSize));
 		nextSegmentSize = longLongAt(bridge);
 		if (!(nextSegmentSize != 0)) break;
-		bridge = (bridge - (2 * (BaseHeaderSize))) + nextSegmentSize;
+		bridgehead = (bridgehead - (2 * (BaseHeaderSize))) + nextSegmentSize;
 	}
 	assert((newBase - (oldSpaceStart())) == (totalBytesRead - (GIV(numSegments) * (bridgeSize()))));
 	/* begin setFreeOldSpaceStart: */
@@ -61218,7 +61366,20 @@
 	return ((self_in_segLimit->segSize)) + ((self_in_segLimit->segStart));
 }
 
+EXPORT(SpurSegmentInfo *)
+segmentContainingObj(sqInt objOop)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt i;
 
+	for (i = (GIV(numSegments) - 1); i >= 0; i += -1) {
+		if (objOop >= (((GIV(segments)[i]).segStart))) {
+			return (&(GIV(segments)[i]));
+		}
+	}
+	return null;
+}
+
+
 /*	Send the calllback message to Alien class with the supplied arg(s). Use
 	either the
 	1 arg invokeCallbackContext: or the 4 arg
@@ -62790,22 +62951,14 @@
     sqInt activeProc;
     sqInt address;
     sqInt bytes;
-    sqInt cameFrom;
-    SpurSegmentInfo * cascade0;
     CogMethod *cogMethod;
     sqInt errorCode;
     usqInt freeChunk;
-    usqInt freeChunk1;
     sqInt i;
     sqInt i1;
-    sqInt i2;
-    sqInt i3;
     usqInt initialIP;
-    sqInt largeChild;
     sqInt methodHeader;
     sqInt newEndOfMemory;
-    sqInt newEndOfMemory1;
-    sqInt next;
     sqInt numArgs;
     sqInt numTemps;
     sqInt object;
@@ -62813,9 +62966,7 @@
     sqInt rcvr;
     sqInt rcvr1;
     sqInt savedTenuringThreshold;
-    SpurSegmentInfo *seg;
     void *setMacType;
-    sqInt smallChild;
     char *sp;
     char *sp1;
     char *sp10;
@@ -62831,7 +62982,6 @@
     char *sp9;
     sqInt stackIndex;
     sqInt table;
-    sqInt treeNode;
 
 
 	/* For now the stack munging below doesn't deal with more than one argument.
@@ -62879,83 +63029,7 @@
 	assert(GIV(pastSpaceStart) == (((pastSpace()).start)));
 	assert(GIV(freeStart) == (((eden()).start)));
 	fullGC();
-	/* begin prepareForSnapshot */
-	for (i2 = 0; i2 < GIV(numSegments); i2 += 1) {
-		cascade0 = (&(GIV(segments)[i2]));
-		(cascade0->savedSegSize = ((GIV(segments)[i2]).segSize));
-		(cascade0->lastFreeObject = null);
-	}
-	/* begin freeTreeNodesDo: */
-	treeNode = GIV(freeLists)[0];
-	if (treeNode == 0) {
-		goto l2;
-	}
-	cameFrom = -1;
-	do {
-		assert((bytesInObject(treeNode)) >= ((numFreeLists()) * (allocationUnit())));
-		smallChild = longAt((treeNode + (BaseHeaderSize)) + (3 << 2));
-		largeChild = longAt((treeNode + (BaseHeaderSize)) + (4 << 2));
-		assert((smallChild == 0)
-		 || (treeNode == (fetchPointerofFreeChunk(freeChunkParentIndex(), smallChild))));
-		assert((largeChild == 0)
-		 || (treeNode == (fetchPointerofFreeChunk(freeChunkParentIndex(), largeChild))));
-		if (((smallChild == 0)
- && (largeChild == 0))
-		 || ((largeChild == 0
-			? cameFrom == smallChild
-			: cameFrom == largeChild))) {
-
-			/* and since we've applied we must move on up */
-
-			next = objectAfterlimit(treeNode, endOfMemory());
-			if (((longAt(next)) & 0x3FFFFF) == 3) {
-				/* begin segmentContainingObj: */
-				for (i1 = (GIV(numSegments) - 1); i1 >= 0; i1 += -1) {
-					if (treeNode >= (((GIV(segments)[i1]).segStart))) {
-						seg = (&(GIV(segments)[i1]));
-						goto l4;
-					}
-				}
-				seg = null;
-			l4:	/* end segmentContainingObj: */;
-				(seg->lastFreeObject = treeNode);
-			}
-			treeNode = treeNode;
-
-			cameFrom = treeNode;
-			treeNode = longAt((treeNode + (BaseHeaderSize)) + (2 << 2));
-		}
-		else {
-			if ((smallChild != 0)
-			 && (cameFrom != smallChild)) {
-				treeNode = smallChild;
-			}
-			else {
-				assert(largeChild != 0);
-				treeNode = largeChild;
-			}
-			cameFrom = -1;
-		}
-	} while(treeNode != 0);
-l2:	/* end freeTreeNodesDo: */;
-	for (i2 = 0; i2 < GIV(numSegments); i2 += 1) {
-		freeChunk = ((GIV(segments)[i2]).lastFreeObject);
-		if (!(freeChunk == null)) {
-			detachFreeObject(freeChunk);
-			((GIV(segments)[i2]).segSize = ((((rawNumSlotsOf(freeChunk)) == 0xFF
-	? freeChunk - (BaseHeaderSize)
-	: freeChunk)) + (2 * (BaseHeaderSize))) - (((GIV(segments)[i2]).segStart)));
-			bridgeFromto((&(GIV(segments)[i2])), (i2 < (GIV(numSegments) - 1)
-				? (&(GIV(segments)[i2 + 1]))
-				: 0));
-		}
-	}
-	/* begin setEndOfMemory: */
-	newEndOfMemory = ((((GIV(segments)[GIV(numSegments) - 1]).segSize)) + (((GIV(segments)[GIV(numSegments) - 1]).segStart))) - (2 * (BaseHeaderSize));
-	GIV(endOfMemory) = newEndOfMemory;
-	if (GIV(freeOldSpaceStart) > newEndOfMemory) {
-		GIV(freeOldSpaceStart) = newEndOfMemory;
-	}
+	prepareForSnapshot();
 	activeContext = GIV(tempOop);
 	GIV(tempOop) = 0;
 	if (!GIV(primFailCode)) {
@@ -62989,25 +63063,25 @@
 		longAtput((activeContext + (BaseHeaderSize)) + (StackPointerIndex << 2), (((stackIndex - 1) << 1) | 1));
 	}
 	/* begin postSnapshot */
-	for (i3 = (GIV(numSegments) - 1); i3 >= 0; i3 += -1) {
-		freeChunk1 = ((GIV(segments)[i3]).lastFreeObject);
-		if (!(freeChunk1 == null)) {
-			address = ((((GIV(segments)[i3]).segSize)) + (((GIV(segments)[i3]).segStart))) - (2 * (BaseHeaderSize));
-			((GIV(segments)[i3]).segSize = ((GIV(segments)[i3]).savedSegSize));
-			bridgeFromto((&(GIV(segments)[i3])), (i3 < (GIV(numSegments) - 1)
-				? (&(GIV(segments)[i3 + 1]))
+	for (i1 = (GIV(numSegments) - 1); i1 >= 0; i1 += -1) {
+		freeChunk = ((GIV(segments)[i1]).lastFreeObject);
+		if (!(freeChunk == null)) {
+			address = ((((GIV(segments)[i1]).segSize)) + (((GIV(segments)[i1]).segStart))) - (2 * (BaseHeaderSize));
+			((GIV(segments)[i1]).segSize = ((GIV(segments)[i1]).savedSegSize));
+			bridgeFromto((&(GIV(segments)[i1])), (i1 < (GIV(numSegments) - 1)
+				? (&(GIV(segments)[i1 + 1]))
 				: 0));
 			/* begin addFreeChunkWithBytes:at: */
-			bytes = (((((GIV(segments)[i3]).segSize)) + (((GIV(segments)[i3]).segStart))) - address) - (2 * (BaseHeaderSize));
+			bytes = (((((GIV(segments)[i1]).segSize)) + (((GIV(segments)[i1]).segStart))) - address) - (2 * (BaseHeaderSize));
 			freeChunkWithBytesat(bytes, address);
 			GIV(totalFreeOldSpace) += bytes;
 		}
 	}
 	/* begin setEndOfMemory: */
-	newEndOfMemory1 = ((((GIV(segments)[GIV(numSegments) - 1]).segSize)) + (((GIV(segments)[GIV(numSegments) - 1]).segStart))) - (2 * (BaseHeaderSize));
-	GIV(endOfMemory) = newEndOfMemory1;
-	if (GIV(freeOldSpaceStart) > newEndOfMemory1) {
-		GIV(freeOldSpaceStart) = newEndOfMemory1;
+	newEndOfMemory = ((((GIV(segments)[GIV(numSegments) - 1]).segSize)) + (((GIV(segments)[GIV(numSegments) - 1]).segStart))) - (2 * (BaseHeaderSize));
+	GIV(endOfMemory) = newEndOfMemory;
+	if (GIV(freeOldSpaceStart) > newEndOfMemory) {
+		GIV(freeOldSpaceStart) = newEndOfMemory;
 	}
 	marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext);
 	if (!GIV(primFailCode)) {
@@ -65609,26 +65683,25 @@
 	return 10;
 }
 
+
+/*	Write the image header and heap contents to imageFile for snapshot. */
+
 static sqInt
 writeImageFileIO(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt bytesWritten;
     sqImageFile f;
     sqInt headerSize;
-    squeakFileOffsetType  headerStart;
+    squeakFileOffsetType headerStart;
     sqInt i;
     sqInt i1;
-    usqInt memStart;
-    sqInt nextSegSize;
+    sqInt imageBytes;
+    extern char imageName[];
     sqInt okToWrite;
     void *sCWIfn;
-    sqInt successBoolean;
     sqInt total;
 
-
-	/* If the security plugin can be loaded, use it to check for write permission.
-	   If not, assume it's ok */
-
+	null;
 	sCWIfn = ioLoadFunctionFrom("secCanWriteImage", "SecurityPlugin");
 	if (sCWIfn != 0) {
 		okToWrite = ((sqInt (*)(void))sCWIfn)();
@@ -65656,12 +65729,22 @@
 		}
 		return null;
 	}
-	headerStart = sqImageFileStartLocation(f,imageName,headerSize+imageBytes);
+	/* begin imageSizeToWrite */
+	assert(newSpaceIsEmpty());
+	/* begin totalBytesInNonEmptySegments */
+	total = 0;
+	for (i1 = 0; i1 < GIV(numSegments); i1 += 1) {
+		if ((((GIV(segments)[i1]).segSize)) > (2 * (BaseHeaderSize))) {
+			total += ((GIV(segments)[i1]).segSize);
+		}
+	}
+	imageBytes = total;
+	headerStart = sqImageFileStartLocation(f, imageName, headerSize + imageBytes);
 	/* Note: on Unix systems one could put an exec command here, padded to 512 bytes */;
 	sqImageFileSeek(f, headerStart);
 	putLongtoFile(imageFormatVersion(), f);
 	putLongtoFile(headerSize, f);
-	putLongtoFile(imageSizeToWrite(), f);
+	putLongtoFile(imageBytes, f);
 	putLongtoFile(GIV(oldSpaceStart), f);
 	putLongtoFile(GIV(specialObjectsOop), f);
 	putLongtoFile(newObjectHash(), f);
@@ -65688,6 +65771,7 @@
 		putLongtoFile(0, f);
 	}
 
+	sqImageFileSeek(f, headerStart + headerSize);
 	if (!(!GIV(primFailCode))) {
 
 		/* file write or seek failure */
@@ -65695,25 +65779,10 @@
 		sqImageFileClose(f);
 		return null;
 	}
-	sqImageFileSeek(f, headerStart + headerSize);
-	/* begin writeImageToFile: */
-	total = 0;
-	assert(((endOfMemory()) == (segLimit(&GIV(segments)[GIV(numSegments) - 1])))
-	 || (((endOfMemory()) + (bridgeSize())) == (segLimit(&GIV(segments)[GIV(numSegments) - 1]))));
-	if (!(GIV(firstSegmentSize) == null)) {
-		assert(GIV(firstSegmentSize) == (((GIV(segments)[0]).segSize)));
-	}
-	for (i1 = 0; i1 < GIV(numSegments); i1 += 1) {
-		nextSegSize = (i1 == (GIV(numSegments) - 1)
-			? 0
-			: ((GIV(segments)[i1 + 1]).segSize));
-		total += writeSegmentnextSegmentSizetoFile((&(GIV(segments)[i1])), nextSegSize, f);
-	}
-	bytesWritten = total;
+	bytesWritten = writeImageSegmentsToFile(f);
 
 	/* begin success: */
-	successBoolean = bytesWritten == (imageSizeToWrite());
-	if (!successBoolean) {
+	if (!(bytesWritten == imageBytes)) {
 
 		/* Don't overwrite an error code that has already been set. */
 
@@ -65725,19 +65794,53 @@
 }
 
 static sqInt
-writeSegmentnextSegmentSizetoFile(SpurSegmentInfo *segment, sqInt nextSegSize, FILE *aBinaryStream)
+writeImageSegmentsToFile(sqImageFile aBinaryStream)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt i;
+    sqInt total;
+
+	assert(((endOfMemory()) == (segLimit(&GIV(segments)[GIV(numSegments) - 1])))
+	 || (((endOfMemory()) + (bridgeSize())) == (segLimit(&GIV(segments)[GIV(numSegments) - 1]))));
+	if (!(GIV(firstSegmentSize) == null)) {
+		assert(GIV(firstSegmentSize) == (((GIV(segments)[0]).segSize)));
+	}
+	assert((((GIV(segments)[0]).segSize)) > 0);
+	total = 0;
+	for (i = 0; i < GIV(numSegments); i += 1) {
+		if ((((GIV(segments)[i]).segSize)) > (2 * (BaseHeaderSize))) {
+			total += writeSegmentnextSegmenttoFile((&(GIV(segments)[i])), nextNonEmptySegmentAfter(i), aBinaryStream);
+		}
+	}
+	return total;
+}
+
+
+/*	Write the segment contents, the size of and the distance to the next
+	segment to aBinaryStream.
+ */
+
+static sqInt
+writeSegmentnextSegmenttoFile(SpurSegmentInfo *segment, SpurSegmentInfo *nextSegment, sqImageFile aBinaryStream)
 {
-    sqInt lastDoubleWord;
+    usqLong firstSavedBridgeWord;
     sqInt nWritten;
-    usqLong savedDoubleWord;
+    sqInt pier1;
+    sqInt pier2;
+    usqLong secondSavedBridgeWord;
 
-	lastDoubleWord = (((segment->segSize)) + ((segment->segStart))) - (BaseHeaderSize);
+	pier1 = (((segment->segSize)) + ((segment->segStart))) - (2 * (BaseHeaderSize));
+	pier2 = pier1 + (BaseHeaderSize);
 	assert(isValidSegmentBridge(bridgeFor(segment)));
-	assert((startOfObject(bridgeFor(segment))) == (lastDoubleWord - (BaseHeaderSize)));
-	savedDoubleWord = longLongAt(lastDoubleWord);
-	longLongAtput(lastDoubleWord, nextSegSize);
+	assert((startOfObject(bridgeFor(segment))) == pier1);
+	firstSavedBridgeWord = longLongAt(pier1);
+	secondSavedBridgeWord = longLongAt(pier2);
+	bridgeFromto(segment, nextSegment);
+	longLongAtput(pier2, (nextSegment == null
+		? 0
+		: (nextSegment->segSize)));
 	nWritten = sqImageFileWrite(((void *)((segment->segStart))), 1, (segment->segSize), aBinaryStream);
-	longLongAtput(lastDoubleWord, savedDoubleWord);
+	longLongAtput(pier1, firstSavedBridgeWord);
+	longLongAtput(pier2, secondSavedBridgeWord);
 	return nWritten;
 }
 
@@ -65800,6 +65903,7 @@
 	{"", "printFramesOnStackPageListInUse\000\377", (void*)printFramesOnStackPageListInUse},
 	{"", "reestablishContextPriorToCallback", (void*)reestablishContextPriorToCallback},
 	{"", "returnAsThroughCallbackContext", (void*)returnAsThroughCallbackContext},
+	{"", "segmentContainingObj", (void*)segmentContainingObj},
 	{"", "sendInvokeCallbackContext", (void*)sendInvokeCallbackContext},
 	{"", "sendInvokeCallbackStackRegistersJmpbuf", (void*)sendInvokeCallbackStackRegistersJmpbuf},
 	{"", "setInterruptCheckChain", (void*)setInterruptCheckChain},

Modified: branches/Cog/nsspursrc/vm/cointerp.h
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.h	2014-03-06 23:26:55 UTC (rev 2873)
+++ branches/Cog/nsspursrc/vm/cointerp.h	2014-03-09 19:17:15 UTC (rev 2874)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743
  */
 
 
@@ -108,6 +108,7 @@
 sqInt implicitReceiverFormixinimplementing(sqInt rcvr, sqInt mixin, sqInt selector);
 sqInt indexablePointersFormat(void);
 sqInt initialPCForHeadermethod(sqInt methodHeader, sqInt theMethod);
+void inOrderPrintFreeTreeprintList(sqInt freeChunk, sqInt printNextList);
 sqInt instanceSizeOf(sqInt classObj);
 usqInt instructionPointerAddress(void);
 usqInt interpretAddress(void);

Modified: branches/Cog/nsspursrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/gcc3x-cointerp.c	2014-03-06 23:26:55 UTC (rev 2873)
+++ branches/Cog/nsspursrc/vm/gcc3x-cointerp.c	2014-03-09 19:17:15 UTC (rev 2874)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743
    from
-	CoInterpreter VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900
+	CoInterpreter VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.630 uuid: 8ca18389-543a-4847-958c-8e818a7e0900 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.635 uuid: d3e35b87-a79e-44a1-975b-549d6ae06743 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -607,6 +607,7 @@
 void findString(char *aCString);
 static sqInt firstAccessibleObject(void);
 sqInt firstByteFormat(void);
+static sqInt firstClassIndexPun(void);
 sqInt firstCompiledMethodFormat(void);
 static sqInt firstCorpse(sqInt headOfCorpseList);
 static void firstFitCompact(void);
@@ -702,7 +703,6 @@
 static sqInt iframeSavedIP(char *theFP);
 void ifValidWriteBackStackPointersSaveTo(void *theCFP, void *theCSP, char **savedFPP, char **savedSPP);
 static sqInt imageFormatVersion(void);
-static sqInt imageSizeToWrite(void);
 sqInt implicitReceiverFormixinimplementing(sqInt rcvr, sqInt mixin, sqInt selector);
 static sqInt inactiveOrFailedToDeferScan(sqInt anEphemeron);
 sqInt includesBehaviorThatOf(sqInt aClass, sqInt aSuperclass);
@@ -714,6 +714,7 @@
 static void initializeStacknumSlotspageSize(char *theStackPages, sqInt stackSlots, sqInt slotsPerPage);
 sqInt initialPCForHeadermethod(sqInt methodHeader, sqInt theMethod);
 static void initSegmentBridgeWithBytesat(usqLong numBytes, sqInt address);
+void inOrderPrintFreeTreeprintList(sqInt freeChunk, sqInt printNextList);
 sqInt instanceSizeOf(sqInt classObj);
 sqInt instantiateClassindexableSize(sqInt classObj, sqInt nElements);
 usqInt instructionPointerAddress(void);
@@ -884,6 +885,7 @@
 static sqInt newObjectHash(void);
 static sqInt newSpaceIsEmpty(void);
 static StackPage * newStackPage(void);
+static SpurSegmentInfo * nextNonEmptySegmentAfter(sqInt i);
 usqInt nextProfileTickAddress(void);
 sqInt nilObject(void);
 static void nilUnmarkedWeaklingSlots(void);
@@ -935,6 +937,7 @@
 unsigned long positiveMachineIntegerValueOf(sqInt oop);
 static void postBecomeOrCompactScanClassTable(sqInt effectsFlags);
 static void postGCAction(sqInt gcModeArg);
+static void prepareForSnapshot(void);
 sqInt primErrTable(void);
 usqInt primFailCodeAddress(void);
 static void primitiveAdd(void);
@@ -1199,6 +1202,7 @@
 sqInt printFrame(char *theFP);
 void printFrameWithSP(char *theFP, char *theSP);
 void printFreeChunk(sqInt freeChunk);
+static void printFreeChunkisNextChunk(sqInt freeChunk, sqInt isNextChunk);

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list