void XPCJSRuntime::TraceXPConnectRoots(JSTracer *trc) { if(mClearedGlobalObjects.ops) { JSContext *iter = nsnull, *acx; while((acx = JS_ContextIterator(GetJSRuntime(), &iter))) { JSDHashEntryHdr* entry = JS_DHashTableOperate(&mClearedGlobalObjects, acx, JS_DHASH_LOOKUP); if(JS_DHASH_ENTRY_IS_BUSY(entry)) { ClearedGlobalObject* clearedGlobal = reinterpret_cast<ClearedGlobalObject*>(entry); JS_CALL_OBJECT_TRACER(trc, clearedGlobal->mGlobalObject, "global object"); } } } XPCWrappedNativeScope::TraceJS(trc, this); for(XPCRootSetElem *e = mVariantRoots; e ; e = e->GetNextRoot()) static_cast<XPCTraceableVariant*>(e)->TraceJS(trc); for(XPCRootSetElem *e = mWrappedJSRoots; e ; e = e->GetNextRoot()) static_cast<nsXPCWrappedJS*>(e)->TraceJS(trc); if(mJSHolders.ops) JS_DHashTableEnumerate(&mJSHolders, TraceJSHolder, trc); }
JSAtom * js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length) { JSString str, *str2; JSAtomState *state; JSDHashEntryHdr *hdr; if (length == 1) { jschar c = *chars; if (c < UNIT_STRING_LIMIT) return (JSAtom *) STRING_TO_JSVAL(JSString::unitString(c)); } str.initFlat((jschar *)chars, length); state = &cx->runtime->atomState; JS_LOCK(cx, &state->lock); hdr = JS_DHashTableOperate(&state->stringAtoms, &str, JS_DHASH_LOOKUP); str2 = JS_DHASH_ENTRY_IS_BUSY(hdr) ? (JSString *)ATOM_ENTRY_KEY(TO_ATOM_ENTRY(hdr)) : NULL; JS_UNLOCK(cx, &state->lock); return str2 ? (JSAtom *)STRING_TO_JSVAL(str2) : NULL; }
void js_StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag, JSResolvingEntry *entry, uint32 generation) { JSDHashTable *table; /* * Clear flag from entry->flags and return early if other flags remain. * We must take care to re-lookup entry if the table has changed since * it was found by js_StartResolving. */ table = cx->resolvingTable; if (!entry || table->generation != generation) { entry = (JSResolvingEntry *) JS_DHashTableOperate(table, key, JS_DHASH_LOOKUP); } JS_ASSERT(JS_DHASH_ENTRY_IS_BUSY(&entry->hdr)); entry->flags &= ~flag; if (entry->flags) return; /* * Do a raw remove only if fewer entries were removed than would cause * alpha to be less than .5 (alpha is at most .75). Otherwise, we just * call JS_DHashTableOperate to re-lookup the key and remove its entry, * compressing or shrinking the table as needed. */ if (table->removedCount < JS_DHASH_TABLE_SIZE(table) >> 2) JS_DHashTableRawRemove(table, &entry->hdr); else JS_DHashTableOperate(table, key, JS_DHASH_REMOVE); }
JSObject* XPCJSRuntime::GetUnsetContextGlobal(JSContext* cx) { if(!mClearedGlobalObjects.ops) return nsnull; JSDHashEntryHdr* entry = JS_DHashTableOperate(&mClearedGlobalObjects, cx, JS_DHASH_LOOKUP); ClearedGlobalObject* clearedGlobal = reinterpret_cast<ClearedGlobalObject*>(entry); return JS_DHASH_ENTRY_IS_BUSY(entry) ? clearedGlobal->mGlobalObject : nsnull; }
void XPCJSRuntime::RestoreContextGlobals() { if(!mClearedGlobalObjects.ops || mClearedGlobalObjects.entryCount == 0) return; JSContext *iter = nsnull, *acx; while((acx = JS_ContextIterator(GetJSRuntime(), &iter))) { JSDHashEntryHdr* entry = JS_DHashTableOperate(&mClearedGlobalObjects, acx, JS_DHASH_LOOKUP); if(JS_DHASH_ENTRY_IS_BUSY(entry)) { ClearedGlobalObject* clearedGlobal = reinterpret_cast<ClearedGlobalObject*>(entry); acx->globalObject = clearedGlobal->mGlobalObject; } } JS_DHashTableEnumerate(&mClearedGlobalObjects, RemoveContextGlobal, nsnull); }
JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name) { uintN i, numclasses; numclasses = xdr->numclasses; if (numclasses >= 10) { JSRegHashEntry *entry; /* Bootstrap reghash from registry on first overpopulated Find. */ if (!xdr->reghash) { xdr->reghash = JS_NewDHashTable(JS_DHashGetStubOps(), NULL, sizeof(JSRegHashEntry), JS_DHASH_DEFAULT_CAPACITY(numclasses)); if (xdr->reghash) { for (i = 0; i < numclasses; i++) { JSClass *clasp = xdr->registry[i]; entry = (JSRegHashEntry *) JS_DHashTableOperate((JSDHashTable *) xdr->reghash, clasp->name, JS_DHASH_ADD); entry->name = clasp->name; entry->index = i; } } } /* If we managed to create reghash, use it for O(1) Find. */ if (xdr->reghash) { entry = (JSRegHashEntry *) JS_DHashTableOperate((JSDHashTable *) xdr->reghash, name, JS_DHASH_LOOKUP); if (JS_DHASH_ENTRY_IS_BUSY(&entry->hdr)) return CLASS_INDEX_TO_ID(entry->index); } } /* Only a few classes, or we couldn't malloc reghash: use linear search. */ for (i = 0; i < numclasses; i++) { if (!strcmp(name, xdr->registry[i]->name)) return CLASS_INDEX_TO_ID(i); } return 0; }