[MLton-commit] r4093

Matthew Fluet MLton@mlton.org
Tue, 13 Sep 2005 19:43:21 -0700


Changed meaning of crossMap to be a byte-offset from card start.
Record the cardinality of the maps, rather than their size.

----------------------------------------------------------------------

U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.c
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.h
U   mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c

----------------------------------------------------------------------

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO	2005-09-12 13:50:36 UTC (rev 4092)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/TODO	2005-09-14 02:43:18 UTC (rev 4093)
@@ -15,5 +15,3 @@
         codegen in thread.h is still true; it used to be the case when
         GC_switchToThread was implemented in codegens.  Now it should
         be implemented in Backend.
-* change the meaning of crossMap to indicate offset in bytes rather
-        than offset in 32-bit words.

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c	2005-09-12 13:50:36 UTC (rev 4092)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/cheney-copy.c	2005-09-14 02:43:18 UTC (rev 4093)
@@ -264,12 +264,11 @@
 
 /* Walk through all the cards and forward all intergenerational pointers. */
 static void forwardInterGenerationalObjptrs (GC_state s) {
-  uint8_t *cardMap;
-  uint8_t *crossMap;
-  size_t numCards;
+  GC_cardMapElem *cardMap;
+  GC_crossMapElem *crossMap;
   pointer oldGenStart, oldGenEnd;
 
-  size_t cardIndex;
+  size_t cardIndex, maxCardIndex;
   pointer cardStart, cardEnd;
   pointer objectStart;
   
@@ -279,7 +278,7 @@
   /* Constants. */
   cardMap = s->generational.cardMap;
   crossMap = s->generational.crossMap;
-  numCards = sizeToCardIndex (align (s->heap.oldGenSize, s->generational.cardSize));
+  maxCardIndex = sizeToCardIndex (align (s->heap.oldGenSize, CARD_SIZE));
   oldGenStart = s->heap.start;
   oldGenEnd = oldGenStart + s->heap.oldGenSize;
   /* Loop variables*/
@@ -287,9 +286,9 @@
   cardIndex = 0;
   cardStart = oldGenStart;
 checkAll:
-  assert (cardIndex <= numCards);
+  assert (cardIndex <= maxCardIndex);
   assert (isAlignedFrontier (s, objectStart));
-  if (cardIndex == numCards)
+  if (cardIndex == maxCardIndex)
     goto done;
 checkCard:
   if (DEBUG_GENERATIONAL)
@@ -313,7 +312,7 @@
       goto skipObjects;
     }
     s->cumulative.minorBytesSkipped += objectStart - lastObject;
-    cardEnd = cardStart + s->generational.cardSize;
+    cardEnd = cardStart + CARD_SIZE;
     if (oldGenEnd < cardEnd) 
       cardEnd = oldGenEnd;
     assert (objectStart < cardEnd);
@@ -334,16 +333,16 @@
     goto checkCard;
   } else {
     unless (CROSS_MAP_EMPTY == crossMap[cardIndex])
-      objectStart = cardStart + (crossMap[cardIndex] >> CROSS_MAP_SCALE);
+      objectStart = cardStart + (size_t)(crossMap[cardIndex]);
     if (DEBUG_GENERATIONAL)
       fprintf (stderr, 
                "card %zu is not marked"
-               "  crossMap[%zu] == %"PRIu8
+               "  crossMap[%zu] == %zu"
                "  objectStart = "FMTPTR"\n", 
                cardIndex, cardIndex, 
-               crossMap[cardIndex], (uintptr_t)objectStart);
+               (size_t)(crossMap[cardIndex]), (uintptr_t)objectStart);
     cardIndex++;
-    cardStart += s->generational.cardSize;
+    cardStart += CARD_SIZE;
     goto checkAll;
   }
   assert (FALSE);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h	2005-09-12 13:50:36 UTC (rev 4092)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/gc_state.h	2005-09-14 02:43:18 UTC (rev 4093)
@@ -10,7 +10,7 @@
   GC_frameLayout *frameLayouts; /* Array of frame layouts. */
   uint32_t frameLayoutsSize; /* Cardinality of frameLayouts array. */
   pointer frontier; /* heap.start <= frontier < limit */
-  struct GC_generationalInfo generational;
+  struct GC_generationalMaps generational;
   objptr *globals;
   uint32_t globalsSize;
   struct GC_heap heap;
@@ -18,6 +18,7 @@
   pointer limit; /* limit = heap.start + heap.totalBytes */
   pointer limitPlusSlop; /* limit + LIMIT_SLOP */
   uint32_t maxFrameSize;
+  /*Bool*/bool mutatorMarksCards;
   GC_objectType *objectTypes; /* Array of object types. */
   uint32_t objectTypesSize; /* Cardinality of objectTypes array. */
   size_t pageSize;

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.c	2005-09-12 13:50:36 UTC (rev 4092)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.c	2005-09-14 02:43:18 UTC (rev 4093)
@@ -6,11 +6,7 @@
  * See the file MLton-LICENSE for details.
  */
 
-/* must agree w/ cardSizeLog2 in ssa-to-rssa.fun */
-#define CARD_SIZE_LOG2 8
-#define CARD_SIZE TWOPOWER(CARD_SIZE_LOG2)
-#define CROSS_MAP_EMPTY 255
-#define CROSS_MAP_SCALE 2
+#define CROSS_MAP_EMPTY ((GC_crossMapElem)255)
 
 static inline uintptr_t pointerToCardIndex (pointer p) {
   return (uintptr_t)p >> CARD_SIZE_LOG2;
@@ -33,64 +29,78 @@
 }
 
 static inline bool cardIsMarked (GC_state s, pointer p) {
-  return (*pointerToCardMapAddr (s, p) != 0);
+  return (*pointerToCardMapAddr (s, p) != 0x0);
 }
 
 static inline void markCard (GC_state s, pointer p) {
   if (DEBUG_CARD_MARKING)
     fprintf (stderr, "markCard ("FMTPTR")\n", (uintptr_t)p);
-  if (s->generational.mutatorMarksCards)
+  if (s->mutatorMarksCards)
     *pointerToCardMapAddr (s, p) = 0x1;
 }
 
 static inline void clearCardMap (GC_state s) {
   if (DEBUG_GENERATIONAL and DEBUG_DETAILED)
     fprintf (stderr, "clearCardMap ()\n");
-  memset (s->generational.cardMap, 0, s->generational.cardMapSize);
+  memset (s->generational.cardMap, 0, 
+          s->generational.cardMapLength * CARD_MAP_ELEM_SIZE);
 }
 
 static inline void clearCrossMap (GC_state s) {
   if (DEBUG_GENERATIONAL and DEBUG_DETAILED)
     fprintf (stderr, "clearCrossMap ()\n");
   s->generational.crossMapValidSize = 0;
-  memset (s->generational.crossMap, CROSS_MAP_EMPTY, s->generational.crossMapSize);
+  memset (s->generational.crossMap, CROSS_MAP_EMPTY, 
+          s->generational.crossMapLength * CROSS_MAP_ELEM_SIZE);
 }
 
 static inline void setCardMapAbsolute (GC_state s) {
-  unless (s->generational.mutatorMarksCards)
+  unless (s->mutatorMarksCards)
     return;
   /* It's OK if the subtraction below underflows because all the
    * subsequent additions to mark the cards will overflow and put us
    * in the right place.
    */
   s->generational.cardMapAbsolute = 
-    s->generational.cardMap - pointerToCardIndex ( s->heap.start);
+    pointerToCardMapAddr (s, s->heap.start);
   if (DEBUG_CARD_MARKING)
     fprintf (stderr, "cardMapAbsolute = "FMTPTR"\n",
              (uintptr_t)s->generational.cardMapAbsolute);
 }
 
 static inline void createCardMapAndCrossMap (GC_state s) {
-  unless (s->generational.mutatorMarksCards) {
-    s->generational.cardMapSize = 0;
+  unless (s->mutatorMarksCards) {
+    s->generational.cardMapLength = 0;
     s->generational.cardMap = NULL;
     s->generational.cardMapAbsolute = NULL;
-    s->generational.crossMapSize = 0;
+    s->generational.crossMapLength = 0;
     s->generational.crossMap = NULL;
     return;
   }
-  assert (isAligned (s->heap.size, s->generational.cardSize));
-  s->generational.cardMapSize = 
-    align (sizeToCardIndex (s->heap.size), s->pageSize);
-  s->generational.crossMapSize = s->generational.cardMapSize;
+  assert (isAligned (s->heap.size, CARD_SIZE));
+
+  size_t cardMapLength, cardMapSize;
+  size_t crossMapLength, crossMapSize;
+  size_t totalMapSize;
+
+  cardMapLength = sizeToCardIndex (s->heap.size);
+  cardMapSize = align (cardMapLength * CARD_MAP_ELEM_SIZE, s->pageSize);
+  cardMapLength = cardMapSize / CARD_MAP_ELEM_SIZE;
+  s->generational.cardMapLength = cardMapLength;
+
+  crossMapLength = sizeToCardIndex (s->heap.size);
+  crossMapSize = align (crossMapLength * CROSS_MAP_ELEM_SIZE, s->pageSize);
+  crossMapLength = crossMapSize / CROSS_MAP_ELEM_SIZE;
+  s->generational.crossMapLength = crossMapLength;
+
+  totalMapSize = cardMapSize + crossMapSize;
   if (DEBUG_MEM)
     fprintf (stderr, "Creating card/cross map of size %zd\n",
-             /*uintToCommaString*/
-             (s->generational.cardMapSize + s->generational.crossMapSize));
+             /*uintToCommaString*/(totalMapSize));
   s->generational.cardMap = 
-    GC_mmapAnon (s->generational.cardMapSize + s->generational.crossMapSize);
+    GC_mmapAnon (totalMapSize);
   s->generational.crossMap = 
-    s->generational.cardMap + s->generational.cardMapSize;
+    (GC_crossMapElem*)((pointer)s->generational.cardMap + cardMapSize);
   if (DEBUG_CARD_MARKING)
     fprintf (stderr, "cardMap = "FMTPTR"  crossMap = "FMTPTR"\n",
              (uintptr_t)s->generational.cardMap,
@@ -108,7 +118,7 @@
    */
   return (p == s->heap.start)
     ? s->heap.start
-    : (p - 1) - ((uintptr_t)(p - 1) % s->generational.cardSize);
+    : (p - 1) - ((uintptr_t)(p - 1) % CARD_SIZE);
 }
 
 /* crossMapIsOK is a slower, but easier to understand, way of
@@ -120,7 +130,8 @@
  */
 
 static inline bool crossMapIsOK (GC_state s) {
-  static uint8_t *map;
+  static GC_crossMapElem *map;
+  size_t mapSize;
 
   pointer front, back;
   size_t cardIndex;
@@ -128,8 +139,9 @@
   
   if (DEBUG)
     fprintf (stderr, "crossMapIsOK ()\n");
-  map = GC_mmapAnon (s->generational.crossMapSize);
-  memset (map, CROSS_MAP_EMPTY, s->generational.crossMapSize);
+  mapSize = s->generational.crossMapLength * CROSS_MAP_ELEM_SIZE;
+  map = GC_mmapAnon (mapSize);
+  memset (map, CROSS_MAP_EMPTY, mapSize);
   back = s->heap.start + s->heap.oldGenSize;
   cardIndex = 0;
   front = alignFrontier (s, s->heap.start);
@@ -137,14 +149,14 @@
   assert (front <= back);
   cardStart = crossMapCardStart (s, front);
   cardIndex = sizeToCardIndex (cardStart - s->heap.start);
-  map[cardIndex] = (front - cardStart) >> CROSS_MAP_SCALE;
+  map[cardIndex] = (front - cardStart);
   if (front < back) {
     front += objectSize (s, objectData (s, front));
     goto loopObjects;
   }
   for (size_t i = 0; i < cardIndex; ++i)
     assert (map[i] == s->generational.crossMap[i]);
-  GC_munmap (map, s->generational.crossMapSize);
+  GC_munmap (map, mapSize);
   return TRUE;
 }
 
@@ -167,7 +179,7 @@
   } else
     cardIndex = sizeToCardIndex (objectStart - 1 - s->heap.start);
   cardStart = s->heap.start + cardIndexToSize (cardIndex);
-  cardEnd = cardStart + s->generational.cardSize;
+  cardEnd = cardStart + CARD_SIZE;
 loopObjects:
   assert (objectStart < oldGenEnd);
   assert ((objectStart == s->heap.start or cardStart < objectStart)
@@ -180,21 +192,21 @@
      */
     size_t offset;
     
-    offset = (objectStart - cardStart) >> CROSS_MAP_SCALE;
+    offset = (objectStart - cardStart);
     assert (offset < CROSS_MAP_EMPTY);
     if (DEBUG_GENERATIONAL)
       fprintf (stderr, "crossMap[%zu] = %zu\n",
                cardIndex, offset);
-    s->generational.crossMap[cardIndex] = (uint8_t)offset;
+    s->generational.crossMap[cardIndex] = (GC_crossMapElem)offset;
     cardIndex = sizeToCardIndex (nextObject - 1 - s->heap.start);
     cardStart = s->heap.start + cardIndexToSize (cardIndex);
-    cardEnd = cardStart + s->generational.cardSize;
+    cardEnd = cardStart + CARD_SIZE;
   }
   objectStart = nextObject;
   if (objectStart < oldGenEnd)
     goto loopObjects;
   assert (objectStart == oldGenEnd);
-  s->generational.crossMap[cardIndex] = (oldGenEnd - cardStart) >> CROSS_MAP_SCALE;
+  s->generational.crossMap[cardIndex] = (GC_crossMapElem)(oldGenEnd - cardStart);
   s->generational.crossMapValidSize = s->heap.oldGenSize;
 done:
   assert (s->generational.crossMapValidSize == s->heap.oldGenSize);
@@ -202,21 +214,22 @@
 }
 
 static inline void resizeCardMapAndCrossMap (GC_state s) {
-  if (s->generational.mutatorMarksCards
-      and s->generational.cardMapSize 
+  if (s->mutatorMarksCards
+      and (s->generational.cardMapLength * CARD_MAP_ELEM_SIZE)
           != align (sizeToCardIndex (s->heap.size), s->pageSize)) {
-    uint8_t *oldCardMap;
+    GC_cardMapElem *oldCardMap;
     size_t oldCardMapSize;
-    uint8_t *oldCrossMap;
+    GC_crossMapElem *oldCrossMap;
     size_t oldCrossMapSize;
     
     oldCardMap = s->generational.cardMap;
-    oldCardMapSize = s->generational.cardMapSize;
+    oldCardMapSize = s->generational.cardMapLength * CARD_MAP_ELEM_SIZE;
     oldCrossMap = s->generational.crossMap;
-    oldCrossMapSize = s->generational.crossMapSize;
+    oldCrossMapSize = s->generational.crossMapLength * CROSS_MAP_ELEM_SIZE;
     createCardMapAndCrossMap (s);
     GC_memcpy ((pointer)oldCrossMap, (pointer)s->generational.crossMap,
-               min (s->generational.crossMapSize, oldCrossMapSize));
+               min (s->generational.crossMapLength * CROSS_MAP_ELEM_SIZE, 
+                    oldCrossMapSize));
     if (DEBUG_MEM)
       fprintf (stderr, "Releasing card/cross map.\n");
     GC_munmap (oldCardMap, oldCardMapSize + oldCrossMapSize);

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.h
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.h	2005-09-12 13:50:36 UTC (rev 4092)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/generational.h	2005-09-14 02:43:18 UTC (rev 4093)
@@ -6,16 +6,37 @@
  * See the file MLton-LICENSE for details.
  */
 
-struct GC_generationalInfo {
-  uint8_t *cardMap;
-  uint8_t *cardMapAbsolute;
-  size_t cardMapSize;
-  size_t cardSize;
-  uint8_t *crossMap;
-  size_t crossMapSize;
-  /* crossMapValidEnd is the size of the prefix of the old generation
+/* must agree w/ cardSizeLog2 in ssa-to-rssa.fun */
+#define CARD_SIZE_LOG2 8
+#define CARD_SIZE TWOPOWER(CARD_SIZE_LOG2)
+
+typedef uint8_t GC_cardMapElem;
+typedef uint8_t GC_crossMapElem;
+
+struct GC_generationalMaps {
+  /* cardMap is an array with cardinality equal to the size of the
+   * heap divided by card size.  Each element in the array is
+   * interpreted as a boolean; true indicates that some mutable field
+   * of some object in the corresponding card in the heap has been
+   * written since the last minor GC; hence, the corresponding card
+   * must be traced at the next minor GC.
+   */
+  GC_cardMapElem *cardMap;
+  GC_cardMapElem *cardMapAbsolute;
+  size_t cardMapLength;
+  /* crossMap is an array with cardinality equal to the size of the
+   * heap divided by card size.  Each element in the array is
+   * interpreted as a byte offset; the offset indicates the start of
+   * the last object in the corresponding card from the start of the
+   * card.
+   */
+  GC_crossMapElem *crossMap;
+  size_t crossMapLength;
+  /* crossMapValidSize the size of the prefix of the old generation
    * for which the crossMap is valid.
    */
   size_t crossMapValidSize;
-  /*Bool*/bool mutatorMarksCards;
 };
+
+#define CARD_MAP_ELEM_SIZE sizeof(GC_cardMapElem)
+#define CROSS_MAP_ELEM_SIZE sizeof(GC_crossMapElem)

Modified: mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c
===================================================================
--- mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c	2005-09-12 13:50:36 UTC (rev 4092)
+++ mlton/branches/on-20050822-x86_64-branch/runtime/gc/invariant.c	2005-09-14 02:43:18 UTC (rev 4093)
@@ -30,16 +30,17 @@
     }
   }
   /* Generational */
-  if (s->generational.mutatorMarksCards) {
+  if (s->mutatorMarksCards) {
     assert (s->generational.cardMap == 
-            &s->generational.cardMapAbsolute
-            [pointerToCardIndex(s->heap.start)]);
-    assert (&s->generational.cardMapAbsolute
-            [pointerToCardIndex(s->heap.start + s->heap.size - 1)]
-            < s->generational.cardMap + s->generational.cardMapSize);
+            &(s->generational.cardMapAbsolute
+              [pointerToCardIndex(s->heap.start)]));
+    assert (&(s->generational.cardMapAbsolute
+              [pointerToCardIndex(s->heap.start + s->heap.size - 1)])
+            < (s->generational.cardMap 
+               + (s->generational.cardMapLength * CARD_MAP_ELEM_SIZE)));
   }
   assert (isAligned (s->heap.size, s->pageSize));
-  assert (isAligned ((size_t)s->heap.start, s->generational.cardSize));
+  assert (isAligned ((size_t)s->heap.start, CARD_SIZE));
   assert (isAlignedFrontier (s, s->heap.start + s->heap.oldGenSize));
   assert (isAlignedFrontier (s, s->heap.nursery));
   assert (isAlignedFrontier (s, s->frontier));