From a32154fadf5c60623954dcef6ee38a7139cd21ad Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Fri, 6 Feb 2015 18:17:00 +0100 Subject: [PATCH] Bug 1129473 - Ensure off-thread parsing sets the is-delegate flag on builtin protos. r=bhackett --HG-- extra : rebase_source : 2eab0362e1207c1bc258346d427498f14ddf1b04 --- js/src/jsobj.h | 4 +--- js/src/vm/HelperThreads.cpp | 19 ++++++++++++++----- js/src/vm/ObjectGroup.cpp | 7 +++++++ js/src/vm/ObjectGroup.h | 4 +--- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 5769ee407d1..9ab325d74d9 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -353,9 +353,7 @@ class JSObject : public js::gc::Cell JSObject *getProto() const { MOZ_ASSERT(!uninlinedIsProxy()); - JSObject *proto = getTaggedProto().toObjectOrNull(); - MOZ_ASSERT_IF(proto && proto->isNative(), proto->isDelegate()); - return proto; + return getTaggedProto().toObjectOrNull(); } // Normal objects and a subset of proxies have uninteresting [[Prototype]]. diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp index 4b197b25a8a..5004630bd38 100644 --- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -845,6 +845,15 @@ LeaveParseTaskZone(JSRuntime *rt, ParseTask *task) rt->clearUsedByExclusiveThread(task->cx->zone()); } +static bool +EnsureConstructor(JSContext *cx, Handle global, JSProtoKey key) +{ + if (!GlobalObject::ensureConstructor(cx, global, key)) + return false; + + return global->getPrototype(key).toObject().setDelegate(cx); +} + JSScript * GlobalHelperThreadState::finishParseTask(JSContext *maybecx, JSRuntime *rt, void *token) { @@ -876,11 +885,11 @@ GlobalHelperThreadState::finishParseTask(JSContext *maybecx, JSRuntime *rt, void // Make sure we have all the constructors we need for the prototype // remapping below, since we can't GC while that's happening. Rooted global(cx, &cx->global()->as()); - if (!GlobalObject::ensureConstructor(cx, global, JSProto_Object) || - !GlobalObject::ensureConstructor(cx, global, JSProto_Array) || - !GlobalObject::ensureConstructor(cx, global, JSProto_Function) || - !GlobalObject::ensureConstructor(cx, global, JSProto_RegExp) || - !GlobalObject::ensureConstructor(cx, global, JSProto_Iterator)) + if (!EnsureConstructor(cx, global, JSProto_Object) || + !EnsureConstructor(cx, global, JSProto_Array) || + !EnsureConstructor(cx, global, JSProto_Function) || + !EnsureConstructor(cx, global, JSProto_RegExp) || + !EnsureConstructor(cx, global, JSProto_Iterator)) { LeaveParseTaskZone(rt, parseTask); return nullptr; diff --git a/js/src/vm/ObjectGroup.cpp b/js/src/vm/ObjectGroup.cpp index 974cb6ebd15..f1713e4b73f 100644 --- a/js/src/vm/ObjectGroup.cpp +++ b/js/src/vm/ObjectGroup.cpp @@ -48,6 +48,13 @@ ObjectGroup::finalize(FreeOp *fop) fop->delete_(maybeUnboxedLayoutDontCheckGeneration()); } +void +ObjectGroup::setProtoUnchecked(TaggedProto proto) +{ + proto_ = proto.raw(); + MOZ_ASSERT_IF(proto_ && proto_->isNative(), proto_->isDelegate()); +} + void ObjectGroup::setProto(JSContext *cx, TaggedProto proto) { diff --git a/js/src/vm/ObjectGroup.h b/js/src/vm/ObjectGroup.h index 51101034455..6dcb6b9b26d 100644 --- a/js/src/vm/ObjectGroup.h +++ b/js/src/vm/ObjectGroup.h @@ -256,9 +256,7 @@ class ObjectGroup : public gc::TenuredCell HeapPtrObject &singletonRaw() { return singleton_; } void setProto(JSContext *cx, TaggedProto proto); - void setProtoUnchecked(TaggedProto proto) { - proto_ = proto.raw(); - } + void setProtoUnchecked(TaggedProto proto); void initSingleton(JSObject *singleton) { singleton_ = singleton;