Loading js/src/jsfun.c +40 −27 Original line number Diff line number Diff line Loading @@ -969,28 +969,6 @@ static JSPropertySpec function_props[] = { {0,0,0,0,0} }; void js_MarkFunction(JSContext *cx, JSFunction *fun) { if (fun->object) GC_MARK(cx, fun->object, "object"); if (fun->atom) GC_MARK_ATOM(cx, fun->atom); if (FUN_INTERPRETED(fun) && fun->u.i.script) js_MarkScript(cx, fun->u.i.script); } void js_FinalizeFunction(JSContext *cx, JSFunction *fun) { /* * Null-check of i.script is required since the parser sets interpreted * very early. */ if (FUN_INTERPRETED(fun) && fun->u.i.script) js_DestroyScript(cx, fun->u.i.script); } static JSBool fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { Loading Loading @@ -1203,6 +1181,36 @@ fun_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp) } } static void fun_finalize(JSContext *cx, JSObject *obj) { JSFunction *fun; JSScript *script; /* No valid function object should lack private data, but check anyway. */ fun = (JSFunction *) JS_GetPrivate(cx, obj); if (!fun) return; if (fun->object == obj) fun->object = NULL; /* * Null-check of i.script is required since the parser sets interpreted * very early. * * Here js_IsAboutToBeFinalized works because obj is finalized before * JSFunction. See comments in js_GC before the finalization loop. */ if (FUN_INTERPRETED(fun) && fun->u.i.script && js_IsAboutToBeFinalized(cx, fun)) { script = fun->u.i.script; fun->u.i.script = NULL; js_DestroyScript(cx, script); } } #if JS_HAS_XDR #include "jsxdrapi.h" Loading Loading @@ -1436,8 +1444,13 @@ fun_mark(JSContext *cx, JSObject *obj, void *arg) JSFunction *fun; fun = (JSFunction *) JS_GetPrivate(cx, obj); if (fun) if (fun) { GC_MARK(cx, fun, "private"); if (fun->atom) GC_MARK_ATOM(cx, fun->atom); if (FUN_INTERPRETED(fun) && fun->u.i.script) js_MarkScript(cx, fun->u.i.script); } return 0; } Loading @@ -1462,7 +1475,7 @@ JS_FRIEND_DATA(JSClass) js_FunctionClass = { JS_PropertyStub, JS_PropertyStub, fun_getProperty, JS_PropertyStub, fun_enumerate, (JSResolveOp)fun_resolve, fun_convert, JS_FinalizeStub, fun_convert, fun_finalize, NULL, NULL, NULL, NULL, fun_xdrObject, fun_hasInstance, Loading Loading @@ -2112,10 +2125,10 @@ js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs, JS_PUSH_SINGLE_TEMP_ROOT(cx, OBJECT_TO_JSVAL(funobj), &tvr); /* * Allocate fun after allocating funobj so allocations in js_NewObject * and hooks called from it do not wipe out fun from newborn[GCX_FUNCTION]. * Allocate fun after allocating funobj so slot allocation in js_NewObject * does not wipe out fun from newborn[GCX_PRIVATE]. */ fun = (JSFunction *) js_NewGCThing(cx, GCX_FUNCTION, sizeof(JSFunction)); fun = (JSFunction *) js_NewGCThing(cx, GCX_PRIVATE, sizeof(JSFunction)); if (!fun) goto out; Loading js/src/jsfun.h +0 −6 Original line number Diff line number Diff line Loading @@ -86,12 +86,6 @@ extern JS_FRIEND_DATA(JSClass) js_FunctionClass; (!JSVAL_IS_PRIMITIVE(v) && \ OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_FunctionClass) extern void js_MarkFunction(JSContext *cx, JSFunction *fun); extern void js_FinalizeFunction(JSContext *cx, JSFunction *fun); extern JSBool js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent, uintN argc, jsval *argv, jsval *rval); Loading js/src/jsgc.c +18 −22 Original line number Diff line number Diff line Loading @@ -242,6 +242,14 @@ 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); /* * Ensure that GC-allocated JSFunction and JSObject would go to different * lists so we can easily finalize JSObject before JSFunction. See comments * in js_GC. */ JS_STATIC_ASSERT(GC_FREELIST_INDEX(sizeof(JSFunction)) != GC_FREELIST_INDEX(sizeof(JSObject))); /* * JSPtrTable capacity growth descriptor. The table grows by powers of two * starting from capacity JSPtrTableInfo.minCapacity, but switching to linear Loading Loading @@ -532,7 +540,7 @@ static GCFinalizeOp gc_finalizers[GCX_NTYPES] = { (GCFinalizeOp) js_FinalizeString, /* GCX_STRING */ (GCFinalizeOp) js_FinalizeDouble, /* GCX_DOUBLE */ (GCFinalizeOp) js_FinalizeString, /* GCX_MUTABLE_STRING */ (GCFinalizeOp) js_FinalizeFunction, /* GCX_FUNCTION */ NULL, /* GCX_PRIVATE */ (GCFinalizeOp) js_FinalizeXMLNamespace, /* GCX_NAMESPACE */ (GCFinalizeOp) js_FinalizeXMLQName, /* GCX_QNAME */ (GCFinalizeOp) js_FinalizeXML, /* GCX_XML */ Loading Loading @@ -1914,17 +1922,6 @@ gc_dump_thing(JSContext *cx, JSGCThing *thing, FILE *fp) fprintf(fp, "object %8p %s", privateThing, className); break; } case GCX_FUNCTION: { JSFunction *fun = (JSFunction *)thing; fprintf(fp, "function"); if (fun->atom && ATOM_IS_STRING(fun->atom)) { fputc(' ', fp); js_FileEscapedString(fp, ATOM_TO_STRING(fun->atom), 0); } break; } #if JS_HAS_XML_SUPPORT case GCX_NAMESPACE: { Loading Loading @@ -1961,6 +1958,9 @@ gc_dump_thing(JSContext *cx, JSGCThing *thing, FILE *fp) case GCX_DOUBLE: fprintf(fp, "double %g", *(jsdouble *)thing); break; case GCX_PRIVATE: fprintf(fp, "private %8p", (void *)thing); break; default: fputs("string ", fp); js_FileEscapedString(fp, (JSString *)thing, 0); Loading Loading @@ -2204,12 +2204,6 @@ MarkGCThingChildren(JSContext *cx, void *thing, uint8 *flagp, goto start; #endif case GCX_FUNCTION: if (RECURSION_TOO_DEEP()) goto add_to_unscanned_bag; js_MarkFunction(cx, (JSFunction *)thing); break; #if JS_HAS_XML_SUPPORT case GCX_NAMESPACE: if (RECURSION_TOO_DEEP()) Loading Loading @@ -2441,7 +2435,6 @@ ScanDelayedChildren(JSContext *cx) */ switch (*flagp & GCF_TYPEMASK) { case GCX_OBJECT: case GCX_FUNCTION: # if JS_HAS_XML_SUPPORT case GCX_NAMESPACE: case GCX_QNAME: Loading Loading @@ -3066,8 +3059,12 @@ restart: * so that any attempt to allocate a GC-thing from a finalizer will fail, * rather than nest badly and leave the unmarked newborn to be swept. * * Here we finalize the list containing JSObject first to ensure that * JSObject finalizers can access JSString * and other GC things safely. * Here we need to ensure that JSObject instances are finalized before GC- * allocated JSFunction instances so fun_finalize from jsfun.c can get the * proper result from the call to js_IsAboutToBeFinalized. For that we * simply finalize the list containing JSObject first since the static * assert at the beginning of the file guarantees that JSFunction instances * are allocated from a different list. */ for (i = 0; i < GC_NUM_FREELISTS; i++) { arenaList = &rt->gcArenaList[i == 0 Loading @@ -3075,7 +3072,6 @@ restart: : i == GC_FREELIST_INDEX(sizeof(JSObject)) ? 0 : i]; arenaList = &rt->gcArenaList[i]; nbytes = arenaList->thingSize; limit = arenaList->lastLimit; for (a = arenaList->last; a; a = a->prev) { Loading js/src/jsgc.h +1 −1 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ JS_BEGIN_EXTERN_C #define GCX_DOUBLE 2 /* jsdouble */ #define GCX_MUTABLE_STRING 3 /* JSString that's mutable -- single-threaded only! */ #define GCX_FUNCTION 4 /* JSFunction */ #define GCX_PRIVATE 4 /* private (unscanned) data */ #define GCX_NAMESPACE 5 /* JSXMLNamespace */ #define GCX_QNAME 6 /* JSXMLQName */ #define GCX_XML 7 /* JSXML */ Loading Loading
js/src/jsfun.c +40 −27 Original line number Diff line number Diff line Loading @@ -969,28 +969,6 @@ static JSPropertySpec function_props[] = { {0,0,0,0,0} }; void js_MarkFunction(JSContext *cx, JSFunction *fun) { if (fun->object) GC_MARK(cx, fun->object, "object"); if (fun->atom) GC_MARK_ATOM(cx, fun->atom); if (FUN_INTERPRETED(fun) && fun->u.i.script) js_MarkScript(cx, fun->u.i.script); } void js_FinalizeFunction(JSContext *cx, JSFunction *fun) { /* * Null-check of i.script is required since the parser sets interpreted * very early. */ if (FUN_INTERPRETED(fun) && fun->u.i.script) js_DestroyScript(cx, fun->u.i.script); } static JSBool fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { Loading Loading @@ -1203,6 +1181,36 @@ fun_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp) } } static void fun_finalize(JSContext *cx, JSObject *obj) { JSFunction *fun; JSScript *script; /* No valid function object should lack private data, but check anyway. */ fun = (JSFunction *) JS_GetPrivate(cx, obj); if (!fun) return; if (fun->object == obj) fun->object = NULL; /* * Null-check of i.script is required since the parser sets interpreted * very early. * * Here js_IsAboutToBeFinalized works because obj is finalized before * JSFunction. See comments in js_GC before the finalization loop. */ if (FUN_INTERPRETED(fun) && fun->u.i.script && js_IsAboutToBeFinalized(cx, fun)) { script = fun->u.i.script; fun->u.i.script = NULL; js_DestroyScript(cx, script); } } #if JS_HAS_XDR #include "jsxdrapi.h" Loading Loading @@ -1436,8 +1444,13 @@ fun_mark(JSContext *cx, JSObject *obj, void *arg) JSFunction *fun; fun = (JSFunction *) JS_GetPrivate(cx, obj); if (fun) if (fun) { GC_MARK(cx, fun, "private"); if (fun->atom) GC_MARK_ATOM(cx, fun->atom); if (FUN_INTERPRETED(fun) && fun->u.i.script) js_MarkScript(cx, fun->u.i.script); } return 0; } Loading @@ -1462,7 +1475,7 @@ JS_FRIEND_DATA(JSClass) js_FunctionClass = { JS_PropertyStub, JS_PropertyStub, fun_getProperty, JS_PropertyStub, fun_enumerate, (JSResolveOp)fun_resolve, fun_convert, JS_FinalizeStub, fun_convert, fun_finalize, NULL, NULL, NULL, NULL, fun_xdrObject, fun_hasInstance, Loading Loading @@ -2112,10 +2125,10 @@ js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs, JS_PUSH_SINGLE_TEMP_ROOT(cx, OBJECT_TO_JSVAL(funobj), &tvr); /* * Allocate fun after allocating funobj so allocations in js_NewObject * and hooks called from it do not wipe out fun from newborn[GCX_FUNCTION]. * Allocate fun after allocating funobj so slot allocation in js_NewObject * does not wipe out fun from newborn[GCX_PRIVATE]. */ fun = (JSFunction *) js_NewGCThing(cx, GCX_FUNCTION, sizeof(JSFunction)); fun = (JSFunction *) js_NewGCThing(cx, GCX_PRIVATE, sizeof(JSFunction)); if (!fun) goto out; Loading
js/src/jsfun.h +0 −6 Original line number Diff line number Diff line Loading @@ -86,12 +86,6 @@ extern JS_FRIEND_DATA(JSClass) js_FunctionClass; (!JSVAL_IS_PRIMITIVE(v) && \ OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_FunctionClass) extern void js_MarkFunction(JSContext *cx, JSFunction *fun); extern void js_FinalizeFunction(JSContext *cx, JSFunction *fun); extern JSBool js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent, uintN argc, jsval *argv, jsval *rval); Loading
js/src/jsgc.c +18 −22 Original line number Diff line number Diff line Loading @@ -242,6 +242,14 @@ 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); /* * Ensure that GC-allocated JSFunction and JSObject would go to different * lists so we can easily finalize JSObject before JSFunction. See comments * in js_GC. */ JS_STATIC_ASSERT(GC_FREELIST_INDEX(sizeof(JSFunction)) != GC_FREELIST_INDEX(sizeof(JSObject))); /* * JSPtrTable capacity growth descriptor. The table grows by powers of two * starting from capacity JSPtrTableInfo.minCapacity, but switching to linear Loading Loading @@ -532,7 +540,7 @@ static GCFinalizeOp gc_finalizers[GCX_NTYPES] = { (GCFinalizeOp) js_FinalizeString, /* GCX_STRING */ (GCFinalizeOp) js_FinalizeDouble, /* GCX_DOUBLE */ (GCFinalizeOp) js_FinalizeString, /* GCX_MUTABLE_STRING */ (GCFinalizeOp) js_FinalizeFunction, /* GCX_FUNCTION */ NULL, /* GCX_PRIVATE */ (GCFinalizeOp) js_FinalizeXMLNamespace, /* GCX_NAMESPACE */ (GCFinalizeOp) js_FinalizeXMLQName, /* GCX_QNAME */ (GCFinalizeOp) js_FinalizeXML, /* GCX_XML */ Loading Loading @@ -1914,17 +1922,6 @@ gc_dump_thing(JSContext *cx, JSGCThing *thing, FILE *fp) fprintf(fp, "object %8p %s", privateThing, className); break; } case GCX_FUNCTION: { JSFunction *fun = (JSFunction *)thing; fprintf(fp, "function"); if (fun->atom && ATOM_IS_STRING(fun->atom)) { fputc(' ', fp); js_FileEscapedString(fp, ATOM_TO_STRING(fun->atom), 0); } break; } #if JS_HAS_XML_SUPPORT case GCX_NAMESPACE: { Loading Loading @@ -1961,6 +1958,9 @@ gc_dump_thing(JSContext *cx, JSGCThing *thing, FILE *fp) case GCX_DOUBLE: fprintf(fp, "double %g", *(jsdouble *)thing); break; case GCX_PRIVATE: fprintf(fp, "private %8p", (void *)thing); break; default: fputs("string ", fp); js_FileEscapedString(fp, (JSString *)thing, 0); Loading Loading @@ -2204,12 +2204,6 @@ MarkGCThingChildren(JSContext *cx, void *thing, uint8 *flagp, goto start; #endif case GCX_FUNCTION: if (RECURSION_TOO_DEEP()) goto add_to_unscanned_bag; js_MarkFunction(cx, (JSFunction *)thing); break; #if JS_HAS_XML_SUPPORT case GCX_NAMESPACE: if (RECURSION_TOO_DEEP()) Loading Loading @@ -2441,7 +2435,6 @@ ScanDelayedChildren(JSContext *cx) */ switch (*flagp & GCF_TYPEMASK) { case GCX_OBJECT: case GCX_FUNCTION: # if JS_HAS_XML_SUPPORT case GCX_NAMESPACE: case GCX_QNAME: Loading Loading @@ -3066,8 +3059,12 @@ restart: * so that any attempt to allocate a GC-thing from a finalizer will fail, * rather than nest badly and leave the unmarked newborn to be swept. * * Here we finalize the list containing JSObject first to ensure that * JSObject finalizers can access JSString * and other GC things safely. * Here we need to ensure that JSObject instances are finalized before GC- * allocated JSFunction instances so fun_finalize from jsfun.c can get the * proper result from the call to js_IsAboutToBeFinalized. For that we * simply finalize the list containing JSObject first since the static * assert at the beginning of the file guarantees that JSFunction instances * are allocated from a different list. */ for (i = 0; i < GC_NUM_FREELISTS; i++) { arenaList = &rt->gcArenaList[i == 0 Loading @@ -3075,7 +3072,6 @@ restart: : i == GC_FREELIST_INDEX(sizeof(JSObject)) ? 0 : i]; arenaList = &rt->gcArenaList[i]; nbytes = arenaList->thingSize; limit = arenaList->lastLimit; for (a = arenaList->last; a; a = a->prev) { Loading
js/src/jsgc.h +1 −1 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ JS_BEGIN_EXTERN_C #define GCX_DOUBLE 2 /* jsdouble */ #define GCX_MUTABLE_STRING 3 /* JSString that's mutable -- single-threaded only! */ #define GCX_FUNCTION 4 /* JSFunction */ #define GCX_PRIVATE 4 /* private (unscanned) data */ #define GCX_NAMESPACE 5 /* JSXMLNamespace */ #define GCX_QNAME 6 /* JSXMLQName */ #define GCX_XML 7 /* JSXML */ Loading