Import Upstream version 20180207
[hcoop/debian/mlton.git] / runtime / gc / invariant.c
CommitLineData
7f918cf1
CE
1/* Copyright (C) 2011-2012,2017 Matthew Fluet.
2 * Copyright (C) 1999-2007 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#if ASSERT
11void assertIsObjptrInFromSpace (GC_state s, objptr *opp) {
12 assert (isObjptrInFromSpace (s, *opp));
13 unless (isObjptrInFromSpace (s, *opp)) {
14 displayGCState (s, stderr);
15 die ("gc.c: assertIsObjptrInFromSpace "
16 "opp = "FMTPTR" "
17 "*opp = "FMTOBJPTR"\n",
18 (uintptr_t)opp, *opp);
19 }
20 /* The following checks that intergenerational pointers have the
21 * appropriate card marked. Unfortunately, it doesn't work because
22 * for stacks, the card containing the beginning of the stack is
23 * marked, but any remaining cards aren't.
24 */
25 if (FALSE and s->mutatorMarksCards
26 and isPointerInOldGen (s, (pointer)opp)
27 and isObjptrInNursery (s, *opp)
28 and not isCardMarked (s, (pointer)opp)) {
29 displayGCState (s, stderr);
30 die ("gc.c: intergenerational pointer from "FMTPTR" to "FMTOBJPTR" with unmarked card.\n",
31 (uintptr_t)opp, *opp);
32 }
33}
34
35bool invariantForGC (GC_state s) {
36 if (DEBUG)
37 fprintf (stderr, "invariantForGC\n");
38 /* Frame layouts */
39 for (unsigned int i = 0; i < s->frameLayoutsLength; ++i) {
40 GC_frameLayout layout;
41
42 layout = &(s->frameLayouts[i]);
43 if (layout->size > 0) {
44 GC_frameOffsets offsets;
45
46 assert (layout->size <= s->maxFrameSize);
47 offsets = layout->offsets;
48 for (unsigned int j = 0; j < offsets[0]; ++j)
49 assert (offsets[j + 1] < layout->size);
50 }
51 }
52 /* Generational */
53 if (s->mutatorMarksCards) {
54 assert (s->generationalMaps.cardMap ==
55 &(s->generationalMaps.cardMapAbsolute
56 [pointerToCardMapIndexAbsolute(s->heap.start)]));
57 assert (&(s->generationalMaps.cardMapAbsolute
58 [pointerToCardMapIndexAbsolute(s->heap.start + s->heap.size - 1)])
59 < (s->generationalMaps.cardMap
60 + (s->generationalMaps.cardMapLength * CARD_MAP_ELEM_SIZE)));
61 }
62 assert (isAligned (s->heap.size, s->sysvals.pageSize));
63 assert (isAligned ((size_t)s->heap.start, CARD_SIZE));
64 assert (isFrontierAligned (s, s->heap.start + s->heap.oldGenSize));
65 assert (isFrontierAligned (s, s->heap.nursery));
66 assert (isFrontierAligned (s, s->frontier));
67 assert (s->heap.start + s->heap.oldGenSize <= s->heap.nursery);
68 assert (s->heap.nursery <= s->heap.start + s->heap.size);
69 assert (s->heap.nursery <= s->frontier);
70 unless (0 == s->heap.size) {
71 assert (s->frontier <= s->limitPlusSlop);
72 assert (s->limit == s->limitPlusSlop - GC_HEAP_LIMIT_SLOP);
73 assert (hasHeapBytesFree (s, 0, 0));
74 }
75 assert (s->secondaryHeap.start == NULL
76 or s->heap.size == s->secondaryHeap.size);
77 /* Check that all pointers are into from space. */
78 foreachGlobalObjptr (s, assertIsObjptrInFromSpace);
79 pointer back = s->heap.start + s->heap.oldGenSize;
80 if (DEBUG_DETAILED)
81 fprintf (stderr, "Checking old generation.\n");
82 foreachObjptrInRange (s, alignFrontier (s, s->heap.start), &back,
83 assertIsObjptrInFromSpace, FALSE);
84 if (DEBUG_DETAILED)
85 fprintf (stderr, "Checking nursery.\n");
86 foreachObjptrInRange (s, s->heap.nursery, &s->frontier,
87 assertIsObjptrInFromSpace, FALSE);
88 /* Current thread. */
89 GC_stack stack = getStackCurrent(s);
90 assert (isStackReservedAligned (s, stack->reserved));
91 assert (s->stackBottom == getStackBottom (s, stack));
92 assert (s->stackTop == getStackTop (s, stack));
93 assert (s->stackLimit == getStackLimit (s, stack));
94 assert (s->stackBottom <= s->stackTop);
95 assert (stack->used == sizeofGCStateCurrentStackUsed (s));
96 assert (stack->used <= stack->reserved);
97 if (DEBUG)
98 fprintf (stderr, "invariantForGC passed\n");
99 return TRUE;
100}
101#endif
102
103bool invariantForMutatorFrontier (GC_state s) {
104 GC_thread thread = getThreadCurrent(s);
105 return (thread->bytesNeeded
106 <= (size_t)(s->limitPlusSlop - s->frontier));
107}
108
109bool invariantForMutatorStack (GC_state s) {
110 GC_stack stack = getStackCurrent(s);
111 return (getStackTop (s, stack)
112 <= getStackLimit (s, stack) + getStackTopFrameSize (s, stack));
113}
114
115#if ASSERT
116bool invariantForMutator (GC_state s, bool frontier, bool stack) {
117 if (DEBUG)
118 displayGCState (s, stderr);
119 if (frontier)
120 assert (invariantForMutatorFrontier(s));
121 if (stack)
122 assert (invariantForMutatorStack(s));
123 assert (invariantForGC (s));
124 return TRUE;
125}
126#endif