From 99058f910f27a3f90e65b9bc49c61cbb2ec4e745 Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Sun, 12 Jul 2009 07:41:20 -0700 Subject: [PATCH] Make sure js_FinalizeStringRT can be inlined into js_GC() (503462, r=dmandelin). --- js/src/jsgc.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++-- js/src/jsgc.h | 10 +++++++ js/src/jsstr.cpp | 73 ------------------------------------------------ js/src/jsstr.h | 18 ++++++------ 4 files changed, 85 insertions(+), 85 deletions(-) diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index c1d7932eeac3..9ef3bcf105b4 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -3247,7 +3247,7 @@ js_DestroyScriptsToGC(JSContext *cx, JSThreadData *data) } static void -FinalizeObject(JSContext *cx, JSObject *obj) +js_FinalizeObject(JSContext *cx, JSObject *obj) { /* Cope with stillborn objects that have no map. */ if (!obj->map) @@ -3271,6 +3271,71 @@ FinalizeObject(JSContext *cx, JSObject *obj) js_FreeSlots(cx, obj); } +static JSStringFinalizeOp str_finalizers[GCX_NTYPES - GCX_EXTERNAL_STRING] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +intN +js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop, + JSStringFinalizeOp newop) +{ + uintN i; + + for (i = 0; i != JS_ARRAY_LENGTH(str_finalizers); i++) { + if (str_finalizers[i] == oldop) { + str_finalizers[i] = newop; + return (intN) i; + } + } + return -1; +} + +/* + * cx is NULL when we are called from js_FinishAtomState to force the + * finalization of the permanently interned strings. + */ +void +js_FinalizeStringRT(JSRuntime *rt, JSString *str, intN type, JSContext *cx) +{ + jschar *chars; + JSBool valid; + JSStringFinalizeOp finalizer; + + JS_RUNTIME_UNMETER(rt, liveStrings); + if (str->isDependent()) { + /* A dependent string can not be external and must be valid. */ + JS_ASSERT(type < 0); + JS_ASSERT(str->dependentBase()); + JS_RUNTIME_UNMETER(rt, liveDependentStrings); + valid = JS_TRUE; + } else { + /* A stillborn string has null chars, so is not valid. */ + chars = str->flatChars(); + valid = (chars != NULL); + if (valid) { + if (IN_UNIT_STRING_SPACE_RT(rt, chars)) { + JS_ASSERT(rt->unitStrings[*chars] == str); + JS_ASSERT(type < 0); + rt->unitStrings[*chars] = NULL; + } else if (type < 0) { + free(chars); + } else { + JS_ASSERT((uintN) type < JS_ARRAY_LENGTH(str_finalizers)); + finalizer = str_finalizers[type]; + if (finalizer) { + /* + * Assume that the finalizer for the permanently interned + * string knows how to deal with null context. + */ + finalizer(cx, str); + } + } + } + } + if (valid && str->isDeflated()) + js_PurgeDeflatedStringCache(rt, str); +} + /* * The gckind flag bit GC_LOCK_HELD indicates a call from js_NewGCThing with * rt->gcLock already held, so the lock should be kept on return. @@ -3607,7 +3672,7 @@ js_GC(JSContext *cx, JSGCInvocationKind gckind) type = flags & GCF_TYPEMASK; switch (type) { case GCX_OBJECT: - FinalizeObject(cx, (JSObject *) thing); + js_FinalizeObject(cx, (JSObject *) thing); break; case GCX_DOUBLE: /* Do nothing. */ diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 80541ebfc924..c3a68a1f8728 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -348,6 +348,16 @@ js_AddAsGCBytes(JSContext *cx, size_t sz); extern void js_RemoveAsGCBytes(JSRuntime* rt, size_t sz); +/* + * Free the chars held by str when it is finalized by the GC. When type is + * less then zero, it denotes an internal string. Otherwise it denotes the + * type of the external string allocated with JS_NewExternalString. + * + * This function always needs rt but can live with null cx. + */ +extern void +js_FinalizeStringRT(JSRuntime *rt, JSString *str, intN type, JSContext *cx); + #ifdef DEBUG_notme #define JS_GCMETER 1 #endif diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 936bc963fbb9..ba14bdf62ddd 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -2607,14 +2607,6 @@ js_InitDeflatedStringCache(JSRuntime *rt) return JS_TRUE; } -#define UNIT_STRING_SPACE(sp) ((jschar *) ((sp) + UNIT_STRING_LIMIT)) -#define UNIT_STRING_SPACE_RT(rt) UNIT_STRING_SPACE((rt)->unitStrings) - -#define IN_UNIT_STRING_SPACE(sp,cp) \ - ((size_t)((cp) - UNIT_STRING_SPACE(sp)) < 2 * UNIT_STRING_LIMIT) -#define IN_UNIT_STRING_SPACE_RT(rt,cp) \ - IN_UNIT_STRING_SPACE((rt)->unitStrings, cp) - JSString * js_GetUnitStringForChar(JSContext *cx, jschar c) { @@ -2886,71 +2878,6 @@ js_PurgeDeflatedStringCache(JSRuntime *rt, JSString *str) JS_RELEASE_LOCK(rt->deflatedStringCacheLock); } -static JSStringFinalizeOp str_finalizers[GCX_NTYPES - GCX_EXTERNAL_STRING] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - -intN -js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop, - JSStringFinalizeOp newop) -{ - uintN i; - - for (i = 0; i != JS_ARRAY_LENGTH(str_finalizers); i++) { - if (str_finalizers[i] == oldop) { - str_finalizers[i] = newop; - return (intN) i; - } - } - return -1; -} - -/* - * cx is NULL when we are called from js_FinishAtomState to force the - * finalization of the permanently interned strings. - */ -void -js_FinalizeStringRT(JSRuntime *rt, JSString *str, intN type, JSContext *cx) -{ - jschar *chars; - JSBool valid; - JSStringFinalizeOp finalizer; - - JS_RUNTIME_UNMETER(rt, liveStrings); - if (str->isDependent()) { - /* A dependent string can not be external and must be valid. */ - JS_ASSERT(type < 0); - JS_ASSERT(str->dependentBase()); - JS_RUNTIME_UNMETER(rt, liveDependentStrings); - valid = JS_TRUE; - } else { - /* A stillborn string has null chars, so is not valid. */ - chars = str->flatChars(); - valid = (chars != NULL); - if (valid) { - if (IN_UNIT_STRING_SPACE_RT(rt, chars)) { - JS_ASSERT(rt->unitStrings[*chars] == str); - JS_ASSERT(type < 0); - rt->unitStrings[*chars] = NULL; - } else if (type < 0) { - free(chars); - } else { - JS_ASSERT((uintN) type < JS_ARRAY_LENGTH(str_finalizers)); - finalizer = str_finalizers[type]; - if (finalizer) { - /* - * Assume that the finalizer for the permanently interned - * string knows how to deal with null context. - */ - finalizer(cx, str); - } - } - } - } - if (valid && str->isDeflated()) - js_PurgeDeflatedStringCache(rt, str); -} - JS_FRIEND_API(const char *) js_ValueToPrintable(JSContext *cx, jsval v, JSValueToStringFun v2sfun) { diff --git a/js/src/jsstr.h b/js/src/jsstr.h index 57f75db9e53f..e16c27df8acb 100644 --- a/js/src/jsstr.h +++ b/js/src/jsstr.h @@ -58,6 +58,14 @@ JS_BEGIN_EXTERN_C #define JSSTRING_BIT(n) ((size_t)1 << (n)) #define JSSTRING_BITMASK(n) (JSSTRING_BIT(n) - 1) +#define UNIT_STRING_SPACE(sp) ((jschar *) ((sp) + UNIT_STRING_LIMIT)) +#define UNIT_STRING_SPACE_RT(rt) UNIT_STRING_SPACE((rt)->unitStrings) + +#define IN_UNIT_STRING_SPACE(sp,cp) \ + ((size_t)((cp) - UNIT_STRING_SPACE(sp)) < 2 * UNIT_STRING_LIMIT) +#define IN_UNIT_STRING_SPACE_RT(rt,cp) \ + IN_UNIT_STRING_SPACE((rt)->unitStrings, cp) + class TraceRecorder; extern jschar * @@ -571,16 +579,6 @@ js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n); extern JSString * js_NewStringCopyZ(JSContext *cx, const jschar *s); -/* - * Free the chars held by str when it is finalized by the GC. When type is - * less then zero, it denotes an internal string. Otherwise it denotes the - * type of the external string allocated with JS_NewExternalString. - * - * This function always needs rt but can live with null cx. - */ -extern void -js_FinalizeStringRT(JSRuntime *rt, JSString *str, intN type, JSContext *cx); - /* * Convert a value to a printable C string. */