mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 06:35:42 +00:00
Make sure js_FinalizeStringRT can be inlined into js_GC() (503462, r=dmandelin).
This commit is contained in:
parent
6f9d3b1b9e
commit
99058f910f
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user