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. @@ |
Free forum by Nabble | Edit this page |