Import Upstream version 20180207
[hcoop/debian/mlton.git] / runtime / gc / cheney-copy.c
CommitLineData
7f918cf1
CE
1/* Copyright (C) 2012,2016 Matthew Fluet.
2 * Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
3 * Jagannathan, and Stephen Weeks.
4 * Copyright (C) 1997-2000 NEC Research Institute.
5 *
6 * MLton is released under a BSD-style license.
7 * See the file MLton-LICENSE for details.
8 */
9
10/* ---------------------------------------------------------------- */
11/* Cheney Copying Collection */
12/* ---------------------------------------------------------------- */
13
14void updateWeaksForCheneyCopy (GC_state s) {
15 pointer p;
16 GC_weak w;
17
18 for (w = s->weaks; w != NULL; w = w->link) {
19 assert (BOGUS_OBJPTR != w->objptr);
20
21 if (DEBUG_WEAK)
22 fprintf (stderr, "updateWeaksForCheneyCopy w = "FMTPTR" ", (uintptr_t)w);
23 p = objptrToPointer (w->objptr, s->heap.start);
24 if (hasFwdPtr(p)) {
25 if (DEBUG_WEAK)
26 fprintf (stderr, "forwarded from "FMTOBJPTR" to "FMTOBJPTR"\n",
27 w->objptr, getFwdPtr(p));
28 w->objptr = getFwdPtr(p);
29 } else {
30 if (DEBUG_WEAK)
31 fprintf (stderr, "cleared\n");
32 *(getHeaderp((pointer)w - offsetofWeak (s))) = GC_WEAK_GONE_HEADER;
33 w->objptr = BOGUS_OBJPTR;
34 }
35 }
36 s->weaks = NULL;
37}
38
39void swapHeapsForCheneyCopy (GC_state s) {
40 struct GC_heap tempHeap;
41
42 tempHeap = s->secondaryHeap;
43 s->secondaryHeap = s->heap;
44 s->heap = tempHeap;
45 setCardMapAndCrossMap (s);
46}
47
48void majorCheneyCopyGC (GC_state s) {
49 size_t bytesCopied;
50 struct rusage ru_start;
51 pointer toStart;
52
53 assert (s->secondaryHeap.size >= s->heap.oldGenSize);
54 if (detailedGCTime (s))
55 startTiming (&ru_start);
56 s->cumulativeStatistics.numCopyingGCs++;
57 s->forwardState.amInMinorGC = FALSE;
58 if (DEBUG or s->controls.messages) {
59 fprintf (stderr,
60 "[GC: Starting major Cheney-copy;]\n");
61 fprintf (stderr,
62 "[GC:\tfrom heap at "FMTPTR" of size %s bytes,]\n",
63 (uintptr_t)(s->heap.start),
64 uintmaxToCommaString(s->heap.size));
65 fprintf (stderr,
66 "[GC:\tto heap at "FMTPTR" of size %s bytes.]\n",
67 (uintptr_t)(s->secondaryHeap.start),
68 uintmaxToCommaString(s->secondaryHeap.size));
69 }
70 s->forwardState.toStart = s->secondaryHeap.start;
71 s->forwardState.toLimit = s->secondaryHeap.start + s->secondaryHeap.size;
72 assert (s->secondaryHeap.start != (pointer)NULL);
73 /* The next assert ensures there is enough space for the copy to
74 * succeed. It does not assert
75 * (s->secondaryHeap.size >= s->heap.size)
76 * because that is too strong.
77 */
78 assert (s->secondaryHeap.size >= s->heap.oldGenSize);
79 toStart = alignFrontier (s, s->secondaryHeap.start);
80 s->forwardState.back = toStart;
81 foreachGlobalObjptr (s, forwardObjptr);
82 foreachObjptrInRange (s, toStart, &s->forwardState.back, forwardObjptr, TRUE);
83 updateWeaksForCheneyCopy (s);
84 s->secondaryHeap.oldGenSize = (size_t)(s->forwardState.back - s->secondaryHeap.start);
85 bytesCopied = s->secondaryHeap.oldGenSize;
86 s->cumulativeStatistics.bytesCopied += bytesCopied;
87 swapHeapsForCheneyCopy (s);
88 s->lastMajorStatistics.kind = GC_COPYING;
89 if (detailedGCTime (s))
90 stopTiming (&ru_start, &s->cumulativeStatistics.ru_gcCopying);
91 if (DEBUG or s->controls.messages)
92 fprintf (stderr,
93 "[GC: Finished major Cheney-copy; copied %s bytes.]\n",
94 uintmaxToCommaString(bytesCopied));
95}
96
97/* ---------------------------------------------------------------- */
98/* Minor Cheney Copying Collection */
99/* ---------------------------------------------------------------- */
100
101void minorCheneyCopyGC (GC_state s) {
102 size_t bytesAllocated;
103 size_t bytesCopied;
104 struct rusage ru_start;
105
106 if (DEBUG_GENERATIONAL)
107 fprintf (stderr, "minorGC nursery = "FMTPTR" frontier = "FMTPTR"\n",
108 (uintptr_t)s->heap.nursery, (uintptr_t)s->frontier);
109 assert (invariantForGC (s));
110 bytesAllocated = (size_t)(s->frontier - s->heap.nursery);
111 if (bytesAllocated == 0)
112 return;
113 s->cumulativeStatistics.bytesAllocated += bytesAllocated;
114 if (not s->canMinor) {
115 s->heap.oldGenSize += bytesAllocated;
116 } else {
117 if (detailedGCTime (s))
118 startTiming (&ru_start);
119 s->cumulativeStatistics.numMinorGCs++;
120 s->forwardState.amInMinorGC = TRUE;
121 if (DEBUG_GENERATIONAL or s->controls.messages) {
122 fprintf (stderr,
123 "[GC: Starting minor Cheney-copy;]\n");
124 fprintf (stderr,
125 "[GC:\tfrom nursery at "FMTPTR" of size %s bytes.]\n",
126 (uintptr_t)(s->heap.nursery),
127 uintmaxToCommaString(bytesAllocated));
128 }
129 s->forwardState.toStart = s->heap.start + s->heap.oldGenSize;
130 assert (isFrontierAligned (s, s->forwardState.toStart));
131 s->forwardState.toLimit = s->forwardState.toStart + bytesAllocated;
132 assert (invariantForGC (s));
133 s->forwardState.back = s->forwardState.toStart;
134 /* Forward all globals. Would like to avoid doing this once all
135 * the globals have been assigned.
136 */
137 foreachGlobalObjptr (s, forwardObjptrIfInNursery);
138 forwardInterGenerationalObjptrs (s);
139 foreachObjptrInRange (s, s->forwardState.toStart, &s->forwardState.back,
140 forwardObjptrIfInNursery, TRUE);
141 updateWeaksForCheneyCopy (s);
142 bytesCopied = (size_t)(s->forwardState.back - s->forwardState.toStart);
143 s->cumulativeStatistics.bytesCopiedMinor += bytesCopied;
144 s->heap.oldGenSize += bytesCopied;
145 s->lastMajorStatistics.numMinorGCs++;
146 if (detailedGCTime (s))
147 stopTiming (&ru_start, &s->cumulativeStatistics.ru_gcMinor);
148 if (DEBUG_GENERATIONAL or s->controls.messages)
149 fprintf (stderr,
150 "[GC: Finished minor Cheney-copy; copied %s bytes.]\n",
151 uintmaxToCommaString(bytesCopied));
152 }
153}