Bug 887334 - Reorder some bookkeeping and assert in setCompartment that both the old and new compartments are marked as entered. r=luke
authorBobby Holley <bobbyholley@gmail.com>
Wed, 17 Jul 2013 11:53:55 -0700
changeset 138967 8bd3aec0de20796a390f6f12d9368b27aae48b11
parent 138966 2e96be43cd12c5e842a9dc2b6c8b69b1a981aef6
child 138968 3c1303aea1115f09db859e832d53003cb0ad50b4
push id24977
push userryanvm@gmail.com
push dateFri, 19 Jul 2013 00:35:38 +0000
treeherdermozilla-central@0d0263a58f06 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs887334
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 887334 - Reorder some bookkeeping and assert in setCompartment that both the old and new compartments are marked as entered. r=luke
js/src/jscntxtinlines.h
js/src/jscompartment.h
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -409,38 +409,45 @@ JSContext::setDefaultCompartmentObjectIf
     if (!defaultCompartmentObject_)
         setDefaultCompartmentObject(obj);
 }
 
 inline void
 JSContext::enterCompartment(JSCompartment *c)
 {
     enterCompartmentDepth_++;
+    c->enter();
     setCompartment(c);
-    c->enter();
     if (throwing)
         wrapPendingException();
 }
 
 inline void
 JSContext::leaveCompartment(JSCompartment *oldCompartment)
 {
     JS_ASSERT(hasEnteredCompartment());
     enterCompartmentDepth_--;
 
-    compartment()->leave();
+    // Only call leave() after we've setCompartment()-ed away from the current
+    // compartment.
+    JSCompartment *startingCompartment = compartment();
     setCompartment(oldCompartment);
+    startingCompartment->leave();
 
     if (throwing && oldCompartment)
         wrapPendingException();
 }
 
 inline void
 JSContext::setCompartment(JSCompartment *comp)
 {
+    // Both the current and the new compartment should be properly marked as
+    // entered at this point.
+    JS_ASSERT_IF(compartment_, compartment_->hasBeenEntered());
+    JS_ASSERT_IF(comp, comp->hasBeenEntered());
     compartment_ = comp;
     zone_ = comp ? comp->zone() : NULL;
     allocator_ = zone_ ? &zone_->allocator : NULL;
 }
 
 inline void
 js::ExclusiveContext::privateSetCompartment(JSCompartment *comp)
 {
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -138,16 +138,17 @@ struct JSCompartment
     friend class js::ExclusiveContext;
     js::ReadBarriered<js::GlobalObject> global_;
 
     unsigned                     enterCompartmentDepth;
 
   public:
     void enter() { enterCompartmentDepth++; }
     void leave() { enterCompartmentDepth--; }
+    bool hasBeenEntered() { return !!enterCompartmentDepth; }
 
     JS::Zone *zone() { return zone_; }
     const JS::Zone *zone() const { return zone_; }
     JS::CompartmentOptions &options() { return options_; }
     const JS::CompartmentOptions &options() const { return options_; }
 
     /*
      * Nb: global_ might be NULL, if (a) it's the atoms compartment, or (b) the