diff --git a/js/src/builtin/RegExp.cpp b/js/src/builtin/RegExp.cpp index 8294ca17dc..9004101e95 100644 --- a/js/src/builtin/RegExp.cpp +++ b/js/src/builtin/RegExp.cpp @@ -217,10 +217,6 @@ js::CreateRegExpMatchResult(JSContext* cx, RegExpShared& re, // Step 34b (reordered) // Set the |indices| property. if (hasIndices) { - fprintf(stderr, - "regexp indices store: arr=%p comp=%p zone=%p | indices=%p comp=%p zone=%p\n", - arr.get(), arr->compartment(), arr->zone(), - indices.get(), indices->compartment(), indices->zone()); arr->setSlot(3, ObjectValue(*indices)); } diff --git a/js/src/vm/NativeObject.h b/js/src/vm/NativeObject.h index 35d26a6778..3a0035a760 100644 --- a/js/src/vm/NativeObject.h +++ b/js/src/vm/NativeObject.h @@ -859,10 +859,8 @@ class NativeObject : public ShapedObject // Check requirements on values stored to this object. MOZ_ALWAYS_INLINE void checkStoredValue(const Value& v) { - if (!IsObjectValueInCompartment(v, compartment())) - MOZ_CRASH("compartment mismatch"); - if (!AtomIsMarked(zoneFromAnyThread(), v)) - MOZ_CRASH("AtomIsMarked failed"); + MOZ_ASSERT(IsObjectValueInCompartment(v, compartment())); + MOZ_ASSERT(AtomIsMarked(zoneFromAnyThread(), v)); } MOZ_ALWAYS_INLINE void setSlot(uint32_t slot, const Value& value) { diff --git a/js/src/vm/RegExpObject.cpp b/js/src/vm/RegExpObject.cpp index faba7b0510..57c58ff2eb 100644 --- a/js/src/vm/RegExpObject.cpp +++ b/js/src/vm/RegExpObject.cpp @@ -1297,12 +1297,11 @@ RegExpShared::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) /* RegExpCompartment */ RegExpCompartment::RegExpCompartment(Zone* zone) - : perCompartment_(zone), - optimizableRegExpPrototypeShape_(nullptr), + : optimizableRegExpPrototypeShape_(nullptr), optimizableRegExpInstanceShape_(nullptr) { - { - MOZ_ALWAYS_TRUE(perCompartment_.init(4)); + for (auto& templateObj : matchResultTemplateObjects_) { + templateObj = nullptr; } } @@ -1312,30 +1311,9 @@ RegExpCompartment::~RegExpCompartment() } ArrayObject* -RegExpCompartment::getOrCreateMatchResultTemplateObject(JSContext* cx, ResultTemplateKind kind) +RegExpCompartment::createMatchResultTemplateObject(JSContext* cx, ResultTemplateKind kind) { - JSCompartment* comp = cx->compartment(); - - auto p = perCompartment_.lookupForAdd(comp); - if (!p) { - PerCompartmentData init; - if (!perCompartment_.add(p, comp, init)) - return nullptr; - } - - PerCompartmentData& data = p->value(); - if (data.matchResultTemplateObjects_[kind]) - return data.matchResultTemplateObjects_[kind]; - - return createMatchResultTemplateObject(cx, kind, data); -} - -ArrayObject* -RegExpCompartment::createMatchResultTemplateObject(JSContext* cx, - ResultTemplateKind kind, - PerCompartmentData& data) -{ - MOZ_ASSERT(!data.matchResultTemplateObjects_[kind]); + MOZ_ASSERT(!matchResultTemplateObjects_[kind]); /* Create template array object */ RootedArrayObject templateObject(cx, NewDenseUnallocatedArray(cx, RegExpObject::MaxPairCount, @@ -1359,8 +1337,8 @@ RegExpCompartment::createMatchResultTemplateObject(JSContext* cx, return nullptr; } AddTypePropertyId(cx, templateObject, NameToId(cx->names().groups), TypeSet::AnyObjectType()); - data.matchResultTemplateObjects_[kind].set(templateObject); - return data.matchResultTemplateObjects_[kind]; + matchResultTemplateObjects_[kind].set(templateObject); + return matchResultTemplateObjects_[kind]; } /* Set dummy index property */ @@ -1399,8 +1377,9 @@ RegExpCompartment::createMatchResultTemplateObject(JSContext* cx, AddTypePropertyId(cx, templateObject, NameToId(cx->names().indices), TypeSet::AnyObjectType()); } - data.matchResultTemplateObjects_[kind].set(templateObject); - return data.matchResultTemplateObjects_[kind]; + matchResultTemplateObjects_[kind].set(templateObject); + + return matchResultTemplateObjects_[kind]; } bool @@ -1418,21 +1397,22 @@ RegExpCompartment::init(JSContext* cx) void RegExpCompartment::sweep(JSRuntime* rt) { - for (auto iter = perCompartment_.all(); !iter.empty(); iter.popFront()) { - PerCompartmentData& data = iter.front().value(); + for (auto& templateObject : matchResultTemplateObjects_) { + if (templateObject && IsAboutToBeFinalized(&templateObject)) { + templateObject.set(nullptr); + } + } - for (auto& templateObject : data.matchResultTemplateObjects_) { - if (templateObject && IsAboutToBeFinalized(&templateObject)) - templateObject.set(nullptr); - } + if (optimizableRegExpPrototypeShape_ && + IsAboutToBeFinalized(&optimizableRegExpPrototypeShape_)) + { + optimizableRegExpPrototypeShape_.set(nullptr); + } - if (data.optimizableRegExpPrototypeShape_ && - IsAboutToBeFinalized(&data.optimizableRegExpPrototypeShape_)) - data.optimizableRegExpPrototypeShape_.set(nullptr); - - if (data.optimizableRegExpInstanceShape_ && - IsAboutToBeFinalized(&data.optimizableRegExpInstanceShape_)) - data.optimizableRegExpInstanceShape_.set(nullptr); + if (optimizableRegExpInstanceShape_ && + IsAboutToBeFinalized(&optimizableRegExpInstanceShape_)) + { + optimizableRegExpInstanceShape_.set(nullptr); } } diff --git a/js/src/vm/RegExpShared.h b/js/src/vm/RegExpShared.h index 58ff907e8a..941dca7f45 100644 --- a/js/src/vm/RegExpShared.h +++ b/js/src/vm/RegExpShared.h @@ -12,7 +12,6 @@ #ifndef vm_RegExpShared_h #define vm_RegExpShared_h -#include "js/GCHashTable.h" #include "mozilla/Assertions.h" #include "mozilla/MemoryReporting.h" @@ -23,7 +22,6 @@ #include "gc/Barrier.h" #include "gc/Heap.h" #include "gc/Marking.h" -#include "jsalloc.h" #include "js/UbiNode.h" #include "js/Vector.h" #include "irregexp/InfallibleVector.h" @@ -312,31 +310,23 @@ public: enum ResultTemplateKind { Normal, WithIndices, Indices, NumKinds }; private: - -struct PerCompartmentData { - ReadBarriered matchResultTemplateObjects_[NumKinds]; - ReadBarriered optimizableRegExpPrototypeShape_; - ReadBarriered optimizableRegExpInstanceShape_; - - PerCompartmentData() - : optimizableRegExpPrototypeShape_(nullptr), - optimizableRegExpInstanceShape_(nullptr) - { - for (auto& t : matchResultTemplateObjects_) - t = nullptr; - } - }; - - using PerCompartmentMap = - GCHashMap, - ZoneAllocPolicy>; - - PerCompartmentMap perCompartment_; // <-- add this - - ArrayObject* createMatchResultTemplateObject(JSContext* cx, - ResultTemplateKind kind, - PerCompartmentData& data); + /* + * The template objects that the result of re.exec() is based on, if + * there is a result. These are used in CreateRegExpMatchResult. + * There are three template objects, each of which is an ArrayObject + * with some additional properties. We decide which to use based on + * the |hasIndices| (/d) flag. + * + * Normal: Has |index|, |input|, and |groups| properties. + * Used for the result object if |hasIndices| is not set. + * + * WithIndices: Has |index|, |input|, |groups|, and |indices| properties. + * Used for the result object if |hasIndices| is set. + * + * Indices: Has a |groups| property. If |hasIndices| is set, used + * for the |.indices| property of the result object. + */ + ReadBarriered matchResultTemplateObjects_[ResultTemplateKind::NumKinds]; /* * The shape of RegExp.prototype object that satisfies following: @@ -359,13 +349,19 @@ struct PerCompartmentData { */ ReadBarriered optimizableRegExpInstanceShape_; + ArrayObject* createMatchResultTemplateObject(JSContext* cx, ResultTemplateKind kind); + public: explicit RegExpCompartment(Zone* zone); void sweep(JSRuntime* rt); - ArrayObject* getOrCreateMatchResultTemplateObject(JSContext* cx, - ResultTemplateKind kind = Normal); + /* Get or create template object used to base the result of .exec() on. */ + ArrayObject* getOrCreateMatchResultTemplateObject(JSContext* cx, ResultTemplateKind kind = ResultTemplateKind::Normal) { + if (matchResultTemplateObjects_[kind]) + return matchResultTemplateObjects_[kind]; + return createMatchResultTemplateObject(cx, kind); + } Shape* getOptimizableRegExpPrototypeShape() { return optimizableRegExpPrototypeShape_;