diff --git a/mps/code/config.h b/mps/code/config.h
index c5dd1405c69..c25b6c443c0 100644
--- a/mps/code/config.h
+++ b/mps/code/config.h
@@ -209,6 +209,10 @@
#define TraceLIMIT ((size_t)1)
/* I count 4 function calls to scan, 10 to copy. */
#define TraceCopyScanRATIO (1.5)
+/* Length (in chars) of a char buffer used to store the reason why a
+ collection started in the TraceStartMessageStruct (used by
+ mps_message_type_gc_start). */
+#define TRACE_START_MESSAGE_WHY_LEN 64
@@ -316,7 +320,7 @@
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2002 Ravenbrook Limited .
+ * Copyright (C) 2001-2003 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/global.c b/mps/code/global.c
index db4a9f2fd0d..2c5a456b894 100644
--- a/mps/code/global.c
+++ b/mps/code/global.c
@@ -628,8 +628,9 @@ Bool ArenaStep(Globals globals, double interval, double multiplier)
stepped = FALSE;
if (arenaShouldCollectWorld(arena, interval, multiplier,
- start, clocks_per_sec)) {
- ArenaStartCollect(globals);
+ start, clocks_per_sec))
+ {
+ ArenaStartCollect(globals, TraceStartWhyOPPORTUNISM);
arena->lastWorldCollect = start;
stepped = TRUE;
}
diff --git a/mps/code/message.c b/mps/code/message.c
index 68662cd28fc..a5f2651b928 100644
--- a/mps/code/message.c
+++ b/mps/code/message.c
@@ -73,6 +73,10 @@ Bool MessageClassCheck(MessageClass class)
CHECKL(class->name != NULL);
CHECKL(FUNCHECK(class->delete));
CHECKL(FUNCHECK(class->finalizationRef));
+ CHECKL(FUNCHECK(class->gcLiveSize));
+ CHECKL(FUNCHECK(class->gcCondemnedSize));
+ CHECKL(FUNCHECK(class->gcNotCondemnedSize));
+ CHECKL(FUNCHECK(class->gcStartWhy));
CHECKL(class->endSig == MessageClassSig);
return TRUE;
@@ -352,6 +356,14 @@ Size MessageGCNotCondemnedSize(Message message)
return (*message->class->gcNotCondemnedSize)(message);
}
+const char *MessageGCStartWhy(Message message)
+{
+ AVERT(Message, message);
+ AVER(message->type == MessageTypeGCSTART);
+
+ return (*message->class->gcStartWhy)(message);
+}
+
/* type-specific stub methods */
@@ -396,6 +408,16 @@ Size MessageNoGCNotCondemnedSize(Message message)
return (Size)0;
}
+const char *MessageNoGCStartWhy(Message message)
+{
+ AVERT(Message, message);
+ UNUSED(message);
+
+ NOTREACHED;
+
+ return NULL;
+}
+
/* C. COPYRIGHT AND LICENSE
*
diff --git a/mps/code/messtest.c b/mps/code/messtest.c
index 71cb9de09b8..f21bb8e2742 100644
--- a/mps/code/messtest.c
+++ b/mps/code/messtest.c
@@ -1,7 +1,7 @@
/* messtest.c: MESSAGE TEST
*
* $Id$
- * Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2003 Ravenbrook Limited. See end of file for license.
*/
#include "mpm.h"
@@ -34,7 +34,8 @@ static MessageClassStruct DFMessageClassStruct = {
MessageNoFinalizationRef, /* FinalizationRef */
MessageNoGCLiveSize, /* GCLiveSize */
MessageNoGCCondemnedSize, /* GCCondemnedSize */
- MessageNoGCNotCondemnedSize, /* GCNoteCondemnedSize */
+ MessageNoGCNotCondemnedSize, /* GCNotCondemnedSize */
+ MessageNoGCStartWhy, /* GCStartWhy */
MessageClassSig /* */
};
@@ -49,6 +50,7 @@ static MessageClassStruct DGCMessageClassStruct = {
MessageNoGCLiveSize, /* GCLiveSize */
MessageNoGCCondemnedSize, /* GCCondemnedSize */
MessageNoGCNotCondemnedSize, /* GCNoteCondemnedSize */
+ MessageNoGCStartWhy, /* GCStartWhy */
MessageClassSig /* */
};
@@ -271,7 +273,7 @@ extern int main(int argc, char *argv[])
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2002 Ravenbrook Limited .
+ * Copyright (C) 2001-2003 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/misc.h b/mps/code/misc.h
index fb3a95a7174..bb805064004 100644
--- a/mps/code/misc.h
+++ b/mps/code/misc.h
@@ -90,6 +90,17 @@ typedef const struct SrcIdStruct {
#define STR_(x) #x
#define STR(x) STR_(x)
+/* NELEMS -- counts number of elements in an array
+ *
+ * NELEMS(a) expands into an expression that is the number
+ * of elements in the array a.
+ *
+ * WARNING: expands a more than once (you'd have to write obviously
+ * perverse code for this to matter though).
+ */
+
+#define NELEMS(a) (sizeof(a)/sizeof((a)[0]))
+
/* DISCARD -- discards an expression, but checks syntax
*
diff --git a/mps/code/mpm.h b/mps/code/mpm.h
index c2b88250774..0badeaa737c 100644
--- a/mps/code/mpm.h
+++ b/mps/code/mpm.h
@@ -309,6 +309,7 @@ extern void MessageFinalizationRef(Ref *refReturn,
extern Size MessageGCLiveSize(Message message);
extern Size MessageGCCondemnedSize(Message message);
extern Size MessageGCNotCondemnedSize(Message message);
+extern const char *MessageGCStartWhy(Message message);
/* Convenience methods */
extern void MessageNoFinalizationRef(Ref *refReturn,
@@ -316,6 +317,7 @@ extern void MessageNoFinalizationRef(Ref *refReturn,
extern Size MessageNoGCLiveSize(Message message);
extern Size MessageNoGCCondemnedSize(Message message);
extern Size MessageNoGCNotCondemnedSize(Message message);
+extern const char *MessageNoGCStartWhy(Message message);
/* Trace Interface -- see */
@@ -350,7 +352,7 @@ extern RefSet ScanStateSummary(ScanState ss);
extern Bool TraceIdCheck(TraceId id);
extern Bool TraceSetCheck(TraceSet ts);
extern Bool TraceCheck(Trace trace);
-extern Res TraceCreate(Trace *traceReturn, Arena arena);
+extern Res TraceCreate(Trace *traceReturn, Arena arena, int why);
extern void TraceDestroy(Trace trace);
extern Res TraceAddWhite(Trace trace, Seg seg);
@@ -475,8 +477,8 @@ extern Bool (ArenaStep)(Globals globals, double interval, double multiplier);
extern void ArenaClamp(Globals globals);
extern void ArenaRelease(Globals globals);
extern void ArenaPark(Globals globals);
-extern Res ArenaStartCollect(Globals globals);
-extern Res ArenaCollect(Globals globals);
+extern Res ArenaStartCollect(Globals globals, int why);
+extern Res ArenaCollect(Globals globals, int why);
extern Bool ArenaHasAddr(Arena arena, Addr addr);
extern Res ControlInit(Arena arena);
diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h
index 2518efff660..b1367b0f92d 100644
--- a/mps/code/mpmst.h
+++ b/mps/code/mpmst.h
@@ -200,9 +200,20 @@ typedef struct MessageClassStruct {
/* methods specific to MessageTypeGC */
MessageGCLiveSizeMethod gcLiveSize;
+
+ /* methods specific to MessageTypeGC and MessageTypeGCGen */
MessageGCCondemnedSizeMethod gcCondemnedSize;
MessageGCNotCondemnedSizeMethod gcNotCondemnedSize;
+ /* methods specific to MessageTypeGCStart */
+ MessageGCStartWhyMethod gcStartWhy;
+
+ /* methods specific to MessageTypeGCGen */
+#if 0 /* @@@@ */
+ MessageGCGenNameMethod gcGenName;
+ MessageGCGenForwardMethod gcGenForward;
+#endif
+
Sig endSig; /* */
} MessageClassStruct;
@@ -442,6 +453,20 @@ typedef struct LDStruct {
RefSet rs; /* RefSet of Add'ed references */
} LDStruct;
+/* TraceStartMessage
+ *
+ * See .
+ *
+ * Embedded in TraceStruct. */
+
+#define TraceStartMessageSig ((Sig)0x51926535) /* SIG TRaceStartMeSsage */
+
+typedef struct TraceStartMessageStruct {
+ Sig sig;
+ char why[TRACE_START_MESSAGE_WHY_LEN];
+ MessageStruct messageStruct;
+} TraceStartMessageStruct;
+
/* ScanState
*
@@ -525,6 +550,9 @@ typedef struct TraceStruct {
Size preservedInPlaceSize; /* bytes preserved in place */
STATISTIC_DECL(Count reclaimCount); /* segments reclaimed */
STATISTIC_DECL(Count reclaimSize); /* bytes reclaimed */
+ /* Always allocated message structure. Implements
+ mps_message_type_gc_start(). See */
+ TraceStartMessageStruct startMessage;
} TraceStruct;
diff --git a/mps/code/mpmtypes.h b/mps/code/mpmtypes.h
index 67b2b7886a4..ace31ae0686 100644
--- a/mps/code/mpmtypes.h
+++ b/mps/code/mpmtypes.h
@@ -76,6 +76,8 @@ typedef PoolClass AbstractBufferPoolClass; /* */
typedef PoolClass AbstractSegBufPoolClass; /* */
typedef PoolClass AbstractScanPoolClass; /* */
typedef PoolClass AbstractCollectPoolClass; /* */
+typedef struct TraceStartMessageStruct
+ *TraceStartMessage; /* */
typedef struct TraceStruct *Trace; /* */
typedef struct ScanStateStruct *ScanState; /* */
typedef struct ChainStruct *Chain; /* */
@@ -232,6 +234,7 @@ typedef void (*MessageFinalizationRefMethod)
typedef Size (*MessageGCLiveSizeMethod)(Message message);
typedef Size (*MessageGCCondemnedSizeMethod)(Message message);
typedef Size (*MessageGCNotCondemnedSizeMethod)(Message message);
+typedef const char * (*MessageGCStartWhyMethod)(Message message);
/* Message Types -- and elsewhere */
@@ -401,6 +404,18 @@ enum {
TraceFINISHED
};
+/* TraceStart reasons. Reasons for why a trace is started. */
+
+enum {
+ TraceStartWhyBASE = 1, /* not a reason, the base of the enum. */
+ TraceStartWhyNURSERY = TraceStartWhyBASE,
+ TraceStartWhyGLOBAL,
+ TraceStartWhyOPPORTUNISM,
+ TraceStartWhyCLIENT,
+ TraceStartWhyWALK,
+ TraceStartWhyLIMIT /* not a reason, the limit of the enum. */
+};
+
/* MessageTypes -- see */
/* .message.types: Keep in sync with */
@@ -408,6 +423,7 @@ enum {
enum {
MessageTypeFINALIZATION,
MessageTypeGC,
+ MessageTypeGCSTART,
MessageTypeLIMIT
};
diff --git a/mps/code/mps.h b/mps/code/mps.h
index 3a032e5d332..b20885c05ab 100644
--- a/mps/code/mps.h
+++ b/mps/code/mps.h
@@ -65,17 +65,20 @@ enum {
MPS_RES_PARAM /* illegal user parameter value */
};
-/* .message.types: Keep in sync with */
+/* Keep in sync with
+ * */
/* Not meant to be used by clients, they should use the macros below. */
enum {
MPS_MESSAGE_TYPE_FINALIZATION,
- MPS_MESSAGE_TYPE_GC
+ MPS_MESSAGE_TYPE_GC,
+ MPS_MESSAGE_TYPE_GC_START
};
/* Message Types
* This is what clients should use. */
#define mps_message_type_finalization() MPS_MESSAGE_TYPE_FINALIZATION
#define mps_message_type_gc() MPS_MESSAGE_TYPE_GC
+#define mps_message_type_gc_start() MPS_MESSAGE_TYPE_GC_START
/* Reference Ranks
diff --git a/mps/code/mpsi.c b/mps/code/mpsi.c
index 316ff6cf03e..06ad8a0ae1b 100644
--- a/mps/code/mpsi.c
+++ b/mps/code/mpsi.c
@@ -346,7 +346,7 @@ mps_res_t mps_arena_start_collect(mps_space_t mps_space)
Res res;
Arena arena = (Arena)mps_space;
ArenaEnter(arena);
- res = ArenaStartCollect(ArenaGlobals(arena));
+ res = ArenaStartCollect(ArenaGlobals(arena), TraceStartWhyCLIENT);
ArenaLeave(arena);
return res;
}
@@ -356,7 +356,7 @@ mps_res_t mps_arena_collect(mps_space_t mps_space)
Res res;
Arena arena = (Arena)mps_space;
ArenaEnter(arena);
- res = ArenaCollect(ArenaGlobals(arena));
+ res = ArenaCollect(ArenaGlobals(arena), TraceStartWhyCLIENT);
ArenaLeave(arena);
return res;
}
diff --git a/mps/code/poolmrg.c b/mps/code/poolmrg.c
index 2353bcafd28..1493991b775 100644
--- a/mps/code/poolmrg.c
+++ b/mps/code/poolmrg.c
@@ -463,7 +463,8 @@ static MessageClassStruct MRGMessageClassStruct = {
MRGMessageFinalizationRef, /* FinalizationRef */
MessageNoGCLiveSize, /* GCLiveSize */
MessageNoGCCondemnedSize, /* GCCondemnedSize */
- MessageNoGCNotCondemnedSize, /* GCNoteCondemnedSize */
+ MessageNoGCNotCondemnedSize, /* GCNotCondemnedSize */
+ MessageNoGCStartWhy, /* GCStartWhy */
MessageClassSig /* */
};
diff --git a/mps/code/trace.c b/mps/code/trace.c
index 5c6ed5e3c43..84dd7880bd0 100644
--- a/mps/code/trace.c
+++ b/mps/code/trace.c
@@ -12,11 +12,16 @@
SRCID(trace, "$Id$");
+/* Forward declarations */
+static void TraceStartMessageInit(Arena arena, TraceStartMessage tsMessage);
/* Types */
-enum {traceAccountingPhaseRootScan = 1, traceAccountingPhaseSegScan,
- traceAccountingPhaseSingleScan};
+enum {
+ traceAccountingPhaseRootScan = 1,
+ traceAccountingPhaseSegScan,
+ traceAccountingPhaseSingleScan
+};
typedef int traceAccountingPhase;
@@ -32,7 +37,7 @@ typedef struct TraceMessageStruct {
MessageStruct messageStruct;
} TraceMessageStruct, *TraceMessage;
-#define TraceMessageMessage(TraceMessage) (&((TraceMessage)->messageStruct))
+#define TraceMessageMessage(traceMessage) (&((traceMessage)->messageStruct))
#define MessageTraceMessage(message) \
(PARENT(TraceMessageStruct, messageStruct, message))
@@ -102,6 +107,7 @@ static MessageClassStruct TraceMessageClassStruct = {
TraceMessageLiveSize, /* GCLiveSize */
TraceMessageCondemnedSize, /* GCCondemnedSize */
TraceMessageNotCondemnedSize, /* GCNotCondemnedSize */
+ MessageNoGCStartWhy, /* GCStartWhy */
MessageClassSig /* */
};
@@ -119,6 +125,135 @@ static void TraceMessageInit(Arena arena, TraceMessage tMessage)
AVERT(TraceMessage, tMessage);
}
+/* TraceStartMessage - manages info needed by start of trace message
+ (mps_message_type_gc_start).
+
+ (structure declared in ) */
+
+#define TraceStartMessageMessage(traceStartMessage) \
+ (&((traceStartMessage)->messageStruct))
+#define MessageTraceStartMessage(message) \
+ (PARENT(TraceStartMessageStruct, messageStruct, message))
+
+static Bool TraceStartMessageCheck(TraceStartMessage message)
+{
+ size_t i;
+
+ CHECKS(TraceStartMessage, message);
+ CHECKD(Message, TraceStartMessageMessage(message));
+ CHECKL(MessageGetType(TraceStartMessageMessage(message)) ==
+ MessageTypeGCSTART);
+
+ /* Check that why is NUL terminated. */
+ for(i=0; iwhy); ++i) {
+ if(message->why[i] == 0) {
+ break;
+ }
+ }
+ CHECKL(iwhy));
+
+ return TRUE;
+}
+
+static void TraceStartMessageDelete(Message message)
+{
+ TraceStartMessage tsMessage;
+
+ AVERT(Message, message);
+ tsMessage = MessageTraceStartMessage(message);
+ AVERT(TraceStartMessage, tsMessage);
+
+ TraceStartMessageInit(MessageArena(message), tsMessage);
+
+ return;
+}
+
+static const char *TraceStartMessageWhy(Message message)
+{
+ TraceStartMessage tsMessage;
+
+ AVERT(Message, message);
+ tsMessage = MessageTraceStartMessage(message);
+ AVERT(TraceStartMessage, tsMessage);
+
+ return tsMessage->why;
+}
+
+static MessageClassStruct TraceStartMessageClassStruct = {
+ MessageClassSig, /* sig */
+ "TraceGCStart", /* name */
+ TraceStartMessageDelete, /* Delete */
+ MessageNoFinalizationRef, /* FinalizationRef */
+ MessageNoGCLiveSize, /* GCLiveSize */
+ MessageNoGCCondemnedSize, /* GCCondemnedSize */
+ MessageNoGCNotCondemnedSize, /* GCNotCondemnedSize */
+ TraceStartMessageWhy, /* GCStartWhy */
+ MessageClassSig /* */
+};
+
+static void TraceStartMessageInit(Arena arena, TraceStartMessage tsMessage)
+{
+ AVERT(Arena, arena);
+
+ MessageInit(arena, TraceStartMessageMessage(tsMessage),
+ &TraceStartMessageClassStruct, MessageTypeGCSTART);
+ tsMessage->why[0] = '\0';
+
+ tsMessage->sig = TraceStartMessageSig;
+ AVERT(TraceStartMessage, tsMessage);
+
+ return;
+}
+
+/* traceStartWhyToString
+ *
+ * Converts a TraceStartWhy* code into a string description.
+ * s specifies the beginning of the buffer to write the string
+ * into, len specifies the length of the buffer.
+ * The string written into will be NUL terminated (truncated if
+ * necessary). */
+static void traceStartWhyToString(char *s, size_t len, int why)
+{
+ const char *r;
+ size_t i;
+
+ AVER(s);
+ /* len can be anything, including 0. */
+ AVER(TraceStartWhyBASE <= why);
+ AVER(why < TraceStartWhyLIMIT);
+
+ switch(why) {
+ case TraceStartWhyNURSERY:
+ r = "Nursery generation is full.";
+ break;
+ case TraceStartWhyGLOBAL:
+ r = "Preventing global exhaustion of memory.";
+ break;
+ case TraceStartWhyOPPORTUNISM:
+ r = "Opportunism.";
+ break;
+ case TraceStartWhyCLIENT:
+ r = "Client request.";
+ break;
+ case TraceStartWhyWALK:
+ r = "Walking.";
+ break;
+ default:
+ NOTREACHED;
+ r = "Unknown reason (internal error).";
+ break;
+ }
+
+ for(i=0; ifix = TraceFix;
TRACE_SET_ITER(ti, trace, ts, arena)
- if (trace->emergency)
+ if (trace->emergency) {
ss->fix = TraceFixEmergency;
+ }
TRACE_SET_ITER_END(ti, trace, ts, arena);
ss->rank = rank;
ss->traces = ts;
@@ -580,6 +716,8 @@ static void traceFlip(Trace trace)
/* collector), so that we allocate grey or white before the flip */
/* and black afterwards. For instance, see */
/* . */
+ /* (surely we mean "write-barrier" not "read-barrier" above? */
+ /* drj 2003-02-19) */
/* Now that the mutator is black we must prevent it from reading */
/* grey objects so that it can't obtain white pointers. This is */
@@ -625,7 +763,7 @@ static void traceFlip(Trace trace)
* This code is written to be adaptable to allocating Trace objects
* dynamically. */
-Res TraceCreate(Trace *traceReturn, Arena arena)
+Res TraceCreate(Trace *traceReturn, Arena arena, int why)
{
TraceId ti;
Trace trace;
@@ -678,6 +816,9 @@ found:
trace->preservedInPlaceSize = (Size)0; /* see .message.data */
STATISTIC(trace->reclaimCount = (Count)0);
STATISTIC(trace->reclaimSize = (Size)0);
+ TraceStartMessageInit(arena, &trace->startMessage);
+ traceStartWhyToString(trace->startMessage.why,
+ sizeof trace->startMessage.why, why);
trace->sig = TraceSig;
arena->busyTraces = TraceSetAdd(arena->busyTraces, trace);
AVERT(Trace, trace);
@@ -1373,8 +1514,9 @@ static Res rootGrey(Root root, void *p)
AVERT(Root, root);
AVERT(Trace, trace);
- if (ZoneSetInter(RootSummary(root), trace->white) != ZoneSetEMPTY)
+ if (ZoneSetInter(RootSummary(root), trace->white) != ZoneSetEMPTY) {
RootGrey(root, trace);
+ }
return ResOK;
}
@@ -1389,9 +1531,10 @@ void TraceStart(Trace trace, double mortality, double finishingTime)
AVERT(Trace, trace);
AVER(trace->state == TraceINIT);
AVER(0.0 <= mortality && mortality <= 1.0);
- arena = trace->arena;
AVER(finishingTime >= 0.0);
+ arena = trace->arena;
+
/* From the already set up white set, derive a grey set. */
/* @@@@ Instead of iterating over all the segments, we could */
@@ -1420,13 +1563,15 @@ void TraceStart(Trace trace, double mortality, double finishingTime)
/* approximation to the white set. */
if (ZoneSetInter(SegSummary(seg), trace->white) != ZoneSetEMPTY) {
PoolGrey(SegPool(seg), trace, seg);
- if (TraceSetIsMember(SegGrey(seg), trace))
+ if (TraceSetIsMember(SegGrey(seg), trace)) {
trace->foundation += size;
+ }
}
if ((SegPool(seg)->class->attr & AttrGC)
- && !TraceSetIsMember(SegWhite(seg), trace))
+ && !TraceSetIsMember(SegWhite(seg), trace)) {
trace->notCondemned += size;
+ }
}
} while (SegNext(&seg, arena, base));
}
@@ -1508,9 +1653,12 @@ static void traceQuantum(Trace trace)
}
/* traceStartCollectAll: start a trace which condemns everything in
- * the arena. */
+ * the arena.
+ *
+ * "why" is a TraceStartWhy* enum member that specifies why the
+ * collection is starting. */
-static Res traceStartCollectAll(Trace *traceReturn, Arena arena)
+static Res traceStartCollectAll(Trace *traceReturn, Arena arena, int why)
{
Trace trace;
Res res;
@@ -1519,16 +1667,17 @@ static Res traceStartCollectAll(Trace *traceReturn, Arena arena)
AVERT(Arena, arena);
AVER(arena->busyTraces == TraceSetEMPTY);
- res = TraceCreate(&trace, arena);
+ res = TraceCreate(&trace, arena, why);
AVER(res == ResOK); /* succeeds because no other trace is busy */
res = traceCondemnAll(trace);
if (res != ResOK) /* should try some other trace, really @@@@ */
goto failCondemn;
finishingTime = ArenaAvail(arena)
- trace->condemned * (1.0 - TraceTopGenMortality);
- if (finishingTime < 0)
+ if (finishingTime < 0) {
/* Run out of time, should really try a smaller collection. @@@@ */
finishingTime = 0.0;
+ }
TraceStart(trace, TraceTopGenMortality, finishingTime);
*traceReturn = trace;
return ResOK;
@@ -1572,7 +1721,7 @@ Size TracePoll(Globals globals)
dynamicDeferral = (double)ArenaAvail(arena) - (double)sConsTrace;
if (dynamicDeferral < 0.0) { /* start full GC */
- res = traceStartCollectAll(&trace, arena);
+ res = traceStartCollectAll(&trace, arena, TraceStartWhyGLOBAL);
if (res != ResOK)
goto failStart;
scannedSize = traceWorkClock(trace);
@@ -1596,7 +1745,7 @@ Size TracePoll(Globals globals)
if (firstTime < 0) {
double mortality;
- res = TraceCreate(&trace, arena);
+ res = TraceCreate(&trace, arena, TraceStartWhyNURSERY);
AVER(res == ResOK);
res = ChainCondemnAuto(&mortality, firstChain, trace);
if (res != ResOK) /* should try some other trace, really @@@@ */
@@ -1675,7 +1824,7 @@ void ArenaPark(Globals globals)
/* ArenaStartCollect -- start a collection of everything in the
* arena; leave unclamped. */
-Res ArenaStartCollect(Globals globals)
+Res ArenaStartCollect(Globals globals, int why)
{
Arena arena;
Res res;
@@ -1685,7 +1834,7 @@ Res ArenaStartCollect(Globals globals)
arena = GlobalsArena(globals);
ArenaPark(globals);
- res = traceStartCollectAll(&trace, arena);
+ res = traceStartCollectAll(&trace, arena, why);
if (res != ResOK)
goto failStart;
ArenaRelease(globals);
@@ -1698,12 +1847,12 @@ failStart:
/* ArenaCollect -- collect everything in arena; leave clamped */
-Res ArenaCollect(Globals globals)
+Res ArenaCollect(Globals globals, int why)
{
Res res;
AVERT(Globals, globals);
- res = ArenaStartCollect(globals);
+ res = ArenaStartCollect(globals, why);
if (res != ResOK)
return res;
diff --git a/mps/code/walk.c b/mps/code/walk.c
index 4789493ce1e..6ea698de217 100644
--- a/mps/code/walk.c
+++ b/mps/code/walk.c
@@ -310,7 +310,7 @@ static Res ArenaRootsWalk(Globals arenaGlobals, mps_roots_stepper_t f,
/* call the client closure. This fix method must perform no tracing */
/* operations of its own. */
- res = TraceCreate(&trace, arena);
+ res = TraceCreate(&trace, arena, TraceStartWhyWALK);
/* Have to fail if no trace available. Unlikely due to .assume.parked. */
if (res != ResOK)
return res;