[MLton-commit] r4145
Matthew Fluet
MLton@mlton.org
Thu, 3 Nov 2005 19:53:13 -0800
Yet more cleanup
----------------------------------------------------------------------
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/array-allocate.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
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.h
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/done.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/enter_leave.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.h
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/handler.c
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/handler.h
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/init-world.c
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/init-world.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/pack.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h
D mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/share.c
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/signals.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/signals.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/size.c
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/switch-thread.c
A mlton/branches/on-20050822-x86_64-branch/runtime/gc/switch-thread.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/weak.c
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/weak.h
U mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.c
----------------------------------------------------------------------
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/Makefile 2005-11-04 03:52:55 UTC (rev 4145)
@@ -88,6 +88,7 @@
copy-thread.c \
current.c \
dfs-mark.c \
+ done.c \
enter_leave.c \
foreach.c \
forward.c \
@@ -95,30 +96,33 @@
garbage-collection.c \
gc_state.c \
generational.c \
+ handler.c \
hash-cons.c \
heap.c \
heap_predicates.c \
+ init-world.c \
+ init.c \
invariant.c \
mark-compact.c \
model.c \
model_predicates.c \
new-object.c \
+ object-size.c \
object.c \
- object-size.c \
pack.c \
pointer.c \
pointer_predicates.c \
+ profiling.c \
share.c \
+ signals.c \
size.c \
stack.c \
stack_predicates.c \
+ switch-thread.c \
thread.c \
translate.c \
weak.c \
world.c \
- profiling.c \
- init.c \
- done.c \
assumptions.c \
gc_suffix.c
@@ -138,38 +142,41 @@
stack.h \
thread.h \
weak.h \
+ int-inf.h \
object-size.h \
- int-inf.h \
+ generational.h \
heap.h \
- major.h \
- generational.h \
current.h \
foreach.h \
- statistics.h \
+ translate.h \
sysvals.h \
- ratios.h \
controls.h \
+ major.h \
+ statistics.h \
forward.h \
cheney-copy.h \
hash-cons.h \
- profiling.h \
- signals.h \
- world.h \
- init.h \
- gc_state.h \
- translate.h \
+ dfs-mark.h \
+ mark-compact.h \
+ invariant.h \
atomic.h \
- invariant.h \
enter_leave.h \
- dfs-mark.h \
- mark-compact.h \
+ signals.h \
+ handler.h \
+ switch-thread.h \
+ garbage-collection.h \
new-object.h \
- garbage-collection.h \
array-allocate.h \
+ profiling.h \
+ init-world.h \
+ world.h \
+ init.h \
+ done.h \
copy-thread.h \
pack.h \
share.h \
size.h \
+ gc_state.h \
gc_suffix.h
all: libgc.o libgc-gdb.o
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO 2005-11-04 03:52:55 UTC (rev 4145)
@@ -18,3 +18,5 @@
* the "skipObjects" loop in forwardInterGenerationalObjptrs appears to
be unnecessary.
* Why do {load,save}Globals differ in the representation of the file?
+* Why does hash-table use malloc/free while generational maps use mmap/munmap?
+
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/array-allocate.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/array-allocate.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/array-allocate.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -42,9 +42,11 @@
/*uintToCommaString*/(arraySize),
/*uintToCommaString*/(ensureBytesFree));
if (arraySize >= s->controls.oldGenArraySize) {
- enter (s);
- doGC (s, arraySize, ensureBytesFree, FALSE, TRUE);
- leave (s);
+ if (not hasHeapBytesFree (s, arraySize, ensureBytesFree)) {
+ enter (s);
+ performGC (s, arraySize, ensureBytesFree, FALSE, TRUE);
+ leave (s);
+ }
frontier = s->heap.start + s->heap.oldGenSize;
last = frontier + arraySize;
s->heap.oldGenSize += arraySize;
@@ -53,9 +55,9 @@
size_t bytesRequested;
bytesRequested = arraySize + ensureBytesFree;
- if (bytesRequested > (size_t)(s->limitPlusSlop - s->frontier)) {
+ if (not hasHeapBytesFree (s, 0, bytesRequested)) {
enter (s);
- doGC (s, 0, bytesRequested, FALSE, TRUE);
+ performGC (s, 0, bytesRequested, FALSE, TRUE);
leave (s);
}
frontier = s->frontier;
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -42,3 +42,27 @@
GC_arrayCounter getArrayCounter (pointer a) {
return *(getArrayCounterp (a));
}
+
+pointer indexArrayAtPointerIndex (GC_state s, pointer a,
+ GC_arrayCounter arrayIndex,
+ uint32_t pointerIndex) {
+ GC_header header;
+ uint16_t numNonObjptrs;
+ uint16_t numObjptrs;
+ GC_objectTypeTag tag;
+
+ header = getHeader (a);
+ splitHeader(s, header, &tag, NULL, &numNonObjptrs, &numObjptrs);
+ assert (tag == ARRAY_TAG);
+
+ size_t nonObjptrBytesPerElement =
+ sizeofNumNonObjptrs (ARRAY_TAG, numNonObjptrs);
+ size_t bytesPerElement =
+ nonObjptrBytesPerElement
+ + (numObjptrs * OBJPTR_SIZE);
+
+ return a
+ + arrayIndex * bytesPerElement
+ + nonObjptrBytesPerElement
+ + pointerIndex * 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-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/array.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -32,3 +32,6 @@
GC_arrayLength getArrayLength (pointer a);
GC_arrayCounter* getArrayCounterp (pointer a);
GC_arrayCounter getArrayCounter (pointer a);
+pointer indexArrayAtPointerIndex (GC_state s, pointer a,
+ GC_arrayCounter arrayIndex,
+ uint32_t pointerIndex);
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-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -103,7 +103,7 @@
if (DEBUG_GENERATIONAL)
fprintf (stderr, "minorGC nursery = "FMTPTR" frontier = "FMTPTR"\n",
(uintptr_t)s->heap.nursery, (uintptr_t)s->frontier);
- assert (invariant (s));
+ assert (invariantForGC (s));
bytesAllocated = s->frontier - s->heap.nursery;
if (bytesAllocated == 0)
return;
@@ -122,7 +122,7 @@
fprintf (stderr, "toStart = "FMTPTR"\n", (uintptr_t)s->forwardState.toStart);
assert (isAlignedFrontier (s, s->forwardState.toStart));
s->forwardState.toLimit = s->forwardState.toStart + bytesAllocated;
- assert (invariant (s));
+ assert (invariantForGC (s));
s->cumulativeStatistics.numMinorGCs++;
s->lastMajorStatistics.numMinorGCs++;
s->forwardState.back = s->forwardState.toStart;
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -14,5 +14,6 @@
return
DEBUG
or s->controls.summary
- or s->controls.messages;
+ or s->controls.messages
+ or s->controls.rusageMeasureGC;
}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.h 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/controls.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -6,6 +6,32 @@
* See the file MLton-LICENSE for details.
*/
+struct GC_ratios {
+ /* Minimum live ratio to use copying GC. */
+ float copy;
+ /* Only use generational GC with copying collection if the ratio of
+ * heap size to live data size is below copyGenerational.
+ */
+ float copyGenerational;
+ float grow;
+ float hashCons;
+ /* 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 ramSlop;
+ float threadShrink;
+};
+
struct GC_controls {
size_t fixedHeap; /* If 0, then no fixed heap. */
size_t maxHeap; /* if zero, then unlimited, else limit total heap */
@@ -14,6 +40,7 @@
bool messages; /* Print a message at the start and end of each gc. */
size_t oldGenArraySize; /* Arrays larger are allocated in old gen, if possible. */
struct GC_ratios ratios;
+ bool rusageMeasureGC;
bool summary; /* Print a summary of gc info when program exits. */
};
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -6,24 +6,6 @@
* See the file MLton-LICENSE for details.
*/
-GC_thread newThread (GC_state s, size_t reserved) {
- GC_stack stack;
- GC_thread thread;
-
- ensureFree (s, sizeofStackWithHeaderAligned (s, reserved) + sizeofThread (s));
- stack = newStack (s, reserved, FALSE);
- thread = (GC_thread) newObject (s, GC_THREAD_HEADER,
- sizeofThread (s),
- FALSE);
- thread->bytesNeeded = 0;
- thread->exnStack = BOGUS_EXN_STACK;
- thread->stack = pointerToObjptr((pointer)stack, s->heap.start);
- if (DEBUG_THREADS)
- fprintf (stderr, FMTPTR" = newThreadOfSize (%zu)\n",
- (uintptr_t)thread, reserved);;
- return thread;
-}
-
GC_thread copyThread (GC_state s, GC_thread from, size_t size) {
GC_thread to;
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.h 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/copy-thread.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -6,7 +6,6 @@
* See the file MLton-LICENSE for details.
*/
-GC_thread newThread (GC_state s, size_t stackSize);
GC_thread copyThread (GC_state s, GC_thread from, size_t size);
void GC_copyCurrentThread (GC_state s);
pointer GC_copyThread (GC_state s, pointer p);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -10,46 +10,22 @@
/* Depth-first Marking */
/* ---------------------------------------------------------------- */
-bool isMarked (pointer p) {
+bool isPointerMarked (pointer p) {
return MARK_MASK & getHeader (p);
}
-bool isMarkedMode (GC_markMode m, pointer p) {
+bool isPointerMarkedByMode (pointer p, GC_markMode m) {
switch (m) {
case MARK_MODE:
- return isMarked (p);
+ return isPointerMarked (p);
case UNMARK_MODE:
- return not isMarked (p);
+ return not isPointerMarked (p);
default:
die ("bad mark mode %u", m);
}
}
-pointer arrayIndexAtPointer (GC_state s, pointer a,
- GC_arrayCounter arrayIndex,
- uint32_t pointerIndex) {
- GC_header header;
- uint16_t numNonObjptrs;
- uint16_t numObjptrs;
- GC_objectTypeTag tag;
-
- header = getHeader (a);
- splitHeader(s, header, &tag, NULL, &numNonObjptrs, &numObjptrs);
- assert (tag == ARRAY_TAG);
-
- size_t nonObjptrBytesPerElement =
- sizeofNumNonObjptrs (ARRAY_TAG, numNonObjptrs);
- size_t bytesPerElement =
- nonObjptrBytesPerElement
- + (numObjptrs * OBJPTR_SIZE);
-
- return a
- + arrayIndex * bytesPerElement
- + nonObjptrBytesPerElement
- + pointerIndex * OBJPTR_SIZE;
-}
-
-/* dfsMark (s, r, m, shc)
+/* dfsMarkByMode (s, r, m, shc)
*
* Sets all the mark bits in the object graph pointed to by r.
*
@@ -60,8 +36,8 @@
*
* It returns the total size in bytes of the objects marked.
*/
-size_t dfsMark (GC_state s, pointer root,
- GC_markMode mode, bool shouldHashCons) {
+size_t dfsMarkByMode (GC_state s, pointer root,
+ GC_markMode mode, bool shouldHashCons) {
GC_header mark; /* Used to set or clear the mark bit. */
size_t size; /* Total number of bytes marked. */
pointer cur; /* The current object being marked. */
@@ -82,7 +58,7 @@
GC_frameLayout frameLayout;
GC_frameOffsets frameOffsets;
- if (isMarkedMode (mode, root))
+ if (isPointerMarkedByMode (root, mode))
/* Object has already been marked. */
return 0;
mark = (MARK_MODE == mode) ? MARK_MASK : 0;
@@ -107,7 +83,7 @@
" prev = "FMTPTR" todo = "FMTPTR"\n",
(uintptr_t)cur, (uintptr_t)next,
(uintptr_t)prev, (uintptr_t)todo);
- assert (not isMarkedMode (mode, next));
+ assert (not isPointerMarkedByMode (next, mode));
assert (nextHeaderp == getHeaderp (next));
assert (nextHeader == getHeader (next));
// assert (*(pointer*) todo == next);
@@ -128,7 +104,7 @@
* headerp points to the header of cur.
* header is the header of cur.
*/
- assert (not isMarkedMode (mode, cur));
+ assert (not isPointerMarkedByMode (cur, mode));
assert (header == getHeader (cur));
assert (headerp == getHeaderp (cur));
header ^= MARK_MASK;
@@ -215,14 +191,14 @@
arrayIndex, index);
assert (arrayIndex < getArrayLength (cur));
assert (index < numObjptrs);
- assert (todo == arrayIndexAtPointer (s, cur, arrayIndex, index));
+ assert (todo == indexArrayAtPointerIndex (s, cur, arrayIndex, index));
// next = *(pointer*)todo;
next = fetchObjptrToPointer (todo, s->heap.start);
if (not (isPointer(next))) {
markNextInArray:
assert (arrayIndex < getArrayLength (cur));
assert (index < numObjptrs);
- assert (todo == arrayIndexAtPointer (s, cur, arrayIndex, index));
+ assert (todo == indexArrayAtPointerIndex (s, cur, arrayIndex, index));
todo += OBJPTR_SIZE;
index++;
if (index < numObjptrs)
@@ -305,7 +281,7 @@
if (DEBUG_MARK_COMPACT)
fprintf (stderr, "return cur = "FMTPTR" prev = "FMTPTR"\n",
(uintptr_t)cur, (uintptr_t)prev);
- assert (isMarkedMode (mode, cur));
+ assert (isPointerMarkedByMode (cur, mode));
if (NULL == prev)
return size;
next = cur;
@@ -356,23 +332,23 @@
assert (FALSE);
}
-void dfsMarkTrue (GC_state s, objptr *opp) {
+void dfsMarkWithHashCons (GC_state s, objptr *opp) {
pointer p;
p = objptrToPointer (*opp, s->heap.start);
- dfsMark (s, p, MARK_MODE, TRUE);
+ dfsMarkByMode (s, p, MARK_MODE, TRUE);
}
-void dfsMarkFalse (GC_state s, objptr *opp) {
+void dfsMarkWithoutHashCons (GC_state s, objptr *opp) {
pointer p;
p = objptrToPointer (*opp, s->heap.start);
- dfsMark (s, p, MARK_MODE, FALSE);
+ dfsMarkByMode (s, p, MARK_MODE, FALSE);
}
void dfsUnmark (GC_state s, objptr *opp) {
pointer p;
p = objptrToPointer (*opp, s->heap.start);
- dfsMark (s, p, UNMARK_MODE, FALSE);
+ dfsMarkByMode (s, p, UNMARK_MODE, FALSE);
}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.h 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/dfs-mark.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -11,14 +11,10 @@
UNMARK_MODE,
} GC_markMode;
-bool isMarked (pointer p);
-bool isMarkedMode (GC_markMode m, pointer p);
-pointer arrayIndexAtPointer (GC_state s,
- pointer a,
- GC_arrayCounter arrayIndex,
- uint32_t pointerIndex);
-size_t dfsMark (GC_state s, pointer root,
- GC_markMode mode, bool shouldHashCons);
-void dfsMarkTrue (GC_state s, objptr *opp);
-void dfsMarkFalse (GC_state s, objptr *opp);
+bool isPointerMarked (pointer p);
+bool isPointerMarkedByMode (pointer p, GC_markMode m);
+size_t dfsMarkByMode (GC_state s, pointer root,
+ GC_markMode mode, bool shouldHashCons);
+void dfsMarkWithHashCons (GC_state s, objptr *opp);
+void dfsMarkWithoutHashCons (GC_state s, objptr *opp);
void dfsUnmark (GC_state s, objptr *opp);
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/done.h (from rev 4143, mlton/branches/on-20050822-x86_64-branch/runtime/gc/done.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/done.c 2005-11-04 00:12:48 UTC (rev 4143)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/done.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -0,0 +1,9 @@
+/* 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.
+ */
+
+void GC_done (GC_state s);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/enter_leave.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/enter_leave.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/enter_leave.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -20,7 +20,7 @@
if (DEBUG)
displayGCState (s, stderr);
beginAtomic (s);
- assert (invariant (s));
+ assert (invariantForGC (s));
if (DEBUG)
fprintf (stderr, "enter ok\n");
}
@@ -31,7 +31,7 @@
/* The mutator frontier invariant may not hold
* for functions that don't ensureBytesFree.
*/
- assert (mutatorInvariant (s, FALSE, TRUE));
+ assert (invariantForMutator (s, FALSE, TRUE));
endAtomic (s);
if (DEBUG)
fprintf (stderr, "leave ok\n");
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -47,6 +47,21 @@
assert (s->heap.oldGenSize + bytesRequested <= s->heap.size);
}
+void growStackCurrent (GC_state s) {
+ size_t size;
+ GC_stack stack;
+
+ size = sizeofStackGrow (s, getStackCurrent(s));
+ if (DEBUG_STACKS or s->controls.messages)
+ fprintf (stderr, "Growing stack to size %zu.\n",
+ /*uintToCommaString*/(sizeofStackWithHeaderAligned (s, size)));
+ assert (hasHeapBytesFree (s, sizeofStackWithHeaderAligned (s, size), 0));
+ stack = newStack (s, size, TRUE);
+ copyStack (s, getStackCurrent(s), stack);
+ getThreadCurrent(s)->stack = pointerToObjptr ((pointer)stack, s->heap.start);
+ markCard (s, objptrToPointer (getThreadCurrentObjptr(s), s->heap.start));
+}
+
void enterGC (GC_state s) {
if (s->profiling.isOn) {
/* We don't need to profileEnter for count profiling because it
@@ -69,11 +84,11 @@
s->amInGC = FALSE;
}
-void doGC (GC_state s,
- size_t oldGenBytesRequested,
- size_t nurseryBytesRequested,
- bool forceMajor,
- bool mayResize) {
+void performGC (GC_state s,
+ size_t oldGenBytesRequested,
+ size_t nurseryBytesRequested,
+ bool forceMajor,
+ bool mayResize) {
uintmax_t gcTime;
bool stackTopOk;
size_t stackBytesRequested;
@@ -85,11 +100,11 @@
fprintf (stderr, "Starting gc. Request %zu nursery bytes and %zu old gen bytes.\n",
/*uintToCommaString*/(nurseryBytesRequested),
/*uintToCommaString*/(oldGenBytesRequested));
- assert (invariant (s));
+ assert (invariantForGC (s));
if (needGCTime (s))
startTiming (&ru_start);
minorGC (s);
- stackTopOk = mutatorStackInvariant (s);
+ stackTopOk = invariantForMutatorStack (s);
stackBytesRequested =
stackTopOk
? 0
@@ -106,7 +121,7 @@
assert (hasHeapBytesFree (s, oldGenBytesRequested + stackBytesRequested,
nurseryBytesRequested));
unless (stackTopOk)
- growStack (s);
+ growStackCurrent (s);
setGCStateCurrentThreadAndStack (s);
if (needGCTime (s)) {
gcTime = stopTiming (&ru_start, &s->cumulativeStatistics.ru_gc);
@@ -134,133 +149,33 @@
if (DEBUG)
displayGCState (s, stderr);
assert (hasHeapBytesFree (s, oldGenBytesRequested, nurseryBytesRequested));
- assert (invariant (s));
+ assert (invariantForGC (s));
leaveGC (s);
}
-void ensureMutatorInvariant (GC_state s, bool force) {
+void ensureInvariantForMutator (GC_state s, bool force) {
if (force
- or not (mutatorFrontierInvariant(s))
- or not (mutatorStackInvariant(s))) {
+ or not (invariantForMutatorFrontier(s))
+ or not (invariantForMutatorStack(s))) {
/* This GC will grow the stack, if necessary. */
- doGC (s, 0, getThreadCurrent(s)->bytesNeeded, force, TRUE);
+ performGC (s, 0, getThreadCurrent(s)->bytesNeeded, force, TRUE);
}
- assert (mutatorFrontierInvariant(s));
- assert (mutatorStackInvariant(s));
+ assert (invariantForMutatorFrontier(s));
+ assert (invariantForMutatorStack(s));
}
-/* ensureFree (s, b) ensures that upon return
- * b <= s->limitPlusSlop - s->frontier
+/* ensureHasHeapBytesFree (s, oldGen, nursery)
*/
-void ensureFree (GC_state s, size_t bytesRequested) {
+void ensureHasHeapBytesFree (GC_state s,
+ size_t oldGenBytesRequested,
+ size_t nurseryBytesRequested) {
+ assert (s->heap.nursery <= s->limitPlusSlop);
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));
+ if (not hasHeapBytesFree (s, oldGenBytesRequested, nurseryBytesRequested))
+ performGC (s, oldGenBytesRequested, nurseryBytesRequested, FALSE, TRUE);
+ assert (hasHeapBytesFree (s, oldGenBytesRequested, nurseryBytesRequested));
}
-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;
- setGCStateCurrentThreadAndStack (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;
-}
-
-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, size_t ensureBytesFree) {
- if (DEBUG_THREADS)
- fprintf (stderr, "GC_switchToThread ("FMTPTR", %zu)\n",
- (uintptr_t)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);
- getThreadCurrent(s)->bytesNeeded = ensureBytesFree;
- switchToThread (s, pointerToObjptr((pointer)t, s->heap.start));
- s->atomicState--;
- maybeSwitchToHandler (s);
- ensureMutatorInvariant (s, FALSE);
- assert (mutatorFrontierInvariant(s));
- assert (mutatorStackInvariant(s));
- leave (s);
- } else {
- /* BEGIN: enter(s); */
- getStackCurrent(s)->used = sizeofGCStateCurrentStackUsed (s);
- getThreadCurrent(s)->exnStack = s->exnStack;
- beginAtomic (s);
- /* END: enter(s); */
- getThreadCurrent(s)->bytesNeeded = ensureBytesFree;
- switchToThread (s, pointerToObjptr((pointer)t, s->heap.start));
- s->atomicState--;
- maybeSwitchToHandler (s);
- /* BEGIN: ensureMutatorInvariant */
- if (not (mutatorFrontierInvariant(s))
- or not (mutatorStackInvariant(s))) {
- /* This GC will grow the stack, if necessary. */
- doGC (s, 0, getThreadCurrent(s)->bytesNeeded, FALSE, TRUE);
- }
- /* END: ensureMutatorInvariant */
- /* BEGIN: leave(s); */
- endAtomic (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)
@@ -272,9 +187,9 @@
if (0 == bytesRequested)
bytesRequested = GC_HEAP_LIMIT_SLOP;
getThreadCurrent(s)->bytesNeeded = bytesRequested;
- maybeSwitchToHandler (s);
- ensureMutatorInvariant (s, force);
- assert (mutatorFrontierInvariant(s));
- assert (mutatorStackInvariant(s));
+ switchToHandlerThreadIfNonAtomicAndSignalPending (s);
+ ensureInvariantForMutator (s, force);
+ assert (invariantForMutatorFrontier(s));
+ assert (invariantForMutatorStack(s));
leave (s);
}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.h 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -8,19 +8,17 @@
void minorGC (GC_state s);
void majorGC (GC_state s, size_t bytesRequested, bool mayResize);
+void growStackCurrent (GC_state s);
void enterGC (GC_state s);
void leaveGC (GC_state s);
-void doGC (GC_state s,
- size_t oldGenBytesRequested,
- size_t nurseryBytesRequested,
- bool forceMajor,
- bool mayResize);
-void ensureMutatorInvariant (GC_state s, bool force);
-void ensureFree (GC_state s, size_t bytesRequested);
-void switchToThread (GC_state s, objptr op);
-void GC_startHandler (GC_state s);
-void GC_finishHandler (GC_state s);
-void maybeSwitchToHandler (GC_state s);
-void GC_switchToThread (GC_state s, GC_thread t, size_t ensureBytesFree);
+void performGC (GC_state s,
+ size_t oldGenBytesRequested,
+ size_t nurseryBytesRequested,
+ bool forceMajor,
+ bool mayResize);
+void ensureInvariantForMutator (GC_state s, bool force);
+void ensureHasHeapBytesFree (GC_state s,
+ size_t oldGenBytesRequested,
+ size_t nurseryBytesRequested);
void GC_gc (GC_state s, size_t bytesRequested, bool force,
char *file, int line);
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/handler.c (from rev 4143, mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c 2005-11-04 00:12:48 UTC (rev 4143)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/handler.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -0,0 +1,68 @@
+/* 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.
+ */
+
+/* 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;
+}
+
+void switchToHandlerThreadIfNonAtomicAndSignalPending (GC_state s) {
+ if (s->atomicState == 1
+ and s->signalsInfo.signalIsPending) {
+ GC_startHandler (s);
+ switchToThread (s, s->signalHandlerThread);
+ }
+}
+
+/* GC_handler sets s->limit = 0 so that the next limit check will
+ * fail. Signals need to be blocked during the handler (i.e. it
+ * should run atomically) because sigaddset does both a read and a
+ * write of s->signalsInfo.signalsPending. The signals are blocked
+ * by Posix_Signal_handle (see Posix/Signal/Signal.c).
+ */
+void GC_handler (GC_state s, int signum) {
+ if (DEBUG_SIGNALS)
+ fprintf (stderr, "GC_handler signum = %d\n", signum);
+ assert (sigismember (&s->signalsInfo.signalsHandled, signum));
+ if (s->atomicState == 0)
+ s->limit = 0;
+ s->signalsInfo.signalIsPending = TRUE;
+ sigaddset (&s->signalsInfo.signalsPending, signum);
+ if (DEBUG_SIGNALS)
+ fprintf (stderr, "GC_handler done\n");
+}
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/handler.h (from rev 4143, mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.h)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.h 2005-11-04 00:12:48 UTC (rev 4143)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/handler.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -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.
+ */
+
+void GC_startHandler (GC_state s);
+void GC_finishHandler (GC_state s);
+void switchToHandlerThreadIfNonAtomicAndSignalPending (GC_state s);
+void GC_handler (GC_state s, int signum);
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/init-world.c (from rev 4143, mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c 2005-11-04 00:12:48 UTC (rev 4143)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/init-world.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -0,0 +1,200 @@
+/* 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.
+ */
+
+/* ---------------------------------------------------------------- */
+/* Initialization */
+/* ---------------------------------------------------------------- */
+
+
+size_t sizeofInitialBytesLive (GC_state s) {
+ uint32_t i;
+ size_t numBytes;
+ size_t total;
+
+ total = 0;
+ for (i = 0; i < s->intInfInitsLength; ++i) {
+ numBytes =
+ sizeof(uint32_t) // for the sign
+ + strlen (s->intInfInits[i].mlstr);
+ total += align (GC_ARRAY_HEADER_SIZE
+ + numBytes,
+ s->alignment);
+ }
+ for (i = 0; i < s->vectorInitsLength; ++i) {
+ numBytes =
+ s->vectorInits[i].bytesPerElement
+ * s->vectorInits[i].numElements;
+ total += align (GC_ARRAY_HEADER_SIZE
+ + ((0 == numBytes)
+ ? OBJPTR_SIZE
+ : numBytes),
+ s->alignment);
+ }
+ return total;
+}
+
+void initIntInfs (GC_state s) {
+ struct GC_intInfInit *inits;
+ pointer frontier;
+ char *str;
+ size_t slen, llen;
+ mp_size_t alen;
+ uint32_t i, j;
+ bool neg, hex;
+ GC_intInf bp;
+ unsigned char *cp;
+
+ assert (isAlignedFrontier (s, s->frontier));
+ frontier = s->frontier;
+ for (i= 0; i < s->intInfInitsLength; i++) {
+ inits = &s->intInfInits[i];
+ str = inits->mlstr;
+ assert (inits->globalIndex < s->globalsLength);
+ neg = *str == '~';
+ if (neg)
+ str++;
+ slen = strlen (str);
+ hex = str[0] == '0' && str[1] == 'x';
+ if (hex) {
+ str += 2;
+ slen -= 2;
+ llen = (slen + 7) / 8;
+ } else
+ llen = (slen + 8) / 9;
+ assert (slen > 0);
+ bp = (GC_intInf)frontier;
+ cp = (unsigned char *)&bp->limbs[llen];
+
+ for (j = 0; j != slen; j++)
+ if ('0' <= str[j] && str[j] <= '9')
+ cp[j] = str[j] - '0' + 0;
+ else if ('a' <= str[j] && str[j] <= 'f')
+ cp[j] = str[j] - 'a' + 0xa;
+ else {
+ assert('A' <= str[j] && str[j] <= 'F');
+ cp[j] = str[j] - 'A' + 0xA;
+ }
+ alen = mpn_set_str ((mp_limb_t*)(bp->limbs), cp, slen, hex ? 0x10 : 10);
+ assert ((size_t)alen <= llen);
+ if (alen <= 1) {
+ uint32_t val, ans;
+
+ if (alen == 0)
+ val = 0;
+ else
+ val = bp->limbs[0];
+ if (neg) {
+ /*
+ * We only fit if val in [1, 2^30].
+ */
+ ans = - val;
+ val = val - 1;
+ } else
+ /*
+ * We only fit if val in [0, 2^30 - 1].
+ */
+ ans = val;
+ if (val < (uint32_t)1<<30) {
+ s->globals[inits->globalIndex] = (objptr)(ans<<1 | 1);
+ continue;
+ }
+ }
+ s->globals[inits->globalIndex] = pointerToObjptr((pointer)(&bp->isneg), s->heap.start);
+ bp->counter = 0;
+ bp->length = alen + 1;
+ bp->header = buildHeaderFromTypeIndex (WORD32_VECTOR_TYPE_INDEX);
+ bp->isneg = neg;
+ frontier = alignFrontier (s, (pointer)&bp->limbs[alen]);
+ }
+ assert (isAlignedFrontier (s, frontier));
+ GC_profileAllocInc (s, (size_t)(frontier - s->frontier));
+ s->frontier = frontier;
+ s->cumulativeStatistics.bytesAllocated += frontier - s->frontier;
+}
+
+void initVectors (GC_state s) {
+ struct GC_vectorInit *inits;
+ pointer frontier;
+ uint32_t i;
+
+ assert (isAlignedFrontier (s, s->frontier));
+ inits = s->vectorInits;
+ frontier = s->frontier;
+ for (i = 0; i < s->vectorInitsLength; i++) {
+ size_t bytesPerElement;
+ size_t dataBytes;
+ size_t objectSize;
+ uint32_t typeIndex;
+
+ bytesPerElement = inits[i].bytesPerElement;
+ dataBytes = bytesPerElement * inits[i].numElements;
+ objectSize = align (GC_ARRAY_HEADER_SIZE
+ + ((0 == dataBytes)
+ ? POINTER_SIZE
+ : dataBytes),
+ s->alignment);
+ assert (objectSize <= (size_t)(s->heap.start + s->heap.size - frontier));
+ *((GC_arrayCounter*)(frontier)) = 0;
+ frontier = frontier + GC_ARRAY_COUNTER_SIZE;
+ *((GC_arrayLength*)(frontier)) = inits[i].numElements;
+ frontier = frontier + GC_ARRAY_LENGTH_SIZE;
+ switch (bytesPerElement) {
+ case 1:
+ typeIndex = WORD8_VECTOR_TYPE_INDEX;
+ break;
+ case 2:
+ typeIndex = WORD16_VECTOR_TYPE_INDEX;
+ break;
+ case 4:
+ typeIndex = WORD32_VECTOR_TYPE_INDEX;
+ break;
+ default:
+ die ("unknown bytes per element in vectorInit: %zu",
+ bytesPerElement);
+ }
+ *((GC_header*)(frontier)) = buildHeaderFromTypeIndex (typeIndex);
+ frontier = frontier + GC_HEADER_SIZE;
+ s->globals[inits[i].globalIndex] = pointerToObjptr(frontier, s->heap.start);
+ if (DEBUG_DETAILED)
+ fprintf (stderr, "allocated vector at "FMTPTR"\n",
+ (uintptr_t)(s->globals[inits[i].globalIndex]));
+ GC_memcpy (inits[i].bytes, frontier, dataBytes);
+ frontier += objectSize - GC_ARRAY_HEADER_SIZE;
+ }
+ if (DEBUG_DETAILED)
+ fprintf (stderr, "frontier after string allocation is "FMTPTR"\n",
+ (uintptr_t)frontier);
+ GC_profileAllocInc (s, (size_t)(frontier - s->frontier));
+ s->cumulativeStatistics.bytesAllocated += (size_t)(frontier - s->frontier);
+ assert (isAlignedFrontier (s, frontier));
+ s->frontier = frontier;
+}
+
+void initWorld (GC_state s) {
+ uint32_t i;
+ pointer start;
+ GC_thread thread;
+
+ for (i = 0; i < s->globalsLength; ++i)
+ s->globals[i] = BOGUS_OBJPTR;
+ s->lastMajorStatistics.bytesLive = sizeofInitialBytesLive (s);
+ createHeap (s, &s->heap,
+ sizeofHeapDesired (s, s->lastMajorStatistics.bytesLive, 0),
+ s->lastMajorStatistics.bytesLive);
+ createCardMapAndCrossMap (s);
+ start = alignFrontier (s, s->heap.start);
+ s->frontier = start;
+ initIntInfs (s);
+ initVectors (s);
+ assert ((size_t)(s->frontier - start) <= s->lastMajorStatistics.bytesLive);
+ s->heap.oldGenSize = s->frontier - s->heap.start;
+ setGCStateCurrentHeap (s, 0, 0);
+ thread = newThread (s, sizeofStackInitial (s));
+ switchToThread (s, pointerToObjptr((pointer)thread, s->heap.start));
+}
+
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/init-world.h (from rev 4143, mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.h)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.h 2005-11-04 00:12:48 UTC (rev 4143)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/init-world.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -0,0 +1,36 @@
+/* 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.
+ */
+
+/* GC_init uses the array of struct intInfInits in s at program start
+ * to allocate intInfs.
+ * The globalIndex'th entry of the globals array in s is set to the
+ * IntInf.int whose value corresponds to the mlstr string.
+ *
+ * The strings pointed to by the mlstr fields consist of
+ * an optional ~
+ * either one or more of [0-9] or
+ * 0x followed by one or more of [0-9a-fA-F]
+ * a trailing EOS
+ */
+struct GC_intInfInit {
+ uint32_t globalIndex;
+ char *mlstr;
+};
+
+/* GC_init allocates a collection of arrays/vectors in the heap. */
+struct GC_vectorInit {
+ pointer bytes;
+ size_t bytesPerElement;
+ uint32_t globalIndex;
+ GC_arrayLength numElements;
+};
+
+size_t sizeofInitialBytesLive (GC_state s);
+void initIntInfs (GC_state s);
+void initVectors (GC_state s);
+void initWorld (GC_state s);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -10,19 +10,6 @@
/* Initialization */
/* ---------------------------------------------------------------- */
-static void initSignalStack (GC_state s) {
-#if HAS_SIGALTSTACK
- static stack_t altstack;
- size_t ss_size = align (SIGSTKSZ, s->sysvals.pageSize);
- size_t psize = s->sysvals.pageSize;
- void *ss_sp = GC_mmap_safe_protect (NULL, 2 * ss_size, psize, psize);
- altstack.ss_sp = (unsigned char*)ss_sp + ss_size;
- altstack.ss_size = ss_size;
- altstack.ss_flags = 0;
- sigaltstack (&altstack, NULL);
-#endif
-}
-
#if FALSE
static bool stringToBool (char *s) {
if (0 == strcmp (s, "false"))
@@ -77,200 +64,14 @@
die ("Invalid @MLton memory amount: %s.", s);
}
-static void setInitialBytesLive (GC_state s) {
- uint32_t i;
- size_t numBytes;
-
- s->lastMajorStatistics.bytesLive = 0;
- for (i = 0; i < s->intInfInitsLength; ++i) {
- numBytes =
- sizeof(uint32_t) // for the sign
- + strlen (s->intInfInits[i].mlstr);
- s->lastMajorStatistics.bytesLive +=
- align (GC_ARRAY_HEADER_SIZE + numBytes,
- s->alignment);
- }
- for (i = 0; i < s->vectorInitsLength; ++i) {
- numBytes =
- s->vectorInits[i].bytesPerElement
- * s->vectorInits[i].numElements;
- s->lastMajorStatistics.bytesLive +=
- align (GC_ARRAY_HEADER_SIZE
- + ((0 == numBytes)
- ? OBJPTR_SIZE
- : numBytes),
- s->alignment);
- }
-}
-
-static void initIntInfs (GC_state s) {
- struct GC_intInfInit *inits;
- pointer frontier;
- char *str;
- size_t slen, llen;
- mp_size_t alen;
- uint32_t i, j;
- bool neg, hex;
- GC_intInf bp;
- unsigned char *cp;
-
- assert (isAlignedFrontier (s, s->frontier));
- frontier = s->frontier;
- for (i= 0; i < s->intInfInitsLength; i++) {
- inits = &s->intInfInits[i];
- str = inits->mlstr;
- assert (inits->globalIndex < s->globalsLength);
- neg = *str == '~';
- if (neg)
- str++;
- slen = strlen (str);
- hex = str[0] == '0' && str[1] == 'x';
- if (hex) {
- str += 2;
- slen -= 2;
- llen = (slen + 7) / 8;
- } else
- llen = (slen + 8) / 9;
- assert (slen > 0);
- bp = (GC_intInf)frontier;
- cp = (unsigned char *)&bp->limbs[llen];
-
- for (j = 0; j != slen; j++)
- if ('0' <= str[j] && str[j] <= '9')
- cp[j] = str[j] - '0' + 0;
- else if ('a' <= str[j] && str[j] <= 'f')
- cp[j] = str[j] - 'a' + 0xa;
- else {
- assert('A' <= str[j] && str[j] <= 'F');
- cp[j] = str[j] - 'A' + 0xA;
- }
- alen = mpn_set_str ((mp_limb_t*)(bp->limbs), cp, slen, hex ? 0x10 : 10);
- assert ((size_t)alen <= llen);
- if (alen <= 1) {
- uint32_t val, ans;
-
- if (alen == 0)
- val = 0;
- else
- val = bp->limbs[0];
- if (neg) {
- /*
- * We only fit if val in [1, 2^30].
- */
- ans = - val;
- val = val - 1;
- } else
- /*
- * We only fit if val in [0, 2^30 - 1].
- */
- ans = val;
- if (val < (uint32_t)1<<30) {
- s->globals[inits->globalIndex] = (objptr)(ans<<1 | 1);
- continue;
- }
- }
- s->globals[inits->globalIndex] = pointerToObjptr((pointer)(&bp->isneg), s->heap.start);
- bp->counter = 0;
- bp->length = alen + 1;
- bp->header = buildHeaderFromTypeIndex (WORD32_VECTOR_TYPE_INDEX);
- bp->isneg = neg;
- frontier = alignFrontier (s, (pointer)&bp->limbs[alen]);
- }
- assert (isAlignedFrontier (s, frontier));
- GC_profileAllocInc (s, (size_t)(frontier - s->frontier));
- s->frontier = frontier;
- s->cumulativeStatistics.bytesAllocated += frontier - s->frontier;
-}
-
-static void initVectors (GC_state s) {
- struct GC_vectorInit *inits;
- pointer frontier;
- uint32_t i;
-
- assert (isAlignedFrontier (s, s->frontier));
- inits = s->vectorInits;
- frontier = s->frontier;
- for (i = 0; i < s->vectorInitsLength; i++) {
- size_t bytesPerElement;
- size_t dataBytes;
- size_t objectSize;
- uint32_t typeIndex;
-
- bytesPerElement = inits[i].bytesPerElement;
- dataBytes = bytesPerElement * inits[i].numElements;
- objectSize = align (GC_ARRAY_HEADER_SIZE
- + ((0 == dataBytes)
- ? POINTER_SIZE
- : dataBytes),
- s->alignment);
- assert (objectSize <= (size_t)(s->heap.start + s->heap.size - frontier));
- *((GC_arrayCounter*)(frontier)) = 0;
- frontier = frontier + GC_ARRAY_COUNTER_SIZE;
- *((GC_arrayLength*)(frontier)) = inits[i].numElements;
- frontier = frontier + GC_ARRAY_LENGTH_SIZE;
- switch (bytesPerElement) {
- case 1:
- typeIndex = WORD8_VECTOR_TYPE_INDEX;
- break;
- case 2:
- typeIndex = WORD16_VECTOR_TYPE_INDEX;
- break;
- case 4:
- typeIndex = WORD32_VECTOR_TYPE_INDEX;
- break;
- default:
- die ("unknown bytes per element in vectorInit: %zu",
- bytesPerElement);
- }
- *((GC_header*)(frontier)) = buildHeaderFromTypeIndex (typeIndex);
- frontier = frontier + GC_HEADER_SIZE;
- s->globals[inits[i].globalIndex] = pointerToObjptr(frontier, s->heap.start);
- if (DEBUG_DETAILED)
- fprintf (stderr, "allocated vector at "FMTPTR"\n",
- (uintptr_t)(s->globals[inits[i].globalIndex]));
- GC_memcpy (inits[i].bytes, frontier, dataBytes);
- frontier += objectSize - GC_ARRAY_HEADER_SIZE;
- }
- if (DEBUG_DETAILED)
- fprintf (stderr, "frontier after string allocation is "FMTPTR"\n",
- (uintptr_t)frontier);
- GC_profileAllocInc (s, (size_t)(frontier - s->frontier));
- s->cumulativeStatistics.bytesAllocated += (size_t)(frontier - s->frontier);
- assert (isAlignedFrontier (s, frontier));
- s->frontier = frontier;
-}
-
-static void newWorld (GC_state s) {
- uint32_t i;
- pointer start;
- GC_thread thread;
-
- for (i = 0; i < s->globalsLength; ++i)
- s->globals[i] = BOGUS_OBJPTR;
- setInitialBytesLive (s);
- createHeap (s, &s->heap,
- sizeofHeapDesired (s, s->lastMajorStatistics.bytesLive, 0),
- s->lastMajorStatistics.bytesLive);
- createCardMapAndCrossMap (s);
- start = alignFrontier (s, s->heap.start);
- s->frontier = start;
- initIntInfs (s);
- initVectors (s);
- assert ((size_t)(s->frontier - start) <= s->lastMajorStatistics.bytesLive);
- s->heap.oldGenSize = s->frontier - s->heap.start;
- setGCStateCurrentHeap (s, 0, 0);
- thread = newThread (s, sizeofStackInitial (s));
- switchToThread (s, pointerToObjptr((pointer)thread, s->heap.start));
-}
-
/* ---------------------------------------------------------------- */
/* GC_init */
/* ---------------------------------------------------------------- */
bool MLton_Platform_CygwinUseMmap;
-static int processAtMLton (GC_state s, int argc, char **argv,
- char **worldFile) {
+int processAtMLton (GC_state s, int argc, char **argv,
+ char **worldFile) {
int i;
i = 1;
@@ -479,7 +280,7 @@
s->signalsInfo.signalIsPending = FALSE;
sigemptyset (&s->signalsInfo.signalsHandled);
sigemptyset (&s->signalsInfo.signalsPending);
- s->startTime = currentTime ();
+ s->startTime = getCurrentTime ();
// s->sysvals.availRam = ;
// s->sysvals.totalRam = ;
// s->sysvals.pageSize = ;
@@ -497,7 +298,6 @@
unless (s->controls.ratios.markCompact <= s->controls.ratios.copy
and s->controls.ratios.copy <= s->controls.ratios.live)
die ("Ratios must satisfy mark-compact-ratio <= copy-ratio <= live-ratio");
- // s->totalRam = totalRam (s);
/* We align s->ram by pageSize so that we can test whether or not we
* we are using mark-compact by comparing heap size to ram size. If
* we didn't round, the size might be slightly off.
@@ -524,36 +324,18 @@
* command-line arguments, because those may just be doing a show
* prof, in which case we don't want to initialize the atExit.
*/
- if (PROFILE_NONE == s->profiling.kind)
- s->profiling.isOn = FALSE;
- else {
- s->profiling.isOn = TRUE;
- assert (s->profiling.frameSourcesLength == s->frameLayoutsLength);
- switch (s->profiling.kind) {
- case PROFILE_ALLOC:
- case PROFILE_COUNT:
- s->profiling.data = GC_profileNew (s);
- break;
- case PROFILE_NONE:
- die ("impossible PROFILE_NONE");
- case PROFILE_TIME:
- profileTimeInit (s);
- break;
- }
- profileEndState = s;
- atexit (profileEnd);
- }
+ initProfiling (s);
if (s->amOriginal) {
- newWorld (s);
+ initWorld (s);
/* The mutator stack invariant doesn't hold,
* because the mutator has yet to run.
*/
- assert (mutatorInvariant (s, TRUE, FALSE));
+ assert (invariantForMutator (s, TRUE, FALSE));
} else {
loadWorldFromFileName (s, worldFile);
if (s->profiling.isOn and s->profiling.stack)
foreachStackFrame (s, enterFrame);
- assert (mutatorInvariant (s, TRUE, TRUE));
+ assert (invariantForMutator (s, TRUE, TRUE));
}
s->amInGC = FALSE;
return res;
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.h 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -6,27 +6,6 @@
* See the file MLton-LICENSE for details.
*/
-
-/* GC_init uses the array of struct intInfInits in s at program start
- * to allocate intInfs.
- * The globalIndex'th entry of the globals array in s is set to the
- * IntInf.int whose value corresponds to the mlstr string.
- *
- * The strings pointed to by the mlstr fields consist of
- * an optional ~
- * either one or more of [0-9] or
- * 0x followed by one or more of [0-9a-fA-F]
- * a trailing EOS
- */
-struct GC_intInfInit {
- uint32_t globalIndex;
- char *mlstr;
-};
-
-/* GC_init allocates a collection of arrays/vectors in the heap. */
-struct GC_vectorInit {
- pointer bytes;
- size_t bytesPerElement;
- uint32_t globalIndex;
- GC_arrayLength numElements;
-};
+int processAtMLton (GC_state s, int argc,
+ char **argv, char **worldFile);
+int GC_init (GC_state s, int argc, char **argv);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -14,9 +14,9 @@
(uintptr_t)opp, *opp);
}
-bool invariant (GC_state s) {
+bool invariantForGC (GC_state s) {
if (DEBUG)
- fprintf (stderr, "invariant\n");
+ fprintf (stderr, "invariantForGC\n");
/* Frame layouts */
for (unsigned int i = 0; i < s->frameLayoutsLength; ++i) {
GC_frameLayout layout;
@@ -54,16 +54,16 @@
assert (s->secondaryHeap.start == NULL
or s->heap.size == s->secondaryHeap.size);
/* Check that all pointers are into from space. */
- foreachGlobalObjptr (s, assertObjptrIsInFromSpace);
+ foreachGlobalObjptr (s, assertIsObjptrInFromSpace);
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,
- assertObjptrIsInFromSpace, FALSE);
+ assertIsObjptrInFromSpace, FALSE);
if (DEBUG_DETAILED)
fprintf (stderr, "Checking nursery.\n");
foreachObjptrInRange (s, s->heap.nursery, &s->frontier,
- assertObjptrIsInFromSpace, FALSE);
+ assertIsObjptrInFromSpace, FALSE);
/* Current thread. */
GC_stack stack = getStackCurrent(s);
assert (isAlignedStackReserved (s, stack->reserved));
@@ -74,29 +74,29 @@
assert (stack->used == sizeofGCStateCurrentStackUsed (s));
assert (stack->used <= stack->reserved);
if (DEBUG)
- fprintf (stderr, "invariant passed\n");
+ fprintf (stderr, "invariantForGC passed\n");
return TRUE;
}
-bool mutatorFrontierInvariant (GC_state s) {
+bool invariantForMutatorFrontier (GC_state s) {
GC_thread thread = getThreadCurrent(s);
return (thread->bytesNeeded
<= (size_t)(s->limitPlusSlop - s->frontier));
}
-bool mutatorStackInvariant (GC_state s) {
+bool invariantForMutatorStack (GC_state s) {
GC_stack stack = getStackCurrent(s);
return (getStackTop (s, stack)
<= getStackLimit (s, stack) + getStackTopFrameSize (s, stack));
}
-bool mutatorInvariant (GC_state s, bool frontier, bool stack) {
+bool invariantForMutator (GC_state s, bool frontier, bool stack) {
if (DEBUG)
displayGCState (s, stderr);
if (frontier)
- assert (mutatorFrontierInvariant(s));
+ assert (invariantForMutatorFrontier(s));
if (stack)
- assert (mutatorStackInvariant(s));
- assert (invariant (s));
+ assert (invariantForMutatorStack(s));
+ assert (invariantForGC (s));
return TRUE;
}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.h 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -6,8 +6,8 @@
* See the file MLton-LICENSE for details.
*/
-void assertObjptrIsInFromSpace (GC_state s, objptr *opp);
-bool invariant (GC_state s);
-bool mutatorFrontierInvariant (GC_state s);
-bool mutatorStackInvariant (GC_state s);
-bool mutatorInvariant (GC_state s, bool frontier, bool stack);
+void assertIsObjptrInFromSpace (GC_state s, objptr *opp);
+bool invariantForGC (GC_state s);
+bool invariantForMutatorFrontier (GC_state s);
+bool invariantForMutatorStack (GC_state s);
+bool invariantForMutator (GC_state s, bool frontier, bool stack);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -12,8 +12,11 @@
/* An object pointer might be larger than a header.
*/
-void threadInternalCopy (pointer dst, pointer src) {
- size_t count = (OBJPTR_SIZE - GC_HEADER_SIZE) / GC_HEADER_SIZE;
+void copyForThreadInternal (pointer dst, pointer src) {
+ size_t count;
+
+ assert (0 == (OBJPTR_SIZE % GC_HEADER_SIZE));
+ count = (OBJPTR_SIZE - GC_HEADER_SIZE) / GC_HEADER_SIZE;
src = src + GC_HEADER_SIZE * count;
for (size_t i = 0; i <= count; i++) {
@@ -35,14 +38,14 @@
"threadInternal opp = "FMTPTR" p = "FMTPTR" header = "FMTHDR"\n",
(uintptr_t)opp, (uintptr_t)p, getHeader (p));
headerp = getHeaderp (p);
- threadInternalCopy ((pointer)(opp), (pointer)(headerp));
- threadInternalCopy ((pointer)(headerp), (pointer)(&opop));
+ copyForThreadInternal ((pointer)(opp), (pointer)(headerp));
+ copyForThreadInternal ((pointer)(headerp), (pointer)(&opop));
}
-/* If p is weak, the object pointer was valid, and points to an unmarked object,
- * then clear the object pointer.
+/* If p is weak, the object pointer was valid, and points to an
+ * unmarked object, then clear the object pointer.
*/
-void maybeClearWeak (GC_state s, pointer p) {
+void clearIfWeakAndUnmarkedForMarkCompact (GC_state s, pointer p) {
GC_header header;
GC_header *headerp;
uint16_t numNonObjptrs, numObjptrs;
@@ -52,14 +55,15 @@
header = *headerp;
splitHeader(s, *headerp, &tag, NULL, &numNonObjptrs, &numObjptrs);
if (WEAK_TAG == tag and 1 == numObjptrs) {
- GC_header h2;
+ GC_header objptrHeader;
if (DEBUG_WEAK)
- fprintf (stderr, "maybeClearWeak ("FMTPTR") header = "FMTHDR"\n",
+ fprintf (stderr, "clearIfWeakAndUnmarkedForMarkCompact ("FMTPTR") header = "FMTHDR"\n",
(uintptr_t)p, header);
- h2 = getHeader (objptrToPointer(((GC_weak)p)->objptr, s->heap.start));
- /* If it's unmarked not threaded, clear the weak pointer. */
- if (1 == ((MARK_MASK | 1) & h2)) {
+ objptrHeader = getHeader (objptrToPointer(((GC_weak)p)->objptr, s->heap.start));
+ /* If it's not threaded and unmarked, clear the weak pointer. */
+ if ((GC_VALID_HEADER_MASK & objptrHeader)
+ and not (MARK_MASK & objptrHeader)) {
((GC_weak)p)->objptr = BOGUS_OBJPTR;
header = GC_WEAK_GONE_HEADER | MARK_MASK;
if (DEBUG_WEAK)
@@ -70,7 +74,7 @@
}
}
-void updateForwardPointers (GC_state s) {
+void updateForwardPointersForMarkCompact (GC_state s) {
pointer back;
pointer endOfLastMarked;
pointer front;
@@ -95,14 +99,14 @@
p = advanceToObjectData (s, front);
headerp = getHeaderp (p);
header = *headerp;
- if (1 == (1 & header)) {
+ if (GC_VALID_HEADER_MASK & header) {
/* It's a header */
if (MARK_MASK & header) {
/* It is marked, but has no forward pointers.
* Thread internal pointers.
*/
thread:
- maybeClearWeak (s, p);
+ clearIfWeakAndUnmarkedForMarkCompact (s, p);
size = sizeofObject (s, p);
if (DEBUG_MARK_COMPACT)
fprintf (stderr, "threading "FMTPTR" of size %zu\n",
@@ -112,10 +116,10 @@
* (GC_ARRAY_HEADER_SIZE + OBJPTR_SIZE) space to be available
* because that is the smallest possible array. You cannot
* use GC_ARRAY_HEADER_SIZE because even zero-length arrays
- * require an extra word for the forwarding pointer. If you
- * did use GC_ARRAY_HEADER_SIZE,
- * updateBackwardPointersAndSlide would skip the extra word
- * and be completely busted.
+ * require extra space for the forwarding pointer. If you did
+ * use GC_ARRAY_HEADER_SIZE,
+ * updateBackwardPointersAndSlideForMarkCompact would skip the
+ * extra space and be completely busted.
*/
if (DEBUG_MARK_COMPACT)
fprintf (stderr, "compressing from "FMTPTR" to "FMTPTR" (length = %zu)\n",
@@ -142,7 +146,7 @@
pointer new;
objptr newObjptr;
- assert (0 == (1 & header));
+ assert (not (GC_VALID_HEADER_MASK & header));
/* It's a pointer. This object must be live. Fix all the forward
* pointers to it, store its header, then thread its internal
* pointers.
@@ -153,10 +157,10 @@
pointer cur;
objptr curObjptr;
- threadInternalCopy ((pointer)(&curObjptr), (pointer)headerp);
+ copyForThreadInternal ((pointer)(&curObjptr), (pointer)headerp);
cur = objptrToPointer (curObjptr, s->heap.start);
- threadInternalCopy ((pointer)headerp, cur);
+ copyForThreadInternal ((pointer)headerp, cur);
*((objptr*)cur) = newObjptr;
header = *headerp;
@@ -168,7 +172,7 @@
return;
}
-void updateBackwardPointersAndSlide (GC_state s) {
+void updateBackwardPointersAndSlideForMarkCompact (GC_state s) {
pointer back;
pointer front;
size_t gap;
@@ -191,7 +195,7 @@
p = advanceToObjectData (s, front);
headerp = getHeaderp (p);
header = *headerp;
- if (1 == (1 & header)) {
+ if (GC_VALID_HEADER_MASK & header) {
/* It's a header */
if (MARK_MASK & header) {
/* It is marked, but has no backward pointers to it.
@@ -225,7 +229,7 @@
pointer new;
objptr newObjptr;
- assert (0 == (1 & header));
+ assert (not (GC_VALID_HEADER_MASK & header));
/* It's a pointer. This object must be live. Fix all the
* backward pointers to it. Then unmark it.
*/
@@ -235,10 +239,10 @@
pointer cur;
objptr curObjptr;
- threadInternalCopy ((pointer)(&curObjptr), (pointer)headerp);
+ copyForThreadInternal ((pointer)(&curObjptr), (pointer)headerp);
cur = objptrToPointer (curObjptr, s->heap.start);
- threadInternalCopy ((pointer)headerp, cur);
+ copyForThreadInternal ((pointer)headerp, cur);
*((objptr*)cur) = newObjptr;
header = *headerp;
@@ -270,14 +274,14 @@
s->lastMajorStatistics.bytesHashConsed = 0;
s->cumulativeStatistics.numHashConsGCs++;
s->objectHashTable = allocHashTable (s);
- foreachGlobalObjptr (s, dfsMarkTrue);
+ foreachGlobalObjptr (s, dfsMarkWithHashCons);
freeHashTable (s->objectHashTable);
} else {
- foreachGlobalObjptr (s, dfsMarkFalse);
+ foreachGlobalObjptr (s, dfsMarkWithoutHashCons);
}
foreachGlobalObjptr (s, threadInternalObjptr);
- updateForwardPointers (s);
- updateBackwardPointersAndSlide (s);
+ updateForwardPointersForMarkCompact (s);
+ updateBackwardPointersAndSlideForMarkCompact (s);
clearCrossMap (s);
s->cumulativeStatistics.bytesMarkCompacted += s->heap.oldGenSize;
s->lastMajorStatistics.kind = GC_MARK_COMPACT;
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.h 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/mark-compact.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -6,9 +6,9 @@
* See the file MLton-LICENSE for details.
*/
-void threadInternalCopy (pointer dst, pointer src);
+void copyForThreadInternal (pointer dst, pointer src);
void threadInternalObjptr (GC_state s, objptr *opp);
-void maybeClearWeak (GC_state s, pointer p);
-void updateForwardPointers (GC_state s);
-void updateBackwardPointersAndSlide (GC_state s);
+void clearIfWeakAndUnmarkedForMarkCompact (GC_state s, pointer p);
+void updateForwardPointersForMarkCompact (GC_state s);
+void updateBackwardPointersAndSlideForMarkComact (GC_state s);
void majorMarkCompactGC (GC_state s);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -54,9 +54,9 @@
reserved = alignStackReserved (s, reserved);
if (reserved > s->cumulativeStatistics.maxStackSizeSeen)
s->cumulativeStatistics.maxStackSizeSeen = reserved;
- stack = (GC_stack) newObject (s, GC_STACK_HEADER,
+ stack = (GC_stack)(newObject (s, GC_STACK_HEADER,
sizeofStackWithHeaderAligned (s, reserved),
- allocInOldGen);
+ allocInOldGen));
stack->reserved = reserved;
stack->used = 0;
if (DEBUG_STACKS)
@@ -66,17 +66,20 @@
return stack;
}
-void growStack (GC_state s) {
- size_t size;
+GC_thread newThread (GC_state s, size_t reserved) {
GC_stack stack;
+ GC_thread thread;
- size = sizeofStackGrow (s, getStackCurrent(s));
- if (DEBUG_STACKS or s->controls.messages)
- fprintf (stderr, "Growing stack to size %zu.\n",
- /*uintToCommaString*/(sizeofStackWithHeaderAligned (s, size)));
- assert (hasHeapBytesFree (s, sizeofStackWithHeaderAligned (s, size), 0));
- stack = newStack (s, size, TRUE);
- copyStack (s, getStackCurrent(s), stack);
- getThreadCurrent(s)->stack = pointerToObjptr ((pointer)stack, s->heap.start);
- markCard (s, objptrToPointer (getThreadCurrentObjptr(s), s->heap.start));
+ ensureHasHeapBytesFree (s, 0, sizeofStackWithHeaderAligned (s, reserved) + sizeofThread (s));
+ stack = newStack (s, reserved, FALSE);
+ thread = (GC_thread)(newObject (s, GC_THREAD_HEADER,
+ sizeofThread (s),
+ FALSE));
+ thread->bytesNeeded = 0;
+ thread->exnStack = BOGUS_EXN_STACK;
+ thread->stack = pointerToObjptr((pointer)stack, s->heap.start);
+ if (DEBUG_THREADS)
+ fprintf (stderr, FMTPTR" = newThreadOfSize (%zu)\n",
+ (uintptr_t)thread, reserved);;
+ return thread;
}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.h 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/new-object.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -9,4 +9,4 @@
pointer newObject (GC_state s, GC_header header,
size_t bytesRequested, bool allocInOldGen);
GC_stack newStack (GC_state s, size_t reserved, bool allocInOldGen);
-void growStack (GC_state s);
+GC_thread newThread (GC_state s, size_t stackSize);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/pack.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/pack.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/pack.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -17,7 +17,7 @@
* allocated since the last collection. But you would still need to
* do a minor GC to make all objects contiguous.
*/
- doGC (s, 0, 0, TRUE, FALSE);
+ performGC (s, 0, 0, TRUE, FALSE);
keep = s->heap.oldGenSize * 1.1;
if (keep <= s->heap.size) {
shrinkHeap (s, &s->heap, keep);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -520,3 +520,25 @@
GC_profileWrite (s, s->profiling.data, fd);
}
}
+
+void initProfiling (GC_state s) {
+ if (PROFILE_NONE == s->profiling.kind)
+ s->profiling.isOn = FALSE;
+ else {
+ s->profiling.isOn = TRUE;
+ assert (s->profiling.frameSourcesLength == s->frameLayoutsLength);
+ switch (s->profiling.kind) {
+ case PROFILE_ALLOC:
+ case PROFILE_COUNT:
+ s->profiling.data = GC_profileNew (s);
+ break;
+ case PROFILE_NONE:
+ die ("impossible PROFILE_NONE");
+ case PROFILE_TIME:
+ profileTimeInit (s);
+ break;
+ }
+ profileEndState = s;
+ atexit (profileEnd);
+ }
+}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/profiling.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -103,7 +103,11 @@
pointer textStart;
};
+static void showProf (GC_state s);
+void initProfiling (GC_state s);
+static void enterFrame (GC_state s, uint32_t i);
+
void GC_profileAllocInc (GC_state s, size_t bytes);
void GC_profileEnter (GC_state s);
Deleted: mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/ratios.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -1,33 +0,0 @@
-/* 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 {
- /* Minimum live ratio to use copying GC. */
- float copy;
- /* Only use generational GC with copying collection if the ratio of
- * heap size to live data size is below copyGenerational.
- */
- float copyGenerational;
- float grow;
- float hashCons;
- /* 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 ramSlop;
- float threadShrink;
-};
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/rusage.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -66,7 +66,7 @@
}
/* Return time as number of milliseconds. */
-uintmax_t currentTime (void) {
+uintmax_t getCurrentTime (void) {
struct rusage ru;
getrusage (RUSAGE_SELF, &ru);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/share.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/share.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/share.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -14,10 +14,10 @@
if (DEBUG_SHARE or s->controls.messages)
s->lastMajorStatistics.bytesHashConsed = 0;
// Don't hash cons during the first round of marking.
- total = dfsMark (s, object, MARK_MODE, FALSE);
+ total = dfsMarkByMode (s, object, MARK_MODE, FALSE);
s->objectHashTable = allocHashTable (s);
// Hash cons during the second round of marking.
- dfsMark (s, object, UNMARK_MODE, TRUE);
+ dfsMarkByMode (s, object, UNMARK_MODE, TRUE);
freeHashTable (s->objectHashTable);
if (DEBUG_SHARE or s->controls.messages)
printBytesHashConsedMessage (s, total);
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/signals.c (from rev 4143, mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/init.c 2005-11-04 00:12:48 UTC (rev 4143)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/signals.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -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.
+ */
+
+/* ---------------------------------------------------------------- */
+/* Initialization */
+/* ---------------------------------------------------------------- */
+
+void initSignalStack (GC_state s) {
+#if HAS_SIGALTSTACK
+ static stack_t altstack;
+ size_t ss_size = align (SIGSTKSZ, s->sysvals.pageSize);
+ size_t psize = s->sysvals.pageSize;
+ void *ss_sp = GC_mmap_safe_protect (NULL, 2 * ss_size, psize, psize);
+ altstack.ss_sp = (unsigned char*)ss_sp + ss_size;
+ altstack.ss_size = ss_size;
+ altstack.ss_flags = 0;
+ sigaltstack (&altstack, NULL);
+#endif
+}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/signals.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/signals.h 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/signals.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -24,3 +24,5 @@
*/
sigset_t signalsPending;
};
+
+void initSignalStack (GC_state s);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/size.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/size.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/size.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -11,9 +11,9 @@
if (DEBUG_SIZE)
fprintf (stderr, "GC_size marking\n");
- res = dfsMark (s, root, MARK_MODE, FALSE);
+ res = dfsMarkByMode (s, root, MARK_MODE, FALSE);
if (DEBUG_SIZE)
fprintf (stderr, "GC_size unmarking\n");
- dfsMark (s, root, UNMARK_MODE, FALSE);
+ dfsMarkByMode (s, root, UNMARK_MODE, FALSE);
return res;
}
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/switch-thread.c (from rev 4143, mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.c 2005-11-04 00:12:48 UTC (rev 4143)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/switch-thread.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -0,0 +1,66 @@
+/* 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.
+ */
+
+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;
+ setGCStateCurrentThreadAndStack (s);
+}
+
+void GC_switchToThread (GC_state s, GC_thread t, size_t ensureBytesFree) {
+ if (DEBUG_THREADS)
+ fprintf (stderr, "GC_switchToThread ("FMTPTR", %zu)\n",
+ (uintptr_t)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);
+ getThreadCurrent(s)->bytesNeeded = ensureBytesFree;
+ switchToThread (s, pointerToObjptr((pointer)t, s->heap.start));
+ s->atomicState--;
+ switchToHandlerThreadIfNonAtomicAndSignalPending (s);
+ ensureInvariantForMutator (s, FALSE);
+ assert (invariantForMutatorFrontier(s));
+ assert (invariantForMutatorStack(s));
+ leave (s);
+ } else {
+ /* BEGIN: enter(s); */
+ getStackCurrent(s)->used = sizeofGCStateCurrentStackUsed (s);
+ getThreadCurrent(s)->exnStack = s->exnStack;
+ beginAtomic (s);
+ /* END: enter(s); */
+ getThreadCurrent(s)->bytesNeeded = ensureBytesFree;
+ switchToThread (s, pointerToObjptr((pointer)t, s->heap.start));
+ s->atomicState--;
+ switchToHandlerThreadIfNonAtomicAndSignalPending (s);
+ /* BEGIN: ensureInvariantForMutator */
+ if (not (invariantForMutatorFrontier(s))
+ or not (invariantForMutatorStack(s))) {
+ /* This GC will grow the stack, if necessary. */
+ performGC (s, 0, getThreadCurrent(s)->bytesNeeded, FALSE, TRUE);
+ }
+ /* END: ensureInvariantForMutator */
+ /* BEGIN: leave(s); */
+ endAtomic (s);
+ /* END: leave(s); */
+ }
+ assert (invariantForMutatorFrontier(s));
+ assert (invariantForMutatorStack(s));
+}
Copied: mlton/branches/on-20050822-x86_64-branch/runtime/gc/switch-thread.h (from rev 4143, mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.h)
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/garbage-collection.h 2005-11-04 00:12:48 UTC (rev 4143)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/switch-thread.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -0,0 +1,10 @@
+/* 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.
+ */
+
+void switchToThread (GC_state s, objptr op);
+void GC_switchToThread (GC_state s, GC_thread t, size_t ensureBytesFree);
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/thread.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -24,6 +24,14 @@
size_t res;
res = GC_NORMAL_HEADER_SIZE + sizeof (struct GC_thread);
+ if (DEBUG) {
+ size_t check;
+ uint16_t numNonObjptrs, numObjptrs;
+
+ splitHeader (s, GC_THREAD_HEADER, NULL, NULL, &numNonObjptrs, &numObjptrs);
+ check = GC_NORMAL_HEADER_SIZE + sizeofNormalNoHeader (s, numNonObjptrs, numObjptrs);
+ assert (check == res);
+ }
/* The following assert depends on struct GC_thread being the right
* size. Right now, it happens that res = 16, which is aligned mod
* 4 and mod 8, which is all that we need. If the struct ever
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/weak.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/weak.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/weak.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -6,7 +6,28 @@
* See the file MLton-LICENSE for details.
*/
+size_t sizeofWeak (GC_state s) {
+ size_t res;
+ res = GC_NORMAL_HEADER_SIZE + sizeof (struct GC_weak);
+ if (DEBUG) {
+ size_t check;
+ uint16_t numNonObjptrs, numObjptrs;
+
+ splitHeader (s, GC_WEAK_GONE_HEADER, NULL, NULL, &numNonObjptrs, &numObjptrs);
+ check = GC_NORMAL_HEADER_SIZE + sizeofNormalNoHeader (s, numNonObjptrs, numObjptrs);
+ assert (check == res);
+ }
+ /* The following assert depends on struct GC_weak being the right
+ * size. Right now, it happens that res = 16, which is aligned mod
+ * 4 and mod 8, which is all that we need. If the struct ever
+ * changes (possible) or we need more alignment (doubtful), we may
+ * need to put some padding at the beginning.
+ */
+ assert (isAligned (res, s->alignment));
+ return res;
+}
+
uint32_t GC_weakCanGet (GC_state s, pointer p) {
uint32_t res;
@@ -28,14 +49,14 @@
}
pointer GC_weakNew (GC_state s, GC_header header, pointer p) {
- pointer res;
+ GC_weak res;
- res = newObject (s, header,
- GC_NORMAL_HEADER_SIZE + sizeof(struct GC_weak),
- FALSE);
- ((GC_weak)res)->objptr = pointerToObjptr(p, s->heap.start);
+ res = (GC_weak)(newObject (s, header,
+ sizeofWeak (s),
+ FALSE));
+ res->objptr = pointerToObjptr(p, s->heap.start);
if (DEBUG_WEAK)
fprintf (stderr, FMTPTR" = GC_weakNew ("FMTHDR", "FMTPTR")\n",
(uintptr_t)res, header, (uintptr_t)p);
- return res;
+ return (pointer)res;
}
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/weak.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/weak.h 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/weak.h 2005-11-04 03:52:55 UTC (rev 4145)
@@ -31,3 +31,9 @@
struct GC_weak *link;
objptr objptr;
} *GC_weak;
+
+size_t sizeofWeak (GC_state s);
+uint32_t GC_weakCanGet (GC_state s, pointer p);
+pointer GC_weakGet (GC_state s, pointer p);
+pointer GC_weakNew (GC_state s, GC_header header, pointer p);
+
Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.c 2005-11-04 01:38:08 UTC (rev 4144)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/world.c 2005-11-04 03:52:55 UTC (rev 4145)
@@ -54,7 +54,7 @@
if (DEBUG_WORLD)
fprintf (stderr, "saveWorld (%d).\n", fd);
/* Compact the heap. */
- doGC (s, 0, 0, TRUE, TRUE);
+ performGC (s, 0, 0, TRUE, TRUE);
sprintf (buf,
"Heap file created by MLton.\nheap.start = "FMTPTR"\nbytesLive = %zu\n",
(uintptr_t)s->heap.start,