Make sure js_FinalizeStringRT can be inlined into js_GC() (503462, r=dmandelin).

This commit is contained in:
Andreas Gal 2009-07-12 07:41:20 -07:00
parent 6f9d3b1b9e
commit 99058f910f
4 changed files with 85 additions and 85 deletions

View File

@ -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. */

View File

@ -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

View File

@ -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)
{

View File

@ -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.
*/