X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FPrinter.c;h=e1c0b4d059bd2544dec7b4f7adf7c6fe7b47015f;hb=423d477bfecd490de1449c59325c8776f91d7aac;hp=abbc91b465331cfdbc341ba5b343c84502919ede;hpb=cc517f07f309c6a46eac9ace167749f6b0648965;p=ghc-hetmet.git diff --git a/ghc/rts/Printer.c b/ghc/rts/Printer.c index abbc91b..e1c0b4d 100644 --- a/ghc/rts/Printer.c +++ b/ghc/rts/Printer.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: Printer.c,v 1.51 2002/02/04 20:26:25 sof Exp $ + * $Id: Printer.c,v 1.63 2004/08/13 13:10:23 simonmar Exp $ * * (c) The GHC Team, 1994-2000. * @@ -11,6 +11,8 @@ #include "Rts.h" #include "Printer.h" +#include + #ifdef DEBUG #include "RtsUtils.h" @@ -19,13 +21,15 @@ #include "Storage.h" #include "Bytecodes.h" /* for InstrPtr */ #include "Disassembler.h" +#include "Apply.h" -#include "Printer.h" +#include +#include #if defined(GRAN) || defined(PAR) // HWL: explicit fixed header size to make debugging easier -int fixed_hs = FIXED_HS, itbl_sz = sizeofW(StgInfoTable), - uf_sz=sizeofW(StgUpdateFrame), sf_sz=sizeofW(StgSeqFrame); +int fixed_hs = sizeof(StgHeader), itbl_sz = sizeofW(StgInfoTable), + uf_sz=sizeofW(StgUpdateFrame); #endif /* -------------------------------------------------------------------------- @@ -33,9 +37,12 @@ int fixed_hs = FIXED_HS, itbl_sz = sizeofW(StgInfoTable), * ------------------------------------------------------------------------*/ static void printStdObject( StgClosure *obj, char* tag ); +static void printStdObjPayload( StgClosure *obj ); +#ifdef USING_LIBBFD static void reset_table ( int size ); static void prepare_table ( void ); static void insert ( unsigned value, const char *name ); +#endif #if 0 /* unused but might be useful sometime */ static rtsBool lookup_name ( char *name, unsigned *result ); static void enZcode ( char *in, char *out ); @@ -55,43 +62,48 @@ void printPtr( StgPtr p ) if (raw != NULL) { printZcoded(raw); } else { - fprintf(stdout, "%p", p); + fprintf(stderr, "%p", p); } } void printObj( StgClosure *obj ) { - fprintf(stdout,"Object "); printPtr((StgPtr)obj); fprintf(stdout," = "); + fprintf(stderr,"Object "); printPtr((StgPtr)obj); fprintf(stderr," = "); printClosure(obj); } -static inline void +STATIC_INLINE void printStdObjHdr( StgClosure *obj, char* tag ) { - fprintf(stdout,"%s(",tag); + fprintf(stderr,"%s(",tag); printPtr((StgPtr)obj->header.info); #ifdef PROFILING - fprintf(stdout,", %s", obj->header.prof.ccs->cc->label); + fprintf(stderr,", %s", obj->header.prof.ccs->cc->label); #endif } static void -printStdObject( StgClosure *obj, char* tag ) +printStdObjPayload( StgClosure *obj ) { StgWord i, j; const StgInfoTable* info; - printStdObjHdr( obj, tag ); - info = get_itbl(obj); for (i = 0; i < info->layout.payload.ptrs; ++i) { - fprintf(stdout,", "); + fprintf(stderr,", "); printPtr((StgPtr)obj->payload[i]); } for (j = 0; j < info->layout.payload.nptrs; ++j) { - fprintf(stdout,", %pd#",obj->payload[i+j]); + fprintf(stderr,", %pd#",obj->payload[i+j]); } - fprintf(stdout,")\n"); + fprintf(stderr,")\n"); +} + +static void +printStdObject( StgClosure *obj, char* tag ) +{ + printStdObjHdr( obj, tag ); + printStdObjPayload( obj ); } void @@ -104,27 +116,81 @@ printClosure( StgClosure *obj ) switch ( info->type ) { case INVALID_OBJECT: barf("Invalid object"); - case BCO: - disassemble( (StgBCO*)obj ); - break; - case MUT_VAR: + case CONSTR: + case CONSTR_1_0: case CONSTR_0_1: + case CONSTR_1_1: case CONSTR_0_2: case CONSTR_2_0: + case CONSTR_INTLIKE: + case CONSTR_CHARLIKE: + case CONSTR_STATIC: + case CONSTR_NOCAF_STATIC: { - StgMutVar* mv = (StgMutVar*)obj; - fprintf(stdout,"MUT_VAR(var=%p, link=%p)\n", mv->var, mv->mut_link); - break; + /* We can't use printStdObject because we want to print the + * tag as well. + */ + StgWord i, j; +#ifdef PROFILING + fprintf(stderr,"%s(", info->prof.closure_desc); + fprintf(stderr,"%s", obj->header.prof.ccs->cc->label); +#else + fprintf(stderr,"CONSTR("); + printPtr((StgPtr)obj->header.info); + fprintf(stderr,"(tag=%d)",info->srt_bitmap); +#endif + for (i = 0; i < info->layout.payload.ptrs; ++i) { + fprintf(stderr,", "); + printPtr((StgPtr)obj->payload[i]); + } + for (j = 0; j < info->layout.payload.nptrs; ++j) { + fprintf(stderr,", %p#", obj->payload[i+j]); + } + fprintf(stderr,")\n"); + break; } - case AP_UPD: + case FUN: + case FUN_1_0: case FUN_0_1: + case FUN_1_1: case FUN_0_2: case FUN_2_0: + case FUN_STATIC: + fprintf(stderr,"FUN/%d(",itbl_to_fun_itbl(info)->f.arity); + printPtr((StgPtr)obj->header.info); +#ifdef PROFILING + fprintf(stderr,", %s", obj->header.prof.ccs->cc->label); +#endif + printStdObjPayload(obj); + break; + + case THUNK: + case THUNK_1_0: case THUNK_0_1: + case THUNK_1_1: case THUNK_0_2: case THUNK_2_0: + case THUNK_STATIC: + /* ToDo: will this work for THUNK_STATIC too? */ +#ifdef PROFILING + printStdObject(obj,info->prof.closure_desc); +#else + printStdObject(obj,"THUNK"); +#endif + break; + + case THUNK_SELECTOR: + printStdObjHdr(obj, "THUNK_SELECTOR"); + fprintf(stderr, ", %p)\n", ((StgSelector *)obj)->selectee); + break; + + case BCO: + disassemble( (StgBCO*)obj ); + break; + + case AP: { - StgAP_UPD* ap = stgCast(StgAP_UPD*,obj); + StgPAP* ap = stgCast(StgPAP*,obj); StgWord i; - fprintf(stdout,"AP_UPD("); printPtr((StgPtr)ap->fun); + fprintf(stderr,"AP("); printPtr((StgPtr)ap->fun); for (i = 0; i < ap->n_args; ++i) { - fprintf(stdout,", "); + fprintf(stderr,", "); printPtr((P_)ap->payload[i]); } - fprintf(stdout,")\n"); + fprintf(stderr,")\n"); break; } @@ -132,241 +198,246 @@ printClosure( StgClosure *obj ) { StgPAP* pap = stgCast(StgPAP*,obj); StgWord i; - fprintf(stdout,"PAP("); printPtr((StgPtr)pap->fun); + fprintf(stderr,"PAP/%d(",pap->arity); + printPtr((StgPtr)pap->fun); for (i = 0; i < pap->n_args; ++i) { - fprintf(stdout,", "); + fprintf(stderr,", "); printPtr((StgPtr)pap->payload[i]); } - fprintf(stdout,")\n"); + fprintf(stderr,")\n"); break; } - case FOREIGN: - fprintf(stdout,"FOREIGN("); - printPtr((StgPtr)( ((StgForeignObj*)obj)->data )); - fprintf(stdout,")\n"); + case AP_STACK: + { + StgAP_STACK* ap = stgCast(StgAP_STACK*,obj); + StgWord i; + fprintf(stderr,"AP_STACK("); printPtr((StgPtr)ap->fun); + for (i = 0; i < ap->size; ++i) { + fprintf(stderr,", "); + printPtr((P_)ap->payload[i]); + } + fprintf(stderr,")\n"); break; + } case IND: - fprintf(stdout,"IND("); + fprintf(stderr,"IND("); printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); - fprintf(stdout,")\n"); + fprintf(stderr,")\n"); break; - case IND_STATIC: - fprintf(stdout,"IND_STATIC("); + case IND_OLDGEN: + fprintf(stderr,"IND_OLDGEN("); printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); - fprintf(stdout,")\n"); + fprintf(stderr,")\n"); break; - case IND_OLDGEN: - fprintf(stdout,"IND_OLDGEN("); + case IND_PERM: + fprintf(stderr,"IND("); printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); - fprintf(stdout,")\n"); + fprintf(stderr,")\n"); break; + case IND_OLDGEN_PERM: + fprintf(stderr,"IND_OLDGEN_PERM("); + printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); + fprintf(stderr,")\n"); + break; + + case IND_STATIC: + fprintf(stderr,"IND_STATIC("); + printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); + fprintf(stderr,")\n"); + break; + + /* Cannot happen -- use default case. + case RET_BCO: + case RET_SMALL: + case RET_VEC_SMALL: + case RET_BIG: + case RET_VEC_BIG: + case RET_DYN: + case RET_FUN: + */ + + case UPDATE_FRAME: + { + StgUpdateFrame* u = stgCast(StgUpdateFrame*,obj); + fprintf(stderr,"UPDATE_FRAME("); + printPtr((StgPtr)GET_INFO(u)); + fprintf(stderr,","); + printPtr((StgPtr)u->updatee); + fprintf(stderr,")\n"); + break; + } + + case CATCH_FRAME: + { + StgCatchFrame* u = stgCast(StgCatchFrame*,obj); + fprintf(stderr,"CATCH_FRAME("); + printPtr((StgPtr)GET_INFO(u)); + fprintf(stderr,","); + printPtr((StgPtr)u->handler); + fprintf(stderr,")\n"); + break; + } + + case STOP_FRAME: + { + StgStopFrame* u = stgCast(StgStopFrame*,obj); + fprintf(stderr,"STOP_FRAME("); + printPtr((StgPtr)GET_INFO(u)); + fprintf(stderr,")\n"); + break; + } + case CAF_BLACKHOLE: - fprintf(stdout,"CAF_BH("); + fprintf(stderr,"CAF_BH("); + printPtr((StgPtr)stgCast(StgBlockingQueue*,obj)->blocking_queue); + fprintf(stderr,")\n"); + break; + + case BLACKHOLE: + fprintf(stderr,"BH\n"); + break; + + case BLACKHOLE_BQ: + fprintf(stderr,"BQ("); printPtr((StgPtr)stgCast(StgBlockingQueue*,obj)->blocking_queue); - fprintf(stdout,")\n"); + fprintf(stderr,")\n"); break; case SE_BLACKHOLE: - fprintf(stdout,"SE_BH\n"); + fprintf(stderr,"SE_BH\n"); break; case SE_CAF_BLACKHOLE: - fprintf(stdout,"SE_CAF_BH\n"); + fprintf(stderr,"SE_CAF_BH\n"); break; - case BLACKHOLE: - fprintf(stdout,"BH\n"); + case ARR_WORDS: + { + StgWord i; + fprintf(stderr,"ARR_WORDS(\""); + /* ToDo: we can't safely assume that this is a string! + for (i = 0; arrWordsGetChar(obj,i); ++i) { + putchar(arrWordsGetChar(obj,i)); + } */ + for (i=0; i<((StgArrWords *)obj)->words; i++) + fprintf(stderr, "%u", ((StgArrWords *)obj)->payload[i]); + fprintf(stderr,"\")\n"); break; + } - case BLACKHOLE_BQ: - fprintf(stdout,"BQ("); - printPtr((StgPtr)stgCast(StgBlockingQueue*,obj)->blocking_queue); - fprintf(stdout,")\n"); + case MUT_ARR_PTRS: + fprintf(stderr,"MUT_ARR_PTRS(size=%d)\n", ((StgMutArrPtrs *)obj)->ptrs); + break; + + case MUT_ARR_PTRS_FROZEN: +#if !defined(XMLAMBDA) + fprintf(stderr,"MUT_ARR_PTRS_FROZEN(size=%d)\n", ((StgMutArrPtrs *)obj)->ptrs); + break; +#else + { + /* rows are mutarrays in xmlambda, maybe we should make a new type: ROW */ + StgWord i; + StgMutArrPtrs* p = stgCast(StgMutArrPtrs*,obj); + + fprintf(stderr,"Row<%i>(",p->ptrs); + for (i = 0; i < p->ptrs; ++i) { + if (i > 0) fprintf(stderr,", "); + printPtr((StgPtr)(p->payload[i])); + } + fprintf(stderr,")\n"); + break; + } +#endif + + case MUT_VAR: + { + StgMutVar* mv = (StgMutVar*)obj; + fprintf(stderr,"MUT_VAR(var=%p, link=%p)\n", mv->var, mv->mut_link); + break; + } + + case WEAK: + fprintf(stderr,"WEAK("); + fprintf(stderr," key=%p value=%p finalizer=%p", + (StgPtr)(((StgWeak*)obj)->key), + (StgPtr)(((StgWeak*)obj)->value), + (StgPtr)(((StgWeak*)obj)->finalizer)); + fprintf(stderr,")\n"); + /* ToDo: chase 'link' ? */ + break; + + case FOREIGN: + fprintf(stderr,"FOREIGN("); + printPtr((StgPtr)( ((StgForeignObj*)obj)->data )); + fprintf(stderr,")\n"); + break; + + case STABLE_NAME: + fprintf(stderr,"STABLE_NAME(%d)\n", ((StgStableName*)obj)->sn); break; case TSO: - fprintf(stdout,"TSO("); - fprintf(stdout,"%d (%p)",((StgTSO*)obj)->id, (StgTSO*)obj); - fprintf(stdout,")\n"); + fprintf(stderr,"TSO("); + fprintf(stderr,"%d (%p)",((StgTSO*)obj)->id, (StgTSO*)obj); + fprintf(stderr,")\n"); break; #if defined(PAR) case BLOCKED_FETCH: - fprintf(stdout,"BLOCKED_FETCH("); + fprintf(stderr,"BLOCKED_FETCH("); printGA(&(stgCast(StgBlockedFetch*,obj)->ga)); printPtr((StgPtr)(stgCast(StgBlockedFetch*,obj)->node)); - fprintf(stdout,")\n"); + fprintf(stderr,")\n"); break; case FETCH_ME: - fprintf(stdout,"FETCH_ME("); + fprintf(stderr,"FETCH_ME("); printGA((globalAddr *)stgCast(StgFetchMe*,obj)->ga); - fprintf(stdout,")\n"); + fprintf(stderr,")\n"); break; -#ifdef DIST - case REMOTE_REF: - fprintf(stdout,"REMOTE_REF("); - printGA((globalAddr *)stgCast(StgFetchMe*,obj)->ga); - fprintf(stdout,")\n"); - break; -#endif - case FETCH_ME_BQ: - fprintf(stdout,"FETCH_ME_BQ("); + fprintf(stderr,"FETCH_ME_BQ("); // printGA((globalAddr *)stgCast(StgFetchMe*,obj)->ga); printPtr((StgPtr)stgCast(StgFetchMeBlockingQueue*,obj)->blocking_queue); - fprintf(stdout,")\n"); + fprintf(stderr,")\n"); break; #endif + #if defined(GRAN) || defined(PAR) case RBH: - fprintf(stdout,"RBH("); + fprintf(stderr,"RBH("); printPtr((StgPtr)stgCast(StgRBH*,obj)->blocking_queue); - fprintf(stdout,")\n"); + fprintf(stderr,")\n"); break; #endif - case CONSTR: - case CONSTR_1_0: case CONSTR_0_1: - case CONSTR_1_1: case CONSTR_0_2: case CONSTR_2_0: - case CONSTR_INTLIKE: - case CONSTR_CHARLIKE: - case CONSTR_STATIC: - case CONSTR_NOCAF_STATIC: - { - /* We can't use printStdObject because we want to print the - * tag as well. - */ - StgWord i, j; -#ifdef PROFILING - fprintf(stdout,"%s(", info->prof.closure_desc); - fprintf(stdout,"%s", obj->header.prof.ccs->cc->label); -#else - fprintf(stdout,"CONSTR("); - printPtr((StgPtr)obj->header.info); - fprintf(stdout,"(tag=%d)",info->srt_len); +#if 0 + /* Symptomatic of a problem elsewhere, have it fall-through & fail */ + case EVACUATED: + fprintf(stderr,"EVACUATED("); + printClosure((StgEvacuated*)obj->evacuee); + fprintf(stderr,")\n"); + break; #endif - for (i = 0; i < info->layout.payload.ptrs; ++i) { - fprintf(stdout,", "); - printPtr((StgPtr)obj->payload[i]); - } - for (j = 0; j < info->layout.payload.nptrs; ++j) { - fprintf(stdout,", %p#", obj->payload[i+j]); - } - fprintf(stdout,")\n"); - break; - } - -#ifdef XMLAMBDA -/* rows are mutarrays in xmlambda, maybe we should make a new type: ROW */ - case MUT_ARR_PTRS_FROZEN: - { - StgWord i; - StgMutArrPtrs* p = stgCast(StgMutArrPtrs*,obj); - - fprintf(stdout,"Row<%i>(",p->ptrs); - for (i = 0; i < p->ptrs; ++i) { - if (i > 0) fprintf(stdout,", "); - printPtr((StgPtr)(p->payload[i])); - } - fprintf(stdout,")\n"); - break; - } -#endif - - case FUN: - case FUN_1_0: case FUN_0_1: - case FUN_1_1: case FUN_0_2: case FUN_2_0: - case FUN_STATIC: - printStdObject(obj,"FUN"); - break; - case THUNK: - case THUNK_1_0: case THUNK_0_1: - case THUNK_1_1: case THUNK_0_2: case THUNK_2_0: - case THUNK_STATIC: - /* ToDo: will this work for THUNK_STATIC too? */ -#ifdef PROFILING - printStdObject(obj,info->prof.closure_desc); -#else - printStdObject(obj,"THUNK"); +#if defined(PAR) && defined(DIST) + case REMOTE_REF: + fprintf(stderr,"REMOTE_REF("); + printGA((globalAddr *)stgCast(StgFetchMe*,obj)->ga); + fprintf(stderr,")\n"); + break; #endif - break; - - case THUNK_SELECTOR: - printStdObjHdr(obj, "THUNK_SELECTOR"); - fprintf(stdout, ", %p)\n", ((StgSelector *)obj)->selectee); - break; - case ARR_WORDS: - { - StgWord i; - fprintf(stdout,"ARR_WORDS(\""); - /* ToDo: we can't safely assume that this is a string! - for (i = 0; arrWordsGetChar(obj,i); ++i) { - putchar(arrWordsGetChar(obj,i)); - } */ - for (i=0; i<((StgArrWords *)obj)->words; i++) - fprintf(stdout, "%u", ((StgArrWords *)obj)->payload[i]); - fprintf(stdout,"\")\n"); - break; - } - - case UPDATE_FRAME: - { - StgUpdateFrame* u = stgCast(StgUpdateFrame*,obj); - fprintf(stdout,"UpdateFrame("); - printPtr((StgPtr)GET_INFO(u)); - fprintf(stdout,","); - printPtr((StgPtr)u->updatee); - fprintf(stdout,","); - printPtr((StgPtr)u->link); - fprintf(stdout,")\n"); - break; - } - - case CATCH_FRAME: - { - StgCatchFrame* u = stgCast(StgCatchFrame*,obj); - fprintf(stdout,"CatchFrame("); - printPtr((StgPtr)GET_INFO(u)); - fprintf(stdout,","); - printPtr((StgPtr)u->handler); - fprintf(stdout,","); - printPtr((StgPtr)u->link); - fprintf(stdout,")\n"); - break; - } - - case SEQ_FRAME: - { - StgSeqFrame* u = stgCast(StgSeqFrame*,obj); - fprintf(stdout,"SeqFrame("); - printPtr((StgPtr)GET_INFO(u)); - fprintf(stdout,","); - printPtr((StgPtr)u->link); - fprintf(stdout,")\n"); - break; - } - - case STOP_FRAME: - { - StgStopFrame* u = stgCast(StgStopFrame*,obj); - fprintf(stdout,"StopFrame("); - printPtr((StgPtr)GET_INFO(u)); - fprintf(stdout,")\n"); - break; - } default: //barf("printClosure %d",get_itbl(obj)->type); - fprintf(stdout, "*** printClosure: unknown type %d ****\n", + fprintf(stderr, "*** printClosure: unknown type %d ****\n", get_itbl(obj)->type ); barf("printClosure %d",get_itbl(obj)->type); return; @@ -380,159 +451,195 @@ void printGraph( StgClosure *obj ) } */ -StgPtr printStackObj( StgPtr sp ) +StgPtr +printStackObj( StgPtr sp ) { - /*fprintf(stdout,"Stack[%d] = ", &stgStack[STACK_SIZE] - sp); */ - - if (IS_ARG_TAG(*sp)) { - nat i; - StgWord tag = *sp++; - fprintf(stdout,"Tagged{"); - for (i = 0; i < tag; i++) { - fprintf(stdout,"0x%x#", (unsigned)(*sp++)); - if (i < tag-1) fprintf(stdout, ", "); - } - fprintf(stdout, "}\n"); - } else { + /*fprintf(stderr,"Stack[%d] = ", &stgStack[STACK_SIZE] - sp); */ + StgClosure* c = (StgClosure*)(*sp); printPtr((StgPtr)*sp); - if (c == (StgClosure*)&stg_ctoi_ret_R1p_info) { - fprintf(stdout, "\t\t\tstg_ctoi_ret_R1p_info\n" ); + if (c == (StgClosure*)&stg_ctoi_R1p_info) { + fprintf(stderr, "\t\t\tstg_ctoi_ret_R1p_info\n" ); } else - if (c == (StgClosure*)&stg_ctoi_ret_R1n_info) { - fprintf(stdout, "\t\t\tstg_ctoi_ret_R1n_info\n" ); + if (c == (StgClosure*)&stg_ctoi_R1n_info) { + fprintf(stderr, "\t\t\tstg_ctoi_ret_R1n_info\n" ); } else - if (c == (StgClosure*)&stg_ctoi_ret_F1_info) { - fprintf(stdout, "\t\t\tstg_ctoi_ret_F1_info\n" ); + if (c == (StgClosure*)&stg_ctoi_F1_info) { + fprintf(stderr, "\t\t\tstg_ctoi_ret_F1_info\n" ); } else - if (c == (StgClosure*)&stg_ctoi_ret_D1_info) { - fprintf(stdout, "\t\t\tstg_ctoi_ret_D1_info\n" ); + if (c == (StgClosure*)&stg_ctoi_D1_info) { + fprintf(stderr, "\t\t\tstg_ctoi_ret_D1_info\n" ); } else - if (c == (StgClosure*)&stg_ctoi_ret_V_info) { - fprintf(stdout, "\t\t\tstg_ctoi_ret_V_info\n" ); + if (c == (StgClosure*)&stg_ctoi_V_info) { + fprintf(stderr, "\t\t\tstg_ctoi_ret_V_info\n" ); } else if (get_itbl(c)->type == BCO) { - fprintf(stdout, "\t\t\t"); - fprintf(stdout, "BCO(...)\n"); + fprintf(stderr, "\t\t\t"); + fprintf(stderr, "BCO(...)\n"); } else { - fprintf(stdout, "\t\t\t"); + fprintf(stderr, "\t\t\t"); printClosure ( (StgClosure*)(*sp)); } sp += 1; - } + return sp; } -void printStackChunk( StgPtr sp, StgPtr spBottom ) +static void +printSmallBitmap( StgPtr spBottom, StgPtr payload, StgWord bitmap, nat size ) +{ + StgPtr p; + nat i; + + p = payload; + for(i = 0; i < size; i++, bitmap >>= 1 ) { + fprintf(stderr," stk[%d] (%p) = ", spBottom-(payload+i), payload+i); + if ((bitmap & 1) == 0) { + printPtr((P_)payload[i]); + fprintf(stderr,"\n"); + } else { + fprintf(stderr,"Word# %d\n", payload[i]); + } + } +} + +static void +printLargeBitmap( StgPtr spBottom, StgPtr payload, StgLargeBitmap* large_bitmap, nat size ) +{ + StgWord bmp; + nat i, j; + + i = 0; + for (bmp=0; i < size; bmp++) { + StgWord bitmap = large_bitmap->bitmap[bmp]; + j = 0; + for(; i < size && j < BITS_IN(W_); j++, i++, bitmap >>= 1 ) { + fprintf(stderr," stk[%d] (%p) = ", spBottom-(payload+i), payload+i); + if ((bitmap & 1) == 0) { + printPtr((P_)payload[i]); + fprintf(stderr,"\n"); + } else { + fprintf(stderr,"Word# %d\n", payload[i]); + } + } + } +} + +void +printStackChunk( StgPtr sp, StgPtr spBottom ) { StgWord bitmap; const StgInfoTable *info; ASSERT(sp <= spBottom); - while (sp < spBottom) { - if (!IS_ARG_TAG(*sp) && LOOKS_LIKE_GHC_INFO(*sp)) { + for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) { + info = get_itbl((StgClosure *)sp); - switch (info->type) { + switch (info->type) { + case UPDATE_FRAME: - printObj( stgCast(StgClosure*,sp) ); - sp += sizeofW(StgUpdateFrame); - continue; - - case SEQ_FRAME: - printObj( stgCast(StgClosure*,sp) ); - sp += sizeofW(StgSeqFrame); - continue; - case CATCH_FRAME: - printObj( stgCast(StgClosure*,sp) ); - sp += sizeofW(StgCatchFrame); - continue; - case STOP_FRAME: - /* not quite: ASSERT(stgCast(StgPtr,su) == spBottom); */ - printObj( stgCast(StgClosure*,sp) ); + printObj((StgClosure*)sp); continue; case RET_DYN: - fprintf(stdout, "RET_DYN (%p)\n", sp); - bitmap = *++sp; - ++sp; - fprintf(stdout, "Bitmap: 0x%x\n", bitmap); - goto small_bitmap; + { + StgRetDyn* r; + StgPtr p; + StgWord dyn; + nat size; + + r = (StgRetDyn *)sp; + dyn = r->liveness; + fprintf(stderr, "RET_DYN (%p)\n", r); + + p = (P_)(r->payload); + printSmallBitmap(spBottom, sp, + RET_DYN_LIVENESS(r->liveness), + RET_DYN_BITMAP_SIZE); + p += RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE; + + for (size = RET_DYN_NONPTRS(dyn); size > 0; size--) { + fprintf(stderr," stk[%ld] (%p) = ", (long)(spBottom-p), p); + fprintf(stderr,"Word# %ld\n", (long)*p); + p++; + } + + for (size = RET_DYN_PTRS(dyn); size > 0; size--) { + fprintf(stderr," stk[%ld] (%p) = ", (long)(spBottom-p), p); + printPtr(p); + p++; + } + continue; + } case RET_SMALL: case RET_VEC_SMALL: - fprintf(stdout, "RET_SMALL (%p)\n", sp); - bitmap = info->layout.bitmap; - sp++; - small_bitmap: - while (bitmap != 0) { - fprintf(stdout," stk[%ld] (%p) = ", spBottom-sp, sp); - if ((bitmap & 1) == 0) { - printPtr((P_)*sp); - fprintf(stdout,"\n"); - } else { - fprintf(stdout,"Word# %ld\n", *sp); - } - sp++; - bitmap = bitmap >> 1; - } - continue; + fprintf(stderr, "RET_SMALL (%p)\n", sp); + bitmap = info->layout.bitmap; + printSmallBitmap(spBottom, sp+1, + BITMAP_BITS(bitmap), BITMAP_SIZE(bitmap)); + continue; - case RET_BIG: - case RET_VEC_BIG: - barf("todo"); + case RET_BCO: { + StgBCO *bco; + + bco = ((StgBCO *)sp[1]); - default: - break; + fprintf(stderr, "RET_BCO (%p)\n", sp); + printLargeBitmap(spBottom, sp+2, + BCO_BITMAP(bco), BCO_BITMAP_SIZE(bco)); + continue; } - } - fprintf(stdout,"Stack[%ld] (%p) = ", spBottom-sp, sp); - sp = printStackObj(sp); - } -} -void printStack( StgPtr sp, StgPtr spBottom, StgUpdateFrame* su ) -{ - /* check everything down to the first update frame */ - printStackChunk( sp, stgCast(StgPtr,su) ); - while ( stgCast(StgPtr,su) < spBottom) { - sp = stgCast(StgPtr,su); - switch (get_itbl(su)->type) { - case UPDATE_FRAME: - printObj( stgCast(StgClosure*,su) ); - sp += sizeofW(StgUpdateFrame); - su = su->link; + case RET_BIG: + case RET_VEC_BIG: + barf("todo"); + + case RET_FUN: + { + StgFunInfoTable *fun_info; + StgRetFun *ret_fun; + nat size; + + ret_fun = (StgRetFun *)sp; + fun_info = get_fun_itbl(ret_fun->fun); + size = ret_fun->size; + fprintf(stderr,"RET_FUN (%p) (type=%d)\n", ret_fun, fun_info->f.fun_type); + switch (fun_info->f.fun_type) { + case ARG_GEN: + printSmallBitmap(spBottom, sp+1, + BITMAP_BITS(fun_info->f.bitmap), + BITMAP_SIZE(fun_info->f.bitmap)); break; - case SEQ_FRAME: - printObj( stgCast(StgClosure*,su) ); - sp += sizeofW(StgSeqFrame); - su = stgCast(StgSeqFrame*,su)->link; + case ARG_GEN_BIG: + printLargeBitmap(spBottom, sp+2, + (StgLargeBitmap *)fun_info->f.bitmap, + BITMAP_SIZE(fun_info->f.bitmap)); break; - case CATCH_FRAME: - printObj( stgCast(StgClosure*,su) ); - sp += sizeofW(StgCatchFrame); - su = stgCast(StgCatchFrame*,su)->link; + default: + printSmallBitmap(spBottom, sp+1, + BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]), + BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type])); break; - case STOP_FRAME: - /* not quite: ASSERT(stgCast(StgPtr,su) == spBottom); */ - printObj( stgCast(StgClosure*,su) ); - return; + } + continue; + } + default: - barf("printStack: weird record found on update frame list."); + fprintf(stderr, "unknown object %d\n", info->type); + barf("printStackChunk"); } - printStackChunk( sp, stgCast(StgPtr,su) ); } - ASSERT(stgCast(StgPtr,su) == spBottom); } void printTSO( StgTSO *tso ) { - printStack( tso->sp, tso->stack+tso->stack_size,tso->su); - /* printStackChunk( tso->sp, tso->stack+tso->stack_size); */ + printStackChunk( tso->sp, tso->stack+tso->stack_size); } /* ----------------------------------------------------------------------------- @@ -542,73 +649,75 @@ void printTSO( StgTSO *tso ) -------------------------------------------------------------------------- */ static char *closure_type_names[] = { - "INVALID_OBJECT", /* 0 */ - "CONSTR", /* 1 */ - "CONSTR_1_0", /* 2 */ - "CONSTR_0_1", /* 3 */ - "CONSTR_2_0", /* 4 */ - "CONSTR_1_1", /* 5 */ - "CONSTR_0_2", /* 6 */ - "CONSTR_INTLIKE", /* 7 */ - "CONSTR_CHARLIKE", /* 8 */ - "CONSTR_STATIC", /* 9 */ - "CONSTR_NOCAF_STATIC", /* 10 */ - "FUN", /* 11 */ - "FUN_1_0", /* 12 */ - "FUN_0_1", /* 13 */ - "FUN_2_0", /* 14 */ - "FUN_1_1", /* 15 */ - "FUN_0_2", /* 16 */ - "FUN_STATIC", /* 17 */ - "THUNK", /* 18 */ - "THUNK_1_0", /* 19 */ - "THUNK_0_1", /* 20 */ - "THUNK_2_0", /* 21 */ - "THUNK_1_1", /* 22 */ - "THUNK_0_2", /* 23 */ - "THUNK_STATIC", /* 24 */ - "THUNK_SELECTOR", /* 25 */ - "BCO", /* 26 */ - "AP_UPD", /* 27 */ - "PAP", /* 28 */ - "IND", /* 29 */ - "IND_OLDGEN", /* 30 */ - "IND_PERM", /* 31 */ - "IND_OLDGEN_PERM", /* 32 */ - "IND_STATIC", /* 33 */ - "CAF_BLACKHOLE", /* 36 */ - "RET_BCO", /* 37 */ - "RET_SMALL", /* 38 */ - "RET_VEC_SMALL", /* 39 */ - "RET_BIG", /* 40 */ - "RET_VEC_BIG", /* 41 */ - "RET_DYN", /* 42 */ - "UPDATE_FRAME", /* 43 */ - "CATCH_FRAME", /* 44 */ - "STOP_FRAME", /* 45 */ - "SEQ_FRAME", /* 46 */ - "BLACKHOLE", /* 47 */ - "BLACKHOLE_BQ", /* 48 */ - "SE_BLACKHOLE", /* 49 */ - "SE_CAF_BLACKHOLE", /* 50 */ - "MVAR", /* 51 */ - "ARR_WORDS", /* 52 */ - "MUT_ARR_PTRS", /* 53 */ - "MUT_ARR_PTRS_FROZEN", /* 54 */ - "MUT_VAR", /* 55 */ - "WEAK", /* 56 */ - "FOREIGN", /* 57 */ - "STABLE_NAME", /* 58 */ - "TSO", /* 59 */ - "BLOCKED_FETCH", /* 60 */ - "FETCH_ME", /* 61 */ - "FETCH_ME_BQ", /* 62 */ - "RBH", /* 63 */ - "EVACUATED", /* 64 */ - "REMOTE_REF", /* 65 */ - "N_CLOSURE_TYPES" /* 66 */ + "INVALID_OBJECT", + "CONSTR", + "CONSTR_1", + "CONSTR_0", + "CONSTR_2", + "CONSTR_1", + "CONSTR_0", + "CONSTR_INTLIKE", + "CONSTR_CHARLIKE", + "CONSTR_STATIC", + "CONSTR_NOCAF_STATIC", + "FUN", + "FUN_1_0", + "FUN_0_1", + "FUN_2_0", + "FUN_1_1", + "FUN_0", + "FUN_STATIC", + "THUNK", + "THUNK_1_0", + "THUNK_0_1", + "THUNK_2_0", + "THUNK_1_1", + "THUNK_0", + "THUNK_STATIC", + "THUNK_SELECTOR", + "BCO", + "AP_UPD", + "PAP", + "AP_STACK", + "IND", + "IND_OLDGEN", + "IND_PERM", + "IND_OLDGEN_PERM", + "IND_STATIC", + "RET_BCO", + "RET_SMALL", + "RET_VEC_SMALL", + "RET_BIG", + "RET_VEC_BIG", + "RET_DYN", + "RET_FUN", + "UPDATE_FRAME", + "CATCH_FRAME", + "STOP_FRAME", + "CAF_BLACKHOLE", + "BLACKHOLE", + "BLACKHOLE_BQ", + "SE_BLACKHOLE", + "SE_CAF_BLACKHOLE", + "MVAR", + "ARR_WORDS", + "MUT_ARR_PTRS", + "MUT_ARR_PTRS_FROZEN", + "MUT_VAR", + "MUT_CONS", + "WEAK", + "FOREIGN", + "STABLE_NAME", + "TSO", + "BLOCKED_FETCH", + "FETCH_ME", + "FETCH_ME_BQ", + "RBH", + "EVACUATED", + "REMOTE_REF" }; + char * info_type(StgClosure *closure){ return closure_type_names[get_itbl(closure)->type]; @@ -641,15 +750,17 @@ struct entry { const char *name; }; -static nat max_table_size; static nat table_size; static struct entry* table; +#ifdef USING_LIBBFD +static nat max_table_size; + static void reset_table( int size ) { max_table_size = size; table_size = 0; - table = (struct entry *) malloc(size * sizeof(struct entry)); + table = (struct entry *)stgMallocBytes(size * sizeof(struct entry), "Printer.c:reset_table()"); } static void prepare_table( void ) @@ -666,7 +777,7 @@ static void insert( unsigned value, const char *name ) table[table_size].name = name; table_size = table_size + 1; } - +#endif #if 0 static rtsBool lookup_name( char *name, unsigned *result ) @@ -829,10 +940,10 @@ static void printZcoded( const char *raw ) while ( raw[j] != '\0' ) { if (raw[j] == 'Z') { - fputc(unZcode(raw[j+1]),stdout); + fputc(unZcode(raw[j+1]),stderr); j = j + 2; } else { - fputc(raw[j],stdout); + fputc(raw[j],stderr); j = j + 1; } } @@ -853,7 +964,7 @@ static void printZcoded( const char *raw ) * rubbish like the obj-splitting symbols */ -static rtsBool isReal( flagword flags, const char *name ) +static rtsBool isReal( flagword flags STG_UNUSED, const char *name ) { #if 0 /* ToDo: make this work on BFD */ @@ -864,7 +975,6 @@ static rtsBool isReal( flagword flags, const char *name ) return rtsFalse; } #else - (void)flags; /* keep gcc -Wall happy */ if (*name == '\0' || (name[0] == 'g' && name[1] == 'c' && name[2] == 'c') || (name[0] == 'c' && name[1] == 'c' && name[2] == '.')) { @@ -916,14 +1026,14 @@ extern void DEBUG_LoadSymbols( char *name ) for( i = 0; i != number_of_symbols; ++i ) { symbol_info info; bfd_get_symbol_info(abfd,symbol_table[i],&info); - /*fprintf(stdout,"\t%c\t0x%x \t%s\n",info.type,(nat)info.value,info.name); */ + /*fprintf(stderr,"\t%c\t0x%x \t%s\n",info.type,(nat)info.value,info.name); */ if (isReal(info.type, info.name)) { num_real_syms += 1; } } - IF_DEBUG(evaluator, - fprintf(stdout,"Loaded %ld symbols. Of which %ld are real symbols\n", + IF_DEBUG(interpreter, + fprintf(stderr,"Loaded %ld symbols. Of which %ld are real symbols\n", number_of_symbols, num_real_syms) ); @@ -936,8 +1046,8 @@ extern void DEBUG_LoadSymbols( char *name ) insert( info.value, info.name ); } } - - free(symbol_table); + + stgFree(symbol_table); } prepare_table(); } @@ -951,8 +1061,6 @@ extern void DEBUG_LoadSymbols( char *name STG_UNUSED ) #endif /* HAVE_BFD_H */ -#include "StoragePriv.h" - void findPtr(P_ p, int); /* keep gcc -Wall happy */ void @@ -961,7 +1069,11 @@ findPtr(P_ p, int follow) nat s, g; P_ q, r; bdescr *bd; +#if defined(__GNUC__) const int arr_size = 1024; +#else +#define arr_size 1024 +#endif StgPtr arr[arr_size]; int i = 0; @@ -977,10 +1089,10 @@ findPtr(P_ p, int follow) if (*q == (W_)p) { if (i < arr_size) { r = q; - while (!LOOKS_LIKE_GHC_INFO(*r) || *r == NULL) { + while (!LOOKS_LIKE_INFO_PTR(*r) || (P_)*r == NULL) { r--; } - fprintf(stdout, "%p = ", r); + fprintf(stderr, "%p = ", r); printClosure((StgClosure *)r); arr[i++] = r; } else { @@ -992,7 +1104,7 @@ findPtr(P_ p, int follow) } } if (follow && i == 1) { - fprintf(stdout, "-->\n"); + fprintf(stderr, "-->\n"); findPtr(arr[0], 1); } } @@ -1000,11 +1112,11 @@ findPtr(P_ p, int follow) #else /* DEBUG */ void printPtr( StgPtr p ) { - fprintf(stdout, "ptr 0x%p (enable -DDEBUG for more info) " , p ); + fprintf(stderr, "ptr 0x%p (enable -DDEBUG for more info) " , p ); } void printObj( StgClosure *obj ) { - fprintf(stdout, "obj 0x%p (enable -DDEBUG for more info) " , obj ); + fprintf(stderr, "obj 0x%p (enable -DDEBUG for more info) " , obj ); } #endif /* DEBUG */