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

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

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

commits-3
 
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. @@