Bug 1298356 - Remove possibility of GC in Nursery::queueSweepAction and crash on alloc failure r=terrence
authorShu-yu Guo <shu@rfrn.org>
Wed, 07 Sep 2016 11:30:50 +0100
changeset 354297 cef1721594bf04fb708e6fb1f5a4d80722443b02
parent 354296 488c4ea38e16888e9ab439f5ef0f258252597848
child 354298 f590934ef71f3fb00a7339c992677eda891d3705
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1298356
milestone51.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 1298356 - Remove possibility of GC in Nursery::queueSweepAction and crash on alloc failure r=terrence
js/src/gc/Nursery.cpp
js/src/jit-test/tests/gc/bug-1298356.js
js/src/vm/Runtime.h
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -948,28 +948,23 @@ js::Nursery::updateNumChunksLocked(unsig
     }
 }
 
 void
 js::Nursery::queueSweepAction(SweepThunk thunk, void* data)
 {
     static_assert(sizeof(SweepAction) % CellSize == 0,
                   "SweepAction size must be a multiple of cell size");
-    MOZ_ASSERT(!runtime()->mainThread.suppressGC);
 
-    SweepAction* action = nullptr;
-    if (isEnabled() && !js::oom::ShouldFailWithOOM())
-        action = reinterpret_cast<SweepAction*>(allocate(sizeof(SweepAction)));
+    MOZ_ASSERT(isEnabled());
 
-    if (!action) {
-        runtime()->gc.evictNursery();
-        AutoSetThreadIsSweeping threadIsSweeping;
-        thunk(data);
-        return;
-    }
+    AutoEnterOOMUnsafeRegion oomUnsafe;
+    auto action = reinterpret_cast<SweepAction*>(allocate(sizeof(SweepAction)));
+    if (!action)
+        oomUnsafe.crash("Nursery::queueSweepAction");
 
     new (action) SweepAction(thunk, data, sweepActions_);
     sweepActions_ = action;
 }
 
 void
 js::Nursery::runSweepActions()
 {
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1298356.js
@@ -0,0 +1,4 @@
+/x/;
+oomTest(function(){
+    offThreadCompileScript('');
+})
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -1649,17 +1649,17 @@ struct MOZ_RAII AutoSetThreadIsSweeping
  * queue to be destroyed at a safe time.
  */
 template <typename T>
 struct GCManagedDeletePolicy
 {
     void operator()(const T* ptr) {
         if (ptr) {
             JSRuntime* rt = TlsPerThreadData.get()->runtimeIfOnOwnerThread();
-            if (rt) {
+            if (rt && rt->gc.nursery.isEnabled()) {
                 // The object may contain nursery pointers and must only be
                 // destroyed after a minor GC.
                 rt->gc.callAfterMinorGC(deletePtr, const_cast<T*>(ptr));
             } else {
                 // The object cannot contain nursery pointers so can be
                 // destroyed immediately.
                 gc::AutoSetThreadIsSweeping threadIsSweeping;
                 js_delete(const_cast<T*>(ptr));