bug 658510 - eliminating JSCOMPARTMENT_NEW and associated compartment initialization race. r=mrbkap

This commit is contained in:
Igor Bukanov 2011-05-22 12:09:28 +02:00
parent 7bb90d74fc
commit d11dcf1ab0
4 changed files with 32 additions and 50 deletions

View File

@ -145,12 +145,12 @@ JSCompartment::init()
return false;
#ifdef JS_METHODJIT
if (!(jaegerCompartment = rt->new_<mjit::JaegerCompartment>()))
jaegerCompartment = rt->new_<mjit::JaegerCompartment>();
if (!jaegerCompartment || !jaegerCompartment->Initialize())
return false;
return jaegerCompartment->Initialize();
#else
return true;
#endif
return true;
}
#ifdef JS_METHODJIT

View File

@ -2222,7 +2222,7 @@ SweepCompartments(JSContext *cx, JSGCInvocationKind gckind)
{
JS_ASSERT(compartment->freeLists.isEmpty());
if (callback)
(void) callback(cx, compartment, JSCOMPARTMENT_DESTROY);
JS_ALWAYS_TRUE(callback(cx, compartment, JSCOMPARTMENT_DESTROY));
if (compartment->principals)
JSPRINCIPALS_DROP(cx, compartment->principals);
cx->delete_(compartment);
@ -2752,48 +2752,6 @@ js_GC(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind)
}
namespace js {
namespace gc {
JSCompartment *
NewCompartment(JSContext *cx, JSPrincipals *principals)
{
JSRuntime *rt = cx->runtime;
JSCompartment *compartment = cx->new_<JSCompartment>(rt);
if (!compartment || !compartment->init()) {
Foreground::delete_(compartment);
JS_ReportOutOfMemory(cx);
return NULL;
}
if (principals) {
compartment->principals = principals;
JSPRINCIPALS_HOLD(cx, principals);
}
compartment->setGCLastBytes(8192);
{
AutoLockGC lock(rt);
if (!rt->compartments.append(compartment)) {
AutoUnlockGC unlock(rt);
Foreground::delete_(compartment);
JS_ReportOutOfMemory(cx);
return NULL;
}
}
JSCompartmentCallback callback = rt->compartmentCallback;
if (callback && !callback(cx, compartment, JSCOMPARTMENT_NEW)) {
AutoLockGC lock(rt);
rt->compartments.popBack();
Foreground::delete_(compartment);
return NULL;
}
return compartment;
}
} /* namespace gc */
class AutoCopyFreeListToArenas {
JSRuntime *rt;
@ -2951,4 +2909,30 @@ IterateCells(JSContext *cx, JSCompartment *comp, uint64 traceKindMask,
}
}
namespace gc {
JSCompartment *
NewCompartment(JSContext *cx, JSPrincipals *principals)
{
JSRuntime *rt = cx->runtime;
JSCompartment *compartment = cx->new_<JSCompartment>(rt);
if (compartment && compartment->init()) {
if (principals) {
compartment->principals = principals;
JSPRINCIPALS_HOLD(cx, principals);
}
compartment->setGCLastBytes(8192);
AutoLockGC lock(rt);
if (rt->compartments.append(compartment))
return compartment;
}
Foreground::delete_(compartment);
JS_ReportOutOfMemory(cx);
return NULL;
}
} /* namespace gc */
} /* namespace js */

View File

@ -548,7 +548,6 @@ typedef JSObject *
(* JSPreWrapCallback)(JSContext *cx, JSObject *scope, JSObject *obj, uintN flags);
typedef enum {
JSCOMPARTMENT_NEW, /* XXX Does it make sense to have a NEW? */
JSCOMPARTMENT_DESTROY
} JSCompartmentOp;

View File

@ -255,8 +255,7 @@ xpc::CompartmentPrivate::~CompartmentPrivate()
static JSBool
CompartmentCallback(JSContext *cx, JSCompartment *compartment, uintN op)
{
if(op == JSCOMPARTMENT_NEW)
return JS_TRUE;
JS_ASSERT(op == JSCOMPARTMENT_DESTROY);
XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
if(!self)