зеркало из https://github.com/mozilla/pjs.git
Back out the patch for bug 400687 to see whether it caused the Ts regression, a=sicking
This commit is contained in:
Родитель
db83a4c09c
Коммит
4122645052
|
@ -2513,10 +2513,9 @@ JS_NewExternalString(JSContext *cx, jschar *chars, size_t length, intN type)
|
|||
JSString *str;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
JS_ASSERT((uintN) type < (uintN) (GCX_NTYPES - GCX_EXTERNAL_STRING));
|
||||
JS_ASSERT(GCX_EXTERNAL_STRING <= type && type < (intN) GCX_NTYPES);
|
||||
|
||||
str = (JSString *) js_NewGCThing(cx, (uintN) type + GCX_EXTERNAL_STRING,
|
||||
sizeof(JSString));
|
||||
str = (JSString *) js_NewGCThing(cx, (uintN) type, sizeof(JSString));
|
||||
if (!str)
|
||||
return NULL;
|
||||
JSSTRING_INIT(str, chars, length);
|
||||
|
@ -2526,7 +2525,12 @@ JS_NewExternalString(JSContext *cx, jschar *chars, size_t length, intN type)
|
|||
JS_PUBLIC_API(intN)
|
||||
JS_GetExternalStringGCType(JSRuntime *rt, JSString *str)
|
||||
{
|
||||
return js_GetExternalStringGCType(str);
|
||||
uint8 type = (uint8) (*js_GetGCThingFlags(str) & GCF_TYPEMASK);
|
||||
|
||||
if (type >= GCX_EXTERNAL_STRING)
|
||||
return (intN)type;
|
||||
JS_ASSERT(type == GCX_STRING);
|
||||
return -1;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
|
|
|
@ -408,7 +408,7 @@ js_string_uninterner(JSDHashTable *table, JSDHashEntryHdr *hdr,
|
|||
str = (JSString *)ATOM_ENTRY_KEY(entry);
|
||||
|
||||
/* Pass null as context. */
|
||||
js_FinalizeStringRT(rt, str, js_GetExternalStringGCType(str), NULL);
|
||||
js_FinalizeStringRT(rt, str, GCF_TYPEMASK & *js_GetGCThingFlags(str), NULL);
|
||||
return JS_DHASH_NEXT;
|
||||
}
|
||||
|
||||
|
|
145
js/src/jsgc.c
145
js/src/jsgc.c
|
@ -359,6 +359,25 @@ JS_STATIC_ASSERT(sizeof(JSGCThing) >= sizeof(jsdouble));
|
|||
/* We want to use all the available GC thing space for object's slots. */
|
||||
JS_STATIC_ASSERT(sizeof(JSObject) % sizeof(JSGCThing) == 0);
|
||||
|
||||
static uint8 GCTypeToTraceKindMap[GCX_NTYPES] = {
|
||||
JSTRACE_OBJECT, /* GCX_OBJECT */
|
||||
JSTRACE_STRING, /* GCX_STRING */
|
||||
JSTRACE_DOUBLE, /* GCX_DOUBLE */
|
||||
JSTRACE_FUNCTION, /* GCX_FUNCTION */
|
||||
JSTRACE_NAMESPACE, /* GCX_NAMESPACE */
|
||||
JSTRACE_QNAME, /* GCX_QNAME */
|
||||
JSTRACE_XML, /* GCX_XML */
|
||||
(uint8)-1, /* unused */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 0 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 1 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 2 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 3 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 4 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 5 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 6 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 7 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Ensure that JSObject is allocated from a different GC-list rather than
|
||||
* jsdouble and JSString so we can easily finalize JSObject before these 2
|
||||
|
@ -765,8 +784,8 @@ FinishGCArenaLists(JSRuntime *rt)
|
|||
JS_ASSERT(rt->gcChunkList == 0);
|
||||
}
|
||||
|
||||
static uint8 *
|
||||
GetGCThingFlags(void *thing)
|
||||
JS_FRIEND_API(uint8 *)
|
||||
js_GetGCThingFlags(void *thing)
|
||||
{
|
||||
JSGCArenaInfo *a;
|
||||
uint32 index;
|
||||
|
@ -776,32 +795,6 @@ GetGCThingFlags(void *thing)
|
|||
return THING_FLAGP(a, index);
|
||||
}
|
||||
|
||||
intN
|
||||
js_GetExternalStringGCType(JSString *str)
|
||||
{
|
||||
uintN type;
|
||||
|
||||
type = (uintN) *GetGCThingFlags(str) & GCF_TYPEMASK;
|
||||
JS_ASSERT(type == GCX_STRING || type >= GCX_EXTERNAL_STRING);
|
||||
return (type == GCX_STRING) ? -1 : (intN) (type - GCX_EXTERNAL_STRING);
|
||||
}
|
||||
|
||||
static uint32
|
||||
MapGCFlagsToTraceKind(uintN flags)
|
||||
{
|
||||
uint32 type;
|
||||
|
||||
type = flags & GCF_TYPEMASK;
|
||||
JS_ASSERT(type < GCX_NTYPES);
|
||||
return (type < GCX_EXTERNAL_STRING) ? type : JSTRACE_STRING;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uint32)
|
||||
js_GetGCThingTraceKind(void *thing)
|
||||
{
|
||||
return MapGCFlagsToTraceKind(*GetGCThingFlags(thing));
|
||||
}
|
||||
|
||||
JSRuntime*
|
||||
js_GetGCStringRuntime(JSString *str)
|
||||
{
|
||||
|
@ -818,11 +811,34 @@ js_GetGCStringRuntime(JSString *str)
|
|||
JSBool
|
||||
js_IsAboutToBeFinalized(JSContext *cx, void *thing)
|
||||
{
|
||||
uint8 flags = *GetGCThingFlags(thing);
|
||||
uint8 flags = *js_GetGCThingFlags(thing);
|
||||
|
||||
return !(flags & (GCF_MARK | GCF_LOCK | GCF_FINAL));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char newborn_external_string[] = "newborn external string";
|
||||
|
||||
static const char *gc_typenames[GCX_NTYPES] = {
|
||||
"newborn object",
|
||||
"newborn string",
|
||||
"newborn double",
|
||||
"newborn mutable string",
|
||||
"newborn function",
|
||||
"newborn Namespace",
|
||||
"newborn QName",
|
||||
"newborn XML",
|
||||
newborn_external_string,
|
||||
newborn_external_string,
|
||||
newborn_external_string,
|
||||
newborn_external_string,
|
||||
newborn_external_string,
|
||||
newborn_external_string,
|
||||
newborn_external_string,
|
||||
newborn_external_string
|
||||
};
|
||||
#endif
|
||||
|
||||
/* This is compatible with JSDHashEntryStub. */
|
||||
typedef struct JSGCRootHashEntry {
|
||||
JSDHashEntryHdr hdr;
|
||||
|
@ -1579,7 +1595,7 @@ js_LockGCThingRT(JSRuntime *rt, void *thing)
|
|||
if (!thing)
|
||||
return ok;
|
||||
|
||||
flagp = GetGCThingFlags(thing);
|
||||
flagp = js_GetGCThingFlags(thing);
|
||||
|
||||
JS_LOCK_GC(rt);
|
||||
flags = *flagp;
|
||||
|
@ -1642,7 +1658,7 @@ js_UnlockGCThingRT(JSRuntime *rt, void *thing)
|
|||
if (!thing)
|
||||
return JS_TRUE;
|
||||
|
||||
flagp = GetGCThingFlags(thing);
|
||||
flagp = js_GetGCThingFlags(thing);
|
||||
JS_LOCK_GC(rt);
|
||||
flags = *flagp;
|
||||
|
||||
|
@ -1860,7 +1876,8 @@ TraceDelayedChildren(JSTracer *trc)
|
|||
--rt->gcTraceLaterCount;
|
||||
#endif
|
||||
thing = FLAGP_TO_THING(flagp, thingSize);
|
||||
JS_TraceChildren(trc, thing, MapGCFlagsToTraceKind(*flagp));
|
||||
JS_TraceChildren(trc, thing,
|
||||
GCTypeToTraceKindMap[*flagp & GCF_TYPEMASK]);
|
||||
} while (++thingIndex != endIndex);
|
||||
}
|
||||
|
||||
|
@ -1915,9 +1932,6 @@ JS_CallTracer(JSTracer *trc, void *thing, uint32 kind)
|
|||
JS_ASSERT(rt->gcMarkingTracer == trc);
|
||||
JS_ASSERT(rt->gcLevel > 0);
|
||||
|
||||
if (rt->gcThingCallback)
|
||||
rt->gcThingCallback(thing, kind, rt->gcThingCallbackClosure);
|
||||
|
||||
/*
|
||||
* Optimize for string and double as their size is known and their tracing
|
||||
* is not recursive.
|
||||
|
@ -1926,7 +1940,10 @@ JS_CallTracer(JSTracer *trc, void *thing, uint32 kind)
|
|||
case JSTRACE_DOUBLE:
|
||||
flagp = THING_TO_FLAGP(thing, sizeof(JSGCThing));
|
||||
JS_ASSERT((*flagp & GCF_FINAL) == 0);
|
||||
JS_ASSERT(kind == MapGCFlagsToTraceKind(*flagp));
|
||||
JS_ASSERT(GCTypeToTraceKindMap[*flagp & GCF_TYPEMASK] == kind);
|
||||
if (rt->gcThingCallback)
|
||||
rt->gcThingCallback(thing, *flagp, rt->gcThingCallbackClosure);
|
||||
|
||||
*flagp |= GCF_MARK;
|
||||
goto out;
|
||||
|
||||
|
@ -1934,7 +1951,10 @@ JS_CallTracer(JSTracer *trc, void *thing, uint32 kind)
|
|||
for (;;) {
|
||||
flagp = THING_TO_FLAGP(thing, sizeof(JSGCThing));
|
||||
JS_ASSERT((*flagp & GCF_FINAL) == 0);
|
||||
JS_ASSERT(kind == MapGCFlagsToTraceKind(*flagp));
|
||||
JS_ASSERT(GCTypeToTraceKindMap[*flagp & GCF_TYPEMASK] == kind);
|
||||
if (rt->gcThingCallback)
|
||||
rt->gcThingCallback(thing, *flagp, rt->gcThingCallbackClosure);
|
||||
|
||||
if (!JSSTRING_IS_DEPENDENT((JSString *) thing)) {
|
||||
*flagp |= GCF_MARK;
|
||||
goto out;
|
||||
|
@ -1943,14 +1963,16 @@ JS_CallTracer(JSTracer *trc, void *thing, uint32 kind)
|
|||
goto out;
|
||||
*flagp |= GCF_MARK;
|
||||
thing = JSSTRDEP_BASE((JSString *) thing);
|
||||
if (rt->gcThingCallback)
|
||||
rt->gcThingCallback(thing, kind, rt->gcThingCallbackClosure);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
flagp = GetGCThingFlags(thing);
|
||||
JS_ASSERT(kind == MapGCFlagsToTraceKind(*flagp));
|
||||
flagp = js_GetGCThingFlags(thing);
|
||||
JS_ASSERT(GCTypeToTraceKindMap[*flagp & GCF_TYPEMASK] == kind);
|
||||
|
||||
if (rt->gcThingCallback)
|
||||
rt->gcThingCallback(thing, *flagp, rt->gcThingCallbackClosure);
|
||||
|
||||
if (*flagp & GCF_MARK)
|
||||
goto out;
|
||||
|
||||
|
@ -2015,11 +2037,10 @@ js_CallValueTracerIfGCThing(JSTracer *trc, jsval v)
|
|||
if (JSVAL_IS_DOUBLE(v) || JSVAL_IS_STRING(v)) {
|
||||
thing = JSVAL_TO_TRACEABLE(v);
|
||||
kind = JSVAL_TRACE_KIND(v);
|
||||
JS_ASSERT(kind == js_GetGCThingTraceKind(JSVAL_TO_GCTHING(v)));
|
||||
} else if (JSVAL_IS_OBJECT(v) && v != JSVAL_NULL) {
|
||||
/* v can be an arbitrary GC thing reinterpreted as an object. */
|
||||
thing = JSVAL_TO_OBJECT(v);
|
||||
kind = js_GetGCThingTraceKind(thing);
|
||||
kind = GCTypeToTraceKindMap[*js_GetGCThingFlags(thing) & GCF_TYPEMASK];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -2081,12 +2102,14 @@ gc_lock_traversal(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num,
|
|||
JSGCLockHashEntry *lhe = (JSGCLockHashEntry *)hdr;
|
||||
void *thing = (void *)lhe->thing;
|
||||
JSTracer *trc = (JSTracer *)arg;
|
||||
uint8 flags;
|
||||
uint32 traceKind;
|
||||
JSRuntime *rt;
|
||||
uint32 n;
|
||||
|
||||
JS_ASSERT(lhe->count >= 1);
|
||||
traceKind = js_GetGCThingTraceKind(thing);
|
||||
flags = *js_GetGCThingFlags(thing);
|
||||
traceKind = GCTypeToTraceKindMap[flags & GCF_TYPEMASK];
|
||||
JS_CALL_TRACER(trc, thing, traceKind, "locked object");
|
||||
|
||||
/*
|
||||
|
@ -2100,7 +2123,7 @@ gc_lock_traversal(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num,
|
|||
rt = trc->context->runtime;
|
||||
if (rt->gcThingCallback) {
|
||||
do {
|
||||
rt->gcThingCallback(thing, traceKind,
|
||||
rt->gcThingCallback(thing, flags,
|
||||
rt->gcThingCallbackClosure);
|
||||
} while (--n != 0);
|
||||
}
|
||||
|
@ -2191,36 +2214,16 @@ js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp)
|
|||
static void
|
||||
TraceWeakRoots(JSTracer *trc, JSWeakRoots *wr)
|
||||
{
|
||||
uint32 i;
|
||||
uintN i;
|
||||
void *thing;
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char *weakRootNames[JSTRACE_LIMIT] = {
|
||||
"newborn object",
|
||||
"newborn double",
|
||||
"newborn string",
|
||||
"newborn function",
|
||||
"newborn namespace",
|
||||
"newborn qname",
|
||||
"newborn xml"
|
||||
};
|
||||
#endif
|
||||
|
||||
for (i = 0; i != JSTRACE_LIMIT; i++) {
|
||||
thing = wr->newborn[i];
|
||||
if (thing)
|
||||
JS_CALL_TRACER(trc, thing, i, weakRootNames[i]);
|
||||
}
|
||||
JS_ASSERT(i == GCX_EXTERNAL_STRING);
|
||||
for (; i != GCX_NTYPES; ++i) {
|
||||
for (i = 0; i < GCX_NTYPES; i++) {
|
||||
thing = wr->newborn[i];
|
||||
if (thing) {
|
||||
JS_SET_TRACING_INDEX(trc, "newborn external string",
|
||||
i - GCX_EXTERNAL_STRING);
|
||||
JS_CallTracer(trc, thing, JSTRACE_STRING);
|
||||
JS_CALL_TRACER(trc, thing, GCTypeToTraceKindMap[i],
|
||||
gc_typenames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
JS_CALL_VALUE_TRACER(trc, wr->lastAtom, "lastAtom");
|
||||
JS_SET_TRACING_NAME(trc, "lastInternalResult");
|
||||
js_CallValueTracerIfGCThing(trc, wr->lastInternalResult);
|
||||
|
@ -2661,9 +2664,7 @@ restart:
|
|||
JS_ASSERT(type == GCX_STRING ||
|
||||
type - GCX_EXTERNAL_STRING <
|
||||
GCX_NTYPES - GCX_EXTERNAL_STRING);
|
||||
js_FinalizeStringRT(rt, (JSString *) thing,
|
||||
(intN) (type - GCX_EXTERNAL_STRING),
|
||||
cx);
|
||||
js_FinalizeStringRT(rt, (JSString *) thing, type, cx);
|
||||
break;
|
||||
}
|
||||
thing->flagp = flagp;
|
||||
|
|
|
@ -49,60 +49,28 @@
|
|||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
JS_STATIC_ASSERT(JSTRACE_STRING == 2);
|
||||
/* GC thing type indexes. */
|
||||
#define GCX_OBJECT 0 /* JSObject */
|
||||
#define GCX_STRING 1 /* JSString */
|
||||
#define GCX_DOUBLE 2 /* jsdouble */
|
||||
#define GCX_FUNCTION 3 /* JSFunction */
|
||||
#define GCX_NAMESPACE 4 /* JSXMLNamespace */
|
||||
#define GCX_QNAME 5 /* JSXMLQName */
|
||||
#define GCX_XML 6 /* JSXML */
|
||||
#define GCX_EXTERNAL_STRING 8 /* JSString w/ external chars */
|
||||
|
||||
#define JSTRACE_FUNCTION 3
|
||||
#define JSTRACE_NAMESPACE 4
|
||||
#define JSTRACE_QNAME 5
|
||||
#define JSTRACE_XML 6
|
||||
|
||||
/*
|
||||
* One past the maximum trace kind.
|
||||
*/
|
||||
#define JSTRACE_LIMIT 7
|
||||
|
||||
/*
|
||||
* We use the trace kinds as the types for all GC things except external
|
||||
* strings.
|
||||
*/
|
||||
#define GCX_OBJECT JSTRACE_OBJECT /* JSObject */
|
||||
#define GCX_DOUBLE JSTRACE_DOUBLE /* jsdouble */
|
||||
#define GCX_STRING JSTRACE_STRING /* JSString */
|
||||
#define GCX_FUNCTION JSTRACE_FUNCTION /* JSFunction */
|
||||
#define GCX_NAMESPACE JSTRACE_NAMESPACE /* JSXMLNamespace */
|
||||
#define GCX_QNAME JSTRACE_QNAME /* JSXMLQName */
|
||||
#define GCX_XML JSTRACE_XML /* JSXML */
|
||||
#define GCX_EXTERNAL_STRING JSTRACE_LIMIT /* JSString with external
|
||||
chars */
|
||||
/*
|
||||
* The number of defined GC types.
|
||||
*/
|
||||
#define GCX_NTYPES (GCX_EXTERNAL_STRING + 8)
|
||||
|
||||
/*
|
||||
* The maximum limit for the number of GC types.
|
||||
*/
|
||||
#define GCX_LIMIT_LOG2 4 /* type index bits */
|
||||
#define GCX_LIMIT JS_BIT(GCX_LIMIT_LOG2)
|
||||
|
||||
JS_STATIC_ASSERT(GCX_NTYPES <= GCX_LIMIT);
|
||||
#define GCX_NTYPES_LOG2 4 /* type index bits */
|
||||
#define GCX_NTYPES JS_BIT(GCX_NTYPES_LOG2)
|
||||
|
||||
/* GC flag definitions, must fit in 8 bits (type index goes in the low bits). */
|
||||
#define GCF_TYPEMASK JS_BITMASK(GCX_LIMIT_LOG2)
|
||||
#define GCF_MARK JS_BIT(GCX_LIMIT_LOG2)
|
||||
#define GCF_FINAL JS_BIT(GCX_LIMIT_LOG2 + 1)
|
||||
#define GCF_LOCKSHIFT (GCX_LIMIT_LOG2 + 2) /* lock bit shift */
|
||||
#define GCF_TYPEMASK JS_BITMASK(GCX_NTYPES_LOG2)
|
||||
#define GCF_MARK JS_BIT(GCX_NTYPES_LOG2)
|
||||
#define GCF_FINAL JS_BIT(GCX_NTYPES_LOG2 + 1)
|
||||
#define GCF_LOCKSHIFT (GCX_NTYPES_LOG2 + 2) /* lock bit shift */
|
||||
#define GCF_LOCK JS_BIT(GCF_LOCKSHIFT) /* lock request bit in API */
|
||||
|
||||
/*
|
||||
* Get the type of the external string or -1 if the string was not created
|
||||
* with JS_NewExternalString.
|
||||
*/
|
||||
extern intN
|
||||
js_GetExternalStringGCType(JSString *str);
|
||||
|
||||
extern JS_FRIEND_API(uint32)
|
||||
js_GetGCThingTraceKind(void *thing);
|
||||
extern JS_FRIEND_API(uint8 *)
|
||||
js_GetGCThingFlags(void *thing);
|
||||
|
||||
/*
|
||||
* The sole purpose of the function is to preserve public API compatibility
|
||||
|
@ -200,6 +168,13 @@ js_IsAboutToBeFinalized(JSContext *cx, void *thing);
|
|||
*/
|
||||
#define IS_GC_MARKING_TRACER(trc) ((trc)->callback == NULL)
|
||||
|
||||
JS_STATIC_ASSERT(JSTRACE_STRING == 2);
|
||||
|
||||
#define JSTRACE_FUNCTION 3
|
||||
#define JSTRACE_NAMESPACE 4
|
||||
#define JSTRACE_QNAME 5
|
||||
#define JSTRACE_XML 6
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
# define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_XML)
|
||||
#else
|
||||
|
@ -214,8 +189,8 @@ JS_STATIC_ASSERT(JSTRACE_FUNCTION + 1 == JSTRACE_NAMESPACE);
|
|||
|
||||
/*
|
||||
* Trace jsval when JSVAL_IS_OBJECT(v) can be an arbitrary GC thing casted as
|
||||
* JSVAL_OBJECT and js_GetGCThingTraceKind has to be used to find the real
|
||||
* type behind v.
|
||||
* JSVAL_OBJECT and js_GetGCThingFlags has to be used to find the real type
|
||||
* behind v.
|
||||
*/
|
||||
extern void
|
||||
js_CallValueTracerIfGCThing(JSTracer *trc, jsval v);
|
||||
|
|
|
@ -637,8 +637,7 @@ typedef JSBool
|
|||
(* JS_DLL_CALLBACK JSGCCallback)(JSContext *cx, JSGCStatus status);
|
||||
|
||||
typedef void
|
||||
(* JS_DLL_CALLBACK JSGCThingCallback)(void *thing, uint32 traceKind,
|
||||
void *closure);
|
||||
(* JS_DLL_CALLBACK JSGCThingCallback)(void *thing, uint8 flags, void *closure);
|
||||
|
||||
/*
|
||||
* Generic trace operation that calls JS_CallTracer on each traceable thing
|
||||
|
|
|
@ -2633,7 +2633,7 @@ js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
|
|||
for (i = 0; i != JS_ARRAY_LENGTH(str_finalizers); i++) {
|
||||
if (str_finalizers[i] == oldop) {
|
||||
str_finalizers[i] = newop;
|
||||
return (intN) i;
|
||||
return (intN) i + GCX_EXTERNAL_STRING;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
@ -2644,15 +2644,15 @@ js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
|
|||
* finalization of the permanently interned strings.
|
||||
*/
|
||||
void
|
||||
js_FinalizeStringRT(JSRuntime *rt, JSString *str, intN type, JSContext *cx)
|
||||
js_FinalizeStringRT(JSRuntime *rt, JSString *str, uintN gctype, JSContext *cx)
|
||||
{
|
||||
JSBool valid;
|
||||
JSStringFinalizeOp finalizer;
|
||||
|
||||
JS_RUNTIME_UNMETER(rt, liveStrings);
|
||||
if (JSSTRING_IS_DEPENDENT(str)) {
|
||||
/* A dependent string can not be external and must be valid. */
|
||||
JS_ASSERT(type < 0);
|
||||
JS_ASSERT(gctype == GCX_STRING);
|
||||
/* If JSSTRFLAG_DEPENDENT is set, this string must be valid. */
|
||||
JS_ASSERT(JSSTRDEP_BASE(str));
|
||||
JS_RUNTIME_UNMETER(rt, liveDependentStrings);
|
||||
valid = JS_TRUE;
|
||||
|
@ -2662,13 +2662,14 @@ js_FinalizeStringRT(JSRuntime *rt, JSString *str, intN type, JSContext *cx)
|
|||
if (valid) {
|
||||
if (IN_UNIT_STRING_SPACE_RT(rt, str->u.chars)) {
|
||||
JS_ASSERT(rt->unitStrings[*str->u.chars] == str);
|
||||
JS_ASSERT(type < 0);
|
||||
JS_ASSERT(gctype == GCX_STRING);
|
||||
rt->unitStrings[*str->u.chars] = NULL;
|
||||
} else if (type < 0) {
|
||||
} else if (gctype == GCX_STRING) {
|
||||
free(str->u.chars);
|
||||
} else {
|
||||
JS_ASSERT((uintN) type < JS_ARRAY_LENGTH(str_finalizers));
|
||||
finalizer = str_finalizers[type];
|
||||
JS_ASSERT(gctype - GCX_EXTERNAL_STRING <
|
||||
JS_ARRAY_LENGTH(str_finalizers));
|
||||
finalizer = str_finalizers[gctype - GCX_EXTERNAL_STRING];
|
||||
if (finalizer) {
|
||||
/*
|
||||
* Assume that the finalizer for the permanently interned
|
||||
|
|
|
@ -407,14 +407,12 @@ 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.
|
||||
* Free the chars held by str when it is finalized by the GC.
|
||||
*
|
||||
* This function always needs rt but can live with null cx.
|
||||
*/
|
||||
extern void
|
||||
js_FinalizeStringRT(JSRuntime *rt, JSString *str, intN type, JSContext *cx);
|
||||
js_FinalizeStringRT(JSRuntime *rt, JSString *str, uintN gctype, JSContext *cx);
|
||||
|
||||
/*
|
||||
* Convert a value to a printable C string.
|
||||
|
|
|
@ -699,6 +699,33 @@ NoteJSChild(JSTracer *trc, void *thing, uint32 kind)
|
|||
}
|
||||
}
|
||||
|
||||
static uint8 GCTypeToTraceKindMap[GCX_NTYPES] = {
|
||||
JSTRACE_OBJECT, /* GCX_OBJECT */
|
||||
JSTRACE_STRING, /* GCX_STRING */
|
||||
JSTRACE_DOUBLE, /* GCX_DOUBLE */
|
||||
JSTRACE_FUNCTION, /* GCX_FUNCTION */
|
||||
JSTRACE_NAMESPACE, /* GCX_NAMESPACE */
|
||||
JSTRACE_QNAME, /* GCX_QNAME */
|
||||
JSTRACE_XML, /* GCX_XML */
|
||||
(uint8)-1, /* unused */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 0 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 1 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 2 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 3 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 4 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 5 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 6 */
|
||||
JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 7 */
|
||||
};
|
||||
|
||||
// static
|
||||
uint8
|
||||
nsXPConnect::GetTraceKind(void *thing)
|
||||
{
|
||||
uint8 type = *js_GetGCThingFlags(thing) & GCF_TYPEMASK;
|
||||
return GCTypeToTraceKindMap[type];
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
||||
{
|
||||
|
@ -707,7 +734,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
|||
|
||||
JSContext *cx = mCycleCollectionContext->GetJSContext();
|
||||
|
||||
uint32 traceKind = js_GetGCThingTraceKind(p);
|
||||
uint8 ty = GetTraceKind(p);
|
||||
|
||||
CCNodeType type;
|
||||
|
||||
|
@ -723,7 +750,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
|||
type = JS_IsAboutToBeFinalized(cx, p) ? GCUnmarked : GCMarked;
|
||||
}
|
||||
|
||||
if(traceKind == JSTRACE_OBJECT)
|
||||
if(ty == GCX_OBJECT)
|
||||
{
|
||||
JSObject *obj = static_cast<JSObject*>(p);
|
||||
JSClass *clazz = OBJ_GET_CLASS(cx, obj);
|
||||
|
@ -830,10 +857,8 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
|||
cb.DescribeNode(type, 0);
|
||||
#endif
|
||||
|
||||
if(traceKind != JSTRACE_OBJECT &&
|
||||
traceKind != JSTRACE_NAMESPACE &&
|
||||
traceKind != JSTRACE_QNAME &&
|
||||
traceKind != JSTRACE_XML)
|
||||
if(ty != GCX_OBJECT && ty != GCX_NAMESPACE && ty != GCX_QNAME &&
|
||||
ty != GCX_XML)
|
||||
return NS_OK;
|
||||
|
||||
#ifndef DEBUG_CC
|
||||
|
@ -848,9 +873,9 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
|||
TraversalTracer trc(cb);
|
||||
|
||||
JS_TRACER_INIT(&trc, cx, NoteJSChild);
|
||||
JS_TraceChildren(&trc, p, traceKind);
|
||||
JS_TraceChildren(&trc, p, GCTypeToTraceKindMap[ty]);
|
||||
|
||||
if(traceKind != JSTRACE_OBJECT)
|
||||
if(ty != GCX_OBJECT)
|
||||
return NS_OK;
|
||||
|
||||
JSObject *obj = static_cast<JSObject*>(p);
|
||||
|
|
|
@ -332,7 +332,7 @@ TraceJSObject(PRUint32 aLangID, void *aScriptThing, void *aClosure)
|
|||
if(aLangID == nsIProgrammingLanguage::JAVASCRIPT)
|
||||
{
|
||||
JS_CALL_TRACER(static_cast<JSTracer*>(aClosure), aScriptThing,
|
||||
js_GetGCThingTraceKind(aScriptThing),
|
||||
nsXPConnect::GetXPConnect()->GetTraceKind(aScriptThing),
|
||||
"JSObjectHolder");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -506,6 +506,8 @@ public:
|
|||
return !mCycleCollecting;
|
||||
}
|
||||
|
||||
static uint8 GetTraceKind(void *thing);
|
||||
|
||||
XPCCallContext* GetCycleCollectionContext()
|
||||
{
|
||||
return mCycleCollectionContext;
|
||||
|
|
Загрузка…
Ссылка в новой задаче