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

📄 jsgc.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
    a->prev = arenaList->last;    a->prevUnscanned = NULL;    a->unscannedPages = 0;    arenaList->last = a;    arenaList->lastLimit = 0;    bytesptr = (arenaList == &rt->gcArenaList[0])               ? &rt->gcBytes               : &rt->gcPrivateBytes;    *bytesptr += GC_ARENA_SIZE;    return JS_TRUE;}static voidDestroyGCArena(JSRuntime *rt, JSGCArenaList *arenaList, JSGCArena **ap){    JSGCArena *a;    uint32 *bytesptr;    a = *ap;    JS_ASSERT(a);    bytesptr = (arenaList == &rt->gcArenaList[0])               ? &rt->gcBytes               : &rt->gcPrivateBytes;    JS_ASSERT(*bytesptr >= GC_ARENA_SIZE);    *bytesptr -= GC_ARENA_SIZE;    METER(rt->gcStats.afree++);    METER(--arenaList->stats.narenas);    if (a == arenaList->last)        arenaList->lastLimit = (uint16)(a->prev ? GC_THINGS_SIZE : 0);    *ap = a->prev;#ifdef DEBUG    memset(a, JS_FREE_PATTERN, GC_ARENA_SIZE);#endif    free(a);}static voidInitGCArenaLists(JSRuntime *rt){    uintN i, thingSize;    JSGCArenaList *arenaList;    for (i = 0; i < GC_NUM_FREELISTS; i++) {        arenaList = &rt->gcArenaList[i];        thingSize = GC_FREELIST_NBYTES(i);        JS_ASSERT((size_t)(uint16)thingSize == thingSize);        arenaList->last = NULL;        arenaList->lastLimit = 0;        arenaList->thingSize = (uint16)thingSize;        arenaList->freeList = NULL;        METER(memset(&arenaList->stats, 0, sizeof arenaList->stats));    }}static voidFinishGCArenaLists(JSRuntime *rt){    uintN i;    JSGCArenaList *arenaList;    for (i = 0; i < GC_NUM_FREELISTS; i++) {        arenaList = &rt->gcArenaList[i];        while (arenaList->last)            DestroyGCArena(rt, arenaList, &arenaList->last);        arenaList->freeList = NULL;    }}uint8 *js_GetGCThingFlags(void *thing){    JSGCPageInfo *pi;    jsuword offsetInArena, thingIndex;    pi = THING_TO_PAGE(thing);    offsetInArena = pi->offsetInArena;    JS_ASSERT(offsetInArena < GC_THINGS_SIZE);    thingIndex = ((offsetInArena & ~GC_PAGE_MASK) |                  ((jsuword)thing & GC_PAGE_MASK)) / sizeof(JSGCThing);    JS_ASSERT(thingIndex < GC_PAGE_SIZE);    if (thingIndex >= (offsetInArena & GC_PAGE_MASK))        thingIndex += GC_THINGS_SIZE;    return (uint8 *)pi - offsetInArena + thingIndex;}JSRuntime*js_GetGCStringRuntime(JSString *str){    JSGCPageInfo *pi;    JSGCArenaList *list;    pi = THING_TO_PAGE(str);    list = PAGE_TO_ARENA(pi)->list;    JS_ASSERT(list->thingSize == sizeof(JSGCThing));    JS_ASSERT(GC_FREELIST_INDEX(sizeof(JSGCThing)) == 0);    return (JSRuntime *)((uint8 *)list - offsetof(JSRuntime, gcArenaList));}JSBooljs_IsAboutToBeFinalized(JSContext *cx, void *thing){    uint8 flags = *js_GetGCThingFlags(thing);    return !(flags & (GCF_MARK | GCF_LOCK | GCF_FINAL));}typedef void (*GCFinalizeOp)(JSContext *cx, JSGCThing *thing);#ifndef DEBUG# define js_FinalizeDouble       NULL#endif#if !JS_HAS_XML_SUPPORT# define js_FinalizeXMLNamespace NULL# define js_FinalizeXMLQName     NULL# define js_FinalizeXML          NULL#endifstatic GCFinalizeOp gc_finalizers[GCX_NTYPES] = {    (GCFinalizeOp) js_FinalizeObject,           /* GCX_OBJECT */    (GCFinalizeOp) js_FinalizeString,           /* GCX_STRING */    (GCFinalizeOp) js_FinalizeDouble,           /* GCX_DOUBLE */    (GCFinalizeOp) js_FinalizeString,           /* GCX_MUTABLE_STRING */    NULL,                                       /* GCX_PRIVATE */    (GCFinalizeOp) js_FinalizeXMLNamespace,     /* GCX_NAMESPACE */    (GCFinalizeOp) js_FinalizeXMLQName,         /* GCX_QNAME */    (GCFinalizeOp) js_FinalizeXML,              /* GCX_XML */    NULL,                                       /* GCX_EXTERNAL_STRING */    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL};#ifdef GC_MARK_DEBUGstatic const char newborn_external_string[] = "newborn external string";static const char *gc_typenames[GCX_NTYPES] = {    "newborn object",    "newborn string",    "newborn double",    "newborn mutable string",    "newborn private",    "newborn Namespace",    "newborn QName",    "newborn XML",    newborn_external_string,    newborn_external_string,    newborn_external_string,    newborn_external_string,    newborn_external_string,    newborn_external_string,    newborn_external_string,    newborn_external_string};#endifintNjs_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,                                 JSStringFinalizeOp newop){    uintN i;    for (i = GCX_EXTERNAL_STRING; i < GCX_NTYPES; i++) {        if (gc_finalizers[i] == (GCFinalizeOp) oldop) {            gc_finalizers[i] = (GCFinalizeOp) newop;            return (intN) i;        }    }    return -1;}/* This is compatible with JSDHashEntryStub. */typedef struct JSGCRootHashEntry {    JSDHashEntryHdr hdr;    void            *root;    const char      *name;} JSGCRootHashEntry;/* Initial size of the gcRootsHash table (SWAG, small enough to amortize). */#define GC_ROOTS_SIZE   256#define GC_FINALIZE_LEN 1024JSBooljs_InitGC(JSRuntime *rt, uint32 maxbytes){    InitGCArenaLists(rt);    if (!JS_DHashTableInit(&rt->gcRootsHash, JS_DHashGetStubOps(), NULL,                           sizeof(JSGCRootHashEntry), GC_ROOTS_SIZE)) {        rt->gcRootsHash.ops = NULL;        return JS_FALSE;    }    rt->gcLocksHash = NULL;     /* create lazily */    /*     * Separate gcMaxMallocBytes from gcMaxBytes but initialize to maxbytes     * for default backward API compatibility.     */    rt->gcMaxBytes = rt->gcMaxMallocBytes = maxbytes;    return JS_TRUE;}#ifdef JS_GCMETERJS_FRIEND_API(void)js_DumpGCStats(JSRuntime *rt, FILE *fp){    uintN i;    size_t totalThings, totalMaxThings, totalBytes;    fprintf(fp, "\nGC allocation statistics:\n");#define UL(x)       ((unsigned long)(x))#define ULSTAT(x)   UL(rt->gcStats.x)    totalThings = 0;    totalMaxThings = 0;    totalBytes = 0;    for (i = 0; i < GC_NUM_FREELISTS; i++) {        JSGCArenaList *list = &rt->gcArenaList[i];        JSGCArenaStats *stats = &list->stats;        if (stats->maxarenas == 0) {            fprintf(fp, "ARENA LIST %u (thing size %lu): NEVER USED\n",                    i, UL(GC_FREELIST_NBYTES(i)));            continue;        }        fprintf(fp, "ARENA LIST %u (thing size %lu):\n",                i, UL(GC_FREELIST_NBYTES(i)));        fprintf(fp, "                     arenas: %lu\n", UL(stats->narenas));        fprintf(fp, "                 max arenas: %lu\n", UL(stats->maxarenas));        fprintf(fp, "                     things: %lu\n", UL(stats->nthings));        fprintf(fp, "                 max things: %lu\n", UL(stats->maxthings));        fprintf(fp, "                  free list: %lu\n", UL(stats->freelen));        fprintf(fp, "          free list density: %.1f%%\n",                stats->narenas == 0                ? 0.0                : (100.0 * list->thingSize * (jsdouble)stats->freelen /                   (GC_THINGS_SIZE * (jsdouble)stats->narenas)));        fprintf(fp, "  average free list density: %.1f%%\n",                stats->totalarenas == 0                ? 0.0                : (100.0 * list->thingSize * (jsdouble)stats->totalfreelen /                   (GC_THINGS_SIZE * (jsdouble)stats->totalarenas)));        fprintf(fp, "                   recycles: %lu\n", UL(stats->recycle));        fprintf(fp, "        recycle/alloc ratio: %.2f\n",                (jsdouble)stats->recycle /                (jsdouble)(stats->totalnew - stats->recycle));        totalThings += stats->nthings;        totalMaxThings += stats->maxthings;        totalBytes += GC_FREELIST_NBYTES(i) * stats->nthings;    }    fprintf(fp, "TOTAL STATS:\n");    fprintf(fp, "     public bytes allocated: %lu\n", UL(rt->gcBytes));    fprintf(fp, "    private bytes allocated: %lu\n", UL(rt->gcPrivateBytes));    fprintf(fp, "             alloc attempts: %lu\n", ULSTAT(alloc));#ifdef JS_THREADSAFE    fprintf(fp, "        alloc without locks: %1u\n", ULSTAT(localalloc));#endif    fprintf(fp, "            total GC things: %lu\n", UL(totalThings));    fprintf(fp, "        max total GC things: %lu\n", UL(totalMaxThings));    fprintf(fp, "             GC things size: %lu\n", UL(totalBytes));    fprintf(fp, "allocation retries after GC: %lu\n", ULSTAT(retry));    fprintf(fp, "        allocation failures: %lu\n", ULSTAT(fail));    fprintf(fp, "         things born locked: %lu\n", ULSTAT(lockborn));    fprintf(fp, "           valid lock calls: %lu\n", ULSTAT(lock));    fprintf(fp, "         valid unlock calls: %lu\n", ULSTAT(unlock));    fprintf(fp, "       mark recursion depth: %lu\n", ULSTAT(depth));    fprintf(fp, "     maximum mark recursion: %lu\n", ULSTAT(maxdepth));    fprintf(fp, "     mark C recursion depth: %lu\n", ULSTAT(cdepth));    fprintf(fp, "   maximum mark C recursion: %lu\n", ULSTAT(maxcdepth));    fprintf(fp, "      delayed scan bag adds: %lu\n", ULSTAT(unscanned));#ifdef DEBUG    fprintf(fp, "  max delayed scan bag size: %lu\n", ULSTAT(maxunscanned));#endif    fprintf(fp, "   maximum GC nesting level: %lu\n", ULSTAT(maxlevel));    fprintf(fp, "potentially useful GC calls: %lu\n", ULSTAT(poke));    fprintf(fp, "           useless GC calls: %lu\n", ULSTAT(nopoke));    fprintf(fp, "  thing arenas freed so far: %lu\n", ULSTAT(afree));    fprintf(fp, "     stack segments scanned: %lu\n", ULSTAT(stackseg));    fprintf(fp, "stack segment slots scanned: %lu\n", ULSTAT(segslots));    fprintf(fp, "reachable closeable objects: %lu\n", ULSTAT(nclose));    fprintf(fp, "    max reachable closeable: %lu\n", ULSTAT(maxnclose));    fprintf(fp, "      scheduled close hooks: %lu\n", ULSTAT(closelater));    fprintf(fp, "  max scheduled close hooks: %lu\n", ULSTAT(maxcloselater));#undef UL#undef US#ifdef JS_ARENAMETER    JS_DumpArenaStats(fp);#endif}#endif#ifdef DEBUGstatic voidCheckLeakedRoots(JSRuntime *rt);#endifvoidjs_FinishGC(JSRuntime *rt){#ifdef JS_ARENAMETER    JS_DumpArenaStats(stdout);#endif#ifdef JS_GCMETER    js_DumpGCStats(rt, stdout);#endif    FreePtrTable(&rt->gcIteratorTable, &iteratorTableInfo);#if JS_HAS_GENERATORS    rt->gcCloseState.reachableList = NULL;    METER(rt->gcStats.nclose = 0);    rt->gcCloseState.todoQueue = NULL;#endif    FinishGCArenaLists(rt);    if (rt->gcRootsHash.ops) {#ifdef DEBUG        CheckLeakedRoots(rt);#endif        JS_DHashTableFinish(&rt->gcRootsHash);        rt->gcRootsHash.ops = NULL;    }    if (rt->gcLocksHash) {        JS_DHashTableDestroy(rt->gcLocksHash);        rt->gcLocksHash = NULL;    }}JSBooljs_AddRoot(JSContext *cx, void *rp, const char *name){    JSBool ok = js_AddRootRT(cx->runtime, rp, name);    if (!ok)        JS_ReportOutOfMemory(cx);    return ok;}JSBooljs_AddRootRT(JSRuntime *rt, void *rp, const char *name){    JSBool ok;    JSGCRootHashEntry *rhe;    /*     * Due to the long-standing, but now removed, use of rt->gcLock across the     * bulk of js_GC, API users have come to depend on JS_AddRoot etc. locking     * properly with a racing GC, without calling JS_AddRoot from a request.     * We have to preserve API compatibility here, now that we avoid holding     * rt->gcLock across the mark phase (including the root hashtable mark).     *     * If the GC is running and we're called on another thread, wait for this     * GC activation to finish.  We can safely wait here (in the case where we     * are called within a request on another thread's context) without fear     * of deadlock because the GC doesn't set rt->gcRunning until after it has     * waited for all active requests to end.     */    JS_LOCK_GC(rt);#ifdef JS_THREADSAFE    JS_ASSERT(!rt->gcRunning || rt->gcLevel > 0);    if (rt->gcRunning && rt->gcThread->id != js_CurrentThreadId()) {        do {            JS_AWAIT_GC_DONE(rt);        } while (rt->gcLevel > 0);    }#endif    rhe = (JSGCRootHashEntry *) JS_DHashTableOperate(&rt->gcRootsHash, rp,                                                     JS_DHASH_ADD);    if (rhe) {        rhe->root = rp;        rhe->name = name;        ok = JS_TRUE;    } else {        ok = JS_FALSE;    }    JS_UNLOCK_GC(rt);    return ok;}JSBooljs_RemoveRoot(JSRuntime *rt, void *rp){    /*     * Due to the JS_RemoveRootRT API, we may be called outside of a request.     * Same synchronization drill as above in js_AddRoot.     */    JS_LOCK_GC(rt);#ifdef JS_THREADSAFE    JS_ASSERT(!rt->gcRunning || rt->gcLevel > 0);    if (rt->gcRunning && rt->gcThread->id != js_CurrentThreadId()) {        do {            JS_AWAIT_GC_DONE(rt);        } while (rt->gcLevel > 0);    }#endif    (void) JS_DHashTableOperate(&rt->gcRootsHash, rp, JS_DHASH_REMOVE);    rt->gcPoke = JS_TRUE;    JS_UNLOCK_GC(rt);    return JS_TRUE;}#ifdef DEBUGJS_STATIC_DLL_CALLBACK(JSDHashOperator)js_root_printer(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 i, void *arg){

⌨️ 快捷键说明

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