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.
6 * MLton is released under a BSD-style license.
7 * See the file MLton-LICENSE for details.
10 /* ---------------------------------------------------------------- */
11 /* Cheney Copying Collection */
12 /* ---------------------------------------------------------------- */
14 void updateWeaksForCheneyCopy (GC_state s
) {
18 for (w
= s
->weaks
; w
!= NULL
; w
= w
->link
) {
19 assert (BOGUS_OBJPTR
!= w
->objptr
);
22 fprintf (stderr
, "updateWeaksForCheneyCopy w = "FMTPTR
" ", (uintptr_t)w
);
23 p
= objptrToPointer (w
->objptr
, s
->heap
.start
);
26 fprintf (stderr
, "forwarded from "FMTOBJPTR
" to "FMTOBJPTR
"\n",
27 w
->objptr
, getFwdPtr(p
));
28 w
->objptr
= getFwdPtr(p
);
31 fprintf (stderr
, "cleared\n");
32 *(getHeaderp((pointer
)w
- offsetofWeak (s
))) = GC_WEAK_GONE_HEADER
;
33 w
->objptr
= BOGUS_OBJPTR
;
39 void swapHeapsForCheneyCopy (GC_state s
) {
40 struct GC_heap tempHeap
;
42 tempHeap
= s
->secondaryHeap
;
43 s
->secondaryHeap
= s
->heap
;
45 setCardMapAndCrossMap (s
);
48 void majorCheneyCopyGC (GC_state s
) {
50 struct rusage ru_start
;
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
) {
60 "[GC: Starting major Cheney-copy;]\n");
62 "[GC:\tfrom heap at "FMTPTR
" of size %s bytes,]\n",
63 (uintptr_t)(s
->heap
.start
),
64 uintmaxToCommaString(s
->heap
.size
));
66 "[GC:\tto heap at "FMTPTR
" of size %s bytes.]\n",
67 (uintptr_t)(s
->secondaryHeap
.start
),
68 uintmaxToCommaString(s
->secondaryHeap
.size
));
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.
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
)
93 "[GC: Finished major Cheney-copy; copied %s bytes.]\n",
94 uintmaxToCommaString(bytesCopied
));
97 /* ---------------------------------------------------------------- */
98 /* Minor Cheney Copying Collection */
99 /* ---------------------------------------------------------------- */
101 void minorCheneyCopyGC (GC_state s
) {
102 size_t bytesAllocated
;
104 struct rusage ru_start
;
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)
113 s
->cumulativeStatistics
.bytesAllocated
+= bytesAllocated
;
114 if (not s
->canMinor
) {
115 s
->heap
.oldGenSize
+= bytesAllocated
;
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
) {
123 "[GC: Starting minor Cheney-copy;]\n");
125 "[GC:\tfrom nursery at "FMTPTR
" of size %s bytes.]\n",
126 (uintptr_t)(s
->heap
.nursery
),
127 uintmaxToCommaString(bytesAllocated
));
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.
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
)
150 "[GC: Finished minor Cheney-copy; copied %s bytes.]\n",
151 uintmaxToCommaString(bytesCopied
));