Commit | Line | Data |
---|---|---|
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 | ||
14 | void 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 | ||
39 | void 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 | ||
48 | void 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 | ||
101 | void 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 | } |