[MLton-commit] r4098
Matthew Fluet
MLton@mlton.org
Sat, 8 Oct 2005 13:36:27 -0700
More invariant and heap functions
----------------------------------------------------------------------
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/align.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/control.h
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/current.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/debug.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/major.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/pointer.h
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.c
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/statistics.h
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/sysvals.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/virtual-memory.h
----------------------------------------------------------------------
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile 2005-10-08 20:36:15 UTC (rev 4098)
@@ -49,14 +49,24 @@
endif
CC = gcc -std=gnu99
-CWFLAGS = -Wall -pedantic -Wextra -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wconversion -Wsign-compare -Wstrict-prototypes -Wredundant-decls -Winline
-CWFLAGS = -pedantic -Wall -Wextra -Wno-unused \
-## -Wshadow \
+CWFLAGS = -pedantic -Wall -Wextra -Wno-unused-parameter \
+ -Wformat-nonliteral \
+ -Wuninitialized -Winit-self \
+ -Wstrict-aliasing=2 \
+ -Wfloat-equal \
+ -Wpointer-arith \
+ -Wbad-function-cast -Wcast-qual -Wcast-align \
+ -Waggregate-return \
+ -Wstrict-prototypes \
+ -Wmissing-noreturn -Wmissing-format-attribute \
+ -Wpacked \
-Wredundant-decls \
- -Wpointer-arith -Wcast-qual -Wcast-align \
-## -Wconversion \
- -Wstrict-prototypes \
- -Winline
+ -Wnested-externs
+## -Wshadow
+## -Wconversion
+## -Wmissing-prototypes
+## -Wmissing-declarations
+## -Winline -Wdisabled-optimization
CFLAGS = -O2 $(CWFLAGS) -I. -D_FILE_OFFSET_BITS=64 $(FLAGS)
DEBUGFLAGS = $(CFLAGS) -Wunused -gstabs+ -g2
@@ -74,9 +84,11 @@
thread.c \
generational.c \
heap.c \
+ ratios.c \
gc_state.c \
+ current.c \
+ foreach.c \
invariant.c \
- foreach.c \
cheney-copy.c \
assumptions.c \
gc_suffix.c
@@ -98,6 +110,9 @@
generational.h \
statistics.h \
heap.h \
+ control.h \
+ sysvals.h \
+ ratios.h \
gc_state.h \
gc_suffix.h
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO 2005-10-08 20:36:15 UTC (rev 4098)
@@ -15,3 +15,5 @@
codegen in thread.h is still true; it used to be the case when
GC_switchToThread was implemented in codegens. Now it should
be implemented in Backend.
+* the "skipObjects" loop in forwardInterGenerationalObjptrs appears to
+ be unnecessary.
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/align.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/align.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/align.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -6,6 +6,10 @@
* See the file MLton-LICENSE for details.
*/
+static inline size_t roundDown (size_t a, size_t b) {
+ return a - (a % b);
+}
+
static inline size_t align (size_t a, size_t b) {
assert (b >= 1);
a += b - 1;
@@ -36,12 +40,10 @@
return isAligned ((uintptr_t)p + GC_NORMAL_HEADER_SIZE, s->alignment);
}
-/*
-static bool isAlignedReserved (GC_state s, uint r) {
- return isAligned (STACK_HEADER_SIZE + sizeof (struct GC_stack) + r,
+static bool isAlignedReserved (GC_state s, size_t reserved) {
+ return isAligned (GC_STACK_HEADER_SIZE + sizeof (struct GC_stack) + reserved,
s->alignment);
}
-*/
#endif
static inline size_t pad (GC_state s, size_t bytes, size_t extra) {
@@ -49,7 +51,11 @@
}
static inline pointer alignFrontier (GC_state s, pointer p) {
- return (pointer) pad (s, (size_t)p, GC_NORMAL_HEADER_SIZE);
+ size_t bytes, res;
+
+ bytes = (size_t) p;
+ res = pad (s, (size_t)p, GC_NORMAL_HEADER_SIZE);
+ return (pointer)res;
}
pointer GC_alignFrontier (GC_state s, pointer p) {
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -42,7 +42,7 @@
GC_arrayLength numElements;
size_t result;
- numElements = arrayNumElements (p);
+ numElements = getArrayLength (p);
bytesPerElement =
numNonObjptrsToBytes(numNonObjptrs, ARRAY_TAG)
+ (numObjptrs * OBJPTR_SIZE);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.h 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -23,10 +23,18 @@
#define GC_ARRAY_COUNTER_SIZE GC_ARRAY_LENGTH_SIZE
#define GC_ARRAY_HEADER_SIZE (GC_ARRAY_COUNTER_SIZE + GC_ARRAY_LENGTH_SIZE + GC_HEADER_SIZE)
-static inline GC_arrayLength* arrayNumElementsp (pointer a) {
+/* getArrayNumElementsp (p)
+ *
+ * Returns a pointer to the length for the array pointed to by p.
+ */
+static inline GC_arrayLength* getArrayLengthp (pointer a) {
return (GC_arrayLength*)(a - GC_HEADER_SIZE - GC_ARRAY_LENGTH_SIZE);
}
-static inline GC_arrayLength arrayNumElements (pointer a) {
- return *(arrayNumElementsp (a));
+/* getArrayNumElements (p)
+ *
+ * Returns the length for the array pointed to by p.
+ */
+static inline GC_arrayLength getArrayLength (pointer a) {
+ return *(getArrayLengthp (a));
}
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-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -24,14 +24,6 @@
};
static struct forwardState forwardState;
-static inline bool pointerIsInFromSpace (GC_state s, pointer p) {
- return (pointerIsInOldGen (s, p) or pointerIsInNursery (s, p));
-}
-
-static inline bool objptrIsInFromSpace (GC_state s, objptr op) {
- return (objptrIsInOldGen (s, op) or objptrIsInNursery (s, op));
-}
-
static inline bool pointerIsInToSpace (pointer p) {
return (not (isPointer (p))
or (forwardState.toStart <= p and p < forwardState.toLimit));
@@ -87,7 +79,7 @@
headerBytes = GC_STACK_HEADER_SIZE;
stack = (GC_stack)p;
- if (currentThreadStack(s) == op) {
+ if (currentThreadStackObjptr(s) == op) {
/* Shrink stacks that don't use a lot of their reserved space;
* but don't violate the stack invariant.
*/
@@ -111,7 +103,7 @@
} else {
/* Shrink heap stacks. */
stack->reserved =
- stackReserved (s, maxZ((size_t)(s->threadShrinkRatio * stack->reserved),
+ stackReserved (s, maxZ((size_t)(s->ratios.threadShrink * stack->reserved),
stack->used));
if (DEBUG_STACKS)
fprintf (stderr, "Shrinking stack to size %zd.\n",
@@ -204,7 +196,7 @@
assert (s->secondaryHeap.size >= s->heap.oldGenSize);
/* if (detailedGCTime (s)) */
/* startTiming (&ru_start); */
- s->cumulative.numCopyingGCs++;
+ s->cumulativeStatistics.numCopyingGCs++;
forwardState.toStart = s->secondaryHeap.start;
forwardState.toLimit = s->secondaryHeap.start + s->secondaryHeap.size;
if (DEBUG or s->messages) {
@@ -229,13 +221,13 @@
foreachObjptrInRange (s, toStart, &forwardState.back, TRUE, forward);
updateWeaks (s);
s->secondaryHeap.oldGenSize = forwardState.back - s->secondaryHeap.start;
- s->cumulative.bytesCopied += s->secondaryHeap.oldGenSize;
+ s->cumulativeStatistics.bytesCopied += s->secondaryHeap.oldGenSize;
if (DEBUG)
fprintf (stderr, "%zd bytes live.\n",
/*uintToCommaString*/(s->secondaryHeap.oldGenSize));
swapHeaps (s);
clearCrossMap (s);
- s->lastMajor.kind = GC_COPYING;
+ s->lastMajorStatistics.kind = GC_COPYING;
/* if (detailedGCTime (s)) */
/* stopTiming (&ru_start, &s->ru_gcCopy); */
if (DEBUG or s->messages)
@@ -276,8 +268,8 @@
fprintf (stderr, "Forwarding inter-generational pointers.\n");
updateCrossMap (s);
/* Constants. */
- cardMap = s->generational.cardMap;
- crossMap = s->generational.crossMap;
+ cardMap = s->generationalMaps.cardMap;
+ crossMap = s->generationalMaps.crossMap;
maxCardIndex = sizeToCardIndex (align (s->heap.oldGenSize, CARD_SIZE));
oldGenStart = s->heap.start;
oldGenEnd = oldGenStart + s->heap.oldGenSize;
@@ -299,7 +291,7 @@
pointer lastObject;
size_t size;
- s->cumulative.markedCards++;
+ s->cumulativeStatistics.markedCards++;
if (DEBUG_GENERATIONAL)
fprintf (stderr, "card %zu is marked objectStart = "FMTPTR"\n",
cardIndex, (uintptr_t)objectStart);
@@ -311,7 +303,7 @@
objectStart += size;
goto skipObjects;
}
- s->cumulative.minorBytesSkipped += objectStart - lastObject;
+ s->cumulativeStatistics.minorBytesSkipped += objectStart - lastObject;
cardEnd = cardStart + CARD_SIZE;
if (oldGenEnd < cardEnd)
cardEnd = oldGenEnd;
@@ -325,7 +317,7 @@
*/
objectStart = foreachObjptrInRange (s, objectStart, &cardEnd,
FALSE, forwardIfInNursery);
- s->cumulative.minorBytesScanned += objectStart - lastObject;
+ s->cumulativeStatistics.minorBytesScanned += objectStart - lastObject;
if (objectStart == oldGenEnd)
goto done;
cardIndex = sizeToCardIndex (objectStart - oldGenStart);
@@ -363,7 +355,7 @@
bytesAllocated = s->frontier - s->heap.nursery;
if (bytesAllocated == 0)
return;
- s->cumulative.bytesAllocated += bytesAllocated;
+ s->cumulativeStatistics.bytesAllocated += bytesAllocated;
if (not s->canMinor) {
s->heap.oldGenSize += bytesAllocated;
bytesCopied = 0;
@@ -379,8 +371,8 @@
assert (isAlignedFrontier (s, forwardState.toStart));
forwardState.toLimit = forwardState.toStart + bytesAllocated;
assert (invariant (s));
- s->cumulative.numMinorGCs++;
- s->lastMajor.numMinorsGCs++;
+ s->cumulativeStatistics.numMinorGCs++;
+ s->lastMajorStatistics.numMinorsGCs++;
forwardState.back = forwardState.toStart;
/* Forward all globals. Would like to avoid doing this once all
* the globals have been assigned.
@@ -391,7 +383,7 @@
TRUE, forwardIfInNursery);
updateWeaks (s);
bytesCopied = forwardState.back - forwardState.toStart;
- s->cumulative.bytesCopiedMinor += bytesCopied;
+ s->cumulativeStatistics.bytesCopiedMinor += bytesCopied;
s->heap.oldGenSize += bytesCopied;
s->amInMinorGC = FALSE;
/* if (detailedGCTime (s)) */
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/control.h (from rev 4097, mlton/branches/on-20050822-x86_64-branch/runtime/gc.h)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc.h 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/control.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -0,0 +1,12 @@
+/* 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_control {
+ size_t fixedHeap; /* If 0, then no fixed heap. */
+ size_t maxHeap; /* if zero, then unlimited, else limit total heap */
+};
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/current.c (from rev 4097, mlton/branches/on-20050822-x86_64-branch/runtime/gc.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/current.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -0,0 +1,30 @@
+/* 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 inline objptr currentThreadObjptr (GC_state s) {
+ return s->currentThread;
+}
+
+static inline GC_thread currentThread (GC_state s) {
+ pointer p = objptrToPointer(currentThreadObjptr(s), s->heap.start);
+ return (GC_thread)p;
+}
+
+static inline objptr currentThreadStackObjptr (GC_state s) {
+ GC_thread ct = currentThread (s);
+ return ct->stack;
+}
+
+static inline GC_stack currentThreadStack (GC_state s) {
+ pointer p = objptrToPointer(currentThreadStackObjptr(s), s->heap.start);
+ return (GC_stack)p;
+}
+
+static inline size_t currentStackUsed (GC_state s) {
+ return s->stackTop - s->stackBottom;
+}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/debug.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/debug.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/debug.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -11,20 +11,22 @@
#endif
enum {
- DEBUG_ARRAY = FALSE,
- DEBUG_CALL_STACK = FALSE,
- DEBUG_CARD_MARKING = FALSE,
- DEBUG_DETAILED = FALSE,
- DEBUG_ENTER_LEAVE = FALSE,
- DEBUG_GENERATIONAL = FALSE,
- DEBUG_MARK_COMPACT = FALSE,
- DEBUG_MEM = FALSE,
- DEBUG_PROFILE = FALSE,
- DEBUG_RESIZING = FALSE,
- DEBUG_SHARE = FALSE,
- DEBUG_SIZE = FALSE,
- DEBUG_STACKS = FALSE,
- DEBUG_THREADS = FALSE,
- DEBUG_WEAK = FALSE,
- DEBUG_WORLD = FALSE,
+ DEBUG_ARRAY = FALSE,
+ DEBUG_CALL_STACK = FALSE,
+ DEBUG_CARD_MARKING = FALSE,
+ DEBUG_DETAILED = FALSE,
+ DEBUG_ENTER_LEAVE = FALSE,
+ DEBUG_GENERATIONAL = FALSE,
+ DEBUG_MARK_COMPACT = FALSE,
+ DEBUG_MEM = FALSE,
+ DEBUG_PROFILE = FALSE,
+ DEBUG_RESIZING = FALSE,
+ DEBUG_SHARE = FALSE,
+ DEBUG_SIZE = FALSE,
+ DEBUG_STACKS = FALSE,
+ DEBUG_THREADS = FALSE,
+ DEBUG_WEAK = FALSE,
+ DEBUG_WORLD = FALSE,
+ FORCE_GENERATIONAL = FALSE,
+ FORCE_MARK_COMPACT = FALSE,
};
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/foreach.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -27,10 +27,10 @@
}
if (DEBUG_DETAILED)
fprintf (stderr, "foreachGlobal threads\n");
- maybeCall (f, s, &s->callFromCHandler);
+ maybeCall (f, s, &s->callFromCHandlerThread);
maybeCall (f, s, &s->currentThread);
maybeCall (f, s, &s->savedThread);
- maybeCall (f, s, &s->signalHandler);
+ maybeCall (f, s, &s->signalHandlerThread);
}
@@ -84,7 +84,7 @@
pointer max;
GC_arrayLength numElements;
- numElements = arrayNumElements (p);
+ numElements = getArrayLength (p);
bytesPerElement =
numNonObjptrsToBytes(numNonObjptrs, ARRAY_TAG)
+ (numObjptrs * OBJPTR_SIZE);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -12,7 +12,7 @@
res = s->returnAddressToFrameIndex (ra);
if (DEBUG_DETAILED)
- fprintf (stderr, "%"PRIu32" = getFrameIndex ("FMTRA")\n",
+ fprintf (stderr, "%"PRIu32" = getFrameIndexFromReturnAddress ("FMTRA")\n",
res, ra);
return res;
}
@@ -23,7 +23,7 @@
if (DEBUG_DETAILED)
fprintf (stderr,
- "index = %"PRIx32
+ "index = %"PRIu32
" frameLayoutsLength = %"PRIu32"\n",
index, s->frameLayoutsLength);
assert (index < s->frameLayoutsLength);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.h 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/frame.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -16,10 +16,10 @@
*
* The frameLayouts pointer is initialized to point to a static array
* of frame layouts that is emitted for each compiled program. The
- * isC field identified whether or not the frame is for a C
- * call. (Note: The ML stack is distinct from the system stack. A C
- * call executes on the system stack. The frame left on the ML stack
- * is just a marker.) The size field indicates the size of the frame,
+ * kind field identifies whether or not the frame is for a C call.
+ * (Note: The ML stack is distinct from the system stack. A C call
+ * executes on the system stack. The frame left on the ML stack is
+ * just a marker.) The size field indicates the size of the frame,
* including space for the return address. The offsets field points
* to an array (the zeroeth element recording the size of the array)
* whose elements record byte offsets from the bottom of the frame at
@@ -27,8 +27,13 @@
*/
typedef uint16_t *GC_frameOffsets;
+typedef enum {
+ C_FRAME,
+ ML_FRAME
+} GC_frameKind;
+
typedef struct GC_frameLayout {
- bool isC;
+ GC_frameKind kind;
uint16_t size;
GC_frameOffsets offsets;
} GC_frameLayout;
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -13,7 +13,7 @@
displayThread (s, (GC_thread)(objptrToPointer (s->currentThread, s->heap.start)),
stream);
fprintf (stream, "\tgenerational\n");
- displayGenerationalMaps (s, &s->generational,
+ displayGenerationalMaps (s, &s->generationalMaps,
stream);
fprintf (stream, "\theap\n");
displayHeap (s, &s->heap,
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-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -3,35 +3,38 @@
size_t alignment; /* */
bool amInGC;
bool amInMinorGC;
- objptr callFromCHandler; /* Handler for exported C calls (in heap). */
+ objptr callFromCHandlerThread; /* Handler for exported C calls (in heap). */
bool canMinor; /* TRUE iff there is space for a minor gc. */
- struct GC_cumulativeStatistics cumulative;
+ struct GC_control control;
+ struct GC_cumulativeStatistics cumulativeStatistics;
objptr currentThread; /* Currently executing thread (in heap). */
GC_frameLayout *frameLayouts; /* Array of frame layouts. */
uint32_t frameLayoutsLength; /* Cardinality of frameLayouts array. */
pointer frontier; /* heap.start <= frontier < limit */
- struct GC_generationalMaps generational;
+ struct GC_generationalMaps generationalMaps;
objptr *globals;
uint32_t globalsLength;
struct GC_heap heap;
- struct GC_lastMajorStatistics lastMajor;
+ struct GC_lastMajorStatistics lastMajorStatistics;
pointer limit; /* limit = heap.start + heap.totalBytes */
pointer limitPlusSlop; /* limit + LIMIT_SLOP */
uint32_t maxFrameSize;
+ /*Bool*/bool messages; /* Print a message at the start and end of each gc. */
/*Bool*/bool mutatorMarksCards;
GC_objectType *objectTypes; /* Array of object types. */
uint32_t objectTypesLength; /* Cardinality of objectTypes array. */
size_t pageSize;
uint32_t (*returnAddressToFrameIndex) (GC_returnAddress ra);
+ struct GC_ratios ratios;
objptr savedThread; /* Result of GC_copyCurrentThread.
* Thread interrupted by arrival of signal.
*/
struct GC_heap secondaryHeap; /* Used for major copying collection. */
- objptr signalHandler; /* Handler for signals (in heap). */
+ objptr signalHandlerThread; /* Handler for signals (in heap). */
pointer stackBottom; /* Bottom of stack in current thread. */
+ pointer stackLimit; /* stackBottom + stackSize - maxFrameSize */
pointer stackTop; /* Top of stack in current thread. */
/*Bool*/bool summary; /* Print a summary of gc info when program exits. */
- /*Bool*/bool messages; /* Print a message at the start and end of each gc. */
- float threadShrinkRatio;
+ 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/generational.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -21,7 +21,7 @@
static inline pointer pointerToCardMapAddr (GC_state s, pointer p) {
pointer res;
- res = &s->generational.cardMapAbsolute [pointerToCardIndex (p)];
+ res = &s->generationalMaps.cardMapAbsolute [pointerToCardIndex (p)];
if (DEBUG_CARD_MARKING)
fprintf (stderr, "pointerToCardMapAddr ("FMTPTR") = "FMTPTR"\n",
(uintptr_t)p, (uintptr_t)res);
@@ -42,16 +42,16 @@
static inline void clearCardMap (GC_state s) {
if (DEBUG_GENERATIONAL and DEBUG_DETAILED)
fprintf (stderr, "clearCardMap ()\n");
- memset (s->generational.cardMap, 0,
- s->generational.cardMapLength * CARD_MAP_ELEM_SIZE);
+ memset (s->generationalMaps.cardMap, 0,
+ s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE);
}
static inline void clearCrossMap (GC_state s) {
if (DEBUG_GENERATIONAL and DEBUG_DETAILED)
fprintf (stderr, "clearCrossMap ()\n");
- s->generational.crossMapValidSize = 0;
- memset (s->generational.crossMap, CROSS_MAP_EMPTY,
- s->generational.crossMapLength * CROSS_MAP_ELEM_SIZE);
+ s->generationalMaps.crossMapValidSize = 0;
+ memset (s->generationalMaps.crossMap, CROSS_MAP_EMPTY,
+ s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE);
}
static inline void setCardMapAbsolute (GC_state s) {
@@ -61,20 +61,20 @@
* subsequent additions to mark the cards will overflow and put us
* in the right place.
*/
- s->generational.cardMapAbsolute =
+ s->generationalMaps.cardMapAbsolute =
pointerToCardMapAddr (s, s->heap.start);
if (DEBUG_CARD_MARKING)
fprintf (stderr, "cardMapAbsolute = "FMTPTR"\n",
- (uintptr_t)s->generational.cardMapAbsolute);
+ (uintptr_t)s->generationalMaps.cardMapAbsolute);
}
static inline void createCardMapAndCrossMap (GC_state s) {
unless (s->mutatorMarksCards) {
- s->generational.cardMapLength = 0;
- s->generational.cardMap = NULL;
- s->generational.cardMapAbsolute = NULL;
- s->generational.crossMapLength = 0;
- s->generational.crossMap = NULL;
+ s->generationalMaps.cardMapLength = 0;
+ s->generationalMaps.cardMap = NULL;
+ s->generationalMaps.cardMapAbsolute = NULL;
+ s->generationalMaps.crossMapLength = 0;
+ s->generationalMaps.crossMap = NULL;
return;
}
assert (isAligned (s->heap.size, CARD_SIZE));
@@ -86,25 +86,25 @@
cardMapLength = sizeToCardIndex (s->heap.size);
cardMapSize = align (cardMapLength * CARD_MAP_ELEM_SIZE, s->pageSize);
cardMapLength = cardMapSize / CARD_MAP_ELEM_SIZE;
- s->generational.cardMapLength = cardMapLength;
+ s->generationalMaps.cardMapLength = cardMapLength;
crossMapLength = sizeToCardIndex (s->heap.size);
crossMapSize = align (crossMapLength * CROSS_MAP_ELEM_SIZE, s->pageSize);
crossMapLength = crossMapSize / CROSS_MAP_ELEM_SIZE;
- s->generational.crossMapLength = crossMapLength;
+ s->generationalMaps.crossMapLength = crossMapLength;
totalMapSize = cardMapSize + crossMapSize;
if (DEBUG_MEM)
fprintf (stderr, "Creating card/cross map of size %zd\n",
/*uintToCommaString*/(totalMapSize));
- s->generational.cardMap =
+ s->generationalMaps.cardMap =
GC_mmapAnon (totalMapSize);
- s->generational.crossMap =
- (GC_crossMapElem*)((pointer)s->generational.cardMap + cardMapSize);
+ s->generationalMaps.crossMap =
+ (GC_crossMapElem*)((pointer)s->generationalMaps.cardMap + cardMapSize);
if (DEBUG_CARD_MARKING)
fprintf (stderr, "cardMap = "FMTPTR" crossMap = "FMTPTR"\n",
- (uintptr_t)s->generational.cardMap,
- (uintptr_t)s->generational.crossMap);
+ (uintptr_t)s->generationalMaps.cardMap,
+ (uintptr_t)s->generationalMaps.crossMap);
setCardMapAbsolute (s);
clearCardMap (s);
clearCrossMap (s);
@@ -139,7 +139,7 @@
if (DEBUG)
fprintf (stderr, "crossMapIsOK ()\n");
- mapSize = s->generational.crossMapLength * CROSS_MAP_ELEM_SIZE;
+ mapSize = s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE;
map = GC_mmapAnon (mapSize);
memset (map, CROSS_MAP_EMPTY, mapSize);
back = s->heap.start + s->heap.oldGenSize;
@@ -155,7 +155,7 @@
goto loopObjects;
}
for (size_t i = 0; i < cardIndex; ++i)
- assert (map[i] == s->generational.crossMap[i]);
+ assert (map[i] == s->generationalMaps.crossMap[i]);
GC_munmap (map, mapSize);
return TRUE;
}
@@ -169,10 +169,10 @@
pointer nextObject, objectStart;
pointer oldGenEnd;
- if (s->generational.crossMapValidSize == s->heap.oldGenSize)
+ if (s->generationalMaps.crossMapValidSize == s->heap.oldGenSize)
goto done;
oldGenEnd = s->heap.start + s->heap.oldGenSize;
- objectStart = s->heap.start + s->generational.crossMapValidSize;
+ objectStart = s->heap.start + s->generationalMaps.crossMapValidSize;
if (objectStart == s->heap.start) {
cardIndex = 0;
objectStart = alignFrontier (s, objectStart);
@@ -197,7 +197,7 @@
if (DEBUG_GENERATIONAL)
fprintf (stderr, "crossMap[%zu] = %zu\n",
cardIndex, offset);
- s->generational.crossMap[cardIndex] = (GC_crossMapElem)offset;
+ s->generationalMaps.crossMap[cardIndex] = (GC_crossMapElem)offset;
cardIndex = sizeToCardIndex (nextObject - 1 - s->heap.start);
cardStart = s->heap.start + cardIndexToSize (cardIndex);
cardEnd = cardStart + CARD_SIZE;
@@ -206,29 +206,29 @@
if (objectStart < oldGenEnd)
goto loopObjects;
assert (objectStart == oldGenEnd);
- s->generational.crossMap[cardIndex] = (GC_crossMapElem)(oldGenEnd - cardStart);
- s->generational.crossMapValidSize = s->heap.oldGenSize;
+ s->generationalMaps.crossMap[cardIndex] = (GC_crossMapElem)(oldGenEnd - cardStart);
+ s->generationalMaps.crossMapValidSize = s->heap.oldGenSize;
done:
- assert (s->generational.crossMapValidSize == s->heap.oldGenSize);
+ assert (s->generationalMaps.crossMapValidSize == s->heap.oldGenSize);
assert (crossMapIsOK (s));
}
static inline void resizeCardMapAndCrossMap (GC_state s) {
if (s->mutatorMarksCards
- and (s->generational.cardMapLength * CARD_MAP_ELEM_SIZE)
+ and (s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE)
!= align (sizeToCardIndex (s->heap.size), s->pageSize)) {
GC_cardMapElem *oldCardMap;
size_t oldCardMapSize;
GC_crossMapElem *oldCrossMap;
size_t oldCrossMapSize;
- oldCardMap = s->generational.cardMap;
- oldCardMapSize = s->generational.cardMapLength * CARD_MAP_ELEM_SIZE;
- oldCrossMap = s->generational.crossMap;
- oldCrossMapSize = s->generational.crossMapLength * CROSS_MAP_ELEM_SIZE;
+ oldCardMap = s->generationalMaps.cardMap;
+ oldCardMapSize = s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE;
+ oldCrossMap = s->generationalMaps.crossMap;
+ oldCrossMapSize = s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE;
createCardMapAndCrossMap (s);
- GC_memcpy ((pointer)oldCrossMap, (pointer)s->generational.crossMap,
- min (s->generational.crossMapLength * CROSS_MAP_ELEM_SIZE,
+ GC_memcpy ((pointer)oldCrossMap, (pointer)s->generationalMaps.crossMap,
+ min (s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE,
oldCrossMapSize));
if (DEBUG_MEM)
fprintf (stderr, "Releasing card/cross map.\n");
@@ -236,7 +236,7 @@
}
}
-void displayGenerationalMaps (GC_state s,
+void displayGenerationalMaps (__attribute__ ((unused)) GC_state s,
struct GC_generationalMaps *generational,
FILE *stream) {
fprintf(stream,
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -46,7 +46,35 @@
return pointerIsInNursery (s, p);
}
-void displayHeap (GC_state s,
+static inline bool pointerIsInFromSpace (GC_state s, pointer p) {
+ return (pointerIsInOldGen (s, p) or pointerIsInNursery (s, p));
+}
+
+static inline bool objptrIsInFromSpace (GC_state s, objptr op) {
+ return (objptrIsInOldGen (s, op) or objptrIsInNursery (s, op));
+}
+
+#if ASSERT
+static bool hasBytesFree (GC_state s, size_t oldGen, size_t nursery) {
+ size_t total;
+ bool res;
+
+ total =
+ s->heap.oldGenSize + oldGen
+ + (s->canMinor ? 2 : 1) * (s->limitPlusSlop - s->heap.nursery);
+ res =
+ (total <= s->heap.size)
+ and (nursery <= (size_t)(s->limitPlusSlop - s->frontier));
+ if (DEBUG_DETAILED)
+ fprintf (stderr, "%s = hasBytesFree (%zd, %zd)\n",
+ res ? "true" : "false",
+ /*uintToCommaString*/(oldGen),
+ /*uintToCommaString*/(nursery));
+ return res;
+}
+#endif
+
+void displayHeap (__attribute__ ((unused)) GC_state s,
GC_heap heap,
FILE *stream) {
fprintf(stream,
@@ -59,3 +87,186 @@
(uintptr_t)heap->start,
heap->size);
}
+
+/* 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 size_t heapDesiredSize (GC_state s, size_t live, size_t currentSize) {
+ size_t res;
+ float ratio;
+
+ ratio = (float)s->sysvals.ram / (float)live;
+ if (ratio >= s->ratios.live + s->ratios.grow) {
+ /* Cheney copying fits in RAM with desired ratios.live. */
+ res = live * s->ratios.live;
+ /* If the heap is currently close in size to what we want, leave
+ * it alone. Favor growing over shrinking.
+ */
+ unless (1.1 * currentSize <= res
+ or res <= .5 * currentSize)
+ res = currentSize;
+ } else if (s->ratios.grow >= s->ratios.copy
+ and ratio >= 2 * s->ratios.copy) {
+ /* Split RAM in half. Round down by pageSize so that the total
+ * amount of space taken isn't greater than RAM once rounding
+ * happens. This is so resizeHeap2 doesn't get confused and free
+ * a semispace in a misguided attempt to avoid paging.
+ */
+ res = roundDown (s->sysvals.ram / 2, s->sysvals.pageSize);
+ } else if (ratio >= s->ratios.copy + s->ratios.grow) {
+ /* Cheney copying fits in RAM. */
+ res = s->sysvals.ram - s->ratios.grow * 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 (currentSize <= res
+ and res <= 1.1 * currentSize)
+ res = currentSize;
+ } else if (ratio >= s->ratios.markCompact) {
+ /* 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 to avoid
+ * paging.
+ */
+ res = s->sysvals.ram;
+ } else { /* Required live ratio. */
+ res = live * s->ratios.markCompact;
+ /* 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 (s->control.fixedHeap > 0) {
+ if (res > s->control.fixedHeap / 2)
+ res = s->control.fixedHeap;
+ else
+ res = s->control.fixedHeap / 2;
+ if (res < live)
+ die ("Out of memory with fixed heap size %zd.",
+ /*uintToCommaString*/(s->control.fixedHeap));
+ } else if (s->control.maxHeap > 0) {
+ if (res > s->control.maxHeap)
+ res = s->control.maxHeap;
+ if (res < live)
+ die ("Out of memory with max heap size %zd.",
+ /*uintToCommaString*/(s->control.maxHeap));
+ }
+ if (DEBUG_RESIZING)
+ fprintf (stderr, "%zd = heapDesiredSize (%zd, %zd)\n",
+ /*uintToCommaString*/(res),
+ /*uintToCommaString*/(live),
+ /*uintToCommaString*/(currentSize));
+ assert (res >= live);
+ return res;
+}
+
+static inline void heapInit (GC_heap h) {
+ h->start = NULL;
+ h->size = 0;
+ h->oldGenSize = 0;
+ h->nursery = NULL;
+}
+
+static inline bool heapIsInit (GC_heap h) {
+ return 0 == h->size;
+}
+
+static void heapRelease (GC_state s, GC_heap h) {
+ if (NULL == h->start)
+ return;
+ if (DEBUG or s->messages)
+ fprintf (stderr, "Releasing heap at "FMTPTR" of size %zd.\n",
+ (uintptr_t)h->start,
+ /*uintToCommaString*/(h->size));
+ GC_release (h->start, h->size);
+ heapInit (h);
+}
+
+static void heapShrink (GC_state s, GC_heap h, size_t keep) {
+ assert (keep <= h->size);
+ if (0 == keep) {
+ heapRelease (s, h);
+ return;
+ }
+ keep = align (keep, s->pageSize);
+ if (keep < h->size) {
+ if (DEBUG or s->messages)
+ fprintf (stderr,
+ "Shrinking heap at "FMTPTR" of size %zd to %zd bytes.\n",
+ (uintptr_t)h->start,
+ /*uintToCommaString*/(h->size),
+ /*uintToCommaString*/(keep));
+ GC_decommit (h->start + keep, h->size - keep);
+ h->size = keep;
+ }
+}
+
+static void heapSetNursery (GC_state s,
+ size_t oldGenBytesRequested,
+ size_t nurseryBytesRequested) {
+ GC_heap h;
+ size_t nurserySize;
+
+ if (DEBUG_DETAILED)
+ fprintf (stderr, "setNursery(%zd, %zd)\n",
+ /*uintToCommaString*/(oldGenBytesRequested),
+ /*uintToCommaString*/(nurseryBytesRequested));
+ h = &s->heap;
+ assert (isAlignedFrontier (s, h->start + h->oldGenSize + oldGenBytesRequested));
+ nurserySize = h->size - h->oldGenSize - oldGenBytesRequested;
+ s->limitPlusSlop = h->start + h->size;
+ s->limit = s->limitPlusSlop - LIMIT_SLOP;
+ assert (isAligned (nurserySize, WORD_SIZE)); // FIXME
+ if (/* The mutator marks cards. */
+ s->mutatorMarksCards
+ /* There is enough space in the nursery. */
+ and (nurseryBytesRequested
+ <= (size_t)(s->limitPlusSlop
+ - alignFrontier (s, (s->limitPlusSlop
+ - nurserySize / 2 + 2))))
+ /* The nursery is large enough to be worth it. */
+ and (((float)(h->size - s->lastMajorStatistics.bytesLive)
+ / (float)nurserySize)
+ <= s->ratios.nursery)
+ and /* There is a reason to use generational GC. */
+ (
+ /* We must use it for debugging pruposes. */
+ FORCE_GENERATIONAL
+ /* We just did a mark compact, so it will be advantageous to to
+ * use it.
+ */
+ or (s->lastMajorStatistics.kind == GC_MARK_COMPACT)
+ /* The live ratio is low enough to make it worthwhile. */
+ or ((float)h->size / (float)s->lastMajorStatistics.bytesLive
+ <= (h->size < s->sysvals.ram
+ ? s->ratios.copyGenerational
+ : s->ratios.markCompactGenerational))
+ )) {
+ s->canMinor = TRUE;
+ nurserySize /= 2;
+ while (not (isAligned (nurserySize, WORD_SIZE))) {
+ nurserySize -= 2;
+ }
+ clearCardMap (s);
+ } else {
+ unless (nurseryBytesRequested
+ <= (size_t)(s->limitPlusSlop
+ - alignFrontier (s, s->limitPlusSlop
+ - nurserySize)))
+ die ("Out of memory. Insufficient space in nursery.");
+ s->canMinor = FALSE;
+ }
+ assert (nurseryBytesRequested
+ <= (size_t)(s->limitPlusSlop
+ - alignFrontier (s, s->limitPlusSlop
+ - nurserySize)));
+ s->heap.nursery = alignFrontier (s, s->limitPlusSlop - nurserySize);
+ s->frontier = s->heap.nursery;
+ assert (nurseryBytesRequested <= (size_t)(s->limitPlusSlop - s->frontier));
+ assert (isAlignedFrontier (s, s->heap.nursery));
+ assert (hasBytesFree (s, oldGenBytesRequested, nurseryBytesRequested));
+}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.h 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/heap.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -18,10 +18,10 @@
*/
typedef struct GC_heap {
- pointer nursery; /* start of nursery */
- size_t oldGenSize; /* size of old generation */
pointer start; /* start of heap (and old generation) */
size_t size; /* size of heap */
+ size_t oldGenSize; /* size of old generation */
+ pointer nursery; /* start of nursery */
} *GC_heap;
#define LIMIT_SLOP 512
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -8,10 +8,18 @@
#if ASSERT
+static inline void assertObjptrIsInFromSpace (GC_state s, objptr *opp) {
+ unless (objptrIsInFromSpace (s, *opp))
+ die ("gc.c: assertObjptrIsInFromSpace "
+ "opp = "FMTPTR" "
+ "*opp = "FMTOBJPTR"\n",
+ (uintptr_t)opp, *opp);
+}
+
static bool invariant (GC_state s) {
if (DEBUG)
fprintf (stderr, "invariant\n");
- // assert (ratiosOk (s));
+ assert (ratiosOk (s->ratios));
/* Frame layouts */
for (unsigned int i = 0; i < s->frameLayoutsLength; ++i) {
GC_frameLayout *layout;
@@ -22,22 +30,17 @@
assert (layout->size <= s->maxFrameSize);
offsets = layout->offsets;
- /* No longer correct, since handler frames have a "size"
- * (i.e. return address) pointing into the middle of the frame.
- */
-/* for (unsigned int j = 0; j < offsets[0]; ++j) */
-/* assert (offsets[j + 1] < layout->numBytes); */
}
}
/* Generational */
if (s->mutatorMarksCards) {
- assert (s->generational.cardMap ==
- &(s->generational.cardMapAbsolute
+ assert (s->generationalMaps.cardMap ==
+ &(s->generationalMaps.cardMapAbsolute
[pointerToCardIndex(s->heap.start)]));
- assert (&(s->generational.cardMapAbsolute
+ assert (&(s->generationalMaps.cardMapAbsolute
[pointerToCardIndex(s->heap.start + s->heap.size - 1)])
- < (s->generational.cardMap
- + (s->generational.cardMapLength * CARD_MAP_ELEM_SIZE)));
+ < (s->generationalMaps.cardMap
+ + (s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE)));
}
assert (isAligned (s->heap.size, s->pageSize));
assert (isAligned ((size_t)s->heap.start, CARD_SIZE));
@@ -49,43 +52,52 @@
assert (s->heap.nursery <= s->frontier);
assert (s->frontier <= s->limitPlusSlop);
assert (s->limit == s->limitPlusSlop - LIMIT_SLOP);
-/* assert (hasBytesFree (s, 0, 0)); */
+ assert (hasBytesFree (s, 0, 0));
}
- assert (s->secondaryHeap.start == NULL or s->heap.size == s->secondaryHeap.size);
-/* /\* Check that all pointers are into from space. *\/ */
-/* foreachGlobal (s, assertIsInFromSpace); */
-/* back = s->heap.start + s->oldGenSize; */
-/* if (DEBUG_DETAILED) */
-/* fprintf (stderr, "Checking old generation.\n"); */
-/* foreachPointerInRange (s, alignFrontier (s, s->heap.start), &back, FALSE, */
-/* assertIsInFromSpace); */
-/* if (DEBUG_DETAILED) */
-/* fprintf (stderr, "Checking nursery.\n"); */
-/* foreachPointerInRange (s, s->nursery, &s->frontier, FALSE, */
-/* assertIsInFromSpace); */
-/* /\* Current thread. *\/ */
-/* stack = s->currentThread->stack; */
-/* assert (isAlignedReserved (s, stack->reserved)); */
-/* assert (s->stackBottom == stackBottom (s, stack)); */
-/* assert (s->stackTop == stackTop (s, stack)); */
-/* assert (s->stackLimit == stackLimit (s, stack)); */
-/* assert (stack->used == currentStackUsed (s)); */
-/* assert (stack->used <= stack->reserved); */
-/* assert (s->stackBottom <= s->stackTop); */
+ assert (s->secondaryHeap.start == NULL
+ or s->heap.size == s->secondaryHeap.size);
+ /* Check that all pointers are into from space. */
+ foreachGlobalObjptr (s, assertObjptrIsInFromSpace);
+ pointer back = s->heap.start + s->heap.oldGenSize;
+ if (DEBUG_DETAILED)
+ fprintf (stderr, "Checking old generation.\n");
+ foreachObjptrInRange (s, alignFrontier (s, s->heap.start), &back,
+ FALSE, assertObjptrIsInFromSpace);
+ if (DEBUG_DETAILED)
+ fprintf (stderr, "Checking nursery.\n");
+ foreachObjptrInRange (s, s->heap.nursery, &s->frontier,
+ FALSE, assertObjptrIsInFromSpace);
+ /* Current thread. */
+ GC_stack stack = currentThreadStack(s);
+ assert (isAlignedReserved (s, stack->reserved));
+ assert (s->stackBottom == stackBottom (s, stack));
+ assert (s->stackTop == stackTop (s, stack));
+ assert (s->stackLimit == stackLimit (s, stack));
+ assert (s->stackBottom <= s->stackTop);
+ assert (stack->used == currentStackUsed (s));
+ assert (stack->used <= stack->reserved);
if (DEBUG)
fprintf (stderr, "invariant passed\n");
return TRUE;
}
+static bool mutatorFrontierInvariant (GC_state s) {
+ GC_thread ct = currentThread(s);
+ return (ct->bytesNeeded <= s->limitPlusSlop - s->frontier);
+}
+
+static bool mutatorStackInvariant (GC_state s) {
+ GC_stack sk = currentThreadStack(s);
+ return (stackTop (s, sk) <= stackLimit (s, sk) + topFrameSize (s, sk));
+}
+
static bool mutatorInvariant (GC_state s, bool frontier, bool stack) {
-#if FALSE
if (DEBUG)
- GC_display (s, stderr);
+ displayGCState (s, stderr);
if (frontier)
assert (mutatorFrontierInvariant(s));
if (stack)
assert (mutatorStackInvariant(s));
-#endif
assert (invariant (s));
return TRUE;
}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/major.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/major.h 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/major.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -9,4 +9,4 @@
typedef enum {
GC_COPYING,
GC_MARK_COMPACT,
-} GC_MajorKind;
+} GC_majorKind;
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -49,7 +49,7 @@
/* isObjptr returns true if p looks like an object pointer. */
static inline bool isObjptr (objptr p) {
- if GC_MODEL_NONPTR {
+ if GC_MODEL_NONOBJPTR {
unsigned int shift = GC_MODEL_MINALIGN_SHIFT - GC_MODEL_SHIFT;
objptr mask = ~((~((objptr)0)) << shift);
return (0 == (p & mask));
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.h 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/model.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -203,7 +203,7 @@
#else
#error gc model unknown
#endif
-#define GC_MODEL_NONPTR ((GC_MODEL_MINALIGN_SHIFT - GC_MODEL_SHIFT) > 0)
+#define GC_MODEL_NONOBJPTR ((GC_MODEL_MINALIGN_SHIFT - GC_MODEL_SHIFT) > 0)
#define GC_MODEL_MINALIGN TWOPOWER(GC_MODEL_MINALIGN_SHIFT)
#define OBJPTR_TYPE__(z) uint ## z ## _t
@@ -216,7 +216,7 @@
#define PRIxOBJPTR PRIxOBJPTR_(GC_MODEL_BITSIZE)
#define FMTOBJPTR "0x%016"PRIxOBJPTR
-#if GC_MODEL_NONPTR
+#if GC_MODEL_NONOBJPTR
#define BOGUS_OBJPTR (objptr)0x1
#else
#error gc model does not admit bogus object pointer
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.h 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/object.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -11,10 +11,10 @@
* array, normal (fixed size), stack, and weak.
*/
typedef enum {
- ARRAY_TAG,
- NORMAL_TAG,
- STACK_TAG,
- WEAK_TAG,
+ ARRAY_TAG,
+ NORMAL_TAG,
+ STACK_TAG,
+ WEAK_TAG,
} GC_objectTypeTag;
/*
@@ -40,7 +40,7 @@
#define COUNTER_SHIFT 20
#define MARK_BITS 1
#define MARK_MASK 0x80000000
-#define MARK_SHIFT 3
+#define MARK_SHIFT 31
/* getHeaderp (p)
*
@@ -103,11 +103,11 @@
* object (and, hence, must be (2,1) or (3,0)).
*/
typedef struct {
- /* Keep tag first, at zero offset, since it is referenced most often. */
- GC_objectTypeTag tag;
- bool hasIdentity;
- uint16_t numNonObjptrs;
- uint16_t numObjptrs;
+ /* Keep tag first, at zero offset, since it is referenced most often. */
+ GC_objectTypeTag tag;
+ bool hasIdentity;
+ uint16_t numNonObjptrs;
+ uint16_t numObjptrs;
} GC_objectType;
enum {
/* The type indices here must agree with those in backend/rep-type.fun. */
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/pointer.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/pointer.h 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/pointer.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -7,6 +7,8 @@
*/
typedef unsigned char* pointer;
-#define POINTER_SIZE sizeof(pointer);
+#define POINTER_SIZE sizeof(pointer)
#define FMTPTR "0x%016"PRIxPTR
#define BOGUS_POINTER (pointer)0x1
+
+#define WORD_SIZE POINTER_SIZE
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.c (from rev 4097, mlton/branches/on-20050822-x86_64-branch/runtime/gc.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -0,0 +1,15 @@
+/* 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 bool ratiosOk (struct GC_ratios ratios) {
+ return 1.0 < ratios.grow
+ and 1.0 < ratios.nursery
+ and 1.0 < ratios.markCompact
+ and ratios.markCompact <= ratios.copy
+ and ratios.copy <= ratios.live;
+}
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h (from rev 4097, mlton/branches/on-20050822-x86_64-branch/runtime/gc.h)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc.h 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -0,0 +1,31 @@
+/* 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_ratios {
+ /* Only use generational GC with copying collection if the ratio of
+ * heap size to live data size is below copyGenerational.
+ */
+ float copyGenerational;
+ /* Minimum live ratio to use copying GC. */
+ float copy;
+ float grow;
+ /* Desired ratio of heap size to live data. */
+ float live;
+ /* Minimum live ratio to us mark-compact GC. */
+ float markCompact;
+ /* Only use generational GC with mark-compact collection if the
+ * ratio of heap size to live data size is below
+ * markCompactGenerational.
+ */
+ float markCompactGenerational;
+ /* As long as the ratio of bytes live to nursery size is greater
+ * than nurseryRatio, use minor GCs.
+ */
+ float nursery;
+ float threadShrink;
+};
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/stack.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -7,7 +7,7 @@
*/
static inline bool stackIsEmpty (GC_stack stack) {
- return 0 == stack->used;
+ return 0 == stack->used;
}
/* stackSlop returns the amount of "slop" space needed between the top
@@ -21,32 +21,42 @@
return stackSlop (s);
}
-static inline size_t stackBytes (GC_state s, size_t size) {
+static inline size_t stackNumBytes (GC_state s, size_t size) {
size_t res;
res = align (GC_STACK_HEADER_SIZE + sizeof (struct GC_stack) + size,
s->alignment);
if (DEBUG_STACKS)
- fprintf (stderr, "%zu = stackBytes (%zu)\n", res, size);
+ fprintf (stderr, "%zu = stackNumBytes (%zu)\n", res, size);
return res;
}
static inline pointer stackBottom (GC_state s, GC_stack stack) {
- pointer res;
-
- res = ((pointer)stack) + sizeof (struct GC_stack);
- assert (isAligned ((uintptr_t)res, s->alignment));
- return res;
+ pointer res;
+
+ res = ((pointer)stack) + sizeof (struct GC_stack);
+ assert (isAligned ((uintptr_t)res, s->alignment));
+ return res;
}
/* Pointer to the topmost word in use on the stack. */
static inline pointer stackTop (GC_state s, GC_stack stack) {
- return stackBottom (s, stack) + stack->used;
+ return stackBottom (s, stack) + stack->used;
}
+/* Pointer to the end of stack. */
+static inline pointer stackLimitPlusSlop (GC_state s, GC_stack stack) {
+ return stackBottom (s, stack) + stack->reserved;
+}
+
+/* The maximum value stackTop may take on. */
+static inline pointer stackLimit (GC_state s, GC_stack stack) {
+ return stackLimitPlusSlop (s, stack) - stackSlop (s);
+}
+
static inline uint32_t topFrameIndex (GC_state s, GC_stack stack) {
uint32_t res;
-
+
res =
getFrameIndexFromReturnAddress
(s, *(GC_returnAddress*)(stackTop (s, stack) - GC_RETURNADDRESS_SIZE));
@@ -72,7 +82,7 @@
static inline size_t stackReserved (GC_state s, size_t r) {
size_t res;
-
+
res = pad (s, r, GC_STACK_HEADER_SIZE + sizeof (struct GC_stack));
if (DEBUG_STACKS)
fprintf (stderr, "%zu = stackReserved (%zu)\n", res, r);
@@ -83,7 +93,7 @@
return stack->used + stackSlop (s) - topFrameSize(s, stack);
}
-void displayStack (GC_state s,
+void displayStack (__attribute__ ((unused)) GC_state s,
GC_stack stack,
FILE *stream) {
fprintf(stream,
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/statistics.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/statistics.h 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/statistics.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -24,10 +24,10 @@
uintmax_t numLimitChecks;
- unsigned int numCopyingGCs;
- unsigned int numHashConsGCs;
- unsigned int numMarkCompactGCs;
- unsigned int numMinorGCs;
+ uintmax_t numCopyingGCs;
+ uintmax_t numHashConsGCs;
+ uintmax_t numMarkCompactGCs;
+ uintmax_t numMinorGCs;
/* struct rusage ru_gc; /\* total resource usage spent in gc *\/ */
/* struct rusage ru_gcCopy; /\* resource usage in major copying gcs. *\/ */
@@ -37,6 +37,6 @@
struct GC_lastMajorStatistics {
size_t bytesLive; /* Number of bytes live at most recent major GC. */
- GC_MajorKind kind;
- unsigned int numMinorsGCs;
+ GC_majorKind kind;
+ uintmax_t numMinorsGCs;
};
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/sysvals.h (from rev 4097, mlton/branches/on-20050822-x86_64-branch/runtime/gc.h)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc.h 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/sysvals.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -0,0 +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.
+ */
+
+struct GC_sysvals {
+ size_t ram;
+ size_t availRam;
+ size_t totalRam;
+ size_t pageSize;
+};
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.c 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.c 2005-10-08 20:36:15 UTC (rev 4098)
@@ -6,16 +6,6 @@
* See the file MLton-LICENSE for details.
*/
-static inline GC_thread currentThread (GC_state s) {
- pointer p = objptrToPointer(s->currentThread, s->heap.start);
- return (GC_thread)p;
-}
-
-static inline objptr currentThreadStack (GC_state s) {
- GC_thread ct = currentThread (s);
- return ct->stack;
-}
-
void displayThread (GC_state s,
GC_thread thread,
FILE *stream) {
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.h 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/util.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -19,11 +19,11 @@
#include <stddef.h>
#include <stdbool.h>
#include <iso646.h>
-#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdlib.h>
-#include <limits.h>
+#include <stdio.h>
#include <string.h>
#include "../assert.h"
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/virtual-memory.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/virtual-memory.h 2005-09-22 22:02:42 UTC (rev 4097)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/virtual-memory.h 2005-10-08 20:36:15 UTC (rev 4098)
@@ -6,6 +6,8 @@
* See the file MLton-LICENSE for details.
*/
+void *GC_mmapAnon (size_t length);
void *GC_mmap (void *start, size_t length);
-void *GC_mmapAnon (size_t length);
void *GC_munmap (void *base, size_t length);
+void GC_release (void *base, size_t length);
+void GC_decommit (void *base, size_t length);