[MLton-devel] cvs commit: heap resizing
Stephen Weeks
sweeks@users.sourceforge.net
Sun, 18 Aug 2002 00:17:24 -0700
sweeks 02/08/18 00:17:24
Modified: include ccodegen.h x86codegen.h
mlton/backend ssa-to-rssa.fun
mlton/codegen/c-codegen c-codegen.fun
mlton/control control.sig control.sml
mlton/main main.sml
runtime gc.c gc.h
Log:
More improvements to heap resizing code. There are now lots of command-line
runtime system controls:
copy-ratio
minimum live ratio for using copying collection (2)
generational-ratio
live ratio above which generational gc is not used (5)
grow-ratio
ratio of extra space reserved for heap growth when using
copying gc (1.5)
live-ratio
desired live ratio (8)
mark-compact-ratio
minimum live ratio for using mark compact gc (1.5)
nursery-ratio
maximum ratio of heap size to nursery size (10)
if the nursery is to small then prepare for a major gc
Renamed -generational as -card-mark.
Revision Changes Path
1.36 +2 -2 mlton/include/ccodegen.h
Index: ccodegen.h
===================================================================
RCS file: /cvsroot/mlton/mlton/include/ccodegen.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- ccodegen.h 7 Aug 2002 01:02:42 -0000 1.35
+++ ccodegen.h 18 Aug 2002 07:17:22 -0000 1.36
@@ -118,14 +118,13 @@
/* main */
/* ------------------------------------------------- */
-#define Main(cs, ufh, fhs, g, mfs, mfi, mot, mg, mc, ml) \
+#define Main(cs, ufh, fhs, mmc, mfs, mfi, mot, mg, mc, ml) \
int main (int argc, char **argv) { \
struct cont cont; \
int l_nextFun; \
gcState.cardSizeLog2 = cs; \
gcState.fixedHeapSize = fhs; \
gcState.frameLayouts = frameLayouts; \
- gcState.generational = g; \
gcState.globals = globalpointer; \
gcState.intInfInits = intInfInits; \
gcState.loadGlobals = &loadGlobals; \
@@ -133,6 +132,7 @@
gcState.maxFrameIndex = mfi; \
gcState.maxFrameSize = mfs; \
gcState.maxObjectTypeIndex = mot; \
+ gcState.mutatorMarksCards = mmc; \
gcState.native = FALSE; \
gcState.numGlobals = cardof(globalpointer); \
gcState.objectTypes = objectTypes; \
1.16 +2 -2 mlton/include/x86codegen.h
Index: x86codegen.h
===================================================================
RCS file: /cvsroot/mlton/mlton/include/x86codegen.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- x86codegen.h 7 Aug 2002 01:02:42 -0000 1.15
+++ x86codegen.h 18 Aug 2002 07:17:22 -0000 1.16
@@ -64,14 +64,13 @@
#define Float(c, f) globaldouble[c] = f;
#define EndFloats }
-#define Main(cs, ufh, fhs, g, mfs, mfi, mot, mg, ml, reserveEsp) \
+#define Main(cs, ufh, fhs, mmc, mfs, mfi, mot, mg, ml, reserveEsp) \
extern pointer ml; \
int main (int argc, char **argv) { \
pointer jump; \
gcState.cardSizeLog2 = cs; \
gcState.fixedHeapSize = fhs; \
gcState.frameLayouts = frameLayouts; \
- gcState.generational = g; \
gcState.globals = globalpointer; \
gcState.intInfInits = intInfInits; \
gcState.loadGlobals = &loadGlobals; \
@@ -79,6 +78,7 @@
gcState.maxFrameIndex = mfi; \
gcState.maxFrameSize = mfs; \
gcState.maxObjectTypeIndex = mot; \
+ gcState.mutatorMarksCards = mmc; \
gcState.native = TRUE; \
gcState.numGlobals = cardof(globalpointer); \
gcState.objectTypes = objectTypes; \
1.23 +2 -2 mlton/mlton/backend/ssa-to-rssa.fun
Index: ssa-to-rssa.fun
===================================================================
RCS file: /cvsroot/mlton/mlton/mlton/backend/ssa-to-rssa.fun,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- ssa-to-rssa.fun 7 Aug 2002 01:02:42 -0000 1.22
+++ ssa-to-rssa.fun 18 Aug 2002 07:17:22 -0000 1.23
@@ -902,7 +902,7 @@
loop (i - 1, prefix ss, t)
end
fun arrayUpdate (ty, src) =
- if !Control.generational andalso Type.isPointer ty
+ if !Control.markCards andalso Type.isPointer ty
then let
val temp = Var.newNoname ()
val tempOp = Operand.Var {var = temp,
@@ -944,7 +944,7 @@
ty = ty},
src = src}
in
- if !Control.generational andalso Type.isPointer ty
+ if !Control.markCards andalso Type.isPointer ty
then updateCard (varOp addr, fn ss => ss, assign)
else loop (i - 1, assign::ss, t)
end
1.29 +1 -1 mlton/mlton/codegen/c-codegen/c-codegen.fun
Index: c-codegen.fun
===================================================================
RCS file: /cvsroot/mlton/mlton/mlton/codegen/c-codegen/c-codegen.fun,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- c-codegen.fun 7 Aug 2002 01:02:43 -0000 1.28
+++ c-codegen.fun 18 Aug 2002 07:17:22 -0000 1.29
@@ -295,7 +295,7 @@
[C.int (!Control.cardSizeLog2),
usedFixedHeap,
C.int fixedHeapSize,
- C.bool (!Control.generational),
+ C.bool (!Control.markCards),
C.int maxFrameSize,
C.int maxFrameIndex,
C.int (Vector.length objectTypes),
1.50 +3 -3 mlton/mlton/control/control.sig
Index: control.sig
===================================================================
RCS file: /cvsroot/mlton/mlton/mlton/control/control.sig,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -r1.49 -r1.50
--- control.sig 7 Aug 2002 01:02:43 -0000 1.49
+++ control.sig 18 Aug 2002 07:17:22 -0000 1.50
@@ -49,9 +49,6 @@
| Every
val gcCheck: gcCheck ref
- (* Does the runtime use generational GC. *)
- val generational: bool ref
-
datatype host =
Cross of string
| Self
@@ -120,6 +117,9 @@
(* Number of times to loop through optimization passes. *)
val loopPasses: int ref
+
+ (* Should the mutator mark cards? *)
+ val markCards: bool ref
structure Native:
sig
1.62 +4 -4 mlton/mlton/control/control.sml
Index: control.sml
===================================================================
RCS file: /cvsroot/mlton/mlton/mlton/control/control.sml,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -r1.61 -r1.62
--- control.sml 7 Aug 2002 01:02:43 -0000 1.61
+++ control.sml 18 Aug 2002 07:17:23 -0000 1.62
@@ -83,10 +83,6 @@
default = Limit,
toString = GcCheck.toString}
-val generational = control {name = "generational",
- default = true,
- toString = Bool.toString}
-
structure Host =
struct
datatype t =
@@ -240,6 +236,10 @@
val loopPasses = control {name = "loop passes",
default = 1,
toString = Int.toString}
+
+val markCards = control {name = "mark cards",
+ default = true,
+ toString = Bool.toString}
structure Native =
struct
1.75 +2 -2 mlton/mlton/main/main.sml
Index: main.sml
===================================================================
RCS file: /cvsroot/mlton/mlton/mlton/main/main.sml,v
retrieving revision 1.74
retrieving revision 1.75
diff -u -r1.74 -r1.75
--- main.sml 7 Aug 2002 01:02:43 -0000 1.74
+++ main.sml 18 Aug 2002 07:17:23 -0000 1.75
@@ -126,8 +126,8 @@
| "first" => First
| "every" => Every
| _ => usage (concat ["invalid -gc-check flag: ", s])))),
- (Expert, "generational", " {true|false}", "use generational GC",
- boolRef Control.generational),
+ (Expert, "mark-cards", " {true|false}", "mutator marks cards",
+ boolRef Control.markCards),
(Normal, "host",
concat [" {",
concat (List.separate (List.map (hostMap (), #host), "|")),
1.73 +199 -169 mlton/runtime/gc.c
Index: gc.c
===================================================================
RCS file: /cvsroot/mlton/mlton/runtime/gc.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -r1.72 -r1.73
--- gc.c 17 Aug 2002 02:08:55 -0000 1.72
+++ gc.c 18 Aug 2002 07:17:23 -0000 1.73
@@ -329,7 +329,7 @@
unless (res == 0)
return (res);
if (times(&tbuff) == -1)
- diee("Impossible: times() failed");
+ diee ("Impossible: times() failed");
switch (who) {
case RUSAGE_SELF:
user = tbuff.tms_utime;
@@ -340,8 +340,8 @@
sys = tbuff.tms_cstime;
break;
default:
- die("getrusage() accepted unknown who: %d", who);
- exit(1); /* needed to keep gcc from whining. */
+ die ("getrusage() accepted unknown who: %d", who);
+ exit (1); /* needed to keep gcc from whining. */
}
rup->ru_utime.tv_sec = user / hz;
rup->ru_utime.tv_usec = (user % hz) * (1000000 / hz);
@@ -495,7 +495,7 @@
}
static inline void markCard (GC_state s, pointer p) {
- if (s->generational)
+ if (s->mutatorMarksCards)
s->heap.cardMap[divCardSize (s, (uint)p)] = '\001';
}
@@ -837,10 +837,12 @@
/* invariant */
/* ---------------------------------------------------------------- */
-static bool liveRatiosOk (GC_state s) {
- return 1.0 < s->liveRatioMarkCompact
- and s->liveRatioMarkCompact <= s->liveRatioCopy
- and s->liveRatioCopy <= s->liveRatioDesired;
+static bool ratiosOk (GC_state s) {
+ return 1.0 < s->growRatio
+ and 1.0 < s->nurseryRatio
+ and 1.0 < s->markCompactRatio
+ and s->markCompactRatio <= s->copyRatio
+ and s->copyRatio <= s->liveRatio;
}
#ifndef NODEBUG
@@ -867,7 +869,7 @@
* for stacks, the card containing the beginning of the stack is marked,
* but any remaining cards aren't.
*/
- if (FALSE and s->generational
+ if (FALSE and s->mutatorMarksCards
and isInOldGen (s, (pointer)p)
and isInNursery (s, *p)
and not cardIsMarked (s, (pointer)p)) {
@@ -888,7 +890,7 @@
pointer back;
GC_stack stack;
- assert (liveRatiosOk (s));
+ assert (ratiosOk (s));
if (DEBUG)
fprintf (stderr, "invariant\n");
/* Frame layouts */
@@ -998,30 +1000,60 @@
/* Heaps */
/* ---------------------------------------------------------------- */
-static W32 heapDesiredSize (GC_state s, W64 live) {
+/* heapDesiredSize (s, l, c) returns the desired heap size for a heap with
+ * l bytes live, given that the current heap size is c.
+ */
+static W32 heapDesiredSize (GC_state s, W64 live, W32 currentSize) {
W32 res;
float ratio;
if (live > s->totalRam + s->totalSwap)
- die ("out of memory: %s bytes live", ullongToCommaString (live));
+ die ("Out of memory: %s bytes live.",
+ ullongToCommaString (live));
ratio = (float)s->ram / (float)live;
if (s->useFixedHeap)
res = s->fixedHeapSize;
- else if (s->liveRatioDesired + 1 <= ratio)
+ else if (ratio >= s->liveRatio + s->growRatio) {
/* Cheney copying fits in RAM with desired liveRatio. */
- res = live * s->liveRatioDesired;
- else if (s->liveRatioCopy <= ratio)
- /* Cheney copying fits in RAM */
- res = s->ram - live;
- else if (s->liveRatioMarkCompact <= ratio)
- /* Mark compact fits in ram */
+ res = live * s->liveRatio;
+ /* If the heap is currently close in size to what we want, leave
+ * it alone. Favor growing over shrinking.
+ */
+ unless (currentSize <= 0.8 * res
+ or currentSize >= 2.0 * res)
+ res = currentSize;
+ } else if (ratio >= s->copyRatio + s->growRatio) {
+ /* Cheney copying fits in RAM. */
+ res = s->ram - s->growRatio * live;
+ /* If the heap isn't too much smaller than what we want, leave
+ * it alone. On the other hand, if it is bigger we want to
+ * leave res as is so that the heap is shrunk, to try to avoid
+ * paging.
+ */
+ if (0.9 * res <= currentSize and currentSize <= res)
+ res = currentSize;
+ } else if (ratio >= s->markCompactRatio) {
+ /* Mark compact fits in ram. It doesn't matter what the current
+ * size is. If the heap is currently smaller, we are using
+ * copying and should switch to mark-compact. If the heap is
+ * currently bigger, we want to shrink back to ram size to avoid
+ * paging.
+ */
res = s->ram;
- else /* Required live ratio. */
- res = min64 (live * s->liveRatioMarkCompact,
+ } else { /* Required live ratio. */
+ res = min64 (live * s->markCompactRatio,
s->totalRam + s->totalSwap);
+ /* If the current heap is bigger than res, the shrinking always
+ * sounds like a good idea. However, depending on what pages
+ * the VM keeps around, growing could be very expensive, if it
+ * involves paging the entire heap. Hopefully the copy loop
+ * in growFromSpace will make the right thing happen.
+ */
+ }
if (DEBUG_RESIZING)
- fprintf (stderr, "%u = heapDesiredSize (%llu)\n",
- (uint)res, live);
+ fprintf (stderr, "%s = heapDesiredSize (%s)\n",
+ uintToCommaString (res),
+ ullongToCommaString (live));
assert (res >= live);
return res;
}
@@ -1086,15 +1118,15 @@
h->nurserySize = h->size - h->oldGenSize;
assert (isAligned (h->nurserySize, WORD_SIZE));
if ( /* The mutator marks cards. */
- s->generational
+ s->mutatorMarksCards
/* The live ratio is low enough to make generational GC
* worthwhile.
*/
and (float)s->heap.size / (float)s->bytesLive
- <= s->liveRatioGenerational
+ <= s->generationalRatio
/* The nursery is large enough to be worth it. */
- and (float)h->nurserySize
- >= (float)s->bytesLive / s->nurseryRatio) {
+ and (float)s->heap.size / (float)h->nurserySize
+ <= s->nurseryRatio) {
h->nurserySize /= 2;
unless (isAligned (h->nurserySize, WORD_SIZE))
h->nurserySize -= 2;
@@ -1130,24 +1162,24 @@
* is unable. If a reasonable size to space is already there, then heapCreate
* leaves it.
*/
-static inline bool heapCreate (GC_state s, GC_heap h, W64 need, W32 minSize) {
+static inline bool heapCreate (GC_state s, GC_heap h,
+ W32 desiredSize, W32 minSize) {
W32 backoff;
- W32 requested;
if (DEBUG)
- fprintf (stderr, "heapCreate need = %llu minSize = %u\n",
- need, (uint)minSize);
- requested = heapDesiredSize (s, need);
- if (requested < minSize)
- requested = minSize;
- requested = align (requested, s->cardSize);
- if (h->size >= minSize and h->size >= requested / 2)
+ fprintf (stderr, "heapCreate desired size = %s min size = %s\n",
+ uintToCommaString (desiredSize),
+ uintToCommaString (minSize));
+ if (desiredSize < minSize)
+ desiredSize = minSize;
+ desiredSize = align (desiredSize, s->cardSize);
+ if (h->size >= minSize and h->size >= desiredSize / 2)
/* Tospace is big enough. Keep it. */
return TRUE;
else
heapRelease (s, h);
assert (0 == h->size and NULL == h->start);
- backoff = (requested - minSize) / 20;
+ backoff = (desiredSize - minSize) / 20;
if (0 == backoff)
backoff = 1; /* enough to terminate the loop below */
backoff = align (backoff, s->cardSize);
@@ -1155,13 +1187,13 @@
* decrease the chance of virtual memory fragmentation causing an mmap
* to fail. This is important for large heaps.
*/
- for (h->size = requested; h->size >= minSize; h->size -= backoff) {
+ for (h->size = desiredSize; h->size >= minSize; h->size -= backoff) {
uint cardMapSpace;
static int direction = 1;
int i;
assert (isAligned (h->size, s->cardSize));
- if (s->generational)
+ if (s->mutatorMarksCards)
h->numCards = divCardSize (s, h->size);
else
h->numCards = 0;
@@ -1204,7 +1236,7 @@
s->maxHeapSizeSeen = h->totalSize;
h->oldGen = h->start + cardMapSpace;
assert (isAligned ((uint)h->oldGen, s->cardSize));
- if (s->generational) {
+ if (s->mutatorMarksCards) {
assert (divCardSize (s, (uint)h->oldGen) <= (uint)h->start);
h->cardMap = h->start
- divCardSize (s, (uint)h->oldGen);
@@ -1224,8 +1256,8 @@
}
}
if (s->messages)
- fprintf(stderr, "[Requested %luM cannot be satisfied, backing off by %luM (need = %luM).\n",
- meg (h->totalSize), meg (backoff), meg (need));
+ fprintf(stderr, "[Requested %luM cannot be satisfied, backing off by %luM (min size = %luM).\n",
+ meg (h->totalSize), meg (backoff), meg (minSize));
}
h->totalSize = 0;
h->size = 0;
@@ -1233,7 +1265,7 @@
}
static inline void setCrossMap (GC_state s, pointer p) {
- if (s->generational and isAligned ((uint)p, s->cardSize)) {
+ if (s->mutatorMarksCards and isAligned ((uint)p, s->cardSize)) {
GC_heap h;
h = s->crossMapHeap;
@@ -1378,7 +1410,8 @@
s->bytesLive = s->back - s->heap2.oldGen;
s->heap2.oldGenSize = s->bytesLive;
if (DEBUG)
- fprintf (stderr, "bytesLive = %u\n", s->bytesLive);
+ fprintf (stderr, "%s bytes live.\n",
+ uintToCommaString (s->bytesLive));
swapSemis (s);
s->bytesCopied += s->bytesLive;
if (DEBUG or s->messages)
@@ -2039,107 +2072,93 @@
}
/* ---------------------------------------------------------------- */
-/* resizeHeap */
+/* growFromSpace */
/* ---------------------------------------------------------------- */
-/* Resize from space and to space, guaranteeing that at least 'need' bytes are
- * available in from space and that to space is either the same size as from
- * space or is unmapped.
- */
-static inline void resizeHeap (GC_state s, W64 need) {
- bool grow;
- W32 keep;
+static inline void growFromSpace (GC_state s, W32 desired, W32 minSize) {
+ pointer old;
+ uint size;
- grow = FALSE;
- keep = 0;
+ assert (desired >= s->heap.size);
if (DEBUG_RESIZING)
- fprintf (stderr, "resizeHeap need = %llu fromSize = %s\n",
- need, uintToCommaString (s->heap.totalSize));
- if (need >= s->heap.size)
- grow = TRUE;
- else {
- W32 desired;
-
- desired = heapDesiredSize (s, need);
- assert (desired >= need);
- if ((s->heap.size >= s->ram and desired <= s->ram)
- or desired < 0.75 * s->heap.size)
- keep = desired;
- else if (desired > 1.25 * s->heap.size)
- grow = TRUE;
- else
- keep = max (s->heap.size, need);
- }
- if (DEBUG_RESIZING)
- fprintf (stderr, "size = %s need = %s keep = %s\n",
- uintToCommaString ((uint)s->heap.totalSize),
- uintToCommaString ((uint)need),
- uintToCommaString ((uint)keep));
- /* Shrink or grow the heap. */
- if (not grow) {
- assert (need <= keep and keep <= s->heap.size);
- shrinkFromSpace (s, keep);
- } else {
- pointer old;
- uint size;
+ fprintf (stderr, "Growing from space. oldGenSize = %s\n",
+ uintToCommaString (s->heap.oldGenSize));
+ releaseToSpace (s);
+ old = s->heap.oldGen;
+ size = s->heap.oldGenSize;
+ assert (size <= s->heap.size);
+ shrinkFromSpace (s, size);
+ /* Allocate a space of the desired size. */
+ if (heapCreate (s, &s->heap2, desired, minSize)) {
+ pointer from;
+ pointer to;
- if (DEBUG_RESIZING)
- fprintf (stderr, "Growing from space. oldGenSize = %u\n",
- (uint)s->heap.oldGenSize);
- releaseToSpace (s);
- old = s->heap.oldGen;
- size = s->heap.oldGenSize;
- assert (size <= s->heap.size);
- shrinkFromSpace (s, size);
- /* Allocate a space of the desired size. */
- if (heapCreate (s, &s->heap2, need, need)) {
- pointer from;
- pointer to;
-
- from = old + size;
- to = s->heap2.oldGen + size;
+ from = old + size;
+ to = s->heap2.oldGen + size;
copy:
- from -= COPY_CHUNK_SIZE;
- to -= COPY_CHUNK_SIZE;
- if (from > old) {
- copy (from, to, COPY_CHUNK_SIZE);
- heapShrink (s, &s->heap, from - old);
- goto copy;
- }
- copy (old, s->heap2.oldGen,
- from + COPY_CHUNK_SIZE - old);
- heapRelease (s, &s->heap);
- swapSemis (s);
+ from -= COPY_CHUNK_SIZE;
+ to -= COPY_CHUNK_SIZE;
+ if (from > old) {
+ copy (from, to, COPY_CHUNK_SIZE);
+ heapShrink (s, &s->heap, from - old);
+ goto copy;
+ }
+ copy (old, s->heap2.oldGen, from + COPY_CHUNK_SIZE - old);
+ heapRelease (s, &s->heap);
+ swapSemis (s);
+ } else {
+ /* Write the heap to a file and try again. */
+ FILE *stream;
+ char template[80] = "/tmp/FromSpaceXXXXXX";
+ int fd;
+
+ fd = smkstemp (template);
+ sclose (fd);
+ if (s->messages)
+ fprintf (stderr, "Paging from space to %s.\n",
+ template);
+ stream = sfopen (template, "wb");
+ sfwrite (old, 1, size, stream);
+ sfclose (stream);
+ heapRelease (s, &s->heap);
+ if (heapCreate (s, &s->heap, desired, minSize)) {
+ stream = sfopen (template, "rb");
+ sfread (s->heap.oldGen, 1, size, stream);
+ sfclose (stream);
+ sunlink (template);
} else {
- /* Write the heap to a file and try again. */
- FILE *stream;
- char template[80] = "/tmp/FromSpaceXXXXXX";
- int fd;
-
- fd = smkstemp (template);
- sclose (fd);
+ sunlink (template);
if (s->messages)
- fprintf (stderr, "Paging from space to %s.\n",
- template);
- stream = sfopen (template, "wb");
- sfwrite (old, 1, size, stream);
- sfclose (stream);
- heapRelease (s, &s->heap);
- if (heapCreate (s, &s->heap, need, need)) {
- stream = sfopen (template, "rb");
- sfread (s->heap.oldGen, 1, size, stream);
- sfclose (stream);
- sunlink (template);
- } else {
- sunlink (template);
- if (s->messages)
- showMem ();
- die ("Out of memory. Need %llu bytes.\n", need);
- }
+ showMem ();
+ die ("Out of memory. Unable to allocate %s bytes.\n",
+ uintToCommaString (minSize));
}
- s->heap.oldGenSize = size;
- translateHeap (s, old, s->heap.oldGen, size);
}
+ s->heap.oldGenSize = size;
+ translateHeap (s, old, s->heap.oldGen, size);
+}
+
+/* ---------------------------------------------------------------- */
+/* resizeHeap */
+/* ---------------------------------------------------------------- */
+/* Resize from space and to space, guaranteeing that at least 'need' bytes are
+ * available in from space and that to space is either the same size as from
+ * space or is unmapped.
+ */
+static inline void resizeHeap (GC_state s, W64 need) {
+ W32 desired;
+
+ if (DEBUG_RESIZING)
+ fprintf (stderr, "resizeHeap need = %s fromSize = %s\n",
+ ullongToCommaString (need),
+ uintToCommaString (s->heap.totalSize));
+ desired = heapDesiredSize (s, need, s->heap.size);
+ assert (need <= desired);
+ /* Shrink or grow the heap. */
+ if (desired <= s->heap.size)
+ shrinkFromSpace (s, desired);
+ else
+ growFromSpace (s, desired, need);
setNursery (s);
setStack (s);
/* Resize to space. */
@@ -2192,12 +2211,12 @@
* requested by 2 since the heap space remaining is split in half, with
* half for the nursery and half for the to space of a minor GC.
*/
- if (s->generational)
+ if (s->mutatorMarksCards)
totalBytesRequested *= 2;
if (not s->useFixedHeap
and s->heap.size < s->ram
and heapCreate (s, &s->heap2,
- (W64)s->bytesLive + totalBytesRequested,
+ heapDesiredSize (s, (W64)s->bytesLive + totalBytesRequested, 0),
s->heap.oldGenSize))
cheneyCopy (s);
else
@@ -2222,8 +2241,8 @@
assert (invariant (s));
if (DEBUG or s->messages)
- fprintf (stderr, "Starting gc. bytesRequested = %u\n",
- bytesRequested);
+ fprintf (stderr, "Starting gc. %s bytes requested.\n",
+ uintToCommaString (bytesRequested));
fixedGetrusage (RUSAGE_SELF, &ru_start);
minorGC (s);
stackBytesRequested = getStackBytesRequested (s);
@@ -2399,8 +2418,8 @@
w64align((W64)eltSize * (W64)numElts + GC_ARRAY_HEADER_SIZE);
require64 = arraySize64 + (W64)ensureBytesFree;
if (require64 >= 0x100000000llu)
- die ("Out of memory: cannot allocate %llu bytes.\n",
- require64);
+ die ("Out of memory: cannot allocate %s bytes.\n",
+ ullongToCommaString (require64));
require = (W32)require64;
arraySize = (W32)arraySize64;
if (DEBUG)
@@ -2589,7 +2608,7 @@
maxMem = 0x100000000llu - s->pageSize;
unless (0 == sysinfo((struct sysinfo*)&sbuf))
- diee("sysinfo failed");
+ diee ("sysinfo failed");
memUnit = sbuf.mem_unit;
/* On 2.2 kernels, mem_unit is not defined, but will be zero, so go
* ahead and pretend it is one.
@@ -2624,7 +2643,7 @@
file = popen("/usr/sbin/swapinfo -k | awk '{ print $4; }'\n", "r");
if (file == NULL)
- diee("swapinfo failed");
+ diee ("swapinfo failed");
/* skip header */
fgets(buffer, 255, file);
@@ -2648,7 +2667,7 @@
file = popen("/sbin/sysctl hw.physmem | awk '{ print $2; }'\n", "r");
if (file == NULL)
- diee("sysctl failed");
+ diee ("sysctl failed");
fgets(buffer, 255, file);
@@ -2665,8 +2684,8 @@
#endif /* definition of setMemInfo */
-static void usage(string s) {
- die("Usage: %s [@MLton [fixed-heap n[{k|m}]] [gc-messages] [gc-summary] [load-world file] [ram-slop x] --] args",
+static void usage (string s) {
+ die ("Usage: %s [@MLton [fixed-heap n[{k|m}]] [gc-messages] [gc-summary] [load-world file] [ram-slop x] --] args",
s);
}
@@ -2865,7 +2884,9 @@
for (i = 0; i < s->numGlobals; ++i)
s->globals[i] = (pointer)BOGUS_POINTER;
setInitialBytesLive (s);
- heapCreate (s, &s->heap, s->bytesLive, s->bytesLive);
+ heapCreate (s, &s->heap,
+ heapDesiredSize (s, s->bytesLive, 0),
+ s->bytesLive);
s->frontier = s->heap.oldGen;
initIntInfs (s);
initStrings (s);
@@ -2892,12 +2913,14 @@
if (EOF == c) die ("Invalid world.");
magic = sfreadUint (file);
unless (s->magic == magic)
- die("Invalid world: wrong magic number.");
+ die ("Invalid world: wrong magic number.");
oldGen = (pointer) sfreadUint (file);
s->heap.oldGenSize = sfreadUint (file);
s->currentThread = (GC_thread) sfreadUint (file);
s->signalHandler = (GC_thread) sfreadUint (file);
- heapCreate (s, &s->heap, s->heap.oldGenSize, s->heap.oldGenSize);
+ heapCreate (s, &s->heap,
+ heapDesiredSize (s, s->heap.oldGenSize, 0),
+ s->heap.oldGenSize);
setNursery (s);
heapInit (s, &s->heap2);
sfread (s->heap.oldGen, 1, s->heap.oldGenSize, file);
@@ -2916,22 +2939,20 @@
char *worldFile;
int i;
- s->pageSize = getpagesize ();
- initSignalStack (s);
s->bytesAllocated = 0;
s->bytesCopied = 0;
s->bytesCopiedMinor = 0;
s->bytesMarkCompacted = 0;
s->canHandle = 0;
s->cardSize = 0x1 << s->cardSizeLog2;
+ s->copyRatio = 2.0;
s->currentThread = BOGUS_THREAD;
- rusageZero (&s->ru_gc);
+ s->generationalRatio = 5.0;
+ s->growRatio = 1.5;
s->inSignalHandler = FALSE;
s->isOriginal = TRUE;
- s->liveRatioCopy = 3.0;
- s->liveRatioDesired = 8.0;
- s->liveRatioGenerational = 5.0;
- s->liveRatioMarkCompact = 1.5;
+ s->liveRatio = 8.0;
+ s->markCompactRatio = 1.5;
s->markedCards = 0;
s->maxBytesLive = 0;
s->maxHeap = 0;
@@ -2947,14 +2968,17 @@
s->numMinorGCs = 0;
s->numMinorsSinceLastMajor = 0;
s->nurseryRatio = 10.0;
+ s->pageSize = getpagesize ();
s->ramSlop = 0.80;
s->savedThread = BOGUS_THREAD;
s->signalHandler = BOGUS_THREAD;
- sigemptyset (&s->signalsHandled);
s->signalIsPending = FALSE;
- sigemptyset (&s->signalsPending);
s->startTime = currentTime ();
s->summary = FALSE;
+ sigemptyset (&s->signalsHandled);
+ initSignalStack (s);
+ sigemptyset (&s->signalsPending);
+ rusageZero (&s->ru_gc);
readProcessor ();
worldFile = NULL;
i = 1;
@@ -2975,7 +2999,7 @@
++i;
if (i == argc)
usage (argv[0]);
- s->liveRatioCopy =
+ s->copyRatio =
stringToFloat (argv[i++]);
} else if (0 == strcmp(arg, "fixed-heap")) {
++i;
@@ -2990,11 +3014,17 @@
} else if (0 == strcmp (arg, "gc-summary")) {
++i;
s->summary = TRUE;
+ } else if (0 == strcmp (arg, "grow-ratio")) {
+ ++i;
+ if (i == argc)
+ usage (argv[0]);
+ s->growRatio =
+ stringToFloat (argv[i++]);
} else if (0 == strcmp (arg, "live-ratio")) {
++i;
if (i == argc)
usage (argv[0]);
- s->liveRatioDesired =
+ s->liveRatio =
stringToFloat (argv[i++]);
} else if (0 == strcmp (arg, "load-world")) {
++i;
@@ -3012,7 +3042,7 @@
++i;
if (i == argc)
usage (argv[0]);
- s->liveRatioMarkCompact =
+ s->markCompactRatio =
stringToFloat (argv[i++]);
} else if (0 == strcmp (arg, "nursery-ratio")) {
++i;
@@ -3035,8 +3065,8 @@
}
}
}
- unless (liveRatiosOk (s))
- die ("invalid live ratios");
+ unless (ratiosOk (s))
+ die ("invalid ratios");
setMemInfo (s);
s->ram = s->ramSlop * s->totalRam;
if (DEBUG or DEBUG_RESIZING)
@@ -3075,16 +3105,16 @@
(0.0 == time) ? 0.0
: 100.0 * ((double) gcTime) / time);
displayUint ("maxPause(ms)", s->maxPause);
- displayUint ("number of minor GCs", s->numMinorGCs);
- displayUint ("number of copying GCs", s->numCopyingGCs);
- displayUint ("number of mark compact GCs", s->numMarkCompactGCs);
displayUllong ("bytes allocated",
s->bytesAllocated
+ (s->frontier - s->heap.nursery));
- displayUllong ("bytes copied (minor)", s->bytesCopiedMinor);
- displayUllong ("bytes copied (major)", s->bytesCopied);
- displayUllong ("bytes mark-compacted", s->bytesMarkCompacted);
displayUint ("max bytes live", s->maxBytesLive);
+ displayUint ("number of copying GCs", s->numCopyingGCs);
+ displayUllong ("bytes copied", s->bytesCopied);
+ displayUint ("number of mark compact GCs", s->numMarkCompactGCs);
+ displayUllong ("bytes mark-compacted", s->bytesMarkCompacted);
+ displayUint ("number of minor GCs", s->numMinorGCs);
+ displayUllong ("bytes copied (minor)", s->bytesCopiedMinor);
displayUllong ("marked cards", s->markedCards);
displayUllong ("minor bytes scanned", s->minorBytesScanned);
displayUllong ("minor bytes skipped", s->minorBytesSkipped);
1.38 +10 -10 mlton/runtime/gc.h
Index: gc.h
===================================================================
RCS file: /cvsroot/mlton/mlton/runtime/gc.h,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- gc.h 17 Aug 2002 02:08:55 -0000 1.37
+++ gc.h 18 Aug 2002 07:17:23 -0000 1.38
@@ -254,14 +254,18 @@
ullong bytesMarkCompacted;
uint cardSize;
uint cardSizeLog2;
+ float copyRatio; /* Minimum live ratio to use copying GC. */
GC_heap crossMapHeap; /* only used during GC. */
GC_thread currentThread; /* This points to a thread in the heap. */
uint fixedHeapSize; /* Only meaningful if useFixedHeap. */
GC_frameLayout *frameLayouts;
- bool generational; /* Whether or not to use generational gc. */
+ /* Only use generational GC if the live ratio is below generationalRatio.
+ */
+ float generationalRatio;
pointer *globals; /* An array of size numGlobals. */
+ float growRatio;
struct GC_heap heap;
- struct GC_heap heap2;
+ struct GC_heap heap2; /* Used for major copying collection. */
bool inSignalHandler; /* TRUE iff a signal handler is running. */
/* canHandle == 0 iff GC may switch to the signal handler
* thread. This is used to implement critical sections.
@@ -270,17 +274,12 @@
volatile int canHandle;
bool isOriginal;
pointer limitPlusSlop; /* limit + LIMIT_SLOP */
- float liveRatioCopy; /* Minimum live ratio to use copying GC. */
- float liveRatioDesired; /* Desired ratio of heap size to live data. */
- /* Only use generational GC if the live ratio is below
- * liveRatioGenerational.
- */
- float liveRatioGenerational;
- /* Minimum live ratio to us mark-compact GC. */
- float liveRatioMarkCompact;
+ float liveRatio; /* Desired ratio of heap size to live data. */
/* loadGlobals loads the globals from the stream. */
void (*loadGlobals)(FILE *file);
uint magic; /* The magic number required for a valid world file. */
+ /* Minimum live ratio to us mark-compact GC. */
+ float markCompactRatio;
ullong markedCards; /* Number of marked cards seen during minor GCs. */
uint maxBytesLive;
uint maxFrameIndex; /* 0 <= frameIndex < maxFrameIndex */
@@ -293,6 +292,7 @@
bool messages; /* Print out a message at the start and end of each gc. */
ullong minorBytesScanned;
ullong minorBytesSkipped;
+ bool mutatorMarksCards;
/* native is true iff the native codegen was used.
* The GC needs to know this because it affects how it finds the
* layout of stack frames.
-------------------------------------------------------
This sf.net email is sponsored by: OSDN - Tired of that same old
cell phone? Get a new here for FREE!
https://www.inphonic.com/r.asp?r=sourceforge1&refcode1=vs3390
_______________________________________________
MLton-devel mailing list
MLton-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mlton-devel