Strip parentheses in expressions contexts in error messages
[ghc.git] / rts / Heap.c
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The University of Glasgow 2006-2017
4 *
5 * Introspection into GHC's heap representation
6 *
7 * ---------------------------------------------------------------------------*/
8
9 #include "Rts.h"
10 #include "RtsAPI.h"
11
12 #include "Capability.h"
13 #include "Printer.h"
14
15 StgWord heap_view_closureSize(StgClosure *closure) {
16 ASSERT(LOOKS_LIKE_CLOSURE_PTR(closure));
17 return closure_sizeW(closure);
18 }
19
20 static void
21 heap_view_closure_ptrs_in_large_bitmap(StgClosure *ptrs[], StgWord *nptrs
22 , StgClosure **p, StgLargeBitmap *large_bitmap
23 , uint32_t size )
24 {
25 uint32_t i, j, b;
26 StgWord bitmap;
27
28 b = 0;
29
30 for (i = 0; i < size; b++) {
31 bitmap = large_bitmap->bitmap[b];
32 j = stg_min(size-i, BITS_IN(W_));
33 i += j;
34 for (; j > 0; j--, p++) {
35 if ((bitmap & 1) == 0) {
36 ptrs[(*nptrs)++] = *p;
37 }
38 bitmap = bitmap >> 1;
39 }
40 }
41 }
42
43 void heap_view_closure_ptrs_in_pap_payload(StgClosure *ptrs[], StgWord *nptrs
44 , StgClosure *fun, StgClosure **payload, StgWord size) {
45 StgWord bitmap;
46 const StgFunInfoTable *fun_info;
47
48 fun_info = get_fun_itbl(UNTAG_CLOSURE(fun));
49 // ASSERT(fun_info->i.type != PAP);
50 StgClosure **p = payload;
51
52 switch (fun_info->f.fun_type) {
53 case ARG_GEN:
54 bitmap = BITMAP_BITS(fun_info->f.b.bitmap);
55 goto small_bitmap;
56 case ARG_GEN_BIG:
57 heap_view_closure_ptrs_in_large_bitmap(ptrs, nptrs, payload,
58 GET_FUN_LARGE_BITMAP(fun_info), size);
59 break;
60 case ARG_BCO:
61 heap_view_closure_ptrs_in_large_bitmap(ptrs, nptrs, payload,
62 BCO_BITMAP(fun), size);
63 break;
64 default:
65 bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]);
66 small_bitmap:
67 while (size > 0) {
68 if ((bitmap & 1) == 0) {
69 ptrs[(*nptrs)++] = *p;
70 }
71 bitmap = bitmap >> 1;
72 p++;
73 size--;
74 }
75 break;
76 }
77 }
78
79 StgMutArrPtrs *heap_view_closurePtrs(Capability *cap, StgClosure *closure) {
80 ASSERT(LOOKS_LIKE_CLOSURE_PTR(closure));
81
82 StgWord size = heap_view_closureSize(closure);
83 StgWord nptrs = 0;
84 StgWord i;
85
86 // First collect all pointers here, with the comfortable memory bound
87 // of the whole closure. Afterwards we know how many pointers are in
88 // the closure and then we can allocate space on the heap and copy them
89 // there
90 StgClosure *ptrs[size];
91
92 StgClosure **end;
93 StgClosure **ptr;
94
95 const StgInfoTable *info = get_itbl(closure);
96
97 switch (info->type) {
98 case INVALID_OBJECT:
99 barf("Invalid Object");
100 break;
101
102 // No pointers
103 case ARR_WORDS:
104 break;
105
106 // Default layout
107 case CONSTR_1_0:
108 case CONSTR_0_1:
109 case CONSTR_2_0:
110 case CONSTR_1_1:
111 case CONSTR_0_2:
112 case CONSTR:
113 case CONSTR_NOCAF:
114
115
116 case PRIM:
117
118 case FUN:
119 case FUN_1_0:
120 case FUN_0_1:
121 case FUN_1_1:
122 case FUN_2_0:
123 case FUN_0_2:
124 case FUN_STATIC:
125 end = closure->payload + info->layout.payload.ptrs;
126 for (ptr = closure->payload; ptr < end; ptr++) {
127 ptrs[nptrs++] = *ptr;
128 }
129 break;
130
131 case THUNK:
132 case THUNK_1_0:
133 case THUNK_0_1:
134 case THUNK_1_1:
135 case THUNK_2_0:
136 case THUNK_0_2:
137 case THUNK_STATIC:
138 end = ((StgThunk *)closure)->payload + info->layout.payload.ptrs;
139 for (ptr = ((StgThunk *)closure)->payload; ptr < end; ptr++) {
140 ptrs[nptrs++] = *ptr;
141 }
142 break;
143
144 case THUNK_SELECTOR:
145 ptrs[nptrs++] = ((StgSelector *)closure)->selectee;
146 break;
147
148 case AP:
149 ptrs[nptrs++] = ((StgAP *)closure)->fun;
150 heap_view_closure_ptrs_in_pap_payload(ptrs, &nptrs,
151 ((StgAP *)closure)->fun,
152 ((StgAP *)closure)->payload,
153 ((StgAP *)closure)->n_args);
154 break;
155
156 case PAP:
157 ptrs[nptrs++] = ((StgPAP *)closure)->fun;
158 heap_view_closure_ptrs_in_pap_payload(ptrs, &nptrs,
159 ((StgPAP *)closure)->fun,
160 ((StgPAP *)closure)->payload,
161 ((StgPAP *)closure)->n_args);
162 break;
163
164 case AP_STACK:
165 ptrs[nptrs++] = ((StgAP_STACK *)closure)->fun;
166 /*
167 The payload is a stack, which consists of a mixture of pointers
168 and non-pointers. We can't simply pretend it's all pointers,
169 because that will cause crashes in the GC later. We could
170 traverse the stack and extract pointers and non-pointers, but that
171 would be complicated, so let's just ignore the payload for now.
172 See #15375.
173 */
174 break;
175
176 case BCO:
177 ptrs[nptrs++] = (StgClosure *)((StgBCO *)closure)->instrs;
178 ptrs[nptrs++] = (StgClosure *)((StgBCO *)closure)->literals;
179 ptrs[nptrs++] = (StgClosure *)((StgBCO *)closure)->ptrs;
180 break;
181
182 case IND:
183 case IND_STATIC:
184 case BLACKHOLE:
185 ptrs[nptrs++] = (StgClosure *)(((StgInd *)closure)->indirectee);
186 break;
187
188 case MUT_ARR_PTRS_CLEAN:
189 case MUT_ARR_PTRS_DIRTY:
190 case MUT_ARR_PTRS_FROZEN_CLEAN:
191 case MUT_ARR_PTRS_FROZEN_DIRTY:
192 for (i = 0; i < ((StgMutArrPtrs *)closure)->ptrs; ++i) {
193 ptrs[nptrs++] = ((StgMutArrPtrs *)closure)->payload[i];
194 }
195 break;
196
197 case SMALL_MUT_ARR_PTRS_CLEAN:
198 case SMALL_MUT_ARR_PTRS_DIRTY:
199 case SMALL_MUT_ARR_PTRS_FROZEN_CLEAN:
200 case SMALL_MUT_ARR_PTRS_FROZEN_DIRTY:
201 for (i = 0; i < ((StgSmallMutArrPtrs *)closure)->ptrs; ++i) {
202 ptrs[nptrs++] = ((StgSmallMutArrPtrs *)closure)->payload[i];
203 }
204 break;
205
206 case MUT_VAR_CLEAN:
207 case MUT_VAR_DIRTY:
208 ptrs[nptrs++] = ((StgMutVar *)closure)->var;
209 break;
210 case MVAR_DIRTY:
211 case MVAR_CLEAN:
212 ptrs[nptrs++] = (StgClosure *)((StgMVar *)closure)->head;
213 ptrs[nptrs++] = (StgClosure *)((StgMVar *)closure)->tail;
214 ptrs[nptrs++] = ((StgMVar *)closure)->value;
215 break;
216
217 case WEAK:
218 ptrs[nptrs++] = (StgClosure *)((StgWeak *)closure)->cfinalizers;
219 ptrs[nptrs++] = (StgClosure *)((StgWeak *)closure)->key;
220 ptrs[nptrs++] = (StgClosure *)((StgWeak *)closure)->value;
221 ptrs[nptrs++] = (StgClosure *)((StgWeak *)closure)->finalizer;
222 ptrs[nptrs++] = (StgClosure *)((StgWeak *)closure)->link;
223 break;
224
225 default:
226 fprintf(stderr,"closurePtrs: Cannot handle type %s yet\n",
227 closure_type_names[info->type]);
228 break;
229 }
230
231 size = nptrs + mutArrPtrsCardTableSize(nptrs);
232 StgMutArrPtrs *arr =
233 (StgMutArrPtrs *)allocate(cap, sizeofW(StgMutArrPtrs) + size);
234 TICK_ALLOC_PRIM(sizeofW(StgMutArrPtrs), nptrs, 0);
235 SET_HDR(arr, &stg_MUT_ARR_PTRS_FROZEN_CLEAN_info, cap->r.rCCCS);
236 arr->ptrs = nptrs;
237 arr->size = size;
238
239 for (i = 0; i<nptrs; i++) {
240 arr->payload[i] = ptrs[i];
241 }
242
243 return arr;
244 }