[Vm-dev] [commit][3427] CogVM source as per VMMaker.oscog-eem.1441

commits at squeakvm.org commits at squeakvm.org
Sat Aug 22 03:39:40 UTC 2015


Revision: 3427
Author:   eliot
Date:     2015-08-21 20:39:38 -0700 (Fri, 21 Aug 2015)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.1441

Modify Spur ImageSegment load to become the segmentWordArray into an Array of
the loaded objects if load is successful, hence decoupling ImageSegment from
the assumption that objects are allocated in order.

Fix use count printing in printStackPagesInUse et al.

Newspeak
Use the isFooMethod: level method privacy accessors to test in two remaining
lookup routines, restricting AccessModifierPublic et al to the inner accessors.

Enable access control in 64-bit Newspeak VMs as well.

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

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

Modified: branches/Cog/nsspursrc/vm/cogit.h
===================================================================
--- branches/Cog/nsspursrc/vm/cogit.h	2015-08-20 19:28:03 UTC (rev 3426)
+++ branches/Cog/nsspursrc/vm/cogit.h	2015-08-22 03:39:38 UTC (rev 3427)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464
+	CCodeGenerator VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7
  */
 
 

Modified: branches/Cog/nsspursrc/vm/cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.c	2015-08-20 19:28:03 UTC (rev 3426)
+++ branches/Cog/nsspursrc/vm/cointerp.c	2015-08-22 03:39:38 UTC (rev 3427)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7
    from
-	CoInterpreter VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464
+	CoInterpreter VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -2414,7 +2414,7 @@
 /*560*/	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0,-1,-1
 	};
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1439";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1441";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -18328,7 +18328,7 @@
 static sqInt
 checkForAndFollowForwardedPrimitiveState(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt accessorDepth;
+    signed char accessorDepth;
     sqInt firstBytecode;
     sqInt found;
     sqInt found1;
@@ -53447,13 +53447,13 @@
 /*	This primitive will load a binary image segment created by
 	primitiveStoreImageSegment. It expects the outPointer array to be of the
 	proper size, and the wordArray to be well formed.
-	It will return as its value the original array of roots, and the erstwhile
-	segmentWordArray will
-	have been truncated to a size of one word, i.e. retaining the version
-	stamp. If this primitive
-	should fail, the segmentWordArray will, sadly, have been reduced to an
-	unrecognizable and
-	unusable jumble. But what more could you have done with it anyway? */
+	It will return as its value the original array of roots, and the
+	segmentWordArray will become an
+	array of the loaded objects. If this primitive should fail, the
+	segmentWordArray will, sadly, have
+	been reduced to an unrecognizable and unusable jumble. But what more could
+	you have done
+	with it anyway? */
 
 	/* SpurMemoryManager>>#loadImageSegmentFrom:outPointers: */
 static sqInt
@@ -53467,11 +53467,17 @@
     sqInt classRef;
     sqInt errorCode;
     sqInt errorCode1;
+    sqInt fillIdx;
     sqInt hash;
     sqInt i;
     sqInt iLimiT;
+    sqInt loadedObjectsArray;
     sqInt mappedOop;
+    usqInt newObj;
+    usqInt numBytes;
+    sqInt numLoadedObjects;
     usqInt numOutPointers;
+    sqInt numSegObjs;
     usqInt numSlots;
     usqInt numSlots1;
     usqInt numSlots11;
@@ -53590,15 +53596,17 @@
 	numOutPointers = (numSlots4 == 0xFF
 		? longAt(outPointerArray - BaseHeaderSize)
 		: numSlots4);
+	numSegObjs = 0;
 	/* begin objectStartingAt: */
 	numSlots13 = byteAt(segmentStart + 7);
 	objOop1 = (numSlots13 == 0xFF
 		? segmentStart + BaseHeaderSize
 		: segmentStart);
 	while (objOop1 < segmentLimit) {
+		numSegObjs += 1;
 		if (((((usqInt) (longAt(objOop1 + 4))) >> 23) & 1) != 0) {
 			errorCode = PrimErrInappropriate;
-			goto l2;
+			goto l3;
 		}
 
 		/* validate the class ref, but don't update it until any internal classes have been added to the class table. */
@@ -53607,14 +53615,14 @@
 		if (classIndex & TopHashBit) {
 			if ((classIndex - TopHashBit) >= numOutPointers) {
 				errorCode = PrimErrBadIndex;
-				goto l2;
+				goto l3;
 			}
 			mappedOop = longAt((outPointerArray + BaseHeaderSize) + ((classIndex - TopHashBit) << (shiftForWord())));
 			hash = (long32At(mappedOop + 4)) & 0x3FFFFF;
 			if (!((hash > 0x1F)
 				 && ((classOrNilAtIndex(hash)) == mappedOop))) {
 				errorCode = PrimErrInappropriate;
-				goto l2;
+				goto l3;
 			}
 		}
 		else {
@@ -53623,11 +53631,11 @@
 
 			if (((oop1 = (classIndex * 8) + segmentStart)) >= segmentLimit) {
 				errorCode = PrimErrBadIndex;
-				goto l2;
+				goto l3;
 			}
 			if (((long32At(oop1 + 4)) & 0x3FFFFF) != 0) {
 				errorCode = PrimErrInappropriate;
-				goto l2;
+				goto l3;
 			}
 		}
 		for (i = 0, iLimiT = ((numPointerSlotsOf(objOop1)) - 1); i <= iLimiT; i += 1) {
@@ -53636,18 +53644,18 @@
 				if (oop1 & TopOopBit) {
 					if (((oop1 = (oop1 - TopOopBit) / BytesPerOop)) >= numOutPointers) {
 						errorCode = PrimErrBadIndex;
-						goto l2;
+						goto l3;
 					}
 					mappedOop = longAt((outPointerArray + BaseHeaderSize) + (oop1 << (shiftForWord())));
 				}
 				else {
 					if ((oop1 & (8 - 1)) != 0) {
 						errorCode = PrimErrInappropriate;
-						goto l2;
+						goto l3;
 					}
 					if (((mappedOop = oop1 + segmentStart)) >= segmentLimit) {
 						errorCode = PrimErrBadIndex;
-						goto l2;
+						goto l3;
 					}
 				}
 				/* begin storePointerUnchecked:ofObject:withValue: */
@@ -53657,11 +53665,52 @@
 		}
 		objOop1 = objectAfterlimit(objOop1, segmentLimit);
 	}
-	errorCode = 0;
-l2:	/* end mapOopsAndValidateClassRefsFrom:to:outPointers: */;
-	if (errorCode != 0) {
+	errorCode = -numSegObjs;
+l3:	/* end mapOopsAndValidateClassRefsFrom:to:outPointers: */;
+	if (errorCode > 0) {
 		return errorCode;
 	}
+	numLoadedObjects = -errorCode;
+	/* begin allocateSlots:format:classIndex: */
+	if (numLoadedObjects >= 0xFF) {
+		newObj = GIV(freeStart) + BaseHeaderSize;
+		numBytes = (BaseHeaderSize + BaseHeaderSize) + ((numLoadedObjects + (numLoadedObjects & 1)) * BytesPerOop);
+	}
+	else {
+		newObj = GIV(freeStart);
+		numBytes = BaseHeaderSize + ((numLoadedObjects <= 1
+	? 8
+	: (numLoadedObjects + (numLoadedObjects & 1)) * BytesPerOop));
+	}
+	if ((GIV(freeStart) + numBytes) > GIV(scavengeThreshold)) {
+		if (!GIV(needGCFlag)) {
+			/* begin scheduleScavenge */
+			GIV(needGCFlag) = 1;
+			forceInterruptCheck();
+		}
+		loadedObjectsArray = allocateSlotsInOldSpacebytesformatclassIndex(numLoadedObjects, numBytes, 2, ClassArrayCompactIndex);
+		goto l1;
+	}
+	if (numLoadedObjects >= 0xFF) {
+
+		/* for header parsing we put a saturated slot count in the prepended overflow size word */
+
+		flag("endianness");
+		longAtput(GIV(freeStart), numLoadedObjects);
+		longAtput(GIV(freeStart) + 4, 0xFF << 24);
+		long64Atput(newObj, (((((usqLong) 0xFF)) << 56) + (2 << 24)) + ClassArrayCompactIndex);
+	}
+	else {
+		long64Atput(newObj, (((((usqLong) numLoadedObjects)) << 56) + (2 << 24)) + ClassArrayCompactIndex);
+	}
+	assert((numBytes % (allocationUnit())) == 0);
+	assert((newObj % (allocationUnit())) == 0);
+	GIV(freeStart) += numBytes;
+	loadedObjectsArray = newObj;
+l1:	/* end allocateSlots:format:classIndex: */;
+	if (!(loadedObjectsArray)) {
+		return PrimErrNoMemory;
+	}
 	/* begin enterClassesIntoClassTableFrom:to: */
 	objOop = objectAfter(objectStartingAt(segmentStart));
 	while ((objOop < segmentLimit)
@@ -53677,26 +53726,31 @@
 				objOop = objectAfterlimit(objOop, segmentLimit);
 			}
 			errorCode = errorCode1;
-			goto l1;
+			goto l2;
 		}
 		objOop = objectAfterlimit(objOop, segmentLimit);
 	}
 	errorCode = 0;
-l1:	/* end enterClassesIntoClassTableFrom:to: */;
+l2:	/* end enterClassesIntoClassTableFrom:to: */;
 	if (errorCode != 0) {
 		return errorCode;
 	}
-	/* begin assignClassIndicesAndPinFrom:to:outPointers: */
+	/* begin assignClassIndicesAndPinFrom:to:outPointers:filling: */
 	/* begin objectStartingAt: */
 	numSlots5 = byteAt(segmentStart + 7);
 	objOop2 = (numSlots5 == 0xFF
 		? segmentStart + BaseHeaderSize
 		: segmentStart);
+	fillIdx = 0;
 	while (objOop2 < segmentLimit) {
+		/* begin storePointerUnchecked:ofObject:withValue: */
+		assert(!(isForwarded(loadedObjectsArray)));
+		longAtput((loadedObjectsArray + BaseHeaderSize) + (fillIdx << (shiftForWord())), objOop2);
 
 		/* In the segment, class indices are offset indexes into the segment data,
 		   or into outPointers.  See mapOopsFrom:to:outPointers:outHashes:. */
 
+		fillIdx += 1;
 		classRef = ((longAt(objOop2)) & 0x3FFFFF) - 16;
 		if (classRef & TopHashBit) {
 			classOop = longAt((outPointerArray + BaseHeaderSize) + ((classRef - TopHashBit) << (shiftForWord())));
@@ -53754,6 +53808,31 @@
 	else {
 		byteAtput(segmentWordArray + 7, 8 / BytesPerOop);
 	}
+	/* begin forward:to: */
+	/* begin set:classIndexTo:formatTo: */
+	assert(((8 >= 0) && (8 <= (classIndexMask()))));
+	assert(((7 >= 0) && (7 <= (formatMask()))));
+	flag("endianness");
+	longAtput(segmentWordArray, ((longAt(segmentWordArray)) & ((unsigned int)~((0x1F << 24) + 0x3FFFFF))) + (8 + (7 << 24)));
+	/* begin storePointer:ofForwarder:withValue: */
+	assert(isForwarded(segmentWordArray));
+	assert(!(isOopForwarded(loadedObjectsArray)));
+	if (isOldObject(segmentWordArray)) {
+
+		/* most stores into young objects */
+
+		if (((loadedObjectsArray & 3) == 0)
+		 && (oopisLessThan(loadedObjectsArray, GIV(newSpaceLimit)))) {
+			/* begin possibleRootStoreInto: */
+			if (!(((((usqInt) (longAt(segmentWordArray))) >> 29) & 1) != 0)) {
+				remember(segmentWordArray);
+			}
+		}
+	}
+	longAtput((segmentWordArray + BaseHeaderSize) + (0 << (shiftForWord())), loadedObjectsArray);
+	if ((byteAt(segmentWordArray + 7)) == 0) {
+		byteAtput(segmentWordArray + 7, 1);
+	}
 	runLeakCheckerFor(GCModeImageSegment);
 	/* begin objectStartingAt: */
 	numSlots1 = byteAt(segmentStart + 7);
@@ -65003,7 +65082,7 @@
 bridgeFromto(SpurSegmentInfo *aSegment, SpurSegmentInfo *nextSegmentOrNil)
 {
     usqInt bridgeSpan;
-    usqInt clifton;
+    sqInt clifton;
     usqInt segEnd;
 
 	segEnd = ((aSegment->segSize)) + ((aSegment->segStart));
@@ -65244,7 +65323,7 @@
     sqInt largeChild;
     sqInt newEndOfMemory;
     sqInt next;
-    usqInt node;
+    sqInt node;
     SpurSegmentInfo *seg;
     sqInt smallChild;
     sqInt treeNode;
@@ -65348,7 +65427,7 @@
 static sqInt
 readHeapFromImageFiledataBytes(sqImageFile f, sqInt numBytes)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt bridge;
+    usqInt bridge;
     usqInt bridgehead;
     usqInt bridgeSpan;
     sqInt bytesRead;
@@ -75528,10 +75607,9 @@
 	n = 0;
 	do {
 		if (!(isFree(page))) {
-			printStackPageuseCount(page, n);
+			printStackPageuseCount(page, (n += 1));
 			/* begin cr */
 			printf("\n");
-			n += 1;
 		}
 	} while(((page = (page->prevPage))) != (mostRecentlyUsedPage()));
 }
@@ -75563,10 +75641,9 @@
 	n = 0;
 	for (i = 0; i < GIV(numStackPages); i += 1) {
 		if (!(isFree(stackPageAt(i)))) {
-			printStackPageuseCount(stackPageAt(i), n);
+			printStackPageuseCount(stackPageAt(i), (n += 1));
 			/* begin cr */
 			printf("\n");
-			n += 1;
 		}
 	}
 }

Modified: branches/Cog/nsspursrc/vm/cointerp.h
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.h	2015-08-20 19:28:03 UTC (rev 3426)
+++ branches/Cog/nsspursrc/vm/cointerp.h	2015-08-22 03:39:38 UTC (rev 3427)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7
  */
 
 

Modified: branches/Cog/nsspursrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/gcc3x-cointerp.c	2015-08-20 19:28:03 UTC (rev 3426)
+++ branches/Cog/nsspursrc/vm/gcc3x-cointerp.c	2015-08-22 03:39:38 UTC (rev 3427)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7
    from
-	CoInterpreter VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464
+	CoInterpreter VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -2417,7 +2417,7 @@
 /*560*/	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0,-1,-1
 	};
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1439";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1441";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -18337,7 +18337,7 @@
 static sqInt
 checkForAndFollowForwardedPrimitiveState(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt accessorDepth;
+    signed char accessorDepth;
     sqInt firstBytecode;
     sqInt found;
     sqInt found1;
@@ -53456,13 +53456,13 @@
 /*	This primitive will load a binary image segment created by
 	primitiveStoreImageSegment. It expects the outPointer array to be of the
 	proper size, and the wordArray to be well formed.
-	It will return as its value the original array of roots, and the erstwhile
-	segmentWordArray will
-	have been truncated to a size of one word, i.e. retaining the version
-	stamp. If this primitive
-	should fail, the segmentWordArray will, sadly, have been reduced to an
-	unrecognizable and
-	unusable jumble. But what more could you have done with it anyway? */
+	It will return as its value the original array of roots, and the
+	segmentWordArray will become an
+	array of the loaded objects. If this primitive should fail, the
+	segmentWordArray will, sadly, have
+	been reduced to an unrecognizable and unusable jumble. But what more could
+	you have done
+	with it anyway? */
 
 	/* SpurMemoryManager>>#loadImageSegmentFrom:outPointers: */
 static sqInt
@@ -53476,11 +53476,17 @@
     sqInt classRef;
     sqInt errorCode;
     sqInt errorCode1;
+    sqInt fillIdx;
     sqInt hash;
     sqInt i;
     sqInt iLimiT;
+    sqInt loadedObjectsArray;
     sqInt mappedOop;
+    usqInt newObj;
+    usqInt numBytes;
+    sqInt numLoadedObjects;
     usqInt numOutPointers;
+    sqInt numSegObjs;
     usqInt numSlots;
     usqInt numSlots1;
     usqInt numSlots11;
@@ -53599,15 +53605,17 @@
 	numOutPointers = (numSlots4 == 0xFF
 		? longAt(outPointerArray - BaseHeaderSize)
 		: numSlots4);
+	numSegObjs = 0;
 	/* begin objectStartingAt: */
 	numSlots13 = byteAt(segmentStart + 7);
 	objOop1 = (numSlots13 == 0xFF
 		? segmentStart + BaseHeaderSize
 		: segmentStart);
 	while (objOop1 < segmentLimit) {
+		numSegObjs += 1;
 		if (((((usqInt) (longAt(objOop1 + 4))) >> 23) & 1) != 0) {
 			errorCode = PrimErrInappropriate;
-			goto l2;
+			goto l3;
 		}
 
 		/* validate the class ref, but don't update it until any internal classes have been added to the class table. */
@@ -53616,14 +53624,14 @@
 		if (classIndex & TopHashBit) {
 			if ((classIndex - TopHashBit) >= numOutPointers) {
 				errorCode = PrimErrBadIndex;
-				goto l2;
+				goto l3;
 			}
 			mappedOop = longAt((outPointerArray + BaseHeaderSize) + ((classIndex - TopHashBit) << (shiftForWord())));
 			hash = (long32At(mappedOop + 4)) & 0x3FFFFF;
 			if (!((hash > 0x1F)
 				 && ((classOrNilAtIndex(hash)) == mappedOop))) {
 				errorCode = PrimErrInappropriate;
-				goto l2;
+				goto l3;
 			}
 		}
 		else {
@@ -53632,11 +53640,11 @@
 
 			if (((oop1 = (classIndex * 8) + segmentStart)) >= segmentLimit) {
 				errorCode = PrimErrBadIndex;
-				goto l2;
+				goto l3;
 			}
 			if (((long32At(oop1 + 4)) & 0x3FFFFF) != 0) {
 				errorCode = PrimErrInappropriate;
-				goto l2;
+				goto l3;
 			}
 		}
 		for (i = 0, iLimiT = ((numPointerSlotsOf(objOop1)) - 1); i <= iLimiT; i += 1) {
@@ -53645,18 +53653,18 @@
 				if (oop1 & TopOopBit) {
 					if (((oop1 = (oop1 - TopOopBit) / BytesPerOop)) >= numOutPointers) {
 						errorCode = PrimErrBadIndex;
-						goto l2;
+						goto l3;
 					}
 					mappedOop = longAt((outPointerArray + BaseHeaderSize) + (oop1 << (shiftForWord())));
 				}
 				else {
 					if ((oop1 & (8 - 1)) != 0) {
 						errorCode = PrimErrInappropriate;
-						goto l2;
+						goto l3;
 					}
 					if (((mappedOop = oop1 + segmentStart)) >= segmentLimit) {
 						errorCode = PrimErrBadIndex;
-						goto l2;
+						goto l3;
 					}
 				}
 				/* begin storePointerUnchecked:ofObject:withValue: */
@@ -53666,11 +53674,52 @@
 		}
 		objOop1 = objectAfterlimit(objOop1, segmentLimit);
 	}
-	errorCode = 0;
-l2:	/* end mapOopsAndValidateClassRefsFrom:to:outPointers: */;
-	if (errorCode != 0) {
+	errorCode = -numSegObjs;
+l3:	/* end mapOopsAndValidateClassRefsFrom:to:outPointers: */;
+	if (errorCode > 0) {
 		return errorCode;
 	}
+	numLoadedObjects = -errorCode;
+	/* begin allocateSlots:format:classIndex: */
+	if (numLoadedObjects >= 0xFF) {
+		newObj = GIV(freeStart) + BaseHeaderSize;
+		numBytes = (BaseHeaderSize + BaseHeaderSize) + ((numLoadedObjects + (numLoadedObjects & 1)) * BytesPerOop);
+	}
+	else {
+		newObj = GIV(freeStart);
+		numBytes = BaseHeaderSize + ((numLoadedObjects <= 1
+	? 8
+	: (numLoadedObjects + (numLoadedObjects & 1)) * BytesPerOop));
+	}
+	if ((GIV(freeStart) + numBytes) > GIV(scavengeThreshold)) {
+		if (!GIV(needGCFlag)) {
+			/* begin scheduleScavenge */
+			GIV(needGCFlag) = 1;
+			forceInterruptCheck();
+		}
+		loadedObjectsArray = allocateSlotsInOldSpacebytesformatclassIndex(numLoadedObjects, numBytes, 2, ClassArrayCompactIndex);
+		goto l1;
+	}
+	if (numLoadedObjects >= 0xFF) {
+
+		/* for header parsing we put a saturated slot count in the prepended overflow size word */
+
+		flag("endianness");
+		longAtput(GIV(freeStart), numLoadedObjects);
+		longAtput(GIV(freeStart) + 4, 0xFF << 24);
+		long64Atput(newObj, (((((usqLong) 0xFF)) << 56) + (2 << 24)) + ClassArrayCompactIndex);
+	}
+	else {
+		long64Atput(newObj, (((((usqLong) numLoadedObjects)) << 56) + (2 << 24)) + ClassArrayCompactIndex);
+	}
+	assert((numBytes % (allocationUnit())) == 0);
+	assert((newObj % (allocationUnit())) == 0);
+	GIV(freeStart) += numBytes;
+	loadedObjectsArray = newObj;
+l1:	/* end allocateSlots:format:classIndex: */;
+	if (!(loadedObjectsArray)) {
+		return PrimErrNoMemory;
+	}
 	/* begin enterClassesIntoClassTableFrom:to: */
 	objOop = objectAfter(objectStartingAt(segmentStart));
 	while ((objOop < segmentLimit)
@@ -53686,26 +53735,31 @@
 				objOop = objectAfterlimit(objOop, segmentLimit);
 			}
 			errorCode = errorCode1;
-			goto l1;
+			goto l2;
 		}
 		objOop = objectAfterlimit(objOop, segmentLimit);
 	}
 	errorCode = 0;
-l1:	/* end enterClassesIntoClassTableFrom:to: */;
+l2:	/* end enterClassesIntoClassTableFrom:to: */;
 	if (errorCode != 0) {
 		return errorCode;
 	}
-	/* begin assignClassIndicesAndPinFrom:to:outPointers: */
+	/* begin assignClassIndicesAndPinFrom:to:outPointers:filling: */
 	/* begin objectStartingAt: */
 	numSlots5 = byteAt(segmentStart + 7);
 	objOop2 = (numSlots5 == 0xFF
 		? segmentStart + BaseHeaderSize
 		: segmentStart);
+	fillIdx = 0;
 	while (objOop2 < segmentLimit) {
+		/* begin storePointerUnchecked:ofObject:withValue: */
+		assert(!(isForwarded(loadedObjectsArray)));
+		longAtput((loadedObjectsArray + BaseHeaderSize) + (fillIdx << (shiftForWord())), objOop2);
 
 		/* In the segment, class indices are offset indexes into the segment data,
 		   or into outPointers.  See mapOopsFrom:to:outPointers:outHashes:. */
 
+		fillIdx += 1;
 		classRef = ((longAt(objOop2)) & 0x3FFFFF) - 16;
 		if (classRef & TopHashBit) {
 			classOop = longAt((outPointerArray + BaseHeaderSize) + ((classRef - TopHashBit) << (shiftForWord())));
@@ -53763,6 +53817,31 @@
 	else {
 		byteAtput(segmentWordArray + 7, 8 / BytesPerOop);
 	}
+	/* begin forward:to: */
+	/* begin set:classIndexTo:formatTo: */
+	assert(((8 >= 0) && (8 <= (classIndexMask()))));
+	assert(((7 >= 0) && (7 <= (formatMask()))));
+	flag("endianness");
+	longAtput(segmentWordArray, ((longAt(segmentWordArray)) & ((unsigned int)~((0x1F << 24) + 0x3FFFFF))) + (8 + (7 << 24)));
+	/* begin storePointer:ofForwarder:withValue: */
+	assert(isForwarded(segmentWordArray));
+	assert(!(isOopForwarded(loadedObjectsArray)));
+	if (isOldObject(segmentWordArray)) {
+
+		/* most stores into young objects */
+
+		if (((loadedObjectsArray & 3) == 0)
+		 && (oopisLessThan(loadedObjectsArray, GIV(newSpaceLimit)))) {
+			/* begin possibleRootStoreInto: */
+			if (!(((((usqInt) (longAt(segmentWordArray))) >> 29) & 1) != 0)) {
+				remember(segmentWordArray);
+			}
+		}
+	}
+	longAtput((segmentWordArray + BaseHeaderSize) + (0 << (shiftForWord())), loadedObjectsArray);
+	if ((byteAt(segmentWordArray + 7)) == 0) {
+		byteAtput(segmentWordArray + 7, 1);
+	}
 	runLeakCheckerFor(GCModeImageSegment);
 	/* begin objectStartingAt: */
 	numSlots1 = byteAt(segmentStart + 7);
@@ -65012,7 +65091,7 @@
 bridgeFromto(SpurSegmentInfo *aSegment, SpurSegmentInfo *nextSegmentOrNil)
 {
     usqInt bridgeSpan;
-    usqInt clifton;
+    sqInt clifton;
     usqInt segEnd;
 
 	segEnd = ((aSegment->segSize)) + ((aSegment->segStart));
@@ -65253,7 +65332,7 @@
     sqInt largeChild;
     sqInt newEndOfMemory;
     sqInt next;
-    usqInt node;
+    sqInt node;
     SpurSegmentInfo *seg;
     sqInt smallChild;
     sqInt treeNode;
@@ -65357,7 +65436,7 @@
 static sqInt
 readHeapFromImageFiledataBytes(sqImageFile f, sqInt numBytes)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt bridge;
+    usqInt bridge;
     usqInt bridgehead;
     usqInt bridgeSpan;
     sqInt bytesRead;
@@ -75537,10 +75616,9 @@
 	n = 0;
 	do {
 		if (!(isFree(page))) {
-			printStackPageuseCount(page, n);
+			printStackPageuseCount(page, (n += 1));
 			/* begin cr */
 			printf("\n");
-			n += 1;
 		}
 	} while(((page = (page->prevPage))) != (mostRecentlyUsedPage()));
 }
@@ -75572,10 +75650,9 @@
 	n = 0;
 	for (i = 0; i < GIV(numStackPages); i += 1) {
 		if (!(isFree(stackPageAt(i)))) {
-			printStackPageuseCount(stackPageAt(i), n);
+			printStackPageuseCount(stackPageAt(i), (n += 1));
 			/* begin cr */
 			printf("\n");
-			n += 1;
 		}
 	}
 }

Modified: branches/Cog/nsspurstack64src/vm/gcc3x-interp.c
===================================================================
--- branches/Cog/nsspurstack64src/vm/gcc3x-interp.c	2015-08-20 19:28:03 UTC (rev 3426)
+++ branches/Cog/nsspurstack64src/vm/gcc3x-interp.c	2015-08-22 03:39:38 UTC (rev 3427)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7
    from
-	StackInterpreter VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464
+	StackInterpreter VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7
  */
-static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464 " __DATE__ ;
+static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -2177,7 +2177,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.1439";
+const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.1441";
 volatile int sendTrace;
 sqInt suppressHeartbeatFlag;
 
@@ -41403,13 +41403,13 @@
 /*	This primitive will load a binary image segment created by
 	primitiveStoreImageSegment. It expects the outPointer array to be of the
 	proper size, and the wordArray to be well formed.
-	It will return as its value the original array of roots, and the erstwhile
-	segmentWordArray will
-	have been truncated to a size of one word, i.e. retaining the version
-	stamp. If this primitive
-	should fail, the segmentWordArray will, sadly, have been reduced to an
-	unrecognizable and
-	unusable jumble. But what more could you have done with it anyway? */
+	It will return as its value the original array of roots, and the
+	segmentWordArray will become an
+	array of the loaded objects. If this primitive should fail, the
+	segmentWordArray will, sadly, have
+	been reduced to an unrecognizable and unusable jumble. But what more could
+	you have done
+	with it anyway? */
 
 	/* SpurMemoryManager>>#loadImageSegmentFrom:outPointers: */
 static sqInt
@@ -41423,6 +41423,7 @@
     sqInt classRef;
     sqInt errorCode;
     sqInt errorCode1;
+    sqInt fillIdx;
     sqInt followingWord;
     sqInt followingWord1;
     sqInt followingWord2;
@@ -41434,8 +41435,13 @@
     sqInt hash;
     sqInt i;
     sqInt iLimiT;
+    sqInt loadedObjectsArray;
     sqInt mappedOop;
+    usqInt newObj;
+    usqInt numBytes;
+    sqInt numLoadedObjects;
     usqInt numOutPointers;
+    sqInt numSegObjs;
     usqInt numSlots;
     usqInt numSlots1;
     usqInt numSlots11;
@@ -41564,15 +41570,17 @@
 	numOutPointers = (numSlots5 == 0xFF
 		? ((usqInt) (((unsigned long)(((long)(longAt(outPointerArray - BaseHeaderSize))) << 8)))) >> 8
 		: numSlots5);
+	numSegObjs = 0;
 	/* begin objectStartingAt: */
 	numSlots14 = byteAt(segmentStart + 7);
 	objOop1 = (numSlots14 == 0xFF
 		? segmentStart + BaseHeaderSize
 		: segmentStart);
 	while (objOop1 < segmentLimit) {
+		numSegObjs += 1;
 		if (((((usqInt) (longAt(objOop1))) >> 55) & 1) != 0) {
 			errorCode = PrimErrInappropriate;
-			goto l5;
+			goto l6;
 		}
 
 		/* validate the class ref, but don't update it until any internal classes have been added to the class table. */
@@ -41581,14 +41589,14 @@
 		if (classIndex & TopHashBit) {
 			if ((classIndex - TopHashBit) >= numOutPointers) {
 				errorCode = PrimErrBadIndex;
-				goto l5;
+				goto l6;
 			}
 			mappedOop = longAt((outPointerArray + BaseHeaderSize) + (((long)(classIndex - TopHashBit)) << (shiftForWord())));
 			hash = (long32At(mappedOop + 4)) & 0x3FFFFF;
 			if (!((hash > 0x1F)
 				 && ((classOrNilAtIndex(hash)) == mappedOop))) {
 				errorCode = PrimErrInappropriate;
-				goto l5;
+				goto l6;
 			}
 		}
 		else {
@@ -41597,11 +41605,11 @@
 
 			if (((oop1 = (classIndex * 8) + segmentStart)) >= segmentLimit) {
 				errorCode = PrimErrBadIndex;
-				goto l5;
+				goto l6;
 			}
 			if (((long32At(oop1 + 4)) & 0x3FFFFF) != 0) {
 				errorCode = PrimErrInappropriate;
-				goto l5;
+				goto l6;
 			}
 		}
 		for (i = 0, iLimiT = ((numPointerSlotsOf(objOop1)) - 1); i <= iLimiT; i += 1) {
@@ -41610,18 +41618,18 @@
 				if (oop1 & TopOopBit) {
 					if (((oop1 = (oop1 - TopOopBit) / BytesPerOop)) >= numOutPointers) {
 						errorCode = PrimErrBadIndex;
-						goto l5;
+						goto l6;
 					}
 					mappedOop = longAt((outPointerArray + BaseHeaderSize) + (((long)oop1) << (shiftForWord())));
 				}
 				else {
 					if ((oop1 & (8 - 1)) != 0) {
 						errorCode = PrimErrInappropriate;
-						goto l5;
+						goto l6;
 					}
 					if (((mappedOop = oop1 + segmentStart)) >= segmentLimit) {
 						errorCode = PrimErrBadIndex;
-						goto l5;
+						goto l6;
 					}
 				}
 				/* begin storePointerUnchecked:ofObject:withValue: */
@@ -41645,20 +41653,64 @@
 		followingWordAddress2 = (objOop1 + BaseHeaderSize) + slotBytes3;
 		if (oopisGreaterThanOrEqualTo(followingWordAddress2, segmentLimit)) {
 			objOop1 = segmentLimit;
-			goto l4;
+			goto l5;
 		}
 		flag("endianness");
 		followingWord2 = longAt(followingWordAddress2);
 		objOop1 = ((((usqInt) followingWord2) >> 56) == 0xFF
 			? followingWordAddress2 + BaseHeaderSize
 			: followingWordAddress2);
-	l4:	/* end objectAfter:limit: */;
+	l5:	/* end objectAfter:limit: */;
 	}
-	errorCode = 0;
-l5:	/* end mapOopsAndValidateClassRefsFrom:to:outPointers: */;
-	if (errorCode != 0) {
+	errorCode = -numSegObjs;
+l6:	/* end mapOopsAndValidateClassRefsFrom:to:outPointers: */;
+	if (errorCode > 0) {
 		return errorCode;
 	}
+	numLoadedObjects = -errorCode;
+	/* begin allocateSlots:format:classIndex: */
+	if (numLoadedObjects >= 0xFF) {
+		if ((((usqInt) numLoadedObjects) >> 56) > 0) {
+			loadedObjectsArray = null;
+			goto l1;
+		}
+		newObj = GIV(freeStart) + BaseHeaderSize;
+		numBytes = (BaseHeaderSize + BaseHeaderSize) + (numLoadedObjects * BytesPerOop);
+	}
+	else {
+		newObj = GIV(freeStart);
+		numBytes = BaseHeaderSize + ((numLoadedObjects < 1
+	? 8
+	: numLoadedObjects * BytesPerOop));
+	}
+	if ((GIV(freeStart) + numBytes) > GIV(scavengeThreshold)) {
+		if (!GIV(needGCFlag)) {
+			/* begin scheduleScavenge */
+			GIV(needGCFlag) = 1;
+			forceInterruptCheck();
+		}
+		loadedObjectsArray = allocateSlotsInOldSpacebytesformatclassIndex(numLoadedObjects, numBytes, 2, ClassArrayCompactIndex);
+		goto l1;
+	}
+	if (numLoadedObjects >= 0xFF) {
+
+		/* for header parsing we put a saturated slot count in the prepended overflow size word */
+
+		flag("endianness");
+		longAtput(GIV(freeStart), (0xFFLL << 56) + numLoadedObjects);
+		longAtput(newObj, ((((long)(((usqLong) 0xFF))) << 56) + (2LL << 24)) + ClassArrayCompactIndex);
+	}
+	else {
+		longAtput(newObj, ((((long)(((usqLong) numLoadedObjects))) << 56) + (2LL << 24)) + ClassArrayCompactIndex);
+	}
+	assert((numBytes % (allocationUnit())) == 0);
+	assert((newObj % (allocationUnit())) == 0);
+	GIV(freeStart) += numBytes;
+	loadedObjectsArray = newObj;
+l1:	/* end allocateSlots:format:classIndex: */;
+	if (!(loadedObjectsArray)) {
+		return PrimErrNoMemory;
+	}
 	/* begin enterClassesIntoClassTableFrom:to: */
 	objOop = objectAfter(objectStartingAt(segmentStart));
 	while ((objOop < segmentLimit)
@@ -41686,17 +41738,17 @@
 				followingWordAddress = (objOop + BaseHeaderSize) + slotBytes2;
 				if (oopisGreaterThanOrEqualTo(followingWordAddress, segmentLimit)) {
 					objOop = segmentLimit;
-					goto l1;
+					goto l3;
 				}
 				flag("endianness");
 				followingWord = longAt(followingWordAddress);
 				objOop = ((((usqInt) followingWord) >> 56) == 0xFF
 					? followingWordAddress + BaseHeaderSize
 					: followingWordAddress);
-			l1:	/* end objectAfter:limit: */;
+			l3:	/* end objectAfter:limit: */;
 			}
 			errorCode = errorCode1;
-			goto l3;
+			goto l4;
 		}
 		/* begin objectAfter:limit: */
 		/* begin addressAfter: */
@@ -41724,21 +41776,26 @@
 	l2:	/* end objectAfter:limit: */;
 	}
 	errorCode = 0;
-l3:	/* end enterClassesIntoClassTableFrom:to: */;
+l4:	/* end enterClassesIntoClassTableFrom:to: */;
 	if (errorCode != 0) {
 		return errorCode;
 	}
-	/* begin assignClassIndicesAndPinFrom:to:outPointers: */
+	/* begin assignClassIndicesAndPinFrom:to:outPointers:filling: */
 	/* begin objectStartingAt: */
 	numSlots6 = byteAt(segmentStart + 7);
 	objOop2 = (numSlots6 == 0xFF
 		? segmentStart + BaseHeaderSize
 		: segmentStart);
+	fillIdx = 0;
 	while (objOop2 < segmentLimit) {
+		/* begin storePointerUnchecked:ofObject:withValue: */
+		assert(!(isForwarded(loadedObjectsArray)));
+		longAtput((loadedObjectsArray + BaseHeaderSize) + (((long)fillIdx) << (shiftForWord())), objOop2);
 
 		/* In the segment, class indices are offset indexes into the segment data,
 		   or into outPointers.  See mapOopsFrom:to:outPointers:outHashes:. */
 
+		fillIdx += 1;
 		classRef = ((longAt(objOop2)) & 0x3FFFFF) - 16;
 		if (classRef & TopHashBit) {
 			classOop = longAt((outPointerArray + BaseHeaderSize) + (((long)(classRef - TopHashBit)) << (shiftForWord())));
@@ -41801,14 +41858,14 @@
 		followingWordAddress3 = (objOop2 + BaseHeaderSize) + slotBytes4;
 		if (oopisGreaterThanOrEqualTo(followingWordAddress3, segmentLimit)) {
 			objOop2 = segmentLimit;
-			goto l6;
+			goto l7;
 		}
 		flag("endianness");
 		followingWord3 = longAt(followingWordAddress3);
 		objOop2 = ((((usqInt) followingWord3) >> 56) == 0xFF
 			? followingWordAddress3 + BaseHeaderSize
 			: followingWordAddress3);
-	l6:	/* end objectAfter:limit: */;
+	l7:	/* end objectAfter:limit: */;
 	}
 	if ((byteAt(segmentWordArray + 7)) == 0xFF) {
 		/* begin rawOverflowSlotsOf:put: */
@@ -41819,6 +41876,30 @@
 	else {
 		byteAtput(segmentWordArray + 7, 8 / BytesPerOop);
 	}
+	/* begin forward:to: */
+	/* begin set:classIndexTo:formatTo: */
+	assert(((8 >= 0) && (8 <= (classIndexMask()))));
+	assert(((7 >= 0) && (7 <= (formatMask()))));
+	longAtput(segmentWordArray, ((longAt(segmentWordArray)) & (~((0x1FLL << 24) + 0x3FFFFF))) + (8 + (7LL << 24)));
+	/* begin storePointer:ofForwarder:withValue: */
+	assert(isForwarded(segmentWordArray));
+	assert(!(isOopForwarded(loadedObjectsArray)));
+	if (isOldObject(segmentWordArray)) {
+
+		/* most stores into young objects */
+
+		if (((loadedObjectsArray & 7) == 0)
+		 && (oopisLessThan(loadedObjectsArray, GIV(newSpaceLimit)))) {
+			/* begin possibleRootStoreInto: */
+			if (!(((((usqInt) (longAt(segmentWordArray))) >> 29) & 1) != 0)) {
+				remember(segmentWordArray);
+			}
+		}
+	}
+	longAtput((segmentWordArray + BaseHeaderSize) + (0LL << (shiftForWord())), loadedObjectsArray);
+	if ((byteAt(segmentWordArray + 7)) == 0) {
+		byteAtput(segmentWordArray + 7, 1);
+	}
 	runLeakCheckerFor(GCModeImageSegment);
 	/* begin objectStartingAt: */
 	numSlots1 = byteAt(segmentStart + 7);
@@ -66755,10 +66836,9 @@
 	n = 0;
 	do {
 		if (!(isFree(page))) {
-			printStackPageuseCount(page, n);
+			printStackPageuseCount(page, (n += 1));
 			/* begin cr */
 			printf("\n");
-			n += 1;
 		}
 	} while(((page = (page->prevPage))) != (mostRecentlyUsedPage()));
 }
@@ -66790,10 +66870,9 @@
 	n = 0;
 	for (i = 0; i < GIV(numStackPages); i += 1) {
 		if (!(isFree(stackPageAt(i)))) {
-			printStackPageuseCount(stackPageAt(i), n);
+			printStackPageuseCount(stackPageAt(i), (n += 1));
 			/* begin cr */
 			printf("\n");
-			n += 1;
 		}
 	}
 }

Modified: branches/Cog/nsspurstack64src/vm/interp.c
===================================================================
--- branches/Cog/nsspurstack64src/vm/interp.c	2015-08-20 19:28:03 UTC (rev 3426)
+++ branches/Cog/nsspurstack64src/vm/interp.c	2015-08-22 03:39:38 UTC (rev 3427)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7
    from
-	StackInterpreter VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464
+	StackInterpreter VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7
  */
-static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464 " __DATE__ ;
+static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -2174,7 +2174,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.1439";
+const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.1441";
 volatile int sendTrace;
 sqInt suppressHeartbeatFlag;
 
@@ -41394,13 +41394,13 @@
 /*	This primitive will load a binary image segment created by
 	primitiveStoreImageSegment. It expects the outPointer array to be of the
 	proper size, and the wordArray to be well formed.
-	It will return as its value the original array of roots, and the erstwhile
-	segmentWordArray will
-	have been truncated to a size of one word, i.e. retaining the version
-	stamp. If this primitive
-	should fail, the segmentWordArray will, sadly, have been reduced to an
-	unrecognizable and
-	unusable jumble. But what more could you have done with it anyway? */
+	It will return as its value the original array of roots, and the
+	segmentWordArray will become an
+	array of the loaded objects. If this primitive should fail, the
+	segmentWordArray will, sadly, have
+	been reduced to an unrecognizable and unusable jumble. But what more could
+	you have done
+	with it anyway? */
 
 	/* SpurMemoryManager>>#loadImageSegmentFrom:outPointers: */
 static sqInt
@@ -41414,6 +41414,7 @@
     sqInt classRef;
     sqInt errorCode;
     sqInt errorCode1;
+    sqInt fillIdx;
     sqInt followingWord;
     sqInt followingWord1;
     sqInt followingWord2;
@@ -41425,8 +41426,13 @@
     sqInt hash;
     sqInt i;
     sqInt iLimiT;
+    sqInt loadedObjectsArray;
     sqInt mappedOop;
+    usqInt newObj;
+    usqInt numBytes;
+    sqInt numLoadedObjects;
     usqInt numOutPointers;
+    sqInt numSegObjs;
     usqInt numSlots;
     usqInt numSlots1;
     usqInt numSlots11;
@@ -41555,15 +41561,17 @@
 	numOutPointers = (numSlots5 == 0xFF
 		? ((usqInt) (((unsigned long)(((long)(longAt(outPointerArray - BaseHeaderSize))) << 8)))) >> 8
 		: numSlots5);
+	numSegObjs = 0;
 	/* begin objectStartingAt: */
 	numSlots14 = byteAt(segmentStart + 7);
 	objOop1 = (numSlots14 == 0xFF
 		? segmentStart + BaseHeaderSize
 		: segmentStart);
 	while (objOop1 < segmentLimit) {
+		numSegObjs += 1;
 		if (((((usqInt) (longAt(objOop1))) >> 55) & 1) != 0) {
 			errorCode = PrimErrInappropriate;
-			goto l5;
+			goto l6;
 		}
 
 		/* validate the class ref, but don't update it until any internal classes have been added to the class table. */
@@ -41572,14 +41580,14 @@
 		if (classIndex & TopHashBit) {
 			if ((classIndex - TopHashBit) >= numOutPointers) {
 				errorCode = PrimErrBadIndex;
-				goto l5;
+				goto l6;
 			}
 			mappedOop = longAt((outPointerArray + BaseHeaderSize) + (((long)(classIndex - TopHashBit)) << (shiftForWord())));
 			hash = (long32At(mappedOop + 4)) & 0x3FFFFF;
 			if (!((hash > 0x1F)
 				 && ((classOrNilAtIndex(hash)) == mappedOop))) {
 				errorCode = PrimErrInappropriate;
-				goto l5;
+				goto l6;
 			}
 		}
 		else {
@@ -41588,11 +41596,11 @@
 
 			if (((oop1 = (classIndex * 8) + segmentStart)) >= segmentLimit) {
 				errorCode = PrimErrBadIndex;
-				goto l5;
+				goto l6;
 			}
 			if (((long32At(oop1 + 4)) & 0x3FFFFF) != 0) {
 				errorCode = PrimErrInappropriate;
-				goto l5;
+				goto l6;
 			}
 		}
 		for (i = 0, iLimiT = ((numPointerSlotsOf(objOop1)) - 1); i <= iLimiT; i += 1) {
@@ -41601,18 +41609,18 @@
 				if (oop1 & TopOopBit) {
 					if (((oop1 = (oop1 - TopOopBit) / BytesPerOop)) >= numOutPointers) {
 						errorCode = PrimErrBadIndex;
-						goto l5;
+						goto l6;
 					}
 					mappedOop = longAt((outPointerArray + BaseHeaderSize) + (((long)oop1) << (shiftForWord())));
 				}
 				else {
 					if ((oop1 & (8 - 1)) != 0) {
 						errorCode = PrimErrInappropriate;
-						goto l5;
+						goto l6;
 					}
 					if (((mappedOop = oop1 + segmentStart)) >= segmentLimit) {
 						errorCode = PrimErrBadIndex;
-						goto l5;
+						goto l6;
 					}
 				}
 				/* begin storePointerUnchecked:ofObject:withValue: */
@@ -41636,20 +41644,64 @@
 		followingWordAddress2 = (objOop1 + BaseHeaderSize) + slotBytes3;
 		if (oopisGreaterThanOrEqualTo(followingWordAddress2, segmentLimit)) {
 			objOop1 = segmentLimit;
-			goto l4;
+			goto l5;
 		}
 		flag("endianness");
 		followingWord2 = longAt(followingWordAddress2);
 		objOop1 = ((((usqInt) followingWord2) >> 56) == 0xFF
 			? followingWordAddress2 + BaseHeaderSize
 			: followingWordAddress2);
-	l4:	/* end objectAfter:limit: */;
+	l5:	/* end objectAfter:limit: */;
 	}
-	errorCode = 0;
-l5:	/* end mapOopsAndValidateClassRefsFrom:to:outPointers: */;
-	if (errorCode != 0) {
+	errorCode = -numSegObjs;
+l6:	/* end mapOopsAndValidateClassRefsFrom:to:outPointers: */;
+	if (errorCode > 0) {
 		return errorCode;
 	}
+	numLoadedObjects = -errorCode;
+	/* begin allocateSlots:format:classIndex: */
+	if (numLoadedObjects >= 0xFF) {
+		if ((((usqInt) numLoadedObjects) >> 56) > 0) {
+			loadedObjectsArray = null;
+			goto l1;
+		}
+		newObj = GIV(freeStart) + BaseHeaderSize;
+		numBytes = (BaseHeaderSize + BaseHeaderSize) + (numLoadedObjects * BytesPerOop);
+	}
+	else {
+		newObj = GIV(freeStart);
+		numBytes = BaseHeaderSize + ((numLoadedObjects < 1
+	? 8
+	: numLoadedObjects * BytesPerOop));
+	}
+	if ((GIV(freeStart) + numBytes) > GIV(scavengeThreshold)) {
+		if (!GIV(needGCFlag)) {
+			/* begin scheduleScavenge */
+			GIV(needGCFlag) = 1;
+			forceInterruptCheck();
+		}
+		loadedObjectsArray = allocateSlotsInOldSpacebytesformatclassIndex(numLoadedObjects, numBytes, 2, ClassArrayCompactIndex);
+		goto l1;
+	}
+	if (numLoadedObjects >= 0xFF) {
+
+		/* for header parsing we put a saturated slot count in the prepended overflow size word */
+
+		flag("endianness");
+		longAtput(GIV(freeStart), (0xFFLL << 56) + numLoadedObjects);
+		longAtput(newObj, ((((long)(((usqLong) 0xFF))) << 56) + (2LL << 24)) + ClassArrayCompactIndex);
+	}
+	else {
+		longAtput(newObj, ((((long)(((usqLong) numLoadedObjects))) << 56) + (2LL << 24)) + ClassArrayCompactIndex);
+	}
+	assert((numBytes % (allocationUnit())) == 0);
+	assert((newObj % (allocationUnit())) == 0);
+	GIV(freeStart) += numBytes;
+	loadedObjectsArray = newObj;
+l1:	/* end allocateSlots:format:classIndex: */;
+	if (!(loadedObjectsArray)) {
+		return PrimErrNoMemory;
+	}
 	/* begin enterClassesIntoClassTableFrom:to: */
 	objOop = objectAfter(objectStartingAt(segmentStart));
 	while ((objOop < segmentLimit)
@@ -41677,17 +41729,17 @@
 				followingWordAddress = (objOop + BaseHeaderSize) + slotBytes2;
 				if (oopisGreaterThanOrEqualTo(followingWordAddress, segmentLimit)) {
 					objOop = segmentLimit;
-					goto l1;
+					goto l3;
 				}
 				flag("endianness");
 				followingWord = longAt(followingWordAddress);
 				objOop = ((((usqInt) followingWord) >> 56) == 0xFF
 					? followingWordAddress + BaseHeaderSize
 					: followingWordAddress);
-			l1:	/* end objectAfter:limit: */;
+			l3:	/* end objectAfter:limit: */;
 			}
 			errorCode = errorCode1;
-			goto l3;
+			goto l4;
 		}
 		/* begin objectAfter:limit: */
 		/* begin addressAfter: */
@@ -41715,21 +41767,26 @@
 	l2:	/* end objectAfter:limit: */;
 	}
 	errorCode = 0;
-l3:	/* end enterClassesIntoClassTableFrom:to: */;
+l4:	/* end enterClassesIntoClassTableFrom:to: */;
 	if (errorCode != 0) {
 		return errorCode;
 	}
-	/* begin assignClassIndicesAndPinFrom:to:outPointers: */
+	/* begin assignClassIndicesAndPinFrom:to:outPointers:filling: */
 	/* begin objectStartingAt: */
 	numSlots6 = byteAt(segmentStart + 7);
 	objOop2 = (numSlots6 == 0xFF
 		? segmentStart + BaseHeaderSize
 		: segmentStart);
+	fillIdx = 0;
 	while (objOop2 < segmentLimit) {
+		/* begin storePointerUnchecked:ofObject:withValue: */
+		assert(!(isForwarded(loadedObjectsArray)));
+		longAtput((loadedObjectsArray + BaseHeaderSize) + (((long)fillIdx) << (shiftForWord())), objOop2);
 
 		/* In the segment, class indices are offset indexes into the segment data,
 		   or into outPointers.  See mapOopsFrom:to:outPointers:outHashes:. */
 
+		fillIdx += 1;
 		classRef = ((longAt(objOop2)) & 0x3FFFFF) - 16;
 		if (classRef & TopHashBit) {
 			classOop = longAt((outPointerArray + BaseHeaderSize) + (((long)(classRef - TopHashBit)) << (shiftForWord())));
@@ -41792,14 +41849,14 @@
 		followingWordAddress3 = (objOop2 + BaseHeaderSize) + slotBytes4;
 		if (oopisGreaterThanOrEqualTo(followingWordAddress3, segmentLimit)) {
 			objOop2 = segmentLimit;
-			goto l6;
+			goto l7;
 		}
 		flag("endianness");
 		followingWord3 = longAt(followingWordAddress3);
 		objOop2 = ((((usqInt) followingWord3) >> 56) == 0xFF
 			? followingWordAddress3 + BaseHeaderSize
 			: followingWordAddress3);
-	l6:	/* end objectAfter:limit: */;
+	l7:	/* end objectAfter:limit: */;
 	}
 	if ((byteAt(segmentWordArray + 7)) == 0xFF) {
 		/* begin rawOverflowSlotsOf:put: */
@@ -41810,6 +41867,30 @@
 	else {
 		byteAtput(segmentWordArray + 7, 8 / BytesPerOop);
 	}
+	/* begin forward:to: */
+	/* begin set:classIndexTo:formatTo: */
+	assert(((8 >= 0) && (8 <= (classIndexMask()))));
+	assert(((7 >= 0) && (7 <= (formatMask()))));
+	longAtput(segmentWordArray, ((longAt(segmentWordArray)) & (~((0x1FLL << 24) + 0x3FFFFF))) + (8 + (7LL << 24)));
+	/* begin storePointer:ofForwarder:withValue: */
+	assert(isForwarded(segmentWordArray));
+	assert(!(isOopForwarded(loadedObjectsArray)));
+	if (isOldObject(segmentWordArray)) {
+
+		/* most stores into young objects */
+
+		if (((loadedObjectsArray & 7) == 0)
+		 && (oopisLessThan(loadedObjectsArray, GIV(newSpaceLimit)))) {
+			/* begin possibleRootStoreInto: */
+			if (!(((((usqInt) (longAt(segmentWordArray))) >> 29) & 1) != 0)) {
+				remember(segmentWordArray);
+			}
+		}
+	}
+	longAtput((segmentWordArray + BaseHeaderSize) + (0LL << (shiftForWord())), loadedObjectsArray);
+	if ((byteAt(segmentWordArray + 7)) == 0) {
+		byteAtput(segmentWordArray + 7, 1);
+	}
 	runLeakCheckerFor(GCModeImageSegment);
 	/* begin objectStartingAt: */
 	numSlots1 = byteAt(segmentStart + 7);
@@ -66746,10 +66827,9 @@
 	n = 0;
 	do {
 		if (!(isFree(page))) {
-			printStackPageuseCount(page, n);
+			printStackPageuseCount(page, (n += 1));
 			/* begin cr */
 			printf("\n");
-			n += 1;
 		}
 	} while(((page = (page->prevPage))) != (mostRecentlyUsedPage()));
 }
@@ -66781,10 +66861,9 @@
 	n = 0;
 	for (i = 0; i < GIV(numStackPages); i += 1) {
 		if (!(isFree(stackPageAt(i)))) {
-			printStackPageuseCount(stackPageAt(i), n);
+			printStackPageuseCount(stackPageAt(i), (n += 1));
 			/* begin cr */
 			printf("\n");
-			n += 1;
 		}
 	}
 }

Modified: branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c
===================================================================
--- branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c	2015-08-20 19:28:03 UTC (rev 3426)
+++ branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c	2015-08-22 03:39:38 UTC (rev 3427)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7
    from
-	StackInterpreter VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464
+	StackInterpreter VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7
  */
-static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.1439 uuid: ce1fb6f7-90ee-48c4-9f60-6ff1731ec464 " __DATE__ ;
+static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.1441 uuid: c41d605b-7d2e-4ecc-95e1-b295119106a7 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -2148,7 +2148,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.1439";
+const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreterPrimitives_VMMaker.oscog-eem.1441";
 volatile int sendTrace;
 sqInt suppressHeartbeatFlag;
 
@@ -38426,13 +38426,13 @@
 /*	This primitive will load a binary image segment created by
 	primitiveStoreImageSegment. It expects the outPointer array to be of the
 	proper size, and the wordArray to be well formed.
-	It will return as its value the original array of roots, and the erstwhile
-	segmentWordArray will
-	have been truncated to a size of one word, i.e. retaining the version
-	stamp. If this primitive
-	should fail, the segmentWordArray will, sadly, have been reduced to an
-	unrecognizable and
-	unusable jumble. But what more could you have done with it anyway? */
+	It will return as its value the original array of roots, and the
+	segmentWordArray will become an
+	array of the loaded objects. If this primitive should fail, the
+	segmentWordArray will, sadly, have
+	been reduced to an unrecognizable and unusable jumble. But what more could
+	you have done
+	with it anyway? */
 
 	/* SpurMemoryManager>>#loadImageSegmentFrom:outPointers: */
 static sqInt
@@ -38446,11 +38446,17 @@
     sqInt classRef;
     sqInt errorCode;
     sqInt errorCode1;
+    sqInt fillIdx;
     sqInt hash;
     sqInt i;
     sqInt iLimiT;
+    sqInt loadedObjectsArray;
     sqInt mappedOop;
+    usqInt newObj;
+    usqInt numBytes;
+    sqInt numLoadedObjects;
     usqInt numOutPointers;
+    sqInt numSegObjs;
     usqInt numSlots;
     usqInt numSlots1;
     usqInt numSlots11;
@@ -38569,15 +38575,17 @@
 	numOutPointers = (numSlots4 == 0xFF
 		? longAt(outPointerArray - BaseHeaderSize)
 		: numSlots4);
+	numSegObjs = 0;
 	/* begin objectStartingAt: */
 	numSlots13 = byteAt(segmentStart + 7);
 	objOop1 = (numSlots13 == 0xFF
 		? segmentStart + BaseHeaderSize
 		: segmentStart);
 	while (objOop1 < segmentLimit) {
+		numSegObjs += 1;
 		if (((((usqInt) (longAt(objOop1 + 4))) >> 23) & 1) != 0) {
 			errorCode = PrimErrInappropriate;
-			goto l2;
+			goto l3;
 		}
 
 		/* validate the class ref, but don't update it until any internal classes have been added to the class table. */
@@ -38586,14 +38594,14 @@
 		if (classIndex & TopHashBit) {
 			if ((classIndex - TopHashBit) >= numOutPointers) {
 				errorCode = PrimErrBadIndex;
-				goto l2;
+				goto l3;
 			}
 			mappedOop = longAt((outPointerArray + BaseHeaderSize) + ((classIndex - TopHashBit) << (shiftForWord())));
 			hash = (long32At(mappedOop + 4)) & 0x3FFFFF;
 			if (!((hash > 0x1F)
 				 && ((classOrNilAtIndex(hash)) == mappedOop))) {
 				errorCode = PrimErrInappropriate;
-				goto l2;
+				goto l3;
 			}
 		}
 		else {
@@ -38602,11 +38610,11 @@
 
 			if (((oop1 = (classIndex * 8) + segmentStart)) >= segmentLimit) {
 				errorCode = PrimErrBadIndex;
-				goto l2;
+				goto l3;
 			}
 			if (((long32At(oop1 + 4)) & 0x3FFFFF) != 0) {
 				errorCode = PrimErrInappropriate;
-				goto l2;
+				goto l3;
 			}
 		}
 		for (i = 0, iLimiT = ((numPointerSlotsOf(objOop1)) - 1); i <= iLimiT; i += 1) {
@@ -38615,18 +38623,18 @@
 				if (oop1 & TopOopBit) {
 					if (((oop1 = (oop1 - TopOopBit) / BytesPerOop)) >= numOutPointers) {
 						errorCode = PrimErrBadIndex;
-						goto l2;
+						goto l3;
 					}
 					mappedOop = longAt((outPointerArray + BaseHeaderSize) + (oop1 << (shiftForWord())));
 				}
 				else {
 					if ((oop1 & (8 - 1)) != 0) {
 						errorCode = PrimErrInappropriate;
-						goto l2;
+						goto l3;
 					}
 					if (((mappedOop = oop1 + segmentStart)) >= segmentLimit) {
 						errorCode = PrimErrBadIndex;
-						goto l2;
+						goto l3;
 					}
 				}
 				/* begin storePointerUnchecked:ofObject:withValue: */
@@ -38636,11 +38644,52 @@
 		}
 		objOop1 = objectAfterlimit(objOop1, segmentLimit);
 	}
-	errorCode = 0;
-l2:	/* end mapOopsAndValidateClassRefsFrom:to:outPointers: */;
-	if (errorCode != 0) {
+	errorCode = -numSegObjs;
+l3:	/* end mapOopsAndValidateClassRefsFrom:to:outPointers: */;
+	if (errorCode > 0) {
 		return errorCode;
 	}
+	numLoadedObjects = -errorCode;
+	/* begin allocateSlots:format:classIndex: */
+	if (numLoadedObjects >= 0xFF) {
+		newObj = GIV(freeStart) + BaseHeaderSize;
+		numBytes = (BaseHeaderSize + BaseHeaderSize) + ((numLoadedObjects + (numLoadedObjects & 1)) * BytesPerOop);
+	}
+	else {
+		newObj = GIV(freeStart);
+		numBytes = BaseHeaderSize + ((numLoadedObjects <= 1
+	? 8
+	: (numLoadedObjects + (numLoadedObjects & 1)) * BytesPerOop));
+	}

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list