#include "Rts.h" StgWord gtc_heap_view_closureSize(StgClosure *closure) { ASSERT(LOOKS_LIKE_CLOSURE_PTR(closure)); return closure_sizeW(closure); } static void gtc_heap_view_closure_ptrs_in_large_bitmap(StgClosure *ptrs[], StgWord *nptrs, StgClosure **p, StgLargeBitmap *large_bitmap, nat size ) { nat i, j, b; StgWord bitmap; b = 0; for (i = 0; i < size; b++) { bitmap = large_bitmap->bitmap[b]; j = stg_min(size-i, BITS_IN(W_)); i += j; for (; j > 0; j--, p++) { if ((bitmap & 1) == 0) { ptrs[(*nptrs)++] = *p; } bitmap = bitmap >> 1; } } } // from rts/Printer.c char *gtc_heap_view_closure_type_names[] = { [INVALID_OBJECT] = "INVALID_OBJECT", [CONSTR] = "CONSTR", [CONSTR_1_0] = "CONSTR_1_0", [CONSTR_0_1] = "CONSTR_0_1", [CONSTR_2_0] = "CONSTR_2_0", [CONSTR_1_1] = "CONSTR_1_1", [CONSTR_0_2] = "CONSTR_0_2", [CONSTR_STATIC] = "CONSTR_STATIC", [CONSTR_NOCAF_STATIC] = "CONSTR_NOCAF_STATIC", [FUN] = "FUN", [FUN_1_0] = "FUN_1_0", [FUN_0_1] = "FUN_0_1", [FUN_2_0] = "FUN_2_0", [FUN_1_1] = "FUN_1_1", [FUN_0_2] = "FUN_0_2", [FUN_STATIC] = "FUN_STATIC", [THUNK] = "THUNK", [THUNK_1_0] = "THUNK_1_0", [THUNK_0_1] = "THUNK_0_1", [THUNK_2_0] = "THUNK_2_0", [THUNK_1_1] = "THUNK_1_1", [THUNK_0_2] = "THUNK_0_2", [THUNK_STATIC] = "THUNK_STATIC", [THUNK_SELECTOR] = "THUNK_SELECTOR", [BCO] = "BCO", [AP] = "AP", [PAP] = "PAP", [AP_STACK] = "AP_STACK", [IND] = "IND", [IND_PERM] = "IND_PERM", [IND_STATIC] = "IND_STATIC", [RET_BCO] = "RET_BCO", [RET_SMALL] = "RET_SMALL", [RET_BIG] = "RET_BIG", [RET_DYN] = "RET_DYN", [RET_FUN] = "RET_FUN", [UPDATE_FRAME] = "UPDATE_FRAME", [CATCH_FRAME] = "CATCH_FRAME", [UNDERFLOW_FRAME] = "UNDERFLOW_FRAME", [STOP_FRAME] = "STOP_FRAME", [BLACKHOLE] = "BLACKHOLE", [BLOCKING_QUEUE] = "BLOCKING_QUEUE", [MVAR_CLEAN] = "MVAR_CLEAN", [MVAR_DIRTY] = "MVAR_DIRTY", [ARR_WORDS] = "ARR_WORDS", [MUT_ARR_PTRS_CLEAN] = "MUT_ARR_PTRS_CLEAN", [MUT_ARR_PTRS_DIRTY] = "MUT_ARR_PTRS_DIRTY", [MUT_ARR_PTRS_FROZEN0] = "MUT_ARR_PTRS_FROZEN0", [MUT_ARR_PTRS_FROZEN] = "MUT_ARR_PTRS_FROZEN", [MUT_VAR_CLEAN] = "MUT_VAR_CLEAN", [MUT_VAR_DIRTY] = "MUT_VAR_DIRTY", [WEAK] = "WEAK", [PRIM] = "PRIM", [MUT_PRIM] = "MUT_PRIM", [TSO] = "TSO", [STACK] = "STACK", [TREC_CHUNK] = "TREC_CHUNK", [ATOMICALLY_FRAME] = "ATOMICALLY_FRAME", [CATCH_RETRY_FRAME] = "CATCH_RETRY_FRAME", [CATCH_STM_FRAME] = "CATCH_STM_FRAME", [WHITEHOLE] = "WHITEHOLE" }; void gtc_heap_view_closure_ptrs_in_pap_payload(StgClosure *ptrs[], StgWord *nptrs, StgClosure *fun, StgClosure **payload, StgWord size) { StgWord bitmap; StgFunInfoTable *fun_info; fun_info = get_fun_itbl(UNTAG_CLOSURE(fun)); // ASSERT(fun_info->i.type != PAP); StgClosure **p = payload; switch (fun_info->f.fun_type) { case ARG_GEN: bitmap = BITMAP_BITS(fun_info->f.b.bitmap); goto small_bitmap; case ARG_GEN_BIG: gtc_heap_view_closure_ptrs_in_large_bitmap(ptrs, nptrs, payload, GET_FUN_LARGE_BITMAP(fun_info), size); break; case ARG_BCO: gtc_heap_view_closure_ptrs_in_large_bitmap(ptrs, nptrs, payload, BCO_BITMAP(fun), size); break; default: bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]); small_bitmap: while (size > 0) { if ((bitmap & 1) == 0) { ptrs[(*nptrs)++] = *p; } bitmap = bitmap >> 1; p++; size--; } break; } } StgMutArrPtrs *gtc_heap_view_closurePtrs(Capability *cap, StgClosure *closure) { ASSERT(LOOKS_LIKE_CLOSURE_PTR(closure)); StgWord size = gtc_heap_view_closureSize(closure); StgWord nptrs = 0; StgWord i; // First collect all pointers here, with the comfortable memory bound // of the whole closure. Afterwards we know how many pointers are in // the closure and then we can allocate space on the heap and copy them // there StgClosure *ptrs[size]; StgClosure **end; StgClosure **ptr; StgInfoTable *info = get_itbl(closure); StgThunkInfoTable *thunk_info; StgFunInfoTable *fun_info; switch (info->type) { case INVALID_OBJECT: barf("Invalid Object"); break; // No pointers case ARR_WORDS: break; // Default layout case CONSTR_1_0: case CONSTR_0_1: case CONSTR_2_0: case CONSTR_1_1: case CONSTR_0_2: case CONSTR: case CONSTR_STATIC: case CONSTR_NOCAF_STATIC: case PRIM: case FUN: case FUN_1_0: case FUN_0_1: case FUN_1_1: case FUN_2_0: case FUN_0_2: case FUN_STATIC: end = closure->payload + info->layout.payload.ptrs; for (ptr = closure->payload; ptr < end; ptr++) { ptrs[nptrs++] = *ptr; } break; case THUNK: case THUNK_1_0: case THUNK_0_1: case THUNK_1_1: case THUNK_2_0: case THUNK_0_2: case THUNK_STATIC: end = ((StgThunk *)closure)->payload + info->layout.payload.ptrs; for (ptr = ((StgThunk *)closure)->payload; ptr < end; ptr++) { ptrs[nptrs++] = *ptr; } break; case THUNK_SELECTOR: ptrs[nptrs++] = ((StgSelector *)closure)->selectee; break; case AP: ptrs[nptrs++] = ((StgAP *)closure)->fun; gtc_heap_view_closure_ptrs_in_pap_payload(ptrs, &nptrs, ((StgAP *)closure)->fun, ((StgAP *)closure)->payload, ((StgAP *)closure)->n_args); break; case PAP: ptrs[nptrs++] = ((StgPAP *)closure)->fun; gtc_heap_view_closure_ptrs_in_pap_payload(ptrs, &nptrs, ((StgPAP *)closure)->fun, ((StgPAP *)closure)->payload, ((StgPAP *)closure)->n_args); break; case AP_STACK: ptrs[nptrs++] = ((StgAP_STACK *)closure)->fun; for (i = 0; i < ((StgAP_STACK *)closure)->size; ++i) { ptrs[nptrs++] = ((StgAP_STACK *)closure)->payload[i]; } break; case BCO: ptrs[nptrs++] = (StgClosure *)((StgBCO *)closure)->instrs; ptrs[nptrs++] = (StgClosure *)((StgBCO *)closure)->literals; ptrs[nptrs++] = (StgClosure *)((StgBCO *)closure)->ptrs; break; case IND: case IND_PERM: case IND_STATIC: case BLACKHOLE: ptrs[nptrs++] = (StgClosure *)(((StgInd *)closure)->indirectee); break; case MUT_ARR_PTRS_CLEAN: case MUT_ARR_PTRS_DIRTY: case MUT_ARR_PTRS_FROZEN: case MUT_ARR_PTRS_FROZEN0: for (i = 0; i < ((StgMutArrPtrs *)closure)->ptrs; ++i) { ptrs[nptrs++] = ((StgMutArrPtrs *)closure)->payload[i]; } break; case MUT_VAR_CLEAN: ptrs[nptrs++] = ((StgMutVar *)closure)->var; break; case MVAR_CLEAN: ptrs[nptrs++] = (StgClosure *)((StgMVar *)closure)->head; ptrs[nptrs++] = (StgClosure *)((StgMVar *)closure)->tail; ptrs[nptrs++] = ((StgMVar *)closure)->value; break; default: //fprintf(stderr,"closurePtrs: Cannot handle type %s yet\n", gtc_heap_view_closure_type_names[info->type]); break; } size = nptrs + mutArrPtrsCardTableSize(nptrs); StgMutArrPtrs *arr = (StgMutArrPtrs *)allocate(cap, sizeofW(StgMutArrPtrs) + size); TICK_ALLOC_PRIM(sizeofW(StgMutArrPtrs), nptrs, 0); SET_HDR(arr, &stg_MUT_ARR_PTRS_FROZEN_info, CCCS); arr->ptrs = nptrs; arr->size = size; for (i = 0; ipayload[i] = ptrs[i]; } return arr; }