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

📄 jsgc.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
                JS_NewDHashTable(JS_DHashGetStubOps(), NULL,                                 sizeof(JSGCLockHashEntry),                                 GC_ROOTS_SIZE);            if (!rt->gcLocksHash) {                ok = JS_FALSE;                goto done;            }        } else if (lock == 0) {#ifdef DEBUG            JSDHashEntryHdr *hdr =                JS_DHashTableOperate(rt->gcLocksHash, thing,                                     JS_DHASH_LOOKUP);            JS_ASSERT(JS_DHASH_ENTRY_IS_FREE(hdr));#endif        }        lhe = (JSGCLockHashEntry *)            JS_DHashTableOperate(rt->gcLocksHash, thing, JS_DHASH_ADD);        if (!lhe) {            ok = JS_FALSE;            goto done;        }        if (!lhe->thing) {            lhe->thing = thing;            lhe->count = deep ? 1 : 2;        } else {            JS_ASSERT(lhe->count >= 1);            lhe->count++;        }    }    *flagp = (uint8)(flags | GCF_LOCK);    METER(rt->gcStats.lock++);    ok = JS_TRUE;done:    JS_UNLOCK_GC(rt);    return ok;}JSBooljs_UnlockGCThingRT(JSRuntime *rt, void *thing){    uint8 *flagp, flags;    JSGCLockHashEntry *lhe;    if (!thing)        return JS_TRUE;    flagp = js_GetGCThingFlags(thing);    JS_LOCK_GC(rt);    flags = *flagp;    if (flags & GCF_LOCK) {        if (!rt->gcLocksHash ||            (lhe = (JSGCLockHashEntry *)                   JS_DHashTableOperate(rt->gcLocksHash, thing,                                        JS_DHASH_LOOKUP),             JS_DHASH_ENTRY_IS_FREE(&lhe->hdr))) {            /* Shallow GC-thing with an implicit lock count of 1. */            JS_ASSERT(!GC_THING_IS_DEEP(flags & GCF_TYPEMASK, thing));        } else {            /* Basis or nested unlock of a deep thing, or nested of shallow. */            if (--lhe->count != 0)                goto out;            JS_DHashTableOperate(rt->gcLocksHash, thing, JS_DHASH_REMOVE);        }        *flagp = (uint8)(flags & ~GCF_LOCK);    }    rt->gcPoke = JS_TRUE;out:    METER(rt->gcStats.unlock++);    JS_UNLOCK_GC(rt);    return JS_TRUE;}#ifdef GC_MARK_DEBUG#include <stdio.h>#include "jsprf.h"typedef struct GCMarkNode GCMarkNode;struct GCMarkNode {    void        *thing;    const char  *name;    GCMarkNode  *next;    GCMarkNode  *prev;};JS_FRIEND_DATA(FILE *) js_DumpGCHeap;JS_EXPORT_DATA(void *) js_LiveThingToFind;#ifdef HAVE_XPCONNECT#include "dump_xpc.h"#endifstatic voidGetObjSlotName(JSScope *scope, JSObject *obj, uint32 slot, char *buf,               size_t bufsize){    jsval nval;    JSScopeProperty *sprop;    JSClass *clasp;    uint32 key;    const char *slotname;    if (!scope) {        JS_snprintf(buf, bufsize, "**UNKNOWN OBJECT MAP ENTRY**");        return;    }    sprop = SCOPE_LAST_PROP(scope);    while (sprop && sprop->slot != slot)        sprop = sprop->parent;    if (!sprop) {        switch (slot) {          case JSSLOT_PROTO:            JS_snprintf(buf, bufsize, "__proto__");            break;          case JSSLOT_PARENT:            JS_snprintf(buf, bufsize, "__parent__");            break;          default:            slotname = NULL;            clasp = LOCKED_OBJ_GET_CLASS(obj);            if (clasp->flags & JSCLASS_IS_GLOBAL) {                key = slot - JSSLOT_START(clasp);#define JS_PROTO(name,code,init) \    if ((code) == key) { slotname = js_##name##_str; goto found; }#include "jsproto.tbl"#undef JS_PROTO            }          found:            if (slotname)                JS_snprintf(buf, bufsize, "CLASS_OBJECT(%s)", slotname);            else                JS_snprintf(buf, bufsize, "**UNKNOWN SLOT %ld**", (long)slot);            break;        }    } else {        nval = ID_TO_VALUE(sprop->id);        if (JSVAL_IS_INT(nval)) {            JS_snprintf(buf, bufsize, "%ld", (long)JSVAL_TO_INT(nval));        } else if (JSVAL_IS_STRING(nval)) {            JS_snprintf(buf, bufsize, "%s",                        JS_GetStringBytes(JSVAL_TO_STRING(nval)));        } else {            JS_snprintf(buf, bufsize, "**FINALIZED ATOM KEY**");        }    }}static const char *gc_object_class_name(void* thing){    uint8 *flagp = js_GetGCThingFlags(thing);    const char *className = "";    static char depbuf[32];    switch (*flagp & GCF_TYPEMASK) {      case GCX_OBJECT: {        JSObject  *obj = (JSObject *)thing;        JSClass   *clasp = JSVAL_TO_PRIVATE(obj->slots[JSSLOT_CLASS]);        className = clasp->name;#ifdef HAVE_XPCONNECT        if (clasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {            jsval privateValue = obj->slots[JSSLOT_PRIVATE];            JS_ASSERT(clasp->flags & JSCLASS_HAS_PRIVATE);            if (!JSVAL_IS_VOID(privateValue)) {                void  *privateThing = JSVAL_TO_PRIVATE(privateValue);                const char *xpcClassName = GetXPCObjectClassName(privateThing);                if (xpcClassName)                    className = xpcClassName;            }        }#endif        break;      }      case GCX_STRING:      case GCX_MUTABLE_STRING: {        JSString *str = (JSString *)thing;        if (JSSTRING_IS_DEPENDENT(str)) {            JS_snprintf(depbuf, sizeof depbuf, "start:%u, length:%u",                        JSSTRDEP_START(str), JSSTRDEP_LENGTH(str));            className = depbuf;        } else {            className = "string";        }        break;      }      case GCX_DOUBLE:        className = "double";        break;    }    return className;}static voidgc_dump_thing(JSContext *cx, JSGCThing *thing, FILE *fp){    GCMarkNode *prev = (GCMarkNode *)cx->gcCurrentMarkNode;    GCMarkNode *next = NULL;    char *path = NULL;    while (prev) {        next = prev;        prev = prev->prev;    }    while (next) {        uint8 nextFlags = *js_GetGCThingFlags(next->thing);        if ((nextFlags & GCF_TYPEMASK) == GCX_OBJECT) {            path = JS_sprintf_append(path, "%s(%s @ 0x%08p).",                                     next->name,                                     gc_object_class_name(next->thing),                                     (JSObject*)next->thing);        } else {            path = JS_sprintf_append(path, "%s(%s).",                                     next->name,                                     gc_object_class_name(next->thing));        }        next = next->next;    }    if (!path)        return;    fprintf(fp, "%08lx ", (long)thing);    switch (*js_GetGCThingFlags(thing) & GCF_TYPEMASK) {      case GCX_OBJECT:      {        JSObject  *obj = (JSObject *)thing;        jsval     privateValue = obj->slots[JSSLOT_PRIVATE];        void      *privateThing = JSVAL_IS_VOID(privateValue)                                  ? NULL                                  : JSVAL_TO_PRIVATE(privateValue);        const char *className = gc_object_class_name(thing);        fprintf(fp, "object %8p %s", privateThing, className);        break;      }#if JS_HAS_XML_SUPPORT      case GCX_NAMESPACE:      {        JSXMLNamespace *ns = (JSXMLNamespace *)thing;        fprintf(fp, "namespace %s:%s",                JS_GetStringBytes(ns->prefix), JS_GetStringBytes(ns->uri));        break;      }      case GCX_QNAME:      {        JSXMLQName *qn = (JSXMLQName *)thing;        fprintf(fp, "qname %s(%s):%s",                JS_GetStringBytes(qn->prefix), JS_GetStringBytes(qn->uri),                JS_GetStringBytes(qn->localName));        break;      }      case GCX_XML:      {        extern const char *js_xml_class_str[];        JSXML *xml = (JSXML *)thing;        fprintf(fp, "xml %8p %s", xml, js_xml_class_str[xml->xml_class]);        break;      }#endif      case GCX_DOUBLE:        fprintf(fp, "double %g", *(jsdouble *)thing);        break;      case GCX_PRIVATE:        fprintf(fp, "private %8p", (void *)thing);        break;      default:        fprintf(fp, "string %s", JS_GetStringBytes((JSString *)thing));        break;    }    fprintf(fp, " via %s\n", path);    free(path);}voidjs_MarkNamedGCThing(JSContext *cx, void *thing, const char *name){    GCMarkNode markNode;    if (!thing)        return;    markNode.thing = thing;    markNode.name  = name;    markNode.next  = NULL;    markNode.prev  = (GCMarkNode *)cx->gcCurrentMarkNode;    if (markNode.prev)        markNode.prev->next = &markNode;    cx->gcCurrentMarkNode = &markNode;    if (thing == js_LiveThingToFind) {        /*         * Dump js_LiveThingToFind each time we reach it during the marking         * phase of GC to print all live references to the thing.         */        gc_dump_thing(cx, thing, stderr);    }    js_MarkGCThing(cx, thing);    if (markNode.prev)        markNode.prev->next = NULL;    cx->gcCurrentMarkNode = markNode.prev;}#endif /* !GC_MARK_DEBUG */static voidgc_mark_atom_key_thing(void *thing, void *arg){    JSContext *cx = (JSContext *) arg;    GC_MARK(cx, thing, "atom");}voidjs_MarkAtom(JSContext *cx, JSAtom *atom){    jsval key;    if (atom->flags & ATOM_MARK)        return;    atom->flags |= ATOM_MARK;    key = ATOM_KEY(atom);    if (JSVAL_IS_GCTHING(key)) {#ifdef GC_MARK_DEBUG        char name[32];        if (JSVAL_IS_STRING(key)) {            JS_snprintf(name, sizeof name, "'%s'",                        JS_GetStringBytes(JSVAL_TO_STRING(key)));        } else {            JS_snprintf(name, sizeof name, "<%x>", key);        }#endif        GC_MARK(cx, JSVAL_TO_GCTHING(key), name);    }    if (atom->flags & ATOM_HIDDEN)        js_MarkAtom(cx, atom->entry.value);}static voidAddThingToUnscannedBag(JSRuntime *rt, void *thing, uint8 *flagp);static voidMarkGCThingChildren(JSContext *cx, void *thing, uint8 *flagp,                    JSBool shouldCheckRecursion){    JSRuntime *rt;    JSObject *obj;    jsval v, *vp, *end;    void *next_thing;    uint8 *next_flagp;    JSString *str;#ifdef JS_GCMETER    uint32 tailCallNesting;#endif#ifdef GC_MARK_DEBUG    JSScope *scope;    char name[32];#endif    /*     * With JS_GC_ASSUME_LOW_C_STACK defined the mark phase of GC always     * uses the non-recursive code that otherwise would be called only on     * a low C stack condition.     */#ifdef JS_GC_ASSUME_LOW_C_STACK# define RECURSION_TOO_DEEP() shouldCheckRecursion#else    int stackDummy;# define RECURSION_TOO_DEEP() (shouldCheckRecursion &&                        \                               !JS_CHECK_STACK_SIZE(cx, stackDummy))#endif    rt = cx->runtime;    METER(tailCallNesting = 0);    METER(if (++rt->gcStats.cdepth > rt->gcStats.maxcdepth)              rt->gcStats.maxcdepth = rt->gcStats.cdepth);#ifndef GC_MARK_DEBUG  start:#endif    JS_ASSERT(flagp);    JS_ASSERT(*flagp & GCF_MARK); /* the caller must already mark the thing */    METER(if (++rt->gcStats.depth > rt->gcStats.maxdepth)              rt->gcStats.maxdepth = rt->gcStats.depth);#ifdef GC_MARK_DEBUG    if (js_DumpGCHeap)        gc_dump_thing(cx, thing, js_DumpGCHeap);#endif    switch (*flagp & GCF_TYPEMASK) {      case GCX_OBJECT:        if (RECURSION_TOO_DEEP())            goto add_to_unscanned_bag;        /* If obj->slots is null, obj must be a newborn. */        obj = (JSObject *) thing;        vp = obj->slots;        if (!vp)            break;        /* Mark slots if they are smal

⌨️ 快捷键说明

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