-
- ASSERT(p && (LOOKS_LIKE_GHC_INFO(info)
- || IS_HUGS_CONSTR_INFO(info)));
-
- switch (info->type) {
- case FUN_0_1:
- case CONSTR_0_1:
- p += sizeofW(StgHeader) + 1;
- break;
-
- case FUN_1_0:
- case CONSTR_1_0:
- thread((StgPtr)&((StgClosure *)p)->payload[0]);
- p += sizeofW(StgHeader) + 1;
- break;
-
- case THUNK_1_0:
- thread((StgPtr)&((StgClosure *)p)->payload[0]);
- p += sizeofW(StgHeader) + 2; // MIN_UPD_SIZE
- break;
-
- case THUNK_0_1: // MIN_UPD_SIZE
- case THUNK_0_2:
- case FUN_0_2:
- case CONSTR_0_2:
- p += sizeofW(StgHeader) + 2;
- break;
-
- case THUNK_1_1:
- case FUN_1_1:
- case CONSTR_1_1:
- thread((StgPtr)&((StgClosure *)p)->payload[0]);
- p += sizeofW(StgHeader) + 2;
- break;
-
- case THUNK_2_0:
- case FUN_2_0:
- case CONSTR_2_0:
- thread((StgPtr)&((StgClosure *)p)->payload[0]);
- thread((StgPtr)&((StgClosure *)p)->payload[1]);
- p += sizeofW(StgHeader) + 2;
- break;
-
- case FUN:
- case THUNK:
- case CONSTR:
- case FOREIGN:
- case STABLE_NAME:
- case BCO:
- case IND_PERM:
- case MUT_VAR:
- case MUT_CONS:
- case CAF_BLACKHOLE:
- case SE_CAF_BLACKHOLE:
- case SE_BLACKHOLE:
- case BLACKHOLE:
- case BLACKHOLE_BQ:
- {
- StgPtr end;
-
- end = (P_)((StgClosure *)p)->payload +
- info->layout.payload.ptrs;
- for (p = (P_)((StgClosure *)p)->payload; p < end; p++) {
- thread(p);
- }
- p += info->layout.payload.nptrs;
- break;
- }
-
- // the info table for a weak ptr lies about the number of ptrs
- // (because we have special GC routines for them, but we
- // want to use the standard evacuate code). So we have to
- // special case here.
- case WEAK:
- {
- StgWeak *w = (StgWeak *)p;
- thread((StgPtr)&w->key);
- thread((StgPtr)&w->value);
- thread((StgPtr)&w->finalizer);
- if (w->link != NULL) {
- thread((StgPtr)&w->link);
- }
- p += sizeofW(StgWeak);
- break;
- }
-
- // again, the info table for MVar isn't suitable here (it includes
- // the mut_link field as a pointer, and we don't want to
- // thread it).
- case MVAR:
- {
- StgMVar *mvar = (StgMVar *)p;
- thread((StgPtr)&mvar->head);
- thread((StgPtr)&mvar->tail);
- thread((StgPtr)&mvar->value);
- p += sizeofW(StgMVar);
- break;
- }
-
- case IND_OLDGEN:
- case IND_OLDGEN_PERM:
- thread((StgPtr)&((StgIndOldGen *)p)->indirectee);
- p += sizeofW(StgIndOldGen);
- break;
-
- case THUNK_SELECTOR:
- {
- StgSelector *s = (StgSelector *)p;
- thread((StgPtr)&s->selectee);
- p += THUNK_SELECTOR_sizeW();
- break;
- }
-
- case AP_UPD: // same as PAPs
- case PAP:
- {
- StgPAP* pap = (StgPAP *)p;
-
- thread((P_)&pap->fun);
- thread_stack((P_)pap->payload, (P_)pap->payload + pap->n_args);
- p += pap_sizeW(pap);
- break;
- }
-
- case ARR_WORDS:
- p += arr_words_sizeW((StgArrWords *)p);
- break;
-
- case MUT_ARR_PTRS:
- case MUT_ARR_PTRS_FROZEN:
- // follow everything
- {
- StgPtr next;
-
- next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
- for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
- thread(p);
- }
- break;
- }
-
- case TSO:
- {
- StgTSO *tso = (StgTSO *)p;
- thread_stack(tso->sp, &(tso->stack[tso->stack_size]));
- thread((StgPtr)&tso->link);
- thread((StgPtr)&tso->global_link);
- p += tso_sizeW(tso);
- break;
- }
-
- default:
- barf("update_fwd: unknown/strange object %d", (int)(info->type));
- }