[MLton-commit] r4114
Matthew Fluet
MLton@mlton.org
Tue, 18 Oct 2005 18:28:42 -0700
GC_gc functionality
----------------------------------------------------------------------
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/atomic.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/debug.c
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_prefix.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/profile.h
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.c
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/signals.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/statistics.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.h
----------------------------------------------------------------------
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile 2005-10-19 01:28:35 UTC (rev 4114)
@@ -107,6 +107,7 @@
dfs-mark.c \
share.c \
mark-compact.c \
+ garbage-collection.c \
assumptions.c \
gc_suffix.c
@@ -131,8 +132,9 @@
sysvals.h \
ratios.h \
hash-cons.h \
+ profiling.h \
+ signals.h \
gc_state.h \
- profile.h \
gc_suffix.h
all: gc.o gc-gdb.o
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/atomic.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/atomic.c 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/atomic.c 2005-10-19 01:28:35 UTC (rev 4114)
@@ -14,6 +14,7 @@
static inline void atomicEnd (GC_state s) {
s->atomicState--;
- if (0 == s->atomicState and s->signalIsPending)
+ if (0 == s->atomicState
+ and s->signalsInfo.signalIsPending)
s->limit = 0;
}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c 2005-10-19 01:28:35 UTC (rev 4114)
@@ -18,6 +18,7 @@
* It also updates the crossMap.
*/
struct forwardState {
+ bool amInMinorGC;
pointer back;
pointer toStart;
pointer toLimit;
@@ -127,7 +128,7 @@
fprintf (stderr, "forwarding weak "FMTPTR" ",
(uintptr_t)w);
if (isObjptr (w->objptr)
- and (not s->amInMinorGC
+ and (not forwardState.amInMinorGC
or objptrIsInNursery (s, w->objptr))) {
if (DEBUG_WEAK)
fprintf (stderr, "linking\n");
@@ -193,6 +194,7 @@
if (detailedGCTime (s))
startTiming (&ru_start);
s->cumulativeStatistics.numCopyingGCs++;
+ forwardState.amInMinorGC = FALSE;
forwardState.toStart = s->secondaryHeap.start;
forwardState.toLimit = s->secondaryHeap.start + s->secondaryHeap.size;
if (DEBUG or s->controls.messages) {
@@ -360,7 +362,7 @@
fprintf (stderr, "Minor copying GC.\n");
if (detailedGCTime (s))
startTiming (&ru_start);
- s->amInMinorGC = TRUE;
+ forwardState.amInMinorGC = TRUE;
forwardState.toStart = s->heap.start + s->heap.oldGenSize;
if (DEBUG_GENERATIONAL)
fprintf (stderr, "toStart = "FMTPTR"\n", (uintptr_t)forwardState.toStart);
@@ -381,7 +383,6 @@
bytesCopied = forwardState.back - forwardState.toStart;
s->cumulativeStatistics.bytesCopiedMinor += bytesCopied;
s->heap.oldGenSize += bytesCopied;
- s->amInMinorGC = FALSE;
if (detailedGCTime (s))
stopTiming (&ru_start, &s->cumulativeStatistics.ru_gcMinor);
if (DEBUG_GENERATIONAL or s->controls.messages)
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/debug.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/debug.c 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/debug.c 2005-10-19 01:28:35 UTC (rev 4114)
@@ -22,6 +22,7 @@
DEBUG_PROFILE = FALSE,
DEBUG_RESIZING = FALSE,
DEBUG_SHARE = FALSE,
+ DEBUG_SIGNALS = FALSE,
DEBUG_SIZE = FALSE,
DEBUG_STACKS = FALSE,
DEBUG_THREADS = FALSE,
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c (from rev 4113, mlton/branches/on-20050822-x86_64-branch/runtime/gc.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc.c 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c 2005-10-19 01:28:35 UTC (rev 4114)
@@ -0,0 +1,284 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ * Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+static void minorGC (GC_state s) {
+ minorCheneyCopyGC (s);
+}
+
+static void majorGC (GC_state s, size_t bytesRequested, bool mayResize) {
+ uintmax_t numGCs;
+ size_t desiredSize;
+
+ s->cumulativeStatistics.numMinorGCs = 0;
+ numGCs =
+ s->cumulativeStatistics.numCopyingGCs
+ + s->cumulativeStatistics.numMarkCompactGCs;
+ if (0 < numGCs
+ and ((float)(s->cumulativeStatistics.numHashConsGCs) / (float)(numGCs)
+ < s->ratios.hashCons))
+ s->hashConsDuringGC = TRUE;
+ desiredSize =
+ heapDesiredSize (s, s->lastMajorStatistics.bytesLive + bytesRequested, 0);
+ if ((not FORCE_MARK_COMPACT)
+ and not s->hashConsDuringGC // only markCompact can hash cons
+ and s->heap.size < s->sysvals.ram
+ and (not heapIsInit (&s->secondaryHeap)
+ or secondaryHeapCreate (s, desiredSize)))
+ majorCheneyCopyGC (s);
+ else
+ majorMarkCompactGC (s);
+ s->hashConsDuringGC = FALSE;
+ s->lastMajorStatistics.bytesLive = s->heap.oldGenSize;
+ if (s->lastMajorStatistics.bytesLive > s->cumulativeStatistics.maxBytesLive)
+ s->cumulativeStatistics.maxBytesLive = s->lastMajorStatistics.bytesLive;
+ /* Notice that the s->bytesLive below is different than the s->bytesLive
+ * used as an argument to heapAllocateSecondSemi above. Above, it was
+ * an estimate. Here, it is exactly how much was live after the GC.
+ */
+ if (mayResize)
+ heapResize (s, s->lastMajorStatistics.bytesLive + bytesRequested);
+ secondaryHeapResize (s);
+ assert (s->heap.oldGenSize + bytesRequested <= s->heap.size);
+}
+
+static inline void enterGC (GC_state s) {
+ if (s->profilingInfo.isOn) {
+ /* We don't need to profileEnter for count profiling because it
+ * has already bumped the counter. If we did allow the bump, then
+ * the count would look like function(s) had run an extra time.
+ */
+ if (s->profilingInfo.stack
+ and not (PROFILE_COUNT == s->profilingInfo.kind))
+ GC_profileEnter (s);
+ }
+ s->amInGC = TRUE;
+}
+
+static inline void leaveGC (GC_state s) {
+ if (s->profilingInfo.isOn) {
+ if (s->profilingInfo.stack
+ and not (PROFILE_COUNT == s->profilingInfo.kind))
+ GC_profileLeave (s);
+ }
+ s->amInGC = FALSE;
+}
+
+static inline bool needGCTime (GC_state s) {
+ return
+ DEBUG
+ or s->controls.summary
+ or s->controls.messages
+ or s->rusageIsEnabled;
+}
+
+static void doGC (GC_state s,
+ size_t oldGenBytesRequested,
+ size_t nurseryBytesRequested,
+ bool forceMajor,
+ bool mayResize) {
+ uintmax_t gcTime;
+ bool stackTopOk;
+ size_t stackBytesRequested;
+ struct rusage ru_start;
+ size_t totalBytesRequested;
+
+ enterGC (s);
+ if (DEBUG or s->controls.messages)
+ fprintf (stderr, "Starting gc. Request %zu nursery bytes and %zu old gen bytes.\n",
+ /*uintToCommaString*/(nurseryBytesRequested),
+ /*uintToCommaString*/(oldGenBytesRequested));
+ assert (invariant (s));
+ if (needGCTime (s))
+ startTiming (&ru_start);
+ minorGC (s);
+ stackTopOk = mutatorStackInvariant (s);
+ stackBytesRequested =
+ stackTopOk ? 0 : stackSizeTotalAligned (s, stackGrowSize (s));
+ totalBytesRequested =
+ oldGenBytesRequested
+ + nurseryBytesRequested
+ + stackBytesRequested;
+ if (forceMajor
+ or totalBytesRequested > s->heap.size - s->heap.oldGenSize)
+ majorGC (s, totalBytesRequested, mayResize);
+ heapSetNursery (s, oldGenBytesRequested + stackBytesRequested,
+ nurseryBytesRequested);
+ assert (heapHasBytesFree (s, oldGenBytesRequested + stackBytesRequested,
+ nurseryBytesRequested));
+ unless (stackTopOk)
+ stackGrow (s);
+ setCurrentStack (s);
+ if (needGCTime (s)) {
+ gcTime = stopTiming (&ru_start, &s->cumulativeStatistics.ru_gc);
+ s->cumulativeStatistics.maxPause =
+ max (s->cumulativeStatistics.maxPause, gcTime);
+ } else
+ gcTime = 0; /* Assign gcTime to quell gcc warning. */
+ if (DEBUG or s->controls.messages) {
+ fprintf (stderr, "Finished gc.\n");
+ fprintf (stderr, "time: %"PRIuMAX" ms\n", /*intToCommaString*/(gcTime));
+ fprintf (stderr, "old gen size: %zu bytes (%.1f%%)\n",
+ /*intToCommaString*/(s->heap.oldGenSize),
+ 100.0 * ((double)(s->heap.oldGenSize)
+ / (double)(s->heap.size)));
+ }
+ /* Send a GC signal. */
+ if (s->signalsInfo.gcSignalHandled
+ and s->signalHandlerThread != BOGUS_OBJPTR) {
+ if (DEBUG_SIGNALS)
+ fprintf (stderr, "GC Signal pending.\n");
+ s->signalsInfo.gcSignalPending = TRUE;
+ unless (s->signalsInfo.amInSignalHandler)
+ s->signalsInfo.signalIsPending = TRUE;
+ }
+ if (DEBUG)
+ displayGCState (s, stderr);
+ assert (heapHasBytesFree (s, oldGenBytesRequested, nurseryBytesRequested));
+ assert (invariant (s));
+ leaveGC (s);
+}
+
+static inline void ensureMutatorInvariant (GC_state s, bool force) {
+ if (force
+ or not (mutatorFrontierInvariant(s))
+ or not (mutatorStackInvariant(s))) {
+ /* This GC will grow the stack, if necessary. */
+ doGC (s, 0, currentThread(s)->bytesNeeded, force, TRUE);
+ }
+ assert (mutatorFrontierInvariant(s));
+ assert (mutatorStackInvariant(s));
+}
+
+/* ensureFree (s, b) ensures that upon return
+ * b <= s->limitPlusSlop - s->frontier
+ */
+static inline void ensureFree (GC_state s, size_t bytesRequested) {
+ assert (s->frontier <= s->limitPlusSlop);
+ if (bytesRequested > (size_t)(s->limitPlusSlop - s->frontier))
+ doGC (s, 0, bytesRequested, FALSE, TRUE);
+ assert (bytesRequested <= (size_t)(s->limitPlusSlop - s->frontier));
+}
+
+static void switchToThread (GC_state s, objptr op) {
+ if (DEBUG_THREADS) {
+ GC_thread thread;
+ GC_stack stack;
+
+ thread = (GC_thread)(objptrToPointer (op, s->heap.start));
+ stack = (GC_stack)(objptrToPointer (thread->stack, s->heap.start));
+
+ fprintf (stderr, "switchToThread ("FMTOBJPTR") used = %zu reserved = %zu\n",
+ op, stack->used, stack->reserved);
+ }
+ s->currentThread = op;
+ setCurrentStack (s);
+}
+
+/* GC_startHandler does not do an enter()/leave(), even though it is
+ * exported. The basis library uses it via _import, not _prim, and so
+ * does not treat it as a runtime call -- so the invariant in enter
+ * would fail miserably. It is OK because GC_startHandler must be
+ * called from within a critical section.
+ *
+ * Don't make it inline, because it is also called in basis/Thread.c,
+ * and when compiling with COMPILE_FAST, they may appear out of order.
+ */
+void GC_startHandler (GC_state s) {
+ /* Switch to the signal handler thread. */
+ if (DEBUG_SIGNALS) {
+ fprintf (stderr, "GC_startHandler\n");
+ }
+ assert (s->atomicState == 1);
+ assert (s->signalsInfo.signalIsPending);
+ s->signalsInfo.signalIsPending = FALSE;
+ s->signalsInfo.amInSignalHandler = TRUE;
+ s->savedThread = s->currentThread;
+ /* Set s->atomicState to 2 when switching to the signal handler
+ * thread; leaving the runtime will decrement s->atomicState to 1,
+ * the signal handler will then run atomically and will finish by
+ * switching to the thread to continue with, which will decrement
+ * s->atomicState to 0.
+ */
+ s->atomicState = 2;
+}
+
+void GC_finishHandler (GC_state s) {
+ if (DEBUG_SIGNALS)
+ fprintf (stderr, "GC_finishHandler ()\n");
+ assert (s->atomicState == 1);
+ s->signalsInfo.amInSignalHandler = FALSE;
+}
+
+static inline void maybeSwitchToHandler (GC_state s) {
+ if (s->atomicState == 1
+ and s->signalsInfo.signalIsPending) {
+ GC_startHandler (s);
+ switchToThread (s, s->signalHandlerThread);
+ }
+}
+
+/* void GC_switchToThread (GC_state s, GC_thread t, uint ensureBytesFree) { */
+/* if (DEBUG_THREADS) */
+/* fprintf (stderr, "GC_switchToThread (0x%08x, %u)\n", (uint)t, ensureBytesFree); */
+/* if (FALSE) { */
+/* /\* This branch is slower than the else branch, especially */
+/* * when debugging is turned on, because it does an invariant */
+/* * check on every thread switch. */
+/* * So, we'll stick with the else branch for now. */
+/* *\/ */
+/* enter (s); */
+/* s->currentThread->bytesNeeded = ensureBytesFree; */
+/* switchToThread (s, t); */
+/* s->canHandle--; */
+/* maybeSwitchToHandler (s); */
+/* ensureMutatorInvariant (s, FALSE); */
+/* assert (mutatorFrontierInvariant(s)); */
+/* assert (mutatorStackInvariant(s)); */
+/* leave (s); */
+/* } else { */
+/* /\* BEGIN: enter(s); *\/ */
+/* s->currentThread->stack->used = currentStackUsed (s); */
+/* s->currentThread->exnStack = s->exnStack; */
+/* atomicBegin (s); */
+/* /\* END: enter(s); *\/ */
+/* s->currentThread->bytesNeeded = ensureBytesFree; */
+/* switchToThread (s, t); */
+/* s->canHandle--; */
+/* maybeSwitchToHandler (s); */
+/* /\* BEGIN: ensureMutatorInvariant *\/ */
+/* if (not (mutatorFrontierInvariant(s)) */
+/* or not (mutatorStackInvariant(s))) { */
+/* /\* This GC will grow the stack, if necessary. *\/ */
+/* doGC (s, 0, s->currentThread->bytesNeeded, FALSE, TRUE); */
+/* } */
+/* /\* END: ensureMutatorInvariant *\/ */
+/* /\* BEGIN: leave(s); *\/ */
+/* atomicEnd (s); */
+/* /\* END: leave(s); *\/ */
+/* } */
+/* assert (mutatorFrontierInvariant(s)); */
+/* assert (mutatorStackInvariant(s)); */
+/* } */
+
+void GC_gc (GC_state s, size_t bytesRequested, bool force,
+ char *file, int line) {
+ if (DEBUG or s->controls.messages)
+ fprintf (stderr, "%s %d: GC_gc\n", file, line);
+ enter (s);
+ /* When the mutator requests zero bytes, it may actually need as
+ * much as LIMIT_SLOP.
+ */
+ if (0 == bytesRequested)
+ bytesRequested = LIMIT_SLOP;
+ currentThread(s)->bytesNeeded = bytesRequested;
+ maybeSwitchToHandler (s);
+ ensureMutatorInvariant (s, force);
+ assert (mutatorFrontierInvariant(s));
+ assert (mutatorStackInvariant(s));
+ leave (s);
+}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_prefix.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_prefix.h 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_prefix.h 2005-10-19 01:28:35 UTC (rev 4114)
@@ -1,2 +1,5 @@
#ifndef _MLTON_GC_H_
#define _MLTON_GC_H_
+
+struct GC_state;
+typedef struct GC_state *GC_state;
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h 2005-10-19 01:28:35 UTC (rev 4114)
@@ -1,8 +1,14 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ * Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
-typedef struct GC_state {
+struct GC_state {
size_t alignment; /* */
bool amInGC;
- bool amInMinorGC;
uint32_t atomicState;
objptr callFromCHandlerThread; /* Handler for exported C calls (in heap). */
bool canMinor; /* TRUE iff there is space for a minor gc. */
@@ -26,17 +32,19 @@
GC_objectHashTable objectHashTable;
GC_objectType *objectTypes; /* Array of object types. */
uint32_t objectTypesLength; /* Cardinality of objectTypes array. */
+ struct GC_profilingInfo profilingInfo;
uint32_t (*returnAddressToFrameIndex) (GC_returnAddress ra);
struct GC_ratios ratios;
+ bool rusageIsEnabled;
objptr savedThread; /* Result of GC_copyCurrentThread.
* Thread interrupted by arrival of signal.
*/
struct GC_heap secondaryHeap; /* Used for major copying collection. */
objptr signalHandlerThread; /* Handler for signals (in heap). */
- /*Bool*/bool signalIsPending;
+ struct GC_signalsInfo signalsInfo;
pointer stackBottom; /* Bottom of stack in current thread. */
pointer stackLimit; /* stackBottom + stackSize - maxFrameSize */
pointer stackTop; /* Top of stack in current thread. */
struct GC_sysvals sysvals;
GC_weak weaks; /* Linked list of (live) weak pointers */
-} *GC_state;
+};
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c 2005-10-19 01:28:35 UTC (rev 4114)
@@ -127,6 +127,17 @@
return FALSE;
}
+/* secondaryHeapCreate (s, desiredSize)
+ */
+static bool secondaryHeapCreate (GC_state s, size_t desiredSize) {
+ if ((s->controls.fixedHeap > 0
+ and s->heap.size + desiredSize > s->controls.fixedHeap)
+ or (s->controls.maxHeap > 0
+ and s->heap.size + desiredSize > s->controls.maxHeap))
+ return FALSE;
+ return heapCreate (s, &s->secondaryHeap, desiredSize, s->heap.oldGenSize);
+}
+
/* heapRemap (s, h, desiredSize, minSize)
*/
static bool heapRemap (GC_state s, GC_heap h,
@@ -346,7 +357,7 @@
size_t nurserySize;
if (DEBUG_DETAILED)
- fprintf (stderr, "setNursery(%zu, %zu)\n",
+ fprintf (stderr, "heapSetNursery(%zu, %zu)\n",
/*uintToCommaString*/(oldGenBytesRequested),
/*uintToCommaString*/(nurseryBytesRequested));
h = &s->heap;
@@ -449,14 +460,3 @@
assert (0 == s->secondaryHeap.size
or s->heap.size == s->secondaryHeap.size);
}
-
-/* secondaryHeapCreate (s, desiredSize)
- */
-static bool secondaryHeapCreate (GC_state s, size_t desiredSize) {
- if ((s->controls.fixedHeap > 0
- and s->heap.size + desiredSize > s->controls.fixedHeap)
- or (s->controls.maxHeap > 0
- and s->heap.size + desiredSize > s->controls.maxHeap))
- return FALSE;
- return heapCreate (s, &s->secondaryHeap, desiredSize, s->heap.oldGenSize);
-}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c 2005-10-19 01:28:35 UTC (rev 4114)
@@ -81,6 +81,8 @@
return TRUE;
}
+#endif /* #if ASSERT */
+
static bool mutatorFrontierInvariant (GC_state s) {
GC_thread ct = currentThread(s);
return (ct->bytesNeeded <= (size_t)(s->limitPlusSlop - s->frontier));
@@ -101,5 +103,3 @@
assert (invariant (s));
return TRUE;
}
-
-#endif /* #if ASSERT */
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/profile.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/profile.h 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/profile.h 2005-10-19 01:28:35 UTC (rev 4114)
@@ -6,18 +6,66 @@
* See the file MLton-LICENSE for details.
*/
-void GC_profileAllocInc (GC_state s, size_t bytes);
+typedef enum {
+ PROFILE_ALLOC,
+ PROFILE_COUNT,
+ PROFILE_NONE,
+ PROFILE_TIME,
+} GC_profileKind;
-void GC_profileDone (GC_state s);
+typedef struct GC_source {
+ uint32_t nameIndex;
+ uint32_t successorsIndex;
+} *GC_source;
-void GC_profileEnter (GC_state s);
+typedef struct GC_sourceLabel {
+ pointer label;
+ uint32_t sourceSeqsIndex;
+} *GC_sourceLabel;
-// void GC_profileFree (GC_state s, GC_profile p);
-void GC_profileInc (GC_state s, size_t bytes);
+/* If profileStack, then there is one struct GC_profileStack for each
+ * function.
+ */
+typedef struct GC_profileStack {
+ /* ticks counts ticks while the function was on the stack. */
+ uintmax_t ticks;
+ /* ticksInGC counts ticks in GC while the function was on the stack. */
+ uintmax_t ticksInGC;
+ /* lastTotal is the value of total when the oldest occurrence of f
+ * on the stack was pushed, i.e., the most recent time that
+ * numTimesOnStack changed from 0 to 1. lastTotal is used to
+ * compute the amount to attribute to f when the oldest occurrence
+ * is finally popped.
+ */
+ uintmax_t lastTotal;
+ /* lastTotalGC is like lastTotal, but for GC ticks. */
+ uintmax_t lastTotalGC;
+ /* numOccurrences is the number of times this function is on the
+ * stack.
+ */
+ uintmax_t numOccurrences;
+} *GC_profileStack;
-void GC_profileLeave (GC_state s);
-
-// GC_profile GC_profileNew (GC_state s);
-
-// void GC_profileWrite (GC_state s, GC_profile p, int fd);
+/* GC_profile is used for both time and allocation profiling.
+ * In the comments below, "ticks" mean clock ticks with time profiling and
+ * bytes allocated with allocation profiling.
+ *
+ * All of the arrays in GC_profile are of length sourcesSize + sourceNamesSize.
+ * The first sourceSizes entries are for handling the duplicate copies of
+ * functions, and the next sourceNamesSize entries are for the master versions.
+ */
+typedef struct GC_profile {
+ /* countTop is an array that counts for each function the number of
+ * ticks that occurred while the function was on top of the stack.
+ */
+ uintmax_t *countTop;
+ /* stack is an array that gives stack info for each function. It is
+ * only used if profileStack.
+ */
+ struct GC_profileStack *stack;
+ /* The total number of mutator ticks. */
+ uintmax_t total;
+ /* The total number of GC ticks. */
+ uintmax_t totalGC;
+} *GC_profile;
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h (from rev 4113, mlton/branches/on-20050822-x86_64-branch/runtime/gc/profile.h)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/profile.h 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h 2005-10-19 01:28:35 UTC (rev 4114)
@@ -0,0 +1,95 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ * Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+typedef enum {
+ PROFILE_ALLOC,
+ PROFILE_COUNT,
+ PROFILE_NONE,
+ PROFILE_TIME,
+} GC_profileKind;
+
+typedef struct GC_source {
+ uint32_t nameIndex;
+ uint32_t successorsIndex;
+} *GC_source;
+
+typedef struct GC_sourceLabel {
+ pointer label;
+ uint32_t sourceSeqsIndex;
+} *GC_sourceLabel;
+
+
+/* If profileStack, then there is one struct GC_profileStack for each
+ * function.
+ */
+typedef struct GC_profileStack {
+ /* ticks counts ticks while the function was on the stack. */
+ uintmax_t ticks;
+ /* ticksInGC counts ticks in GC while the function was on the stack. */
+ uintmax_t ticksInGC;
+ /* lastTotal is the value of total when the oldest occurrence of f
+ * on the stack was pushed, i.e., the most recent time that
+ * numTimesOnStack changed from 0 to 1. lastTotal is used to
+ * compute the amount to attribute to f when the oldest occurrence
+ * is finally popped.
+ */
+ uintmax_t lastTotal;
+ /* lastTotalGC is like lastTotal, but for GC ticks. */
+ uintmax_t lastTotalGC;
+ /* numOccurrences is the number of times this function is on the
+ * stack.
+ */
+ uintmax_t numOccurrences;
+} *GC_profileStack;
+
+/* GC_profile is used for both time and allocation profiling.
+ * In the comments below, "ticks" mean clock ticks with time profiling and
+ * bytes allocated with allocation profiling.
+ *
+ * All of the arrays in GC_profile are of length sourcesSize + sourceNamesSize.
+ * The first sourceSizes entries are for handling the duplicate copies of
+ * functions, and the next sourceNamesSize entries are for the master versions.
+ */
+typedef struct GC_profile {
+ /* countTop is an array that counts for each function the number of
+ * ticks that occurred while the function was on top of the stack.
+ */
+ uintmax_t *countTop;
+ /* stack is an array that gives stack info for each function. It is
+ * only used if profileStack.
+ */
+ struct GC_profileStack *stack;
+ /* The total number of mutator ticks. */
+ uintmax_t total;
+ /* The total number of GC ticks. */
+ uintmax_t totalGC;
+} *GC_profile;
+
+struct GC_profilingInfo {
+ bool isOn;
+ GC_profile profile;
+ GC_profileKind kind;
+ bool stack;
+};
+
+
+void GC_profileAllocInc (GC_state s, size_t bytes);
+
+void GC_profileDone (GC_state s);
+
+void GC_profileEnter (GC_state s);
+
+void GC_profileFree (GC_state s, GC_profile p);
+
+void GC_profileInc (GC_state s, size_t bytes);
+
+void GC_profileLeave (GC_state s);
+
+GC_profile GC_profileNew (GC_state s);
+
+void GC_profileWrite (GC_state s, GC_profile p, int fd);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h 2005-10-19 01:28:35 UTC (rev 4114)
@@ -14,6 +14,7 @@
/* Minimum live ratio to use copying GC. */
float copy;
float grow;
+ float hashCons;
/* Desired ratio of heap size to live data. */
float live;
/* Minimum live ratio to us mark-compact GC. */
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.c 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.c 2005-10-19 01:28:35 UTC (rev 4114)
@@ -77,7 +77,7 @@
getrusage (RUSAGE_SELF, ru_start);
}
-static uint stopTiming (struct rusage *ru_start, struct rusage *ru_gc) {
+static uintmax_t stopTiming (struct rusage *ru_start, struct rusage *ru_gc) {
struct rusage ru_finish, ru_total;
getrusage (RUSAGE_SELF, &ru_finish);
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/signals.h (from rev 4113, mlton/branches/on-20050822-x86_64-branch/runtime/gc.h)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc.h 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/signals.h 2005-10-19 01:28:35 UTC (rev 4114)
@@ -0,0 +1,24 @@
+/* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+ * Jagannathan, and Stephen Weeks.
+ * Copyright (C) 1997-2000 NEC Research Institute.
+ *
+ * MLton is released under a BSD-style license.
+ * See the file MLton-LICENSE for details.
+ */
+
+struct GC_signalsInfo {
+ bool amInSignalHandler; /* TRUE iff a signal handler is running. */
+ bool gcSignalHandled;
+ bool gcSignalPending;
+ volatile bool signalIsPending; /* TRUE iff a signal has been received
+ * but not handled by the mutator.
+ */
+ /* signalsHandled is the set of signals for which a mutator signal
+ * handler needs to run in order to handle the signal.
+ */
+ sigset_t signalsHandled;
+ /* The signals that have been recieved but not processed by the mutator
+ * signal handler.
+ */
+ sigset_t signalsPending;
+};
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/statistics.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/statistics.h 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/statistics.h 2005-10-19 01:28:35 UTC (rev 4114)
@@ -29,6 +29,7 @@
uintmax_t numMarkCompactGCs;
uintmax_t numMinorGCs;
+ uintmax_t maxPause;
struct rusage ru_gc; /* total resource usage spent in gc */
struct rusage ru_gcCopy; /* resource usage in major copying gcs. */
struct rusage ru_gcMarkCompact; /* resource usage in mark-compact gcs. */
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.h 2005-10-18 17:12:55 UTC (rev 4113)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.h 2005-10-19 01:28:35 UTC (rev 4114)
@@ -21,5 +21,3 @@
*/
objptr stack; /* The stack for this thread. */
} *GC_thread;
-
-#define BOGUS_THREAD (GC_thread)BOGUS_POINTER