mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 790865 - Add more compartment assertions (r=terrence)
This commit is contained in:
parent
e3dfeea781
commit
64cccf1287
@ -3273,11 +3273,80 @@ ShouldPreserveJITCode(JSCompartment *c, int64_t currentTime)
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
struct CompartmentCheckTracer : public JSTracer
|
||||
{
|
||||
Cell *src;
|
||||
JSGCTraceKind srcKind;
|
||||
JSCompartment *compartment;
|
||||
};
|
||||
|
||||
static bool
|
||||
InCrossCompartmentMap(JSObject *src, Cell *dst, JSGCTraceKind dstKind)
|
||||
{
|
||||
JSCompartment *srccomp = src->compartment();
|
||||
|
||||
if (dstKind == JSTRACE_OBJECT) {
|
||||
Value key = ObjectValue(*static_cast<JSObject *>(dst));
|
||||
WrapperMap::Ptr p = srccomp->crossCompartmentWrappers.lookup(key);
|
||||
if (*p->value.unsafeGet() == ObjectValue(*src))
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the cross-compartment edge is caused by the debugger, then we don't
|
||||
* know the right hashtable key, so we have to iterate.
|
||||
*/
|
||||
for (WrapperMap::Enum e(srccomp->crossCompartmentWrappers); !e.empty(); e.popFront()) {
|
||||
if (e.front().key.wrapped == dst && ToMarkable(e.front().value) == src)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
CheckCompartmentCallback(JSTracer *trcArg, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
CompartmentCheckTracer *trc = static_cast<CompartmentCheckTracer *>(trcArg);
|
||||
Cell *thing = (Cell *)*thingp;
|
||||
JS_ASSERT(thing->compartment() == trc->compartment ||
|
||||
thing->compartment() == trc->runtime->atomsCompartment ||
|
||||
(trc->srcKind == JSTRACE_OBJECT &&
|
||||
InCrossCompartmentMap((JSObject *)trc->src, thing, kind)));
|
||||
}
|
||||
|
||||
static void
|
||||
CheckForCompartmentMismatches(JSRuntime *rt)
|
||||
{
|
||||
if (rt->gcDisableStrictProxyCheckingCount)
|
||||
return;
|
||||
|
||||
CompartmentCheckTracer trc;
|
||||
JS_TracerInit(&trc, rt, CheckCompartmentCallback);
|
||||
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
trc.compartment = c;
|
||||
for (size_t thingKind = 0; thingKind < FINALIZE_LAST; thingKind++) {
|
||||
for (CellIterUnderGC i(c, AllocKind(thingKind)); !i.done(); i.next()) {
|
||||
trc.src = i.getCell();
|
||||
trc.srcKind = MapAllocToTraceKind(AllocKind(thingKind));
|
||||
JS_TraceChildren(&trc, trc.src, trc.srcKind);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
BeginMarkPhase(JSRuntime *rt)
|
||||
{
|
||||
int64_t currentTime = PRMJ_Now();
|
||||
|
||||
#ifdef DEBUG
|
||||
CheckForCompartmentMismatches(rt);
|
||||
#endif
|
||||
|
||||
rt->gcIsFull = true;
|
||||
DebugOnly<bool> any = false;
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
|
@ -2063,6 +2063,9 @@ TypeCompartment::newTypeObject(JSContext *cx, JSScript *script,
|
||||
JSProtoKey key, JSObject *proto_, bool unknown,
|
||||
bool isDOM)
|
||||
{
|
||||
JS_ASSERT_IF(script, cx->compartment == script->compartment());
|
||||
JS_ASSERT_IF(proto_, cx->compartment == proto_->compartment());
|
||||
|
||||
RootedObject proto(cx, proto_);
|
||||
TypeObject *object = gc::NewGCThing<TypeObject>(cx, gc::FINALIZE_TYPE_OBJECT, sizeof(TypeObject));
|
||||
if (!object)
|
||||
@ -5579,6 +5582,8 @@ JSObject::shouldSplicePrototype(JSContext *cx)
|
||||
bool
|
||||
JSObject::splicePrototype(JSContext *cx, JSObject *proto_)
|
||||
{
|
||||
JS_ASSERT(cx->compartment == compartment());
|
||||
|
||||
RootedObject proto(cx, proto_);
|
||||
RootedObject self(cx, this);
|
||||
|
||||
@ -5639,6 +5644,7 @@ TypeObject *
|
||||
JSObject::makeLazyType(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(hasLazyType());
|
||||
JS_ASSERT(cx->compartment == compartment());
|
||||
|
||||
RootedObject self(cx, this);
|
||||
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(getClass());
|
||||
@ -5749,6 +5755,8 @@ JSObject::setNewTypeUnknown(JSContext *cx)
|
||||
TypeObject *
|
||||
JSObject::getNewType(JSContext *cx, JSFunction *fun_, bool isDOM)
|
||||
{
|
||||
JS_ASSERT(cx->compartment == compartment());
|
||||
|
||||
TypeObjectSet &table = cx->compartment->newTypeObjects;
|
||||
|
||||
if (!table.initialized() && !table.init())
|
||||
@ -5837,6 +5845,9 @@ JSObject::getNewType(JSContext *cx, JSFunction *fun_, bool isDOM)
|
||||
TypeObject *
|
||||
JSCompartment::getLazyType(JSContext *cx, JSObject *proto_)
|
||||
{
|
||||
JS_ASSERT(cx->compartment == this);
|
||||
JS_ASSERT_IF(proto_, cx->compartment == proto_->compartment());
|
||||
|
||||
RootedObject proto(cx, proto_);
|
||||
MaybeCheckStackRoots(cx);
|
||||
|
||||
|
@ -2660,6 +2660,9 @@ bool
|
||||
JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *a, JSObject *b,
|
||||
TradeGutsReserved &reserved)
|
||||
{
|
||||
JS_ASSERT(a->compartment() == b->compartment());
|
||||
AutoCompartment ac(cx, a);
|
||||
|
||||
/*
|
||||
* When performing multiple swaps between objects which may have different
|
||||
* numbers of fixed slots, we reserve all space ahead of time so that the
|
||||
|
@ -663,6 +663,7 @@ JSObject::setSingletonType(JSContext *cx, js::HandleObject obj)
|
||||
inline js::types::TypeObject *
|
||||
JSObject::getType(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(cx->compartment == compartment());
|
||||
if (hasLazyType())
|
||||
return makeLazyType(cx);
|
||||
return type_;
|
||||
@ -672,6 +673,7 @@ JSObject::getType(JSContext *cx)
|
||||
JSObject::clearType(JSContext *cx, js::HandleObject obj)
|
||||
{
|
||||
JS_ASSERT(!obj->hasSingletonType());
|
||||
JS_ASSERT(cx->compartment == obj->compartment());
|
||||
|
||||
js::types::TypeObject *type = cx->compartment->getEmptyType(cx);
|
||||
if (!type)
|
||||
@ -692,6 +694,7 @@ JSObject::setType(js::types::TypeObject *newType)
|
||||
JS_ASSERT_IF(hasSpecialEquality(),
|
||||
newType->hasAnyFlags(js::types::OBJECT_FLAG_SPECIAL_EQUALITY));
|
||||
JS_ASSERT(!hasSingletonType());
|
||||
JS_ASSERT(compartment() == newType->compartment());
|
||||
type_ = newType;
|
||||
}
|
||||
|
||||
@ -824,6 +827,7 @@ JSObject::create(JSContext *cx, js::gc::AllocKind kind,
|
||||
JS_ASSERT(shape && type);
|
||||
JS_ASSERT(!!dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan()) == !!slots);
|
||||
JS_ASSERT(js::gc::GetGCKindSlots(kind, shape->getObjectClass()) == shape->numFixedSlots());
|
||||
JS_ASSERT(cx->compartment == type->compartment());
|
||||
|
||||
JSObject *obj = js_NewGCObject(cx, kind);
|
||||
if (!obj)
|
||||
@ -852,6 +856,7 @@ JSObject::createDenseArray(JSContext *cx, js::gc::AllocKind kind,
|
||||
{
|
||||
JS_ASSERT(shape && type);
|
||||
JS_ASSERT(shape->getObjectClass() == &js::ArrayClass);
|
||||
JS_ASSERT(cx->compartment == type->compartment());
|
||||
|
||||
/*
|
||||
* Dense arrays are non-native, and never have properties to store.
|
||||
|
@ -3059,6 +3059,7 @@ js::NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv_,
|
||||
JS_ASSERT_IF(proto, cx->compartment == proto->compartment());
|
||||
JS_ASSERT_IF(parent, cx->compartment == parent->compartment());
|
||||
JS_ASSERT_IF(construct, cx->compartment == construct->compartment());
|
||||
JS_ASSERT_IF(call && cx->compartment != call->compartment(), priv.get() == ObjectValue(*call));
|
||||
bool fun = call || construct;
|
||||
Class *clasp;
|
||||
if (fun)
|
||||
|
@ -928,6 +928,7 @@ JSObject::rollbackProperties(JSContext *cx, uint32_t slotSpan)
|
||||
Shape *
|
||||
JSObject::replaceWithNewEquivalentShape(JSContext *cx, Shape *oldShape, Shape *newShape)
|
||||
{
|
||||
JS_ASSERT(cx->compartment == oldShape->compartment());
|
||||
JS_ASSERT_IF(oldShape != lastProperty(),
|
||||
inDictionaryMode() &&
|
||||
nativeLookupNoAllocation(oldShape->propidRef()) == oldShape);
|
||||
@ -1202,6 +1203,9 @@ InitialShapeEntry::match(const InitialShapeEntry &key, const Lookup &lookup)
|
||||
EmptyShape::getInitialShape(JSContext *cx, Class *clasp, JSObject *proto, JSObject *parent,
|
||||
AllocKind kind, uint32_t objectFlags)
|
||||
{
|
||||
JS_ASSERT_IF(proto, cx->compartment == proto->compartment());
|
||||
JS_ASSERT_IF(parent, cx->compartment == parent->compartment());
|
||||
|
||||
InitialShapeSet &table = cx->compartment->initialShapes;
|
||||
|
||||
if (!table.initialized() && !table.init())
|
||||
|
Loading…
Reference in New Issue
Block a user