⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prmsgc.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************/typedef void (*WalkObject_t)(FILE *out, GCType* tp, PRWord *obj,			     size_t bytes, PRBool detailed);typedef void (*WalkUnknown_t)(FILE *out, GCType* tp, PRWord tix, PRWord *p,			      size_t bytes, PRBool detailed);typedef void (*WalkFree_t)(FILE *out, PRWord *p, size_t size, PRBool detailed);typedef void (*WalkSegment_t)(FILE *out, GCSeg* sp, PRBool detailed);static voidpr_WalkSegment(FILE* out, GCSeg* sp, PRBool detailed,           char* enterMsg, char* exitMsg,           WalkObject_t walkObject, WalkUnknown_t walkUnknown, WalkFree_t walkFree){    PRWord *p, *limit;    p = (PRWord *) sp->base;    limit = (PRWord *) sp->limit;    if (enterMsg)    fprintf(out, enterMsg, p);    while (p < limit)    {    if (IS_HBIT(sp, p)) /* Is this an object header? */    {        PRWord h = p[0];        PRWord tix = GET_TYPEIX(h);        size_t bytes = OBJ_BYTES(h);        PRWord* np = (PRWord*) ((char*)p + bytes);        GCType* tp = &_pr_collectorTypes[tix].gctype;        if ((0 != tp) && walkObject)        walkObject(out, tp, p, bytes, detailed);        else if (walkUnknown)        walkUnknown(out, tp, tix, p, bytes, detailed);        p = np;    }    else    {        /* Must be a freelist item */        size_t size = ((GCFreeChunk*)p)->chunkSize;        if (walkFree)        walkFree(out, p, size, detailed);        p = (PRWord*)((char*)p + size);    }    }    if (p != limit)    fprintf(out, "SEGMENT OVERRUN (end should be at 0x%p)\n", limit);    if (exitMsg)    fprintf(out, exitMsg, p);}static voidpr_WalkSegments(FILE *out, WalkSegment_t walkSegment, PRBool detailed){    GCSeg *sp = segs;    GCSeg *esp;    LOCK_GC();    esp = sp + nsegs;    while (sp < esp)    {    walkSegment(out, sp, detailed);    sp++;    }    fprintf(out, "End of heap\n");    UNLOCK_GC();}/******************************************************************************* * Heap Dumper ******************************************************************************/PR_IMPLEMENT(void)PR_DumpIndent(FILE *out, int indent){    while (--indent >= 0)    fprintf(out, " ");}static voidPR_DumpHexWords(FILE *out, PRWord *p, int nWords,        int indent, int nWordsPerLine){    while (nWords > 0)    {    int i;    PR_DumpIndent(out, indent);    i = nWordsPerLine;    if (i > nWords)        i = nWords;    nWords -= i;    while (i--)    {        fprintf(out, "0x%.8lX", (long) *p++);        if (i)        fputc(' ', out);    }    fputc('\n', out);    }}static void PR_CALLBACKpr_DumpObject(FILE *out, GCType* tp, PRWord *p,           size_t bytes, PRBool detailed){    char kindChar = tp->kindChar;    fprintf(out, "0x%p: 0x%.6lX %c  ",            p, (long) bytes, kindChar ? kindChar : '?');    if (tp->dump)    (*tp->dump)(out, (void*) (p + 1), detailed, 0);    if (detailed)    PR_DumpHexWords(out, p, bytes>>2, 22, 4);}    static void PR_CALLBACKpr_DumpUnknown(FILE *out, GCType* tp, PRWord tix, PRWord *p,            size_t bytes, PRBool detailed){    char kindChar = tp->kindChar;    fprintf(out, "0x%p: 0x%.6lX %c  ",            p, (long) bytes, kindChar ? kindChar : '?');    fprintf(out, "UNKNOWN KIND %ld\n", (long) tix);    if (detailed)    PR_DumpHexWords(out, p, bytes>>2, 22, 4);}static void PR_CALLBACKpr_DumpFree(FILE *out, PRWord *p, size_t size, PRBool detailed){#if defined(XP_MAC) && XP_MAC# pragma unused( detailed )#endif    fprintf(out, "0x%p: 0x%.6lX -  FREE\n", p, (long) size);}static void PR_CALLBACKpr_DumpSegment(FILE* out, GCSeg* sp, PRBool detailed){    pr_WalkSegment(out, sp, detailed,           "\n   Address: Length\n0x%p: Beginning of segment\n",           "0x%p: End of segment\n\n",           pr_DumpObject, pr_DumpUnknown, pr_DumpFree);}static void pr_DumpRoots(FILE *out);/*** Dump out the GC heap.*/PR_IMPLEMENT(void)PR_DumpGCHeap(FILE *out, PRBool detailed){    fprintf(out, "\n"        "The kinds are:\n"        " U unscanned block\n"        " W weak link block\n"        " S scanned block\n"        " F scanned and final block\n"        " C class record\n"        " X context record\n"        " - free list item\n"        " ? other\n");    LOCK_GC();    pr_WalkSegments(out, pr_DumpSegment, detailed);    if (detailed)    pr_DumpRoots(out);    UNLOCK_GC();}PR_IMPLEMENT(void)PR_DumpMemory(PRBool detailed){    PR_DumpToFile("memory.out", "Dumping memory", PR_DumpGCHeap, detailed);}/******************************************************************************/static PRInt32 PR_CALLBACKpr_DumpRootPointer(PRWord* p, void* data){#ifdef XP_MAC#pragma unused(data)#endif    PRWord h = p[0];    PRWord tix = GET_TYPEIX(h);      size_t bytes = OBJ_BYTES(h);            GCType* tp = &_pr_collectorTypes[tix].gctype;      if (0 != tp)      pr_DumpObject(_pr_gcData.dumpOutput, tp, p, bytes, PR_FALSE);      else      pr_DumpUnknown(_pr_gcData.dumpOutput, tp, tix, p, bytes, PR_FALSE);    return 0;}static void PR_CALLBACKpr_ConservativeDumpRootPointer(void* ptr){    (void)pr_ConservativeWalkPointer(ptr, (PRWalkFun) pr_DumpRootPointer, NULL);}static void PR_CALLBACKpr_ConservativeDumpRootBlock(void **base, PRInt32 count){    (void)pr_ConservativeWalkBlock(base, count, (PRWalkFun) pr_DumpRootPointer, NULL);}extern intDumpThreadRoots(PRThread *t, int i, void *notused);static voidpr_DumpRoots(FILE *out){    RootFinder *rf;    void (*liveBlock)(void **base, PRInt32 count);    void (*livePointer)(void *ptr);    void (*processRootBlock)(void **base, PRInt32 count);    void (*processRootPointer)(void *ptr);    LOCK_GC();    liveBlock = _pr_gcData.liveBlock;    livePointer = _pr_gcData.livePointer;    processRootBlock = _pr_gcData.processRootBlock;    processRootPointer = _pr_gcData.processRootPointer;        _pr_gcData.liveBlock = pr_ConservativeDumpRootBlock;    _pr_gcData.livePointer = pr_ConservativeDumpRootPointer;    _pr_gcData.processRootBlock = pr_ConservativeDumpRootBlock;    _pr_gcData.processRootPointer = pr_ConservativeDumpRootPointer;    _pr_gcData.dumpOutput = out;    rf = _pr_rootFinders;    while (rf) {    fprintf(out, "\n===== Roots for %s\n", rf->name);    (*rf->func)(rf->arg);    rf = rf->next;    }    _pr_gcData.liveBlock = liveBlock;    _pr_gcData.livePointer = livePointer;    _pr_gcData.processRootBlock = processRootBlock;    _pr_gcData.processRootPointer = processRootPointer;    _pr_gcData.dumpOutput = NULL;    UNLOCK_GC();}/******************************************************************************* * Heap Summary Dumper ******************************************************************************/PRSummaryPrinter summaryPrinter = NULL;void* summaryPrinterClosure = NULL;PR_IMPLEMENT(void) PR_RegisterSummaryPrinter(PRSummaryPrinter fun, void* closure){    summaryPrinter = fun;    summaryPrinterClosure = closure;}static void PR_CALLBACKpr_SummarizeObject(FILE *out, GCType* tp, PRWord *p,           size_t bytes, PRBool detailed){#if defined(XP_MAC) && XP_MAC# pragma unused( out, detailed )#endif    if (tp->summarize)    (*tp->summarize)((void GCPTR*)(p + 1), bytes);}static void PR_CALLBACKpr_DumpSummary(FILE* out, GCSeg* sp, PRBool detailed){    pr_WalkSegment(out, sp, detailed, NULL, NULL,           pr_SummarizeObject, NULL, NULL);}PR_IMPLEMENT(void)PR_DumpGCSummary(FILE *out, PRBool detailed){    if (summaryPrinter) {    pr_WalkSegments(out, pr_DumpSummary, detailed);    summaryPrinter(out, summaryPrinterClosure);    }#if 0    fprintf(out, "\nFinalizable objects:\n");    {    PRCList *qp;    qp = _pr_pendingFinalQueue.next;    while (qp != &_pr_pendingFinalQueue) {        GCFinal* fp = FinalPtr(qp);        PRWord h = fp->object[0];        /* Grab header word */        PRWord tix = GET_TYPEIX(h);        GCType* tp = _pr_gcTypes[tix];        size_t bytes = OBJ_BYTES(h);        pr_DumpObject(out, tp, fp->object, bytes, PR_FALSE);        qp = qp->next;    }    }#endif}PR_IMPLEMENT(void)PR_DumpMemorySummary(void){    PR_DumpToFile("memory.out", "Memory Summary", PR_DumpGCSummary, PR_FALSE);}/******************************************************************************* * End Of Heap Walker  ******************************************************************************/#ifdef GC_TRACEROOTSPRInt32 pr_traceGen = 0;static PRBoolpr_IsMarked(PRWord* p){    GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));    PR_ASSERT(end->check == PR_BLOCK_END);    return end->traceGeneration == pr_traceGen;}static voidpr_Mark(PRWord* p){    GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));    PR_ASSERT(end->check == PR_BLOCK_END);    end->traceGeneration = pr_traceGen;}PRWord* pr_traceObj;	/* set this in the debugger, then execute PR_TraceRoot() */static PRInt32 PR_CALLBACKpr_TraceRootObject(void* obj, void* data);static PRInt32 PR_CALLBACKpr_TraceRootPointer(PRWord *p, void* data){    PRInt32 printTrace = 0;    PRWord h = p[0];    PRWord tix = GET_TYPEIX(h);    GCType* tp = &_pr_collectorTypes[tix].gctype;    FILE* out = _pr_gcData.dumpOutput;    PR_ASSERT(tp);    if (pr_IsMarked(p))	return printTrace;    pr_Mark(p);    if (p == pr_traceObj) {	fprintf(out, "\n### Found path to:\n");	printTrace = 1;    }    else {	if (PR_StackSpaceLeft(PR_CurrentThread()) < 512) {	    fprintf(out, "\n### Path too deep (giving up):\n");	    printTrace = 1;	}	else if (tp->walk) {	    printTrace = tp->walk((void*)(p + 1), pr_TraceRootObject, data);	}	/* else there's no way to walk this object, so we	   haven't found what we're looking for */    }    if (printTrace == 1) {	PR_ASSERT(tp->dump);	fprintf(out, "0x%p: ", p);	tp->dump(out, (void*)(p + 1), PR_FALSE, 1);    }    return printTrace;}static PRInt32 PR_CALLBACKpr_TraceRootObject(void* obj, void* data){    /* This version of pr_TraceRootPointer takes object       pointers, instead of gc header pointers. */    return pr_TraceRootPointer((PRWord*)obj - 1, data);}static void PR_CALLBACKpr_ConservativeTraceRootPointer(PRWord *p){    PRInt32 status;    ++pr_traceGen;    status = pr_ConservativeWalkPointer(p, pr_TraceRootPointer, NULL);    if (status) {	FILE* out = _pr_gcData.dumpOutput;	fprintf(out, "### from root at 0x%p\n\n", p);    }}static void PR_CALLBACKpr_ConservativeTraceRootBlock(void **base, PRInt32 count){    PRInt32 status;    ++pr_traceGen;    status = pr_ConservativeWalkBlock(base, count, pr_TraceRootPointer, NULL);    if (status) {	FILE* out = _pr_gcData.dumpOutput;	fprintf(out, "### from root in range 0x%p + 0x%lx\n\n",                base, (long) count);    }}static voidPR_TraceRoot1(FILE* out, PRBool detailed){    RootFinder *rf;    void (*liveBlock)(void **base, PRInt32 count);    void (*livePointer)(void *ptr);    void (*processRootBlock)(void **base, PRInt32 count);    void (*processRootPointer)(void *ptr);    LOCK_GC();    liveBlock = _pr_gcData.liveBlock;    livePointer = _pr_gcData.livePointer;    processRootBlock = _pr_gcData.processRootBlock;    processRootPointer = _pr_gcData.processRootPointer;        _pr_gcData.liveBlock = pr_ConservativeTraceRootBlock;    _pr_gcData.livePointer = pr_ConservativeTraceRootPointer;    _pr_gcData.processRootBlock = pr_ConservativeTraceRootBlock;    _pr_gcData.processRootPointer = pr_ConservativeTraceRootPointer;    _pr_gcData.dumpOutput = out;    fprintf(out, "### Looking for paths to 0x%p\n\n", pr_traceObj);    rf = _pr_rootFinders;    while (rf) {	fprintf(out, "\n===== Roots for %s\n", rf->name);	(*rf->func)(rf->arg);	rf = rf->next;    }    _pr_gcData.liveBlock = liveBlock;    _pr_gcData.livePointer = livePointer;    _pr_gcData.processRootBlock = processRootBlock;    _pr_gcData.processRootPointer = processRootPointer;    _pr_gcData.dumpOutput = NULL;    UNLOCK_GC();}PR_PUBLIC_API(void)PR_TraceRoot(){    /*    ** How this works:     ** Once you find the object you want to trace the roots of, set the    ** global variable pr_traceObj to point to it (the header, not the    ** java handle), and then call this routine (on Windows, you can set    ** a breakpoint at the end of a function that returns void (e.g. dogc)    ** and then do a "set next statement" to point to this routine and go.    ** This will dump a list of the paths from the roots to the object in    ** question to your memory.out file.    */    PR_DumpToFile("memory.out", "Tracing Roots", PR_TraceRoot1, PR_FALSE);}#endif /* GC_TRACEROOTS *//******************************************************************************/#if defined(DEBUG) && defined(WIN32)static void DumpApplicationHeap(FILE *out, HA

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -