js_atom_uninterner(JSHashEntry *he, intN i, void *arg) { JSAtom *atom; UninternArgs *args; atom = (JSAtom *)he; args = (UninternArgs *)arg; if (ATOM_IS_STRING(atom)) js_FinalizeStringRT(args->rt, ATOM_TO_STRING(atom)); else if (ATOM_IS_OBJECT(atom)) args->leaks++; return HT_ENUMERATE_NEXT; }
static size_t GetAtomTotalSize(JSContext *cx, JSAtom *atom) { size_t nbytes; nbytes = sizeof *atom; if (ATOM_IS_STRING(atom)) { nbytes += sizeof(JSString); nbytes += (ATOM_TO_STRING(atom)->length + 1) * sizeof(jschar); } else if (ATOM_IS_DOUBLE(atom)) { nbytes += sizeof(jsdouble); } else if (ATOM_IS_OBJECT(atom)) { nbytes += JS_GetObjectTotalSize(cx, ATOM_TO_OBJECT(atom)); } return nbytes; }
extern JSBool js_XDRStringAtom(JSXDRState *xdr, JSAtom **atomp) { JSString *str; uint32 nchars; JSAtom *atom; JSContext *cx; jschar *chars; jschar stackChars[256]; if (xdr->mode == JSXDR_ENCODE) { JS_ASSERT(ATOM_IS_STRING(*atomp)); str = ATOM_TO_STRING(*atomp); return JS_XDRString(xdr, &str); } /* * Inline JS_XDRString when decoding to avoid JSString allocation * for already existing atoms. See bug 321985. */ if (!JS_XDRUint32(xdr, &nchars)) return JS_FALSE; atom = NULL; cx = xdr->cx; if (nchars <= JS_ARRAY_LENGTH(stackChars)) { chars = stackChars; } else { /* * This is very uncommon. Don't use the tempPool arena for this as * most allocations here will be bigger than tempPool's arenasize. */ chars = (jschar *) cx->malloc(nchars * sizeof(jschar)); if (!chars) return JS_FALSE; } if (XDRChars(xdr, chars, nchars)) atom = js_AtomizeChars(cx, chars, nchars, 0); if (chars != stackChars) cx->free(chars); if (!atom) return JS_FALSE; *atomp = atom; return JS_TRUE; }
extern JSBool js_XDRStringAtom(JSXDRState *xdr, JSAtom **atomp) { JSString *str; uint32 nchars; JSAtom *atom; JSContext *cx; void *mark; jschar *chars; if (xdr->mode == JSXDR_ENCODE) { JS_ASSERT(ATOM_IS_STRING(*atomp)); str = ATOM_TO_STRING(*atomp); return JS_XDRString(xdr, &str); } /* * Inline JS_XDRString when decoding to avoid JSString allocation * for already existing atoms. See bug 321985. */ if (!JS_XDRUint32(xdr, &nchars)) return JS_FALSE; atom = NULL; cx = xdr->cx; mark = JS_ARENA_MARK(&cx->tempPool); JS_ARENA_ALLOCATE_CAST(chars, jschar *, &cx->tempPool, nchars * sizeof(jschar)); if (!chars) JS_ReportOutOfMemory(cx); else if (XDRChars(xdr, chars, nchars)) atom = js_AtomizeChars(cx, chars, nchars, 0); JS_ARENA_RELEASE(&cx->tempPool, mark); if (!atom) return JS_FALSE; *atomp = atom; return JS_TRUE; }
/* * FIXME: This performs lossy conversion and we need to switch to * js_XDRStringAtom while allowing to read older XDR files. See bug 325202. */ JSBool js_XDRCStringAtom(JSXDRState *xdr, JSAtom **atomp) { char *bytes; uint32 nbytes; JSAtom *atom; JSContext *cx; void *mark; if (xdr->mode == JSXDR_ENCODE) { JS_ASSERT(ATOM_IS_STRING(*atomp)); bytes = JS_GetStringBytes(ATOM_TO_STRING(*atomp)); return JS_XDRCString(xdr, &bytes); } /* * Inline JS_XDRCString when decoding not to malloc temporary buffer * just to free it after atomization. See bug 321985. */ if (!JS_XDRUint32(xdr, &nbytes)) return JS_FALSE; atom = NULL; cx = xdr->cx; mark = JS_ARENA_MARK(&cx->tempPool); JS_ARENA_ALLOCATE_CAST(bytes, char *, &cx->tempPool, nbytes * sizeof *bytes); if (!bytes) JS_ReportOutOfMemory(cx); else if (JS_XDRBytes(xdr, bytes, nbytes)) atom = js_Atomize(cx, bytes, nbytes, 0); JS_ARENA_RELEASE(&cx->tempPool, mark); if (!atom) return JS_FALSE; *atomp = atom; return JS_TRUE; }
// convert a readable to a JSString, copying string data // static jsval XPCStringConvert::ReadableToJSVal(JSContext *cx, const nsAString &readable) { JSString *str; PRUint32 length = readable.Length(); JSAtom *atom; if (length == 0 && (atom = cx->runtime->atomState.emptyAtom)) { NS_ASSERTION(ATOM_IS_STRING(atom), "What kind of atom is this?"); return ATOM_KEY(atom); } nsStringBuffer *buf = nsStringBuffer::FromString(readable); if (buf) { // yay, we can share the string's buffer! if (sDOMStringFinalizerIndex == -1) { sDOMStringFinalizerIndex = JS_AddExternalStringFinalizer(DOMStringFinalizer); if (sDOMStringFinalizerIndex == -1) return JSVAL_NULL; } str = JS_NewExternalString(cx, reinterpret_cast<jschar *>(buf->Data()), length, sDOMStringFinalizerIndex); if (str) buf->AddRef(); } else { // blech, have to copy. jschar *chars = reinterpret_cast<jschar *> (JS_malloc(cx, (length + 1) * sizeof(jschar))); if (!chars) return JSVAL_NULL; if (length && !CopyUnicodeTo(readable, 0, reinterpret_cast<PRUnichar *>(chars), length)) { JS_free(cx, chars); return JSVAL_NULL; } chars[length] = 0; str = JS_NewUCString(cx, chars, length); if (!str) JS_free(cx, chars); } return STRING_TO_JSVAL(str); }