... |
... |
@@ -26,11 +26,6 @@ |
26
|
26
|
#include <string.h>
|
27
|
27
|
|
28
|
28
|
|
29
|
|
-static StgWord getStackFrameCount(StgStack* stack);
|
30
|
|
-static StgWord getStackChunkClosureCount(StgStack* stack);
|
31
|
|
-static StgArrBytes* allocateByteArray(Capability *cap, StgWord bytes);
|
32
|
|
-static void copyPtrsToArray(StgArrBytes* arr, StgStack* stack);
|
33
|
|
-
|
34
|
29
|
static StgStack* cloneStackChunk(Capability* capability, const StgStack* stack)
|
35
|
30
|
{
|
36
|
31
|
StgWord spOffset = stack->sp - stack->stack;
|
... |
... |
@@ -112,94 +107,3 @@ void sendCloneStackMessage(StgTSO *tso STG_UNUSED, HsStablePtr mvar STG_UNUSED) |
112
|
107
|
}
|
113
|
108
|
|
114
|
109
|
#endif // end !defined(THREADED_RTS) |
115
|
|
-
|
116
|
|
-// Creates a MutableArray# (Haskell representation) that contains a
|
117
|
|
-// InfoProvEnt* for every stack frame on the given stack. Thus, the size of the
|
118
|
|
-// array is the count of stack frames.
|
119
|
|
-// Each InfoProvEnt* is looked up by lookupIPE(). If there's no IPE for a stack
|
120
|
|
-// frame it's represented by null.
|
121
|
|
-StgArrBytes* decodeClonedStack(Capability *cap, StgStack* stack) {
|
122
|
|
- StgWord closureCount = getStackFrameCount(stack);
|
123
|
|
-
|
124
|
|
- StgArrBytes* array = allocateByteArray(cap, sizeof(StgInfoTable*) * closureCount);
|
125
|
|
-
|
126
|
|
- copyPtrsToArray(array, stack);
|
127
|
|
-
|
128
|
|
- return array;
|
129
|
|
-}
|
130
|
|
-
|
131
|
|
-// Count the stack frames that are on the given stack.
|
132
|
|
-// This is the sum of all stack frames in all stack chunks of this stack.
|
133
|
|
-StgWord getStackFrameCount(StgStack* stack) {
|
134
|
|
- StgWord closureCount = 0;
|
135
|
|
- StgStack *last_stack = stack;
|
136
|
|
- while (true) {
|
137
|
|
- closureCount += getStackChunkClosureCount(last_stack);
|
138
|
|
-
|
139
|
|
- // check whether the stack ends in an underflow frame
|
140
|
|
- StgUnderflowFrame *frame = (StgUnderflowFrame *) (last_stack->stack
|
141
|
|
- + last_stack->stack_size - sizeofW(StgUnderflowFrame));
|
142
|
|
- if (frame->info == &stg_stack_underflow_frame_d_info
|
143
|
|
- ||frame->info == &stg_stack_underflow_frame_v16_info
|
144
|
|
- ||frame->info == &stg_stack_underflow_frame_v32_info
|
145
|
|
- ||frame->info == &stg_stack_underflow_frame_v64_info) {
|
146
|
|
- last_stack = frame->next_chunk;
|
147
|
|
- } else {
|
148
|
|
- break;
|
149
|
|
- }
|
150
|
|
- }
|
151
|
|
- return closureCount;
|
152
|
|
-}
|
153
|
|
-
|
154
|
|
-StgWord getStackChunkClosureCount(StgStack* stack) {
|
155
|
|
- StgWord closureCount = 0;
|
156
|
|
- StgPtr sp = stack->sp;
|
157
|
|
- StgPtr spBottom = stack->stack + stack->stack_size;
|
158
|
|
- for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) {
|
159
|
|
- closureCount++;
|
160
|
|
- }
|
161
|
|
-
|
162
|
|
- return closureCount;
|
163
|
|
-}
|
164
|
|
-
|
165
|
|
-// Allocate and initialize memory for a ByteArray# (Haskell representation).
|
166
|
|
-StgArrBytes* allocateByteArray(Capability *cap, StgWord bytes) {
|
167
|
|
- // Idea stolen from PrimOps.cmm:stg_newArrayzh()
|
168
|
|
- StgWord words = sizeofW(StgArrBytes) + bytes;
|
169
|
|
-
|
170
|
|
- StgArrBytes* array = (StgArrBytes*) allocate(cap, words);
|
171
|
|
-
|
172
|
|
- SET_HDR(array, &stg_ARR_WORDS_info, CCS_SYSTEM);
|
173
|
|
- array->bytes = bytes;
|
174
|
|
- return array;
|
175
|
|
-}
|
176
|
|
-
|
177
|
|
-static void copyPtrsToArray(StgArrBytes* arr, StgStack* stack) {
|
178
|
|
- StgWord index = 0;
|
179
|
|
- StgStack *last_stack = stack;
|
180
|
|
- const StgInfoTable **result = (const StgInfoTable **) arr->payload;
|
181
|
|
- while (true) {
|
182
|
|
- StgPtr sp = last_stack->sp;
|
183
|
|
- StgPtr spBottom = last_stack->stack + last_stack->stack_size;
|
184
|
|
- for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) {
|
185
|
|
- const StgInfoTable* infoTable = ((StgClosure *)sp)->header.info;
|
186
|
|
- result[index] = infoTable;
|
187
|
|
- index++;
|
188
|
|
- }
|
189
|
|
-
|
190
|
|
- // Ensure that we didn't overflow the result array
|
191
|
|
- ASSERT(index-1 < arr->bytes / sizeof(StgInfoTable*));
|
192
|
|
-
|
193
|
|
- // check whether the stack ends in an underflow frame
|
194
|
|
- StgUnderflowFrame *frame = (StgUnderflowFrame *) (last_stack->stack
|
195
|
|
- + last_stack->stack_size - sizeofW(StgUnderflowFrame));
|
196
|
|
- if (frame->info == &stg_stack_underflow_frame_d_info
|
197
|
|
- ||frame->info == &stg_stack_underflow_frame_v16_info
|
198
|
|
- ||frame->info == &stg_stack_underflow_frame_v32_info
|
199
|
|
- ||frame->info == &stg_stack_underflow_frame_v64_info) {
|
200
|
|
- last_stack = frame->next_chunk;
|
201
|
|
- } else {
|
202
|
|
- break;
|
203
|
|
- }
|
204
|
|
- }
|
205
|
|
-} |