Bug 875661 - Followup: fix ggc bustage. (r=terrence)
authorShu-yu Guo <shu@rfrn.org>
Thu, 20 Jun 2013 17:39:24 -0700
changeset 135932 9695f620df742ab9ee758163dd2b24b2d53693e9
parent 135931 16ddd7268abc50388dbfe2860c815d73ecff4fa7
child 135933 d33262333925bb94d46d986d9fc2052aeefd65ae
push id24856
push useremorley@mozilla.com
push dateFri, 21 Jun 2013 14:42:16 +0000
treeherdermozilla-central@61c3c8b85563 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs875661
milestone24.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 875661 - Followup: fix ggc bustage. (r=terrence)
js/src/gc/Nursery.cpp
js/src/gc/Zone.h
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jsgcinlines.h
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -326,45 +326,45 @@ js::Nursery::moveSlotsToTenured(JSObject
     if (!src->hasDynamicSlots())
         return 0;
 
     if (!isInside(src->slots)) {
         hugeSlots.remove(src->slots);
         return 0;
     }
 
-    Allocator *alloc = &src->zone()->allocator;
+    Zone *zone = src->zone();
     size_t count = src->numDynamicSlots();
-    dst->slots = alloc->pod_malloc<HeapSlot>(count);
+    dst->slots = zone->pod_malloc<HeapSlot>(count);
     PodCopy(dst->slots, src->slots, count);
     return count * sizeof(HeapSlot);
 }
 
 size_t
 js::Nursery::moveElementsToTenured(JSObject *dst, JSObject *src, AllocKind dstKind)
 {
     if (src->hasEmptyElements())
         return 0;
 
-    Allocator *alloc = &src->zone()->allocator;
+    Zone *zone = src->zone();
     ObjectElements *srcHeader = src->getElementsHeader();
     ObjectElements *dstHeader;
 
     /* TODO Bug 874151: Prefer to put element data inline if we have space. */
     if (!isInside(srcHeader)) {
         JS_ASSERT(src->elements == dst->elements);
         hugeSlots.remove(reinterpret_cast<HeapSlot*>(srcHeader));
         return 0;
     }
 
     /* ArrayBuffer stores byte-length, not Value count. */
     if (src->is<ArrayBufferObject>()) {
         size_t nbytes = sizeof(ObjectElements) + srcHeader->initializedLength;
         if (src->hasDynamicElements()) {
-            dstHeader = static_cast<ObjectElements *>(alloc->malloc_(nbytes));
+            dstHeader = static_cast<ObjectElements *>(zone->malloc_(nbytes));
             if (!dstHeader)
                 MOZ_CRASH();
         } else {
             dst->setFixedElements();
             dstHeader = dst->getElementsHeader();
         }
         js_memcpy(dstHeader, srcHeader, nbytes);
         dst->elements = dstHeader->elements();
@@ -377,17 +377,17 @@ js::Nursery::moveElementsToTenured(JSObj
     if (src->isArray() && nslots <= GetGCKindSlots(dstKind)) {
         dst->setFixedElements();
         dstHeader = dst->getElementsHeader();
         js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot));
         return nslots * sizeof(HeapSlot);
     }
 
     size_t nbytes = nslots * sizeof(HeapValue);
-    dstHeader = static_cast<ObjectElements *>(alloc->malloc_(nbytes));
+    dstHeader = static_cast<ObjectElements *>(zone->malloc_(nbytes));
     if (!dstHeader)
         MOZ_CRASH();
     js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot));
     dst->elements = dstHeader->elements();
     return nslots * sizeof(HeapSlot);
 }
 
 static bool
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -94,17 +94,19 @@ namespace JS {
  * shapes within it are alive.
  *
  * We always guarantee that a zone has at least one live compartment by refusing
  * to delete the last compartment in a live zone. (This could happen, for
  * example, if the conservative scanner marks a string in an otherwise dead
  * zone.)
  */
 
-struct Zone : private JS::shadow::Zone, public js::gc::GraphNodeBase<JS::Zone>
+struct Zone : private JS::shadow::Zone,
+              public js::gc::GraphNodeBase<JS::Zone>,
+              public js::MallocProvider<JS::Zone>
 {
     JSRuntime                    *rt;
     js::Allocator                allocator;
 
     js::CompartmentVector        compartments;
 
     bool                         hold;
 
@@ -277,16 +279,23 @@ struct Zone : private JS::shadow::Zone, 
     }
 
     bool isTooMuchMalloc() const {
         return gcMallocBytes <= 0;
      }
 
     void onTooMuchMalloc();
 
+    void *onOutOfMemory(void *p, size_t nbytes) {
+        return rt->onOutOfMemory(p, nbytes);
+    }
+    void reportAllocationOverflow() {
+        js_ReportAllocationOverflow(NULL);
+    }
+
     void markTypes(JSTracer *trc);
 
     js::types::TypeZone types;
 
     void sweep(js::FreeOp *fop, bool releaseTypes);
 
   private:
     void sweepBreakpoints(js::FreeOp *fop);
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -1535,18 +1535,24 @@ struct ThreadSafeContext : js::ContextFr
 
     bool isJSContext() const;
     JSContext *asJSContext();
 
     bool isForkJoinSlice() const;
     ForkJoinSlice *asForkJoinSlice();
 
 #ifdef JSGC_GENERATIONAL
-    inline bool hasNursery() const;
-    inline js::Nursery &nursery();
+    inline bool hasNursery() const {
+        return isJSContext();
+    }
+
+    inline js::Nursery &nursery() {
+        JS_ASSERT(hasNursery());
+        return runtime_->gcNursery;
+    }
 #endif
 
     /*
      * Allocator used when allocating GCThings on this context. If we are a
      * JSContext, this is the Zone allocator of the JSContext's zone. If we
      * are the per-thread data of a ForkJoinSlice, this is a per-thread
      * allocator.
      *
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -577,38 +577,16 @@ JSContext::setCompartment(JSCompartment 
 
 template <typename T>
 inline bool
 js::ThreadSafeContext::isInsideCurrentZone(T thing) const
 {
     return thing->isInsideZone(zone_);
 }
 
-#ifdef JSGC_GENERATIONAL
-inline bool
-js::ThreadSafeContext::hasNursery() const
-{
-    return isJSContext();
-}
-
-inline js::Nursery &
-js::ThreadSafeContext::nursery()
-{
-    JS_ASSERT(hasNursery());
-    return runtime_->gcNursery;
-}
-#endif /* JSGC_GENERATIONAL */
-
-inline js::Allocator *const
-js::ThreadSafeContext::allocator()
-{
-    JS_ASSERT_IF(isJSContext(), &asJSContext()->zone()->allocator == allocator_);
-    return allocator_;
-}
-
 inline js::AllowGC
 js::ThreadSafeContext::allowGC() const
 {
     switch (contextKind_) {
       case Context_JS:
         return CanGC;
       case Context_ForkJoin:
         return NoGC;
--- a/js/src/jsgcinlines.h
+++ b/js/src/jsgcinlines.h
@@ -42,16 +42,23 @@ struct AutoMarkInDeadZone
         zone->scheduledForDestruction = scheduled;
     }
 
   private:
     JS::Zone *zone;
     bool scheduled;
 };
 
+inline Allocator *const
+ThreadSafeContext::allocator()
+{
+    JS_ASSERT_IF(isJSContext(), &asJSContext()->zone()->allocator == allocator_);
+    return allocator_;
+}
+
 namespace gc {
 
 /* Capacity for slotsToThingKind */
 const size_t SLOTS_TO_THING_KIND_LIMIT = 17;
 
 extern const AllocKind slotsToThingKind[];
 
 /* Get the best kind to use when making an object with the given slot count. */
@@ -536,29 +543,16 @@ NewGCThing(js::ThreadSafeContext *tcx, A
 #ifdef DEBUG
     if (tcx->isJSContext()) {
         Zone *zone = tcx->asJSContext()->zone();
         JS_ASSERT_IF(t && zone->wasGCStarted() && (zone->isGCMarking() || zone->isGCSweeping()),
                      t->arenaHeader()->allocatedDuringIncremental);
     }
 #endif
 
-#if defined(JSGC_GENERATIONAL) && defined(JS_GC_ZEAL)
-    if (tcx->hasNursery()) {
-        JSContext *cx = tcx->asJSContext();
-
-        if (cx->runtime()->gcVerifyPostData &&
-            ShouldNurseryAllocate(cx->runtime()->gcVerifierNursery, kind, heap))
-        {
-            JS_ASSERT(!IsAtomsCompartment(cx->compartment()));
-            cx->runtime()->gcVerifierNursery.insertPointer(t);
-        }
-    }
-#endif
-
     return t;
 }
 
 } /* namespace gc */
 } /* namespace js */
 
 template <js::AllowGC allowGC>
 inline JSObject *