[MLton-commit] r6773
Matthew Fluet
fluet at mlton.org
Tue Aug 19 17:43:29 PDT 2008
Integrate Nicolas Bertolotti's card-cross-map-in-heap patch.
----------------------------------------------------------------------
U mlton/trunk/runtime/gc/cheney-copy.c
U mlton/trunk/runtime/gc/done.c
U mlton/trunk/runtime/gc/generational.c
U mlton/trunk/runtime/gc/generational.h
U mlton/trunk/runtime/gc/heap.c
U mlton/trunk/runtime/gc/virtual-memory.c
U mlton/trunk/runtime/gc.h
----------------------------------------------------------------------
Modified: mlton/trunk/runtime/gc/cheney-copy.c
===================================================================
--- mlton/trunk/runtime/gc/cheney-copy.c 2008-08-20 00:08:27 UTC (rev 6772)
+++ mlton/trunk/runtime/gc/cheney-copy.c 2008-08-20 00:43:27 UTC (rev 6773)
@@ -39,6 +39,7 @@
void swapHeapsForCheneyCopy (GC_state s) {
struct GC_heap tempHeap;
+ copyCardMapAndCrossMap (s, &s->secondaryHeap);
tempHeap = s->secondaryHeap;
s->secondaryHeap = s->heap;
s->heap = tempHeap;
Modified: mlton/trunk/runtime/gc/done.c
===================================================================
--- mlton/trunk/runtime/gc/done.c 2008-08-20 00:08:27 UTC (rev 6772)
+++ mlton/trunk/runtime/gc/done.c 2008-08-20 00:43:27 UTC (rev 6773)
@@ -93,5 +93,4 @@
}
releaseHeap (s, &s->heap);
releaseHeap (s, &s->secondaryHeap);
- releaseCardMapAndCrossMap (s);
}
Modified: mlton/trunk/runtime/gc/generational.c
===================================================================
--- mlton/trunk/runtime/gc/generational.c 2008-08-20 00:08:27 UTC (rev 6772)
+++ mlton/trunk/runtime/gc/generational.c 2008-08-20 00:43:27 UTC (rev 6773)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
+/* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
*
@@ -119,8 +119,35 @@
s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE);
}
-void createCardMapAndCrossMap (GC_state s) {
+/* Compute the number of bytes that are needed to store the card map and
+ cross map at the end of a heap with the given size. */
+size_t computeCardMapAndCrossMapSize (GC_state s, size_t size) {
unless (s->mutatorMarksCards) {
+ return 0;
+ }
+ assert (isAligned (size, CARD_SIZE));
+
+ GC_cardMapIndex cardMapLength;
+ size_t cardMapSize;
+ GC_crossMapIndex crossMapLength;
+ size_t crossMapSize;
+ size_t totalMapSize;
+
+ cardMapLength = sizeToCardMapIndex (size);
+ cardMapSize = align (cardMapLength * CARD_MAP_ELEM_SIZE, s->sysvals.pageSize);
+ cardMapLength = (GC_cardMapIndex)(cardMapSize / CARD_MAP_ELEM_SIZE);
+
+ crossMapLength = sizeToCardMapIndex (size);
+ crossMapSize = align (crossMapLength * CROSS_MAP_ELEM_SIZE, s->sysvals.pageSize);
+ crossMapLength = (GC_crossMapIndex)(crossMapSize / CROSS_MAP_ELEM_SIZE);
+
+ totalMapSize = cardMapSize + crossMapSize;
+
+ return totalMapSize;
+}
+
+static inline void initCardMapAndCrossMap (GC_state s, GC_heap h, size_t size) {
+ unless (s->mutatorMarksCards) {
s->generationalMaps.cardMapLength = 0;
s->generationalMaps.cardMap = NULL;
s->generationalMaps.cardMapAbsolute = NULL;
@@ -128,7 +155,7 @@
s->generationalMaps.crossMap = NULL;
return;
}
- assert (isAligned (s->heap.size, CARD_SIZE));
+ assert (isAligned (size, CARD_SIZE));
GC_cardMapIndex cardMapLength;
size_t cardMapSize;
@@ -136,21 +163,22 @@
size_t crossMapSize;
size_t totalMapSize;
- cardMapLength = sizeToCardMapIndex (s->heap.size);
+ cardMapLength = sizeToCardMapIndex (size);
cardMapSize = align (cardMapLength * CARD_MAP_ELEM_SIZE, s->sysvals.pageSize);
cardMapLength = (GC_cardMapIndex)(cardMapSize / CARD_MAP_ELEM_SIZE);
s->generationalMaps.cardMapLength = cardMapLength;
- crossMapLength = sizeToCardMapIndex (s->heap.size);
+ crossMapLength = sizeToCardMapIndex (size);
crossMapSize = align (crossMapLength * CROSS_MAP_ELEM_SIZE, s->sysvals.pageSize);
crossMapLength = (GC_crossMapIndex)(crossMapSize / CROSS_MAP_ELEM_SIZE);
s->generationalMaps.crossMapLength = crossMapLength;
totalMapSize = cardMapSize + crossMapSize;
+ /* The card map starts at the end of the heap. */
s->generationalMaps.cardMap =
- GC_mmapAnon_safe (NULL, totalMapSize);
+ (GC_cardMap) (h->start + size);
s->generationalMaps.crossMap =
- (s->generationalMaps.cardMap + (cardMapSize / CARD_MAP_ELEM_SIZE));
+ (GC_crossMap) (s->generationalMaps.cardMap + (cardMapSize / CARD_MAP_ELEM_SIZE));
if (DEBUG_MEM or s->controls.messages)
fprintf (stderr,
"[GC: Created card/cross map at "FMTPTR" of size %s bytes.]\n",
@@ -161,64 +189,104 @@
(uintptr_t)s->generationalMaps.cardMap,
(uintptr_t)s->generationalMaps.crossMap);
setCardMapAbsolute (s);
- clearCardMap (s);
- clearCrossMap (s);
}
-void releaseCardMapAndCrossMapAux (GC_state s,
- GC_cardMap cardMap,
- size_t cardMapSize,
- __attribute__ ((unused)) GC_crossMap crossMap,
- size_t crossMapSize) {
+void createCardMapAndCrossMap (GC_state s) {
+ initCardMapAndCrossMap (s, &s->heap, s->heap.size);
+ if (s->mutatorMarksCards) {
+ clearCardMap (s);
+ clearCrossMap (s);
+ }
+}
- size_t totalMapSize;
+/* This function is called before the given heap becomes the new current heap
+ used to store the program datas.
+ The 2 heaps can have a different size. */
+void copyCardMapAndCrossMap (GC_state s, GC_heap h) {
+ if (s->mutatorMarksCards) {
+ GC_cardMap oldCardMap;
+ size_t oldCardMapSize;
+ GC_crossMap oldCrossMap;
+ size_t oldCrossMapSize;
- assert (crossMap == cardMap + (cardMapSize / CARD_MAP_ELEM_SIZE));
- totalMapSize = cardMapSize + crossMapSize;
- if (DEBUG_MEM or s->controls.messages)
- fprintf (stderr,
- "[GC: Releasing card/cross map at "FMTPTR" of size %s bytes.]\n",
- (uintptr_t)cardMap,
- uintmaxToCommaString(totalMapSize));
- GC_release (cardMap, totalMapSize);
+ oldCardMap = s->generationalMaps.cardMap;
+ oldCardMapSize = s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE;
+ oldCrossMap = s->generationalMaps.crossMap;
+ oldCrossMapSize = s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE;
+
+ initCardMapAndCrossMap (s, h, h->size);
+
+ clearCardMap (s);
+ GC_memcpy ((pointer)oldCardMap, (pointer)s->generationalMaps.cardMap,
+ min (s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE,
+ oldCardMapSize));
+ clearCrossMap (s);
+ GC_memcpy ((pointer)oldCrossMap, (pointer)s->generationalMaps.crossMap,
+ min (s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE,
+ oldCrossMapSize));
+ }
}
-void releaseCardMapAndCrossMap (GC_state s) {
- unless (s->mutatorMarksCards)
- return;
+/* This function is called before we shrink the heap buffer which contains the
+ card/cross map datas. */
+void shrinkCardMapAndCrossMap (GC_state s, size_t keep) {
+ if (s->mutatorMarksCards) {
+ GC_crossMap oldCrossMap;
- GC_cardMap cardMap;
- size_t cardMapSize;
- GC_crossMap crossMap;
- size_t crossMapSize;
+ oldCrossMap = s->generationalMaps.crossMap;
- cardMap = s->generationalMaps.cardMap;
- cardMapSize = s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE;
- crossMap = s->generationalMaps.crossMap;
- crossMapSize = s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE;
- releaseCardMapAndCrossMapAux (s, cardMap, cardMapSize, crossMap, crossMapSize);
+ initCardMapAndCrossMap (s, &s->heap, keep);
+
+ GC_memmove ((pointer)oldCrossMap, (pointer)s->generationalMaps.crossMap,
+ s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE);
+ clearCardMap (s);
+ }
}
-void resizeCardMapAndCrossMap (GC_state s) {
- if (s->mutatorMarksCards
- and (s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE)
- != align (sizeToCardMapIndex (s->heap.size), s->sysvals.pageSize)) {
+/* This function is called after we remap the heap buffer which contains the
+ card/cross map datas.
+ The remapped heap must be bigger than the original one. */
+void remapCardMapAndCrossMap (GC_state s, pointer orig) {
+ if (s->mutatorMarksCards) {
GC_cardMap oldCardMap;
size_t oldCardMapSize;
GC_crossMap oldCrossMap;
size_t oldCrossMapSize;
- oldCardMap = s->generationalMaps.cardMap;
+ oldCardMap = (GC_cardMap) ((pointer) s->generationalMaps.cardMap + (s->heap.start - orig));
oldCardMapSize = s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE;
- oldCrossMap = s->generationalMaps.crossMap;
+ oldCrossMap = (GC_crossMap) (oldCardMap + (oldCardMapSize / CARD_MAP_ELEM_SIZE));
oldCrossMapSize = s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE;
- createCardMapAndCrossMap (s);
- GC_memcpy ((pointer)oldCrossMap, (pointer)s->generationalMaps.crossMap,
- min (s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE,
- oldCrossMapSize));
- releaseCardMapAndCrossMapAux (s,
- oldCardMap, oldCardMapSize,
- oldCrossMap, oldCrossMapSize);
+
+ initCardMapAndCrossMap (s, &s->heap, s->heap.size);
+
+ if (DEBUG_MEM or s->controls.messages) {
+ fprintf (stderr, "[GC: oldCardMap = "FMTPTR" oldCrossMap = "FMTPTR"]\n",
+ (uintptr_t)oldCardMap,
+ (uintptr_t)oldCrossMap);
+ fprintf (stderr,
+ "[GC: oldCardMapSize = %s bytes oldCrossMapSize = %s bytes]\n",
+ uintmaxToCommaString(oldCardMapSize), uintmaxToCommaString(oldCrossMapSize));
+ fprintf (stderr, "[GC: cardMap = "FMTPTR" crossMap = "FMTPTR"]\n",
+ (uintptr_t)s->generationalMaps.cardMap,
+ (uintptr_t)s->generationalMaps.crossMap);
+ }
+ GC_memmove ((pointer)oldCrossMap, (pointer)s->generationalMaps.crossMap,
+ oldCrossMapSize);
+ if (DEBUG_MEM or s->controls.messages) {
+ fprintf (stderr,
+ "[GC: crossMapSize = %s bytes]\n",
+ uintmaxToCommaString(s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE));
+ }
+ memset((pointer)s->generationalMaps.crossMap + oldCrossMapSize, CROSS_MAP_EMPTY,
+ s->generationalMaps.crossMapLength * CROSS_MAP_ELEM_SIZE - oldCrossMapSize);
+ if (DEBUG_MEM or s->controls.messages) {
+ fprintf(stderr, "[GC: cross map OK]\n");
+ }
+ clearCardMap (s);
+ if (DEBUG_MEM or s->controls.messages) {
+ fprintf(stderr, "[GC: card map OK]\n");
+ }
}
}
Modified: mlton/trunk/runtime/gc/generational.h
===================================================================
--- mlton/trunk/runtime/gc/generational.h 2008-08-20 00:08:27 UTC (rev 6772)
+++ mlton/trunk/runtime/gc/generational.h 2008-08-20 00:43:27 UTC (rev 6773)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
+/* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
*
@@ -76,12 +76,11 @@
static inline void clearCardMap (GC_state s);
static inline void clearCrossMap (GC_state s);
+static size_t computeCardMapAndCrossMapSize (GC_state s, size_t size);
static void createCardMapAndCrossMap (GC_state s);
-static void releaseCardMapAndCrossMap (GC_state s);
-static void releaseCardMapAndCrossMapAux (GC_state s,
- GC_cardMap cardMap, size_t cardMapSize,
- GC_crossMap crossMap, size_t crossMapSize);
-static void resizeCardMapAndCrossMap (GC_state s);
+static void copyCardMapAndCrossMap (GC_state s, GC_heap h);
+static void shrinkCardMapAndCrossMap (GC_state s, size_t keep);
+static void remapCardMapAndCrossMap (GC_state s, pointer orig);
#if ASSERT
static bool isCrossMapOk (GC_state s);
Modified: mlton/trunk/runtime/gc/heap.c
===================================================================
--- mlton/trunk/runtime/gc/heap.c 2008-08-20 00:08:27 UTC (rev 6772)
+++ mlton/trunk/runtime/gc/heap.c 2008-08-20 00:43:27 UTC (rev 6773)
@@ -114,7 +114,7 @@
"[GC: Releasing heap at "FMTPTR" of size %s bytes.]\n",
(uintptr_t)(h->start),
uintmaxToCommaString(h->size));
- GC_release (h->start, h->size);
+ GC_release (h->start, h->size + computeCardMapAndCrossMapSize(s, h->size));
initHeap (s, h);
}
@@ -126,13 +126,17 @@
}
keep = align (keep, s->sysvals.pageSize);
if (keep < h->size) {
+ size_t oldMapSize, newMapSize;
if (DEBUG or s->controls.messages)
fprintf (stderr,
"[GC: Shrinking heap at "FMTPTR" of size %s bytes to size %s bytes.]\n",
(uintptr_t)(h->start),
uintmaxToCommaString(h->size),
uintmaxToCommaString(keep));
- GC_decommit (h->start + keep, h->size - keep);
+ shrinkCardMapAndCrossMap(s, keep);
+ oldMapSize = computeCardMapAndCrossMapSize(s, h->size);
+ newMapSize = computeCardMapAndCrossMapSize(s, keep);
+ GC_decommit (h->start + keep + newMapSize, h->size - keep + oldMapSize - newMapSize);
h->size = keep;
}
}
@@ -149,6 +153,7 @@
size_t minSize) {
size_t backoff;
size_t newSize;
+ size_t newWithMapsSize;
if (DEBUG_MEM)
fprintf (stderr, "createHeap desired size = %s min size = %s\n",
@@ -183,8 +188,10 @@
static bool direction = TRUE;
unsigned int i;
- assert (isAligned (newSize, s->sysvals.pageSize));
+ newWithMapsSize = newSize + computeCardMapAndCrossMapSize (s, newSize);
+ assert (isAligned (newWithMapsSize, s->sysvals.pageSize));
+
for (i = 1; i <= count; i++) {
size_t address;
pointer newStart;
@@ -196,7 +203,7 @@
if (i == count)
address = 0;
- newStart = GC_mmapAnon ((pointer)address, newSize);
+ newStart = GC_mmapAnon ((pointer)address, newWithMapsSize);
unless ((void*)-1 == newStart) {
direction = not direction;
h->start = newStart;
@@ -249,7 +256,9 @@
size_t minSize) {
size_t backoff;
size_t newSize;
+ size_t newWithMapsSize;
size_t origSize;
+ size_t origWithMapsSize;
#if not HAS_REMAP
return FALSE;
@@ -260,19 +269,23 @@
uintmaxToCommaString(minSize));
assert (minSize <= desiredSize);
assert (desiredSize >= h->size);
+ minSize = align (minSize, s->sysvals.pageSize);
desiredSize = align (desiredSize, s->sysvals.pageSize);
backoff = (desiredSize - minSize) / 20;
if (0 == backoff)
backoff = 1; /* enough to terminate the loop below */
backoff = align (backoff, s->sysvals.pageSize);
origSize = h->size;
+ origWithMapsSize = origSize + computeCardMapAndCrossMapSize (s, origSize);
newSize = desiredSize;
do {
pointer newStart;
- assert (isAligned (newSize, s->sysvals.pageSize));
+ newWithMapsSize = newSize + computeCardMapAndCrossMapSize (s, newSize);
- newStart = GC_mremap (h->start, origSize, newSize);
+ assert (isAligned (newWithMapsSize, s->sysvals.pageSize));
+
+ newStart = GC_mremap (h->start, origWithMapsSize, newWithMapsSize);
unless ((void*)-1 == newStart) {
h->start = newStart;
h->size = newSize;
@@ -319,6 +332,10 @@
size_t size;
assert (desiredSize >= s->heap.size);
+ /* Now the card/cross map is stored at the end of the heap buffer, make sure we
+ won't actually shrink the heap. */
+ if (minSize < s->heap.size)
+ minSize = s->heap.size;
if (DEBUG_RESIZING or s->controls.messages) {
fprintf (stderr,
"[GC: Growing heap at "FMTPTR" of size %s bytes,]\n",
@@ -333,8 +350,10 @@
orig = curHeapp->start;
size = curHeapp->oldGenSize;
assert (size <= s->heap.size);
- if (remapHeap (s, curHeapp, desiredSize, minSize))
+ if (remapHeap (s, curHeapp, desiredSize, minSize)) {
+ remapCardMapAndCrossMap (s, orig);
goto done;
+ }
shrinkHeap (s, curHeapp, size);
initHeap (s, &newHeap);
/* Allocate a space of the desired size. */
@@ -346,21 +365,26 @@
from = curHeapp->start + size;
to = newHeap.start + size;
remaining = size;
+ copyCardMapAndCrossMap(s, &newHeap);
+ GC_decommit(orig + curHeapp->size, computeCardMapAndCrossMapSize(s, curHeapp->size));
copy:
assert (remaining == (size_t)(from - curHeapp->start)
and from >= curHeapp->start
and to >= newHeap.start);
if (remaining < COPY_CHUNK_SIZE) {
GC_memcpy (orig, newHeap.start, remaining);
+ GC_release (orig, curHeapp->size);
} else {
+ size_t keep;
remaining -= COPY_CHUNK_SIZE;
from -= COPY_CHUNK_SIZE;
to -= COPY_CHUNK_SIZE;
GC_memcpy (from, to, COPY_CHUNK_SIZE);
- shrinkHeap (s, curHeapp, remaining);
+ keep = align (remaining, s->sysvals.pageSize);
+ GC_decommit (orig + keep, (size_t)(curHeapp->size - keep));
+ curHeapp->size = keep;
goto copy;
}
- releaseHeap (s, curHeapp);
newHeap.oldGenSize = size;
*curHeapp = newHeap;
} else if (s->controls.mayPageHeap) {
@@ -375,7 +399,6 @@
}
data = GC_diskBack_write (orig, size);
releaseHeap (s, curHeapp);
- releaseCardMapAndCrossMap (s);
if (createHeap (s, curHeapp, desiredSize, minSize)) {
if (DEBUG or s->controls.messages) {
fprintf (stderr,
@@ -421,13 +444,12 @@
uintmaxToCommaString(s->heap.size));
desiredSize = sizeofHeapDesired (s, minSize, s->heap.size);
assert (minSize <= desiredSize);
- if (desiredSize <= s->heap.size)
+ if (desiredSize <= s->heap.size) {
shrinkHeap (s, &s->heap, desiredSize);
- else {
+ } else {
releaseHeap (s, &s->secondaryHeap);
growHeap (s, desiredSize, minSize);
}
- resizeCardMapAndCrossMap (s);
assert (s->heap.size >= minSize);
}
Modified: mlton/trunk/runtime/gc/virtual-memory.c
===================================================================
--- mlton/trunk/runtime/gc/virtual-memory.c 2008-08-20 00:08:27 UTC (rev 6772)
+++ mlton/trunk/runtime/gc/virtual-memory.c 2008-08-20 00:43:27 UTC (rev 6773)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
+/* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
*
@@ -12,7 +12,7 @@
result = GC_mmapAnon (p, length);
if ((void*)-1 == result) {
GC_displayMem ();
- die ("Out of memory.");
+ die ("Out of memory (2). Unable to allocate %s bytes.\n", uintmaxToCommaString(length));
}
return result;
}
@@ -29,3 +29,10 @@
return;
memcpy (dst, src, size);
}
+
+static inline void GC_memmove (pointer src, pointer dst, size_t size) {
+ if (DEBUG_DETAILED)
+ fprintf (stderr, "GC_memmove ("FMTPTR", "FMTPTR", %"PRIuMAX")\n",
+ (uintptr_t)src, (uintptr_t)dst, (uintmax_t)size);
+ memmove (dst, src, size);
+}
Modified: mlton/trunk/runtime/gc.h
===================================================================
--- mlton/trunk/runtime/gc.h 2008-08-20 00:08:27 UTC (rev 6772)
+++ mlton/trunk/runtime/gc.h 2008-08-20 00:43:27 UTC (rev 6773)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
+/* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
*
@@ -38,8 +38,8 @@
#include "gc/int-inf.h"
#include "gc/string.h"
#include "gc/object-size.h"
+#include "gc/heap.h"
#include "gc/generational.h"
-#include "gc/heap.h"
#include "gc/current.h"
#include "gc/foreach.h"
#include "gc/translate.h"
More information about the MLton-commit
mailing list