commit dcaf26b42bbfbb61c7ed1df992c3919052fa82a9
Author: Jon Coppeard <jcoppeard(a)mozilla.com>
Date: Mon Mar 24 21:45:23 2014 +0000
Bug 986843 - Replace AutoHoldZone with AutoCompartmentRooter. r=terrence, a=lsblakk
---
js/src/gc/RootMarking.cpp | 2 +-
js/src/gc/Zone.cpp | 11 ++++++++++-
js/src/gc/Zone.h | 4 ++--
js/src/jsapi.cpp | 29 ++++++++++++++++++-----------
js/src/jscompartment.cpp | 2 +-
js/src/jscompartment.h | 2 +-
js/src/jsgc.cpp | 8 +++++---
7 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp
index 861c2d6..88574f3 100644
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -744,7 +744,7 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
#endif
for (CompartmentsIter c(rt); !c.done(); c.next())
- c->mark(trc);
+ c->markRoots(trc);
/* The embedding can register additional roots here. */
for (size_t i = 0; i < rt->gcBlackRootTracers.length(); i++) {
diff --git a/js/src/gc/Zone.cpp b/js/src/gc/Zone.cpp
index 5625b99..e1f0147 100644
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -23,7 +23,6 @@ using namespace js::gc;
JS::Zone::Zone(JSRuntime *rt)
: rt(rt),
allocator(this),
- hold(false),
ionUsingBarriers_(false),
active(false),
gcScheduled(false),
@@ -227,3 +226,13 @@ Zone::discardJitCode(FreeOp *fop, bool discardConstraints)
}
#endif
}
+
+bool
+Zone::hasMarkedCompartments()
+{
+ for (CompartmentsInZoneIter comp(this); !comp.done(); comp.next()) {
+ if (comp->marked)
+ return true;
+ }
+ return false;
+}
diff --git a/js/src/gc/Zone.h b/js/src/gc/Zone.h
index 73e7043..d740306 100644
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -108,8 +108,6 @@ struct Zone : private JS::shadow::Zone,
js::CompartmentVector compartments;
- bool hold;
-
private:
bool ionUsingBarriers_;
@@ -300,6 +298,8 @@ struct Zone : private JS::shadow::Zone,
void sweep(js::FreeOp *fop, bool releaseTypes);
+ bool hasMarkedCompartments();
+
private:
void sweepBreakpoints(js::FreeOp *fop);
};
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index 3632a74..68b6afa 100644
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -3171,23 +3171,32 @@ JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp)
return JS_TRUE;
}
-class AutoHoldZone
+class AutoCompartmentRooter : private JS::CustomAutoRooter
{
public:
- explicit AutoHoldZone(Zone *zone
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : holdp(&zone->hold)
+ explicit AutoCompartmentRooter(JSContext *cx, JSCompartment *comp
+ MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+ : CustomAutoRooter(cx), compartment(comp)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- *holdp = true;
}
- ~AutoHoldZone() {
- *holdp = false;
+ operator JSCompartment *() {
+ return compartment;
+ }
+
+ JSCompartment *operator->() {
+ return compartment;
+ }
+
+ protected:
+ virtual void trace(JSTracer *trc)
+ {
+ compartment->mark();
}
private:
- bool *holdp;
+ JSCompartment *compartment;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
@@ -3209,7 +3218,7 @@ JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals,
else
zone = ((JSObject *)options.zoneSpec)->zone();
- JSCompartment *compartment = NewCompartment(cx, zone, principals, options);
+ AutoCompartmentRooter compartment(cx, NewCompartment(cx, zone, principals, options));
if (!compartment)
return NULL;
@@ -3218,8 +3227,6 @@ JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals,
rt->systemZone->isSystem = true;
}
- AutoHoldZone hold(compartment->zone());
-
Rooted<GlobalObject *> global(cx);
{
AutoCompartment ac(cx, compartment);
diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp
index c448e10..2e66253 100644
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -488,7 +488,7 @@ JSCompartment::markAllCrossCompartmentWrappers(JSTracer *trc)
}
void
-JSCompartment::mark(JSTracer *trc)
+JSCompartment::markRoots(JSTracer *trc)
{
#ifdef JS_ION
if (ionCompartment_)
diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h
index 6cc1bc8..1ef2ed8 100644
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -293,7 +293,7 @@ struct JSCompartment
WrapperEnum(JSCompartment *c) : js::WrapperMap::Enum(c->crossCompartmentWrappers) {}
};
- void mark(JSTracer *trc);
+ void markRoots(JSTracer *trc);
bool isDiscardingJitCode(JSTracer *trc);
void sweep(js::FreeOp *fop, bool releaseTypes);
void sweepCrossCompartmentWrappers();
diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp
index 53a636e..0db550f 100644
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2541,8 +2541,10 @@ SweepZones(FreeOp *fop, bool lastGC)
while (read < end) {
Zone *zone = *read++;
- if (!zone->hold && zone->wasGCStarted()) {
- if (zone->allocator.arenas.arenaListsAreEmpty() || lastGC) {
+ if (zone->wasGCStarted()) {
+ if ((zone->allocator.arenas.arenaListsAreEmpty() && !zone->hasMarkedCompartments()) ||
+ lastGC)
+ {
zone->allocator.arenas.checkEmptyFreeLists();
if (callback)
callback(zone);
@@ -2723,7 +2725,7 @@ BeginMarkPhase(JSRuntime *rt)
}
zone->scheduledForDestruction = false;
- zone->maybeAlive = zone->hold;
+ zone->maybeAlive = false;
zone->setPreservingCode(false);
}