[Vm-dev] [commit][2928] CogVM source as per VMMaker.oscog-eem.730

commits at squeakvm.org commits at squeakvm.org
Wed May 21 19:18:14 UTC 2014


Revision: 2928
Author:   eliot
Date:     2014-05-21 12:18:13 -0700 (Wed, 21 May 2014)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.730

Spur:
Implement memory shrinkage.
Check free space around SpurSegmentManager prepareForSnapshot & postSnapshot.

Modified Paths:
--------------
    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/platforms/Cross/vm/sq.h
    branches/Cog/platforms/Mac OS/vm/sqMacMemory.c
    branches/Cog/platforms/unix/vm/sqUnixMemory.c
    branches/Cog/platforms/win32/vm/sqWin32Alloc.c
    branches/Cog/spursistasrc/vm/cointerp.c
    branches/Cog/spursistasrc/vm/cointerp.h
    branches/Cog/spursistasrc/vm/gcc3x-cointerp.c
    branches/Cog/spursistasrc/vm/interp.h
    branches/Cog/spursistasrc/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

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

Modified: branches/Cog/nsspursrc/vm/cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.c	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/nsspursrc/vm/cointerp.c	2014-05-21 19:18:13 UTC (rev 2928)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
    from
-	CoInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CoInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -753,6 +753,7 @@
 static sqInt isContextNonImm(sqInt oop) NoDbgRegParms;
 static sqInt isContext(sqInt oop) NoDbgRegParms;
 static sqInt isEmptyObjStack(sqInt objStack) NoDbgRegParms;
+static sqInt isEmptySegment(SpurSegmentInfo *seg) NoDbgRegParms;
 static sqInt isEnumerableObjectNoAssert(sqInt objOop) NoDbgRegParms;
 static sqInt isEnumerableObject(sqInt objOop) NoDbgRegParms;
 static sqInt isEphemeron(sqInt objOop) NoDbgRegParms;
@@ -1454,15 +1455,15 @@
 _iss sqInt hiddenRootsObj;
 _iss usqInt endOfMemory;
 _iss sqInt trueObj;
+_iss SpurSegmentInfo * segments;
 _iss sqInt remapBufferCount;
 _iss sqInt needGCFlag;
 _iss sqInt falseObj;
-_iss SpurSegmentInfo * segments;
 _iss sqInt traceLogIndex;
 _iss sqInt bytesPerPage;
 _iss sqInt totalFreeOldSpace;
+_iss sqInt numSegments;
 _iss usqInt pastSpaceStart;
-_iss sqInt numSegments;
 _iss char * stackLimit;
 _iss usqInt scavengeThreshold;
 _iss sqInt * freeLists;
@@ -1492,18 +1493,18 @@
 _iss SpurNewSpaceSpace eden;
 _iss sqInt profileSemaphore;
 _iss sqInt ephemeronList;
+_iss usqInt freeOldSpaceStart;
 _iss sqInt profileProcess;
 _iss sqInt tenureThreshold;
 _iss sqInt extraRootCount;
 _iss sqInt invalidObjStackPage;
 _iss sqInt previousRememberedSetSize;
 _iss unsigned char * classTableBitmap;
-_iss usqInt freeOldSpaceStart;
+_iss sqInt growHeadroom;
 _iss sqInt longRunningPrimitiveCheckMethod;
 _iss sqInt profileMethod;
 _iss sqInt classTableIndex;
 _iss sqInt ephemeronQueue;
-_iss sqInt growHeadroom;
 _iss sqInt lastMethodCacheProbeWrite;
 _iss sqInt lkupClass;
 _iss sqInt backwardJumpCount;
@@ -2219,7 +2220,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.727";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.730";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -31130,7 +31131,24 @@
 	 && (0 == (longAt((objStack + (BaseHeaderSize)) + (ObjStackNextx << 2))));
 }
 
+static sqInt
+isEmptySegment(SpurSegmentInfo *seg)
+{
+    sqInt address;
+    sqInt firstObj;
+    usqInt numSlots;
 
+	/* begin objectStartingAt: */
+	address = (seg->segStart);
+	numSlots = byteAt(address + 7);
+	firstObj = (numSlots == 0xFF
+		? address + (BaseHeaderSize)
+		: address);
+	return (((longAt(firstObj)) & 0x3FFFFF) == 0)
+	 && ((addressAfter(firstObj)) == ((((seg->segSize)) + ((seg->segStart))) - (2 * (BaseHeaderSize))));
+}
+
+
 /*	Answer if objOop should be included in an allObjects...Do: enumeration.
 	This is for assert-checking only. */
 
@@ -37838,7 +37856,17 @@
 static void
 postGCAction(sqInt gcModeArg)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt best;
+    usqInt currentEnd;
+    sqInt delta1;
+    SpurSegmentInfo *emptySeg;
     sqInt freeSizeNow;
+    sqInt i;
+    sqInt i1;
+    sqInt i2;
+    sqInt j;
+    SpurSegmentInfo *seg;
+    sqInt shrinkage;
 
 	assert(gcModeArg == GIV(gcMode));
 	if ((gcModeArg == GCModeFull)
@@ -37853,9 +37881,59 @@
 			/* Attempt to shrink memory after successfully reclaiming lots of memory */
 
 			/* begin shrinkObjectMemory: */
-			print("shrinkObjectMemory: shouldBeImplemented");
-			/* begin cr */
-			printf("\n");
+			shrinkage = freeSizeNow - GIV(growHeadroom);
+			while (1) {
+				/* begin findEmptySegNearestInSizeTo: */
+				best = null;
+				delta1 = shrinkage;
+				for (i = 0; i < GIV(numSegments); i += 1) {
+					seg = (&(GIV(segments)[i]));
+					if (isEmptySegment(seg)) {
+						if (best == null) {
+							best = seg;
+						}
+						else {
+							if ((shrinkage >= (((seg->segSize)) * 0.75))
+							 && ((abs(((seg->segSize)) - shrinkage)) < delta1)) {
+								best = seg;
+								delta1 = abs(((seg->segSize)) - shrinkage);
+							}
+						}
+					}
+				}
+				emptySeg = ((sqInt) best);
+				if (!(emptySeg != null)) break;
+				shrinkage -= (emptySeg->segSize);
+				detachFreeObject(objectStartingAt((emptySeg->segStart)));
+				/* begin removeSegment: */
+				/* begin indexOfSegment: */
+				for (i1 = 0; i1 < GIV(numSegments); i1 += 1) {
+					if (((emptySeg->segStart)) == (((GIV(segments)[i1]).segStart))) {
+						i2 = i1;
+						goto l1;
+					}
+				}
+				error("segment not found");
+			l1:	/* end indexOfSegment: */;
+				assert(i2 > 0);
+				sqDeallocateMemorySegmentAtOfSize((emptySeg->segStart), (emptySeg->segSize));
+				for (j = i2; j < GIV(numSegments); j += 1) {
+					GIV(segments)[j] = (GIV(segments)[j + 1]);
+				}
+				null;
+				GIV(numSegments) -= 1;
+				bridgeFromto((&(GIV(segments)[i2 - 1])), (i2 <= (GIV(numSegments) - 1)
+					? (&(GIV(segments)[i2]))
+					: 0));
+				/* begin setLastSegment: */
+				currentEnd = (((((&(GIV(segments)[GIV(numSegments) - 1])))->segSize)) + ((((&(GIV(segments)[GIV(numSegments) - 1])))->segStart))) - (2 * (BaseHeaderSize));
+				if (currentEnd <= GIV(endOfMemory)) {
+					GIV(endOfMemory) = currentEnd;
+					if (GIV(freeOldSpaceStart) > currentEnd) {
+						GIV(freeOldSpaceStart) = currentEnd;
+					}
+				}
+			}
 		}
 	}
 	signalSemaphoreWithIndex(GIV(gcSemaphoreIndex));
@@ -37909,6 +37987,9 @@
 			GIV(totalFreeOldSpace) += bytes;
 		}
 	}
+	/* begin checkFreeSpace */
+	assert(bitsSetInFreeSpaceMaskForAllFreeLists());
+	assert(GIV(totalFreeOldSpace) == (totalFreeListBytes()));
 }
 
 
@@ -62861,6 +62942,9 @@
 	assert(GIV(freeStart) == (((eden()).start)));
 	fullGC();
 	prepareForSnapshot();
+	/* begin checkFreeSpace */
+	assert(bitsSetInFreeSpaceMaskForAllFreeLists());
+	assert(GIV(totalFreeOldSpace) == (totalFreeListBytes()));
 	activeContext = GIV(tempOop);
 	GIV(tempOop) = 0;
 	if (!GIV(primFailCode)) {

Modified: branches/Cog/nsspursrc/vm/cointerp.h
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.h	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/nsspursrc/vm/cointerp.h	2014-05-21 19:18:13 UTC (rev 2928)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
 
 

Modified: branches/Cog/nsspursrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/gcc3x-cointerp.c	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/nsspursrc/vm/gcc3x-cointerp.c	2014-05-21 19:18:13 UTC (rev 2928)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
    from
-	CoInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CoInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -756,6 +756,7 @@
 static sqInt isContextNonImm(sqInt oop) NoDbgRegParms;
 static sqInt isContext(sqInt oop) NoDbgRegParms;
 static sqInt isEmptyObjStack(sqInt objStack) NoDbgRegParms;
+static sqInt isEmptySegment(SpurSegmentInfo *seg) NoDbgRegParms;
 static sqInt isEnumerableObjectNoAssert(sqInt objOop) NoDbgRegParms;
 static sqInt isEnumerableObject(sqInt objOop) NoDbgRegParms;
 static sqInt isEphemeron(sqInt objOop) NoDbgRegParms;
@@ -1457,15 +1458,15 @@
 _iss sqInt hiddenRootsObj;
 _iss usqInt endOfMemory;
 _iss sqInt trueObj;
+_iss SpurSegmentInfo * segments;
 _iss sqInt remapBufferCount;
 _iss sqInt needGCFlag;
 _iss sqInt falseObj;
-_iss SpurSegmentInfo * segments;
 _iss sqInt traceLogIndex;
 _iss sqInt bytesPerPage;
 _iss sqInt totalFreeOldSpace;
+_iss sqInt numSegments;
 _iss usqInt pastSpaceStart;
-_iss sqInt numSegments;
 _iss char * stackLimit;
 _iss usqInt scavengeThreshold;
 _iss sqInt * freeLists;
@@ -1495,18 +1496,18 @@
 _iss SpurNewSpaceSpace eden;
 _iss sqInt profileSemaphore;
 _iss sqInt ephemeronList;
+_iss usqInt freeOldSpaceStart;
 _iss sqInt profileProcess;
 _iss sqInt tenureThreshold;
 _iss sqInt extraRootCount;
 _iss sqInt invalidObjStackPage;
 _iss sqInt previousRememberedSetSize;
 _iss unsigned char * classTableBitmap;
-_iss usqInt freeOldSpaceStart;
+_iss sqInt growHeadroom;
 _iss sqInt longRunningPrimitiveCheckMethod;
 _iss sqInt profileMethod;
 _iss sqInt classTableIndex;
 _iss sqInt ephemeronQueue;
-_iss sqInt growHeadroom;
 _iss sqInt lastMethodCacheProbeWrite;
 _iss sqInt lkupClass;
 _iss sqInt backwardJumpCount;
@@ -2222,7 +2223,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.727";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.730";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -31139,7 +31140,24 @@
 	 && (0 == (longAt((objStack + (BaseHeaderSize)) + (ObjStackNextx << 2))));
 }
 
+static sqInt
+isEmptySegment(SpurSegmentInfo *seg)
+{
+    sqInt address;
+    sqInt firstObj;
+    usqInt numSlots;
 
+	/* begin objectStartingAt: */
+	address = (seg->segStart);
+	numSlots = byteAt(address + 7);
+	firstObj = (numSlots == 0xFF
+		? address + (BaseHeaderSize)
+		: address);
+	return (((longAt(firstObj)) & 0x3FFFFF) == 0)
+	 && ((addressAfter(firstObj)) == ((((seg->segSize)) + ((seg->segStart))) - (2 * (BaseHeaderSize))));
+}
+
+
 /*	Answer if objOop should be included in an allObjects...Do: enumeration.
 	This is for assert-checking only. */
 
@@ -37847,7 +37865,17 @@
 static void
 postGCAction(sqInt gcModeArg)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt best;
+    usqInt currentEnd;
+    sqInt delta1;
+    SpurSegmentInfo *emptySeg;
     sqInt freeSizeNow;
+    sqInt i;
+    sqInt i1;
+    sqInt i2;
+    sqInt j;
+    SpurSegmentInfo *seg;
+    sqInt shrinkage;
 
 	assert(gcModeArg == GIV(gcMode));
 	if ((gcModeArg == GCModeFull)
@@ -37862,9 +37890,59 @@
 			/* Attempt to shrink memory after successfully reclaiming lots of memory */
 
 			/* begin shrinkObjectMemory: */
-			print("shrinkObjectMemory: shouldBeImplemented");
-			/* begin cr */
-			printf("\n");
+			shrinkage = freeSizeNow - GIV(growHeadroom);
+			while (1) {
+				/* begin findEmptySegNearestInSizeTo: */
+				best = null;
+				delta1 = shrinkage;
+				for (i = 0; i < GIV(numSegments); i += 1) {
+					seg = (&(GIV(segments)[i]));
+					if (isEmptySegment(seg)) {
+						if (best == null) {
+							best = seg;
+						}
+						else {
+							if ((shrinkage >= (((seg->segSize)) * 0.75))
+							 && ((abs(((seg->segSize)) - shrinkage)) < delta1)) {
+								best = seg;
+								delta1 = abs(((seg->segSize)) - shrinkage);
+							}
+						}
+					}
+				}
+				emptySeg = ((sqInt) best);
+				if (!(emptySeg != null)) break;
+				shrinkage -= (emptySeg->segSize);
+				detachFreeObject(objectStartingAt((emptySeg->segStart)));
+				/* begin removeSegment: */
+				/* begin indexOfSegment: */
+				for (i1 = 0; i1 < GIV(numSegments); i1 += 1) {
+					if (((emptySeg->segStart)) == (((GIV(segments)[i1]).segStart))) {
+						i2 = i1;
+						goto l1;
+					}
+				}
+				error("segment not found");
+			l1:	/* end indexOfSegment: */;
+				assert(i2 > 0);
+				sqDeallocateMemorySegmentAtOfSize((emptySeg->segStart), (emptySeg->segSize));
+				for (j = i2; j < GIV(numSegments); j += 1) {
+					GIV(segments)[j] = (GIV(segments)[j + 1]);
+				}
+				null;
+				GIV(numSegments) -= 1;
+				bridgeFromto((&(GIV(segments)[i2 - 1])), (i2 <= (GIV(numSegments) - 1)
+					? (&(GIV(segments)[i2]))
+					: 0));
+				/* begin setLastSegment: */
+				currentEnd = (((((&(GIV(segments)[GIV(numSegments) - 1])))->segSize)) + ((((&(GIV(segments)[GIV(numSegments) - 1])))->segStart))) - (2 * (BaseHeaderSize));
+				if (currentEnd <= GIV(endOfMemory)) {
+					GIV(endOfMemory) = currentEnd;
+					if (GIV(freeOldSpaceStart) > currentEnd) {
+						GIV(freeOldSpaceStart) = currentEnd;
+					}
+				}
+			}
 		}
 	}
 	signalSemaphoreWithIndex(GIV(gcSemaphoreIndex));
@@ -37918,6 +37996,9 @@
 			GIV(totalFreeOldSpace) += bytes;
 		}
 	}
+	/* begin checkFreeSpace */
+	assert(bitsSetInFreeSpaceMaskForAllFreeLists());
+	assert(GIV(totalFreeOldSpace) == (totalFreeListBytes()));
 }
 
 
@@ -62870,6 +62951,9 @@
 	assert(GIV(freeStart) == (((eden()).start)));
 	fullGC();
 	prepareForSnapshot();
+	/* begin checkFreeSpace */
+	assert(bitsSetInFreeSpaceMaskForAllFreeLists());
+	assert(GIV(totalFreeOldSpace) == (totalFreeListBytes()));
 	activeContext = GIV(tempOop);
 	GIV(tempOop) = 0;
 	if (!GIV(primFailCode)) {

Modified: branches/Cog/nsspursrc/vm/interp.h
===================================================================
--- branches/Cog/nsspursrc/vm/interp.h	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/nsspursrc/vm/interp.h	2014-05-21 19:18:13 UTC (rev 2928)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
 
 #define VM_PROXY_MAJOR 1

Modified: branches/Cog/nsspursrc/vm/vmCallback.h
===================================================================
--- branches/Cog/nsspursrc/vm/vmCallback.h	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/nsspursrc/vm/vmCallback.h	2014-05-21 19:18:13 UTC (rev 2928)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
 
 #define VM_CALLBACK_INC 1

Modified: branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c
===================================================================
--- branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c	2014-05-21 19:18:13 UTC (rev 2928)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
    from
-	StackInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	StackInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
-static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659 " __DATE__ ;
+static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -631,6 +631,7 @@
 static sqInt isContextNonImm(sqInt oop) NoDbgRegParms;
 static sqInt isContext(sqInt oop) NoDbgRegParms;
 static sqInt isEmptyObjStack(sqInt objStack) NoDbgRegParms;
+static sqInt isEmptySegment(SpurSegmentInfo *seg) NoDbgRegParms;
 static sqInt isEnumerableObjectNoAssert(sqInt objOop) NoDbgRegParms;
 static sqInt isEnumerableObject(sqInt objOop) NoDbgRegParms;
 static sqInt isEphemeron(sqInt objOop) NoDbgRegParms;
@@ -1263,16 +1264,16 @@
 _iss usqInt instructionPointer;
 _iss sqInt hiddenRootsObj;
 _iss usqInt endOfMemory;
+_iss SpurSegmentInfo * segments;
 _iss sqInt trueObj;
 _iss sqInt remapBufferCount;
 _iss sqInt needGCFlag;
 _iss sqInt falseObj;
-_iss SpurSegmentInfo * segments;
+_iss sqInt numSegments;
 _iss StackPage * pages;
 _iss sqInt totalFreeOldSpace;
 _iss usqInt pastSpaceStart;
 _iss char * stackMemory;
-_iss sqInt numSegments;
 _iss char * stackLimit;
 _iss sqInt bytesPerPage;
 _iss usqInt scavengeThreshold;
@@ -1295,11 +1296,13 @@
 _iss sqInt numClassTablePages;
 _iss sqInt numStackPages;
 _iss sqInt tempOop;
+_iss usqInt freeOldSpaceStart;
 _iss sqInt futureSurvivorStart;
 _iss sqLong nextProfileTick;
 _iss char * objStackInvalidBecause;
 _iss SpurNewSpaceSpace eden;
 _iss sqInt ephemeronList;
+_iss sqInt growHeadroom;
 _iss sqInt numPages;
 _iss sqInt profileProcess;
 _iss sqInt tenureThreshold;
@@ -1307,8 +1310,6 @@
 _iss sqInt invalidObjStackPage;
 _iss sqInt previousRememberedSetSize;
 _iss unsigned char * classTableBitmap;
-_iss usqInt freeOldSpaceStart;
-_iss sqInt growHeadroom;
 _iss sqInt longRunningPrimitiveCheckMethod;
 _iss sqInt longRunningPrimitiveCheckSemaphore;
 _iss sqInt profileMethod;
@@ -2009,7 +2010,7 @@
  0 };
 char * breakSelector;
 sqInt breakSelectorLength = -1;
-const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreter_VMMaker.oscog-eem.727";
+const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreter_VMMaker.oscog-eem.730";
 volatile int sendTrace;
 sqInt suppressHeartbeatFlag;
 
@@ -24611,9 +24612,19 @@
 usqLong
 fullGC(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt best;
+    usqInt currentEnd;
+    sqInt delta1;
+    SpurSegmentInfo *emptySeg;
     sqInt freeSizeNow;
     sqInt i;
     sqInt i1;
+    sqInt i11;
+    sqInt i2;
+    sqInt i3;
+    sqInt j;
+    SpurSegmentInfo *seg;
+    sqInt shrinkage;
 
 	GIV(needGCFlag) = 0;
 	GIV(gcStartUsecs) = ioUTCMicrosecondsNow();
@@ -24674,9 +24685,59 @@
 		/* Attempt to shrink memory after successfully reclaiming lots of memory */
 
 		/* begin shrinkObjectMemory: */
-		print("shrinkObjectMemory: shouldBeImplemented");
-		/* begin cr */
-		printf("\n");
+		shrinkage = freeSizeNow - GIV(growHeadroom);
+		while (1) {
+			/* begin findEmptySegNearestInSizeTo: */
+			best = null;
+			delta1 = shrinkage;
+			for (i3 = 0; i3 < GIV(numSegments); i3 += 1) {
+				seg = (&(GIV(segments)[i3]));
+				if (isEmptySegment(seg)) {
+					if (best == null) {
+						best = seg;
+					}
+					else {
+						if ((shrinkage >= (((seg->segSize)) * 0.75))
+						 && ((abs(((seg->segSize)) - shrinkage)) < delta1)) {
+							best = seg;
+							delta1 = abs(((seg->segSize)) - shrinkage);
+						}
+					}
+				}
+			}
+			emptySeg = ((sqInt) best);
+			if (!(emptySeg != null)) break;
+			shrinkage -= (emptySeg->segSize);
+			detachFreeObject(objectStartingAt((emptySeg->segStart)));
+			/* begin removeSegment: */
+			/* begin indexOfSegment: */
+			for (i11 = 0; i11 < GIV(numSegments); i11 += 1) {
+				if (((emptySeg->segStart)) == (((GIV(segments)[i11]).segStart))) {
+					i2 = i11;
+					goto l1;
+				}
+			}
+			error("segment not found");
+		l1:	/* end indexOfSegment: */;
+			assert(i2 > 0);
+			sqDeallocateMemorySegmentAtOfSize((emptySeg->segStart), (emptySeg->segSize));
+			for (j = i2; j < GIV(numSegments); j += 1) {
+				GIV(segments)[j] = (GIV(segments)[j + 1]);
+			}
+			null;
+			GIV(numSegments) -= 1;
+			bridgeFromto((&(GIV(segments)[i2 - 1])), (i2 <= (GIV(numSegments) - 1)
+				? (&(GIV(segments)[i2]))
+				: 0));
+			/* begin setLastSegment: */
+			currentEnd = (((((&(GIV(segments)[GIV(numSegments) - 1])))->segSize)) + ((((&(GIV(segments)[GIV(numSegments) - 1])))->segStart))) - (2 * (BaseHeaderSize));
+			if (currentEnd <= GIV(endOfMemory)) {
+				GIV(endOfMemory) = currentEnd;
+				if (GIV(freeOldSpaceStart) > currentEnd) {
+					GIV(freeOldSpaceStart) = currentEnd;
+				}
+			}
+		}
 	}
 
 	signalSemaphoreWithIndex(GIV(gcSemaphoreIndex));
@@ -26552,7 +26613,24 @@
 	 && (0 == (longAt((objStack + (BaseHeaderSize)) + (ObjStackNextx << 2))));
 }
 
+static sqInt
+isEmptySegment(SpurSegmentInfo *seg)
+{
+    sqInt address;
+    sqInt firstObj;
+    usqInt numSlots;
 
+	/* begin objectStartingAt: */
+	address = (seg->segStart);
+	numSlots = byteAt(address + 7);
+	firstObj = (numSlots == 0xFF
+		? address + (BaseHeaderSize)
+		: address);
+	return (((longAt(firstObj)) & 0x3FFFFF) == 0)
+	 && ((addressAfter(firstObj)) == ((((seg->segSize)) + ((seg->segStart))) - (2 * (BaseHeaderSize))));
+}
+
+
 /*	Answer if objOop should be included in an allObjects...Do: enumeration.
 	This is for assert-checking only. */
 
@@ -32345,6 +32423,9 @@
 			GIV(totalFreeOldSpace) += bytes;
 		}
 	}
+	/* begin checkFreeSpace */
+	assert(bitsSetInFreeSpaceMaskForAllFreeLists());
+	assert(GIV(totalFreeOldSpace) == (totalFreeListBytes()));
 }
 
 
@@ -54303,12 +54384,22 @@
 static void
 scavengingGCTenuringIf(sqInt tenuringCriterion)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt best;
+    usqInt currentEnd;
+    sqInt delta1;
+    SpurSegmentInfo *emptySeg;
     sqInt freeSizeNow;
     sqInt i;
     sqInt i1;
     sqInt i11;
+    sqInt i12;
     sqInt i2;
+    sqInt i21;
+    sqInt i3;
+    sqInt j;
     sqInt probe;
+    SpurSegmentInfo *seg;
+    sqInt shrinkage;
     usqLong statSGCDeltaUsecs = 0;
 
 	assert(GIV(remapBufferCount) == 0);
@@ -55855,6 +55946,9 @@
 	assert(GIV(freeStart) == (((eden()).start)));
 	fullGC();
 	prepareForSnapshot();
+	/* begin checkFreeSpace */
+	assert(bitsSetInFreeSpaceMaskForAllFreeLists());
+	assert(GIV(totalFreeOldSpace) == (totalFreeListBytes()));
 	activeContext = GIV(tempOop);
 	GIV(tempOop) = 0;
 	if (!GIV(primFailCode)) {

Modified: branches/Cog/nsspurstacksrc/vm/interp.c
===================================================================
--- branches/Cog/nsspurstacksrc/vm/interp.c	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/nsspurstacksrc/vm/interp.c	2014-05-21 19:18:13 UTC (rev 2928)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
    from
-	StackInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	StackInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
-static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659 " __DATE__ ;
+static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -628,6 +628,7 @@
 static sqInt isContextNonImm(sqInt oop) NoDbgRegParms;
 static sqInt isContext(sqInt oop) NoDbgRegParms;
 static sqInt isEmptyObjStack(sqInt objStack) NoDbgRegParms;
+static sqInt isEmptySegment(SpurSegmentInfo *seg) NoDbgRegParms;
 static sqInt isEnumerableObjectNoAssert(sqInt objOop) NoDbgRegParms;
 static sqInt isEnumerableObject(sqInt objOop) NoDbgRegParms;
 static sqInt isEphemeron(sqInt objOop) NoDbgRegParms;
@@ -1260,16 +1261,16 @@
 _iss usqInt instructionPointer;
 _iss sqInt hiddenRootsObj;
 _iss usqInt endOfMemory;
+_iss SpurSegmentInfo * segments;
 _iss sqInt trueObj;
 _iss sqInt remapBufferCount;
 _iss sqInt needGCFlag;
 _iss sqInt falseObj;
-_iss SpurSegmentInfo * segments;
+_iss sqInt numSegments;
 _iss StackPage * pages;
 _iss sqInt totalFreeOldSpace;
 _iss usqInt pastSpaceStart;
 _iss char * stackMemory;
-_iss sqInt numSegments;
 _iss char * stackLimit;
 _iss sqInt bytesPerPage;
 _iss usqInt scavengeThreshold;
@@ -1292,11 +1293,13 @@
 _iss sqInt numClassTablePages;
 _iss sqInt numStackPages;
 _iss sqInt tempOop;
+_iss usqInt freeOldSpaceStart;
 _iss sqInt futureSurvivorStart;
 _iss sqLong nextProfileTick;
 _iss char * objStackInvalidBecause;
 _iss SpurNewSpaceSpace eden;
 _iss sqInt ephemeronList;
+_iss sqInt growHeadroom;
 _iss sqInt numPages;
 _iss sqInt profileProcess;
 _iss sqInt tenureThreshold;
@@ -1304,8 +1307,6 @@
 _iss sqInt invalidObjStackPage;
 _iss sqInt previousRememberedSetSize;
 _iss unsigned char * classTableBitmap;
-_iss usqInt freeOldSpaceStart;
-_iss sqInt growHeadroom;
 _iss sqInt longRunningPrimitiveCheckMethod;
 _iss sqInt longRunningPrimitiveCheckSemaphore;
 _iss sqInt profileMethod;
@@ -2006,7 +2007,7 @@
  0 };
 char * breakSelector;
 sqInt breakSelectorLength = -1;
-const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreter_VMMaker.oscog-eem.727";
+const char *interpreterVersion = "Newspeak Virtual Machine StackInterpreter_VMMaker.oscog-eem.730";
 volatile int sendTrace;
 sqInt suppressHeartbeatFlag;
 
@@ -24602,9 +24603,19 @@
 usqLong
 fullGC(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt best;
+    usqInt currentEnd;
+    sqInt delta1;
+    SpurSegmentInfo *emptySeg;
     sqInt freeSizeNow;
     sqInt i;
     sqInt i1;
+    sqInt i11;
+    sqInt i2;
+    sqInt i3;
+    sqInt j;
+    SpurSegmentInfo *seg;
+    sqInt shrinkage;
 
 	GIV(needGCFlag) = 0;
 	GIV(gcStartUsecs) = ioUTCMicrosecondsNow();
@@ -24665,9 +24676,59 @@
 		/* Attempt to shrink memory after successfully reclaiming lots of memory */
 
 		/* begin shrinkObjectMemory: */
-		print("shrinkObjectMemory: shouldBeImplemented");
-		/* begin cr */
-		printf("\n");
+		shrinkage = freeSizeNow - GIV(growHeadroom);
+		while (1) {
+			/* begin findEmptySegNearestInSizeTo: */
+			best = null;
+			delta1 = shrinkage;
+			for (i3 = 0; i3 < GIV(numSegments); i3 += 1) {
+				seg = (&(GIV(segments)[i3]));
+				if (isEmptySegment(seg)) {
+					if (best == null) {
+						best = seg;
+					}
+					else {
+						if ((shrinkage >= (((seg->segSize)) * 0.75))
+						 && ((abs(((seg->segSize)) - shrinkage)) < delta1)) {
+							best = seg;
+							delta1 = abs(((seg->segSize)) - shrinkage);
+						}
+					}
+				}
+			}
+			emptySeg = ((sqInt) best);
+			if (!(emptySeg != null)) break;
+			shrinkage -= (emptySeg->segSize);
+			detachFreeObject(objectStartingAt((emptySeg->segStart)));
+			/* begin removeSegment: */
+			/* begin indexOfSegment: */
+			for (i11 = 0; i11 < GIV(numSegments); i11 += 1) {
+				if (((emptySeg->segStart)) == (((GIV(segments)[i11]).segStart))) {
+					i2 = i11;
+					goto l1;
+				}
+			}
+			error("segment not found");
+		l1:	/* end indexOfSegment: */;
+			assert(i2 > 0);
+			sqDeallocateMemorySegmentAtOfSize((emptySeg->segStart), (emptySeg->segSize));
+			for (j = i2; j < GIV(numSegments); j += 1) {
+				GIV(segments)[j] = (GIV(segments)[j + 1]);
+			}
+			null;
+			GIV(numSegments) -= 1;
+			bridgeFromto((&(GIV(segments)[i2 - 1])), (i2 <= (GIV(numSegments) - 1)
+				? (&(GIV(segments)[i2]))
+				: 0));
+			/* begin setLastSegment: */
+			currentEnd = (((((&(GIV(segments)[GIV(numSegments) - 1])))->segSize)) + ((((&(GIV(segments)[GIV(numSegments) - 1])))->segStart))) - (2 * (BaseHeaderSize));
+			if (currentEnd <= GIV(endOfMemory)) {
+				GIV(endOfMemory) = currentEnd;
+				if (GIV(freeOldSpaceStart) > currentEnd) {
+					GIV(freeOldSpaceStart) = currentEnd;
+				}
+			}
+		}
 	}
 
 	signalSemaphoreWithIndex(GIV(gcSemaphoreIndex));
@@ -26543,7 +26604,24 @@
 	 && (0 == (longAt((objStack + (BaseHeaderSize)) + (ObjStackNextx << 2))));
 }
 
+static sqInt
+isEmptySegment(SpurSegmentInfo *seg)
+{
+    sqInt address;
+    sqInt firstObj;
+    usqInt numSlots;
 
+	/* begin objectStartingAt: */
+	address = (seg->segStart);
+	numSlots = byteAt(address + 7);
+	firstObj = (numSlots == 0xFF
+		? address + (BaseHeaderSize)
+		: address);
+	return (((longAt(firstObj)) & 0x3FFFFF) == 0)
+	 && ((addressAfter(firstObj)) == ((((seg->segSize)) + ((seg->segStart))) - (2 * (BaseHeaderSize))));
+}
+
+
 /*	Answer if objOop should be included in an allObjects...Do: enumeration.
 	This is for assert-checking only. */
 
@@ -32336,6 +32414,9 @@
 			GIV(totalFreeOldSpace) += bytes;
 		}
 	}
+	/* begin checkFreeSpace */
+	assert(bitsSetInFreeSpaceMaskForAllFreeLists());
+	assert(GIV(totalFreeOldSpace) == (totalFreeListBytes()));
 }
 
 
@@ -54294,12 +54375,22 @@
 static void
 scavengingGCTenuringIf(sqInt tenuringCriterion)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt best;
+    usqInt currentEnd;
+    sqInt delta1;
+    SpurSegmentInfo *emptySeg;
     sqInt freeSizeNow;
     sqInt i;
     sqInt i1;
     sqInt i11;
+    sqInt i12;
     sqInt i2;
+    sqInt i21;
+    sqInt i3;
+    sqInt j;
     sqInt probe;
+    SpurSegmentInfo *seg;
+    sqInt shrinkage;
     usqLong statSGCDeltaUsecs = 0;
 
 	assert(GIV(remapBufferCount) == 0);
@@ -55846,6 +55937,9 @@
 	assert(GIV(freeStart) == (((eden()).start)));
 	fullGC();
 	prepareForSnapshot();
+	/* begin checkFreeSpace */
+	assert(bitsSetInFreeSpaceMaskForAllFreeLists());
+	assert(GIV(totalFreeOldSpace) == (totalFreeListBytes()));
 	activeContext = GIV(tempOop);
 	GIV(tempOop) = 0;
 	if (!GIV(primFailCode)) {

Modified: branches/Cog/nsspurstacksrc/vm/interp.h
===================================================================
--- branches/Cog/nsspurstacksrc/vm/interp.h	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/nsspurstacksrc/vm/interp.h	2014-05-21 19:18:13 UTC (rev 2928)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
 
 #define VM_PROXY_MAJOR 1

Modified: branches/Cog/nsspurstacksrc/vm/vmCallback.h
===================================================================
--- branches/Cog/nsspurstacksrc/vm/vmCallback.h	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/nsspurstacksrc/vm/vmCallback.h	2014-05-21 19:18:13 UTC (rev 2928)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
 
 #define VM_CALLBACK_INC 1

Modified: branches/Cog/platforms/Cross/vm/sq.h
===================================================================
--- branches/Cog/platforms/Cross/vm/sq.h	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/platforms/Cross/vm/sq.h	2014-05-21 19:18:13 UTC (rev 2928)
@@ -83,6 +83,7 @@
  * start of the region and assign its size through asp.
  */
 extern void *sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto(sqInt sz, void *minAddr, sqInt *asp);
+extern void sqDeallocateMemorySegmentAtOfSize(void *addr, sqInt sz);
 #endif /* SPURVM */
 /* Platform-dependent memory size adjustment macro. */
 


Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Tue May 20 15:55:19 PDT 2014
   + Wed May 21 12:17:41 PDT 2014

Modified: branches/Cog/platforms/Mac OS/vm/sqMacMemory.c
===================================================================
--- branches/Cog/platforms/Mac OS/vm/sqMacMemory.c	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/platforms/Mac OS/vm/sqMacMemory.c	2014-05-21 19:18:13 UTC (rev 2928)
@@ -175,9 +175,20 @@
 		}
 		if (alloc >= minAddress)
 			return alloc;
-		munmap(alloc, bytes);
+		if (munmap(alloc, bytes) != 0)
+			perror("sqAllocateMemorySegment... munmap");
 		minAddress = (void *)((char *)minAddress + bytes);
 	}
 	return 0;
 }
+
+/* Deallocate a region of memory previously allocated by
+ * sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto.  Cannot fail.
+ */
+void
+sqDeallocateMemorySegmentAtOfSize(void *addr, sqInt sz)
+{
+	if (munmap(addr, sz) != 0)
+		perror("sqDeallocateMemorySegment... munmap");
+}
 #endif /* SPURVM */

Modified: branches/Cog/platforms/unix/vm/sqUnixMemory.c
===================================================================
--- branches/Cog/platforms/unix/vm/sqUnixMemory.c	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/platforms/unix/vm/sqUnixMemory.c	2014-05-21 19:18:13 UTC (rev 2928)
@@ -358,11 +358,22 @@
 		}
 		if (alloc >= minAddress)
 			return alloc;
-		munmap(alloc, bytes);
+		if (munmap(alloc, bytes) != 0)
+			perror("sqAllocateMemorySegment... munmap");
 		minAddress = (void *)((char *)minAddress + bytes);
 	}
 	return 0;
 }
+
+/* Deallocate a region of memory previously allocated by
+ * sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto.  Cannot fail.
+ */
+void
+sqDeallocateMemorySegmentAtOfSize(void *addr, sqInt sz)
+{
+	if (munmap(addr, sz) != 0)
+		perror("sqDeallocateMemorySegment... munmap");
+}
 #endif /* SPURVM */
 
 

Modified: branches/Cog/platforms/win32/vm/sqWin32Alloc.c
===================================================================
--- branches/Cog/platforms/win32/vm/sqWin32Alloc.c	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/platforms/win32/vm/sqWin32Alloc.c	2014-05-21 19:18:13 UTC (rev 2928)
@@ -246,4 +246,16 @@
 				bytes, minAddress);
 	return NULL;
 }
+
+/* Deallocate a region of memory previously allocated by
+ * sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto.  Cannot fail.
+ */
+void
+sqDeallocateMemorySegmentAtOfSize(void *addr, sqInt sz)
+{
+	if (!VirtualFree(addr, sz, MEM_RELEASE))
+		sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Warning:"),
+					"Unable to VirtualFree committed memory (%d bytes requested)",
+					sz);
+}
 #endif /* SPURVM */

Modified: branches/Cog/spursistasrc/vm/cointerp.c
===================================================================
--- branches/Cog/spursistasrc/vm/cointerp.c	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/spursistasrc/vm/cointerp.c	2014-05-21 19:18:13 UTC (rev 2928)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
    from
-	CoInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CoInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -747,6 +747,7 @@
 static sqInt isContextNonImm(sqInt oop) NoDbgRegParms;
 static sqInt isContext(sqInt oop) NoDbgRegParms;
 static sqInt isEmptyObjStack(sqInt objStack) NoDbgRegParms;
+static sqInt isEmptySegment(SpurSegmentInfo *seg) NoDbgRegParms;
 static sqInt isEnumerableObjectNoAssert(sqInt objOop) NoDbgRegParms;
 static sqInt isEnumerableObject(sqInt objOop) NoDbgRegParms;
 static sqInt isEphemeron(sqInt objOop) NoDbgRegParms;
@@ -1318,7 +1319,7 @@
 static void setSignalLowSpaceFlagAndSaveProcess(void);
 static void setTraceFlagOnContextsFramesPageIfNeeded(sqInt aContext) NoDbgRegParms;
 sqInt shiftForWord(void);
-static usqInt shortentoIndexableSize(sqInt objOop, sqInt indexableSize) NoDbgRegParms;
+static sqInt shortentoIndexableSize(sqInt objOop, sqInt indexableSize) NoDbgRegParms;
 static sqInt shortPrintContext(sqInt aContext) NoDbgRegParms;
 static sqInt shortPrintFrameAndCallers(char *theFP) NoDbgRegParms;
 EXPORT(void) shortPrintFramesInPage(StackPage *thePage);
@@ -1448,16 +1449,16 @@
 _iss char * stackBasePlus1;
 _iss sqInt hiddenRootsObj;
 _iss usqInt endOfMemory;
+_iss SpurSegmentInfo * segments;
 _iss sqInt remapBufferCount;
 _iss sqInt trueObj;
-_iss SpurSegmentInfo * segments;
 _iss sqInt falseObj;
 _iss sqInt needGCFlag;
 _iss sqInt traceLogIndex;
 _iss sqInt bytesPerPage;
 _iss sqInt totalFreeOldSpace;
+_iss sqInt numSegments;
 _iss usqInt pastSpaceStart;
-_iss sqInt numSegments;
 _iss char * stackLimit;
 _iss sqInt * freeLists;
 _iss usqInt scavengeThreshold;
@@ -1487,18 +1488,18 @@
 _iss SpurNewSpaceSpace eden;
 _iss sqInt profileSemaphore;
 _iss sqInt ephemeronList;
+_iss usqInt freeOldSpaceStart;
 _iss sqInt profileProcess;
 _iss sqInt tenureThreshold;
 _iss sqInt extraRootCount;
 _iss sqInt invalidObjStackPage;
 _iss sqInt previousRememberedSetSize;
 _iss unsigned char * classTableBitmap;
-_iss usqInt freeOldSpaceStart;
+_iss sqInt growHeadroom;
 _iss sqInt longRunningPrimitiveCheckMethod;
 _iss sqInt profileMethod;
 _iss sqInt classTableIndex;
 _iss sqInt ephemeronQueue;
-_iss sqInt growHeadroom;
 _iss sqInt lastMethodCacheProbeWrite;
 _iss sqInt lkupClass;
 _iss sqInt metaclassNumSlots;
@@ -2214,7 +2215,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.727]";
+const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.730]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -26023,7 +26024,24 @@
 	 && (0 == (longAt((objStack + (BaseHeaderSize)) + (ObjStackNextx << 2))));
 }
 
+static sqInt
+isEmptySegment(SpurSegmentInfo *seg)
+{
+    sqInt address;
+    sqInt firstObj;
+    usqInt numSlots;
 
+	/* begin objectStartingAt: */
+	address = (seg->segStart);
+	numSlots = byteAt(address + 7);
+	firstObj = (numSlots == 0xFF
+		? address + (BaseHeaderSize)
+		: address);
+	return (((longAt(firstObj)) & 0x3FFFFF) == 0)
+	 && ((addressAfter(firstObj)) == ((((seg->segSize)) + ((seg->segStart))) - (2 * (BaseHeaderSize))));
+}
+
+
 /*	Answer if objOop should be included in an allObjects...Do: enumeration.
 	This is for assert-checking only. */
 
@@ -32666,7 +32684,17 @@
 static void
 postGCAction(sqInt gcModeArg)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt best;
+    usqInt currentEnd;
+    sqInt delta1;
+    SpurSegmentInfo *emptySeg;
     sqInt freeSizeNow;
+    sqInt i;
+    sqInt i1;
+    sqInt i2;
+    sqInt j;
+    SpurSegmentInfo *seg;
+    sqInt shrinkage;
 
 	assert(gcModeArg == GIV(gcMode));
 	if ((gcModeArg == GCModeFull)
@@ -32681,9 +32709,59 @@
 			/* Attempt to shrink memory after successfully reclaiming lots of memory */
 
 			/* begin shrinkObjectMemory: */
-			print("shrinkObjectMemory: shouldBeImplemented");
-			/* begin cr */
-			printf("\n");
+			shrinkage = freeSizeNow - GIV(growHeadroom);
+			while (1) {
+				/* begin findEmptySegNearestInSizeTo: */
+				best = null;
+				delta1 = shrinkage;
+				for (i = 0; i < GIV(numSegments); i += 1) {
+					seg = (&(GIV(segments)[i]));
+					if (isEmptySegment(seg)) {
+						if (best == null) {
+							best = seg;
+						}
+						else {
+							if ((shrinkage >= (((seg->segSize)) * 0.75))
+							 && ((abs(((seg->segSize)) - shrinkage)) < delta1)) {
+								best = seg;
+								delta1 = abs(((seg->segSize)) - shrinkage);
+							}
+						}
+					}
+				}
+				emptySeg = ((sqInt) best);
+				if (!(emptySeg != null)) break;
+				shrinkage -= (emptySeg->segSize);
+				detachFreeObject(objectStartingAt((emptySeg->segStart)));
+				/* begin removeSegment: */
+				/* begin indexOfSegment: */
+				for (i1 = 0; i1 < GIV(numSegments); i1 += 1) {
+					if (((emptySeg->segStart)) == (((GIV(segments)[i1]).segStart))) {
+						i2 = i1;
+						goto l1;
+					}
+				}
+				error("segment not found");
+			l1:	/* end indexOfSegment: */;
+				assert(i2 > 0);
+				sqDeallocateMemorySegmentAtOfSize((emptySeg->segStart), (emptySeg->segSize));
+				for (j = i2; j < GIV(numSegments); j += 1) {
+					GIV(segments)[j] = (GIV(segments)[j + 1]);
+				}
+				null;
+				GIV(numSegments) -= 1;
+				bridgeFromto((&(GIV(segments)[i2 - 1])), (i2 <= (GIV(numSegments) - 1)
+					? (&(GIV(segments)[i2]))
+					: 0));
+				/* begin setLastSegment: */
+				currentEnd = (((((&(GIV(segments)[GIV(numSegments) - 1])))->segSize)) + ((((&(GIV(segments)[GIV(numSegments) - 1])))->segStart))) - (2 * (BaseHeaderSize));
+				if (currentEnd <= GIV(endOfMemory)) {
+					GIV(endOfMemory) = currentEnd;
+					if (GIV(freeOldSpaceStart) > currentEnd) {
+						GIV(freeOldSpaceStart) = currentEnd;
+					}
+				}
+			}
 		}
 	}
 	signalSemaphoreWithIndex(GIV(gcSemaphoreIndex));
@@ -32737,6 +32815,9 @@
 			GIV(totalFreeOldSpace) += bytes;
 		}
 	}
+	/* begin checkFreeSpace */
+	assert(bitsSetInFreeSpaceMaskForAllFreeLists());
+	assert(GIV(totalFreeOldSpace) == (totalFreeListBytes()));
 }
 
 
@@ -56593,7 +56674,7 @@
 	zero if no change
 	was possible. */
 
-static usqInt
+static sqInt
 shortentoIndexableSize(sqInt objOop, sqInt indexableSize)
 {
     usqInt bytesAfter;
@@ -57637,6 +57718,9 @@
 	assert(GIV(freeStart) == (((eden()).start)));
 	fullGC();
 	prepareForSnapshot();
+	/* begin checkFreeSpace */
+	assert(bitsSetInFreeSpaceMaskForAllFreeLists());
+	assert(GIV(totalFreeOldSpace) == (totalFreeListBytes()));
 	activeContext = GIV(tempOop);
 	GIV(tempOop) = 0;
 	if (!GIV(primFailCode)) {

Modified: branches/Cog/spursistasrc/vm/cointerp.h
===================================================================
--- branches/Cog/spursistasrc/vm/cointerp.h	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/spursistasrc/vm/cointerp.h	2014-05-21 19:18:13 UTC (rev 2928)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
 
 

Modified: branches/Cog/spursistasrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/spursistasrc/vm/gcc3x-cointerp.c	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/spursistasrc/vm/gcc3x-cointerp.c	2014-05-21 19:18:13 UTC (rev 2928)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
    from
-	CoInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CoInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -750,6 +750,7 @@
 static sqInt isContextNonImm(sqInt oop) NoDbgRegParms;
 static sqInt isContext(sqInt oop) NoDbgRegParms;
 static sqInt isEmptyObjStack(sqInt objStack) NoDbgRegParms;
+static sqInt isEmptySegment(SpurSegmentInfo *seg) NoDbgRegParms;
 static sqInt isEnumerableObjectNoAssert(sqInt objOop) NoDbgRegParms;
 static sqInt isEnumerableObject(sqInt objOop) NoDbgRegParms;
 static sqInt isEphemeron(sqInt objOop) NoDbgRegParms;
@@ -1321,7 +1322,7 @@
 static void setSignalLowSpaceFlagAndSaveProcess(void);
 static void setTraceFlagOnContextsFramesPageIfNeeded(sqInt aContext) NoDbgRegParms;
 sqInt shiftForWord(void);
-static usqInt shortentoIndexableSize(sqInt objOop, sqInt indexableSize) NoDbgRegParms;
+static sqInt shortentoIndexableSize(sqInt objOop, sqInt indexableSize) NoDbgRegParms;
 static sqInt shortPrintContext(sqInt aContext) NoDbgRegParms;
 static sqInt shortPrintFrameAndCallers(char *theFP) NoDbgRegParms;
 EXPORT(void) shortPrintFramesInPage(StackPage *thePage);
@@ -1451,16 +1452,16 @@
 _iss char * stackBasePlus1;
 _iss sqInt hiddenRootsObj;
 _iss usqInt endOfMemory;
+_iss SpurSegmentInfo * segments;
 _iss sqInt remapBufferCount;
 _iss sqInt trueObj;
-_iss SpurSegmentInfo * segments;
 _iss sqInt falseObj;
 _iss sqInt needGCFlag;
 _iss sqInt traceLogIndex;
 _iss sqInt bytesPerPage;
 _iss sqInt totalFreeOldSpace;
+_iss sqInt numSegments;
 _iss usqInt pastSpaceStart;
-_iss sqInt numSegments;
 _iss char * stackLimit;
 _iss sqInt * freeLists;
 _iss usqInt scavengeThreshold;
@@ -1490,18 +1491,18 @@
 _iss SpurNewSpaceSpace eden;
 _iss sqInt profileSemaphore;
 _iss sqInt ephemeronList;
+_iss usqInt freeOldSpaceStart;
 _iss sqInt profileProcess;
 _iss sqInt tenureThreshold;
 _iss sqInt extraRootCount;
 _iss sqInt invalidObjStackPage;
 _iss sqInt previousRememberedSetSize;
 _iss unsigned char * classTableBitmap;
-_iss usqInt freeOldSpaceStart;
+_iss sqInt growHeadroom;
 _iss sqInt longRunningPrimitiveCheckMethod;
 _iss sqInt profileMethod;
 _iss sqInt classTableIndex;
 _iss sqInt ephemeronQueue;
-_iss sqInt growHeadroom;
 _iss sqInt lastMethodCacheProbeWrite;
 _iss sqInt lkupClass;
 _iss sqInt metaclassNumSlots;
@@ -2217,7 +2218,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.727]";
+const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.730]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -26032,7 +26033,24 @@
 	 && (0 == (longAt((objStack + (BaseHeaderSize)) + (ObjStackNextx << 2))));
 }
 
+static sqInt
+isEmptySegment(SpurSegmentInfo *seg)
+{
+    sqInt address;
+    sqInt firstObj;
+    usqInt numSlots;
 
+	/* begin objectStartingAt: */
+	address = (seg->segStart);
+	numSlots = byteAt(address + 7);
+	firstObj = (numSlots == 0xFF
+		? address + (BaseHeaderSize)
+		: address);
+	return (((longAt(firstObj)) & 0x3FFFFF) == 0)
+	 && ((addressAfter(firstObj)) == ((((seg->segSize)) + ((seg->segStart))) - (2 * (BaseHeaderSize))));
+}
+
+
 /*	Answer if objOop should be included in an allObjects...Do: enumeration.
 	This is for assert-checking only. */
 
@@ -32675,7 +32693,17 @@
 static void
 postGCAction(sqInt gcModeArg)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt best;
+    usqInt currentEnd;
+    sqInt delta1;
+    SpurSegmentInfo *emptySeg;
     sqInt freeSizeNow;
+    sqInt i;
+    sqInt i1;
+    sqInt i2;
+    sqInt j;
+    SpurSegmentInfo *seg;
+    sqInt shrinkage;
 
 	assert(gcModeArg == GIV(gcMode));
 	if ((gcModeArg == GCModeFull)
@@ -32690,9 +32718,59 @@
 			/* Attempt to shrink memory after successfully reclaiming lots of memory */
 
 			/* begin shrinkObjectMemory: */
-			print("shrinkObjectMemory: shouldBeImplemented");
-			/* begin cr */
-			printf("\n");
+			shrinkage = freeSizeNow - GIV(growHeadroom);
+			while (1) {
+				/* begin findEmptySegNearestInSizeTo: */
+				best = null;
+				delta1 = shrinkage;
+				for (i = 0; i < GIV(numSegments); i += 1) {
+					seg = (&(GIV(segments)[i]));
+					if (isEmptySegment(seg)) {
+						if (best == null) {
+							best = seg;
+						}
+						else {
+							if ((shrinkage >= (((seg->segSize)) * 0.75))
+							 && ((abs(((seg->segSize)) - shrinkage)) < delta1)) {
+								best = seg;
+								delta1 = abs(((seg->segSize)) - shrinkage);
+							}
+						}
+					}
+				}
+				emptySeg = ((sqInt) best);
+				if (!(emptySeg != null)) break;
+				shrinkage -= (emptySeg->segSize);
+				detachFreeObject(objectStartingAt((emptySeg->segStart)));
+				/* begin removeSegment: */
+				/* begin indexOfSegment: */
+				for (i1 = 0; i1 < GIV(numSegments); i1 += 1) {
+					if (((emptySeg->segStart)) == (((GIV(segments)[i1]).segStart))) {
+						i2 = i1;
+						goto l1;
+					}
+				}
+				error("segment not found");
+			l1:	/* end indexOfSegment: */;
+				assert(i2 > 0);
+				sqDeallocateMemorySegmentAtOfSize((emptySeg->segStart), (emptySeg->segSize));
+				for (j = i2; j < GIV(numSegments); j += 1) {
+					GIV(segments)[j] = (GIV(segments)[j + 1]);
+				}
+				null;
+				GIV(numSegments) -= 1;
+				bridgeFromto((&(GIV(segments)[i2 - 1])), (i2 <= (GIV(numSegments) - 1)
+					? (&(GIV(segments)[i2]))
+					: 0));
+				/* begin setLastSegment: */
+				currentEnd = (((((&(GIV(segments)[GIV(numSegments) - 1])))->segSize)) + ((((&(GIV(segments)[GIV(numSegments) - 1])))->segStart))) - (2 * (BaseHeaderSize));
+				if (currentEnd <= GIV(endOfMemory)) {
+					GIV(endOfMemory) = currentEnd;
+					if (GIV(freeOldSpaceStart) > currentEnd) {
+						GIV(freeOldSpaceStart) = currentEnd;
+					}
+				}
+			}
 		}
 	}
 	signalSemaphoreWithIndex(GIV(gcSemaphoreIndex));
@@ -32746,6 +32824,9 @@
 			GIV(totalFreeOldSpace) += bytes;
 		}
 	}
+	/* begin checkFreeSpace */
+	assert(bitsSetInFreeSpaceMaskForAllFreeLists());
+	assert(GIV(totalFreeOldSpace) == (totalFreeListBytes()));
 }
 
 
@@ -56602,7 +56683,7 @@
 	zero if no change
 	was possible. */
 
-static usqInt
+static sqInt
 shortentoIndexableSize(sqInt objOop, sqInt indexableSize)
 {
     usqInt bytesAfter;
@@ -57646,6 +57727,9 @@
 	assert(GIV(freeStart) == (((eden()).start)));
 	fullGC();
 	prepareForSnapshot();
+	/* begin checkFreeSpace */
+	assert(bitsSetInFreeSpaceMaskForAllFreeLists());
+	assert(GIV(totalFreeOldSpace) == (totalFreeListBytes()));
 	activeContext = GIV(tempOop);
 	GIV(tempOop) = 0;
 	if (!GIV(primFailCode)) {

Modified: branches/Cog/spursistasrc/vm/interp.h
===================================================================
--- branches/Cog/spursistasrc/vm/interp.h	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/spursistasrc/vm/interp.h	2014-05-21 19:18:13 UTC (rev 2928)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
 
 #define VM_PROXY_MAJOR 1

Modified: branches/Cog/spursistasrc/vm/vmCallback.h
===================================================================
--- branches/Cog/spursistasrc/vm/vmCallback.h	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/spursistasrc/vm/vmCallback.h	2014-05-21 19:18:13 UTC (rev 2928)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
 
 #define VM_CALLBACK_INC 1

Modified: branches/Cog/spursrc/vm/cointerp.c
===================================================================
--- branches/Cog/spursrc/vm/cointerp.c	2014-05-20 22:55:52 UTC (rev 2927)
+++ branches/Cog/spursrc/vm/cointerp.c	2014-05-21 19:18:13 UTC (rev 2928)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
    from
-	CoInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659
+	CoInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.727 uuid: c4880b9d-5eff-44bc-8908-a6e831764659 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.730 uuid: 721dc8e5-985a-41a1-8e5d-09d9095df7d8 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -745,6 +745,7 @@
 static sqInt isContextNonImm(sqInt oop) NoDbgRegParms;
 static sqInt isContext(sqInt oop) NoDbgRegParms;
 static sqInt isEmptyObjStack(sqInt objStack) NoDbgRegParms;
+static sqInt isEmptySegment(SpurSegmentInfo *seg) NoDbgRegParms;
 static sqInt isEnumerableObjectNoAssert(sqInt objOop) NoDbgRegParms;

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list