Bug 1282113 - When we're shutting down the runtime, only allow shutdown GCs. r=terrence
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 28 Jun 2016 11:56:08 +0200
changeset 302863 bc6e009a06d2683fbee66e8806eb8c993aabfe96
parent 302862 cbf85303aeb2cea6326574a39db03dad860b578f
child 302864 22dded92077567a244d017b412ab2cdd9aa682a1
push id19791
push usercbook@mozilla.com
push dateTue, 28 Jun 2016 14:15:17 +0000
treeherderfx-team@e774866bf8a1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1282113
milestone50.0a1
Bug 1282113 - When we're shutting down the runtime, only allow shutdown GCs. r=terrence
devtools/client/locales/en-US/markers.properties
js/public/GCAPI.h
js/src/doc/Debugger/Debugger.Memory.md
js/src/jit-test/tests/gc/bug1282113.js
js/src/jsgc.cpp
--- a/devtools/client/locales/en-US/markers.properties
+++ b/devtools/client/locales/en-US/markers.properties
@@ -98,17 +98,16 @@ marker.value.DOMEventTargetPhase=Target
 marker.value.DOMEventCapturingPhase=Capture
 marker.value.DOMEventBubblingPhase=Bubbling
 
 # LOCALIZATION NOTE (marker.gcreason.label.*):
 # These strings are used to give a concise but readable description of a GC reason.
 marker.gcreason.label.API=API Call
 marker.gcreason.label.EAGER_ALLOC_TRIGGER=Eager Allocation Trigger
 marker.gcreason.label.DESTROY_RUNTIME=Shutdown
-marker.gcreason.label.DESTROY_CONTEXT=Shutdown
 marker.gcreason.label.LAST_DITCH=Out of Memory
 marker.gcreason.label.TOO_MUCH_MALLOC=Too Many Bytes Allocated
 marker.gcreason.label.ALLOC_TRIGGER=Too Many Allocations
 marker.gcreason.label.DEBUG_GC=Debug GC
 marker.gcreason.label.COMPARTMENT_REVIVED=Dead Global Revived
 marker.gcreason.label.RESET=Finish Incremental Cycle
 marker.gcreason.label.OUT_OF_NURSERY=Nursery is Full
 marker.gcreason.label.EVICT_NURSERY=Nursery Eviction
@@ -138,17 +137,16 @@ marker.gcreason.label.USER_INACTIVE=User
 # The name of a nursery collection.
 marker.nurseryCollection=Nursery Collection
 
 # LOCALIZATION NOTE (marker.gcreason.description.*):
 # These strings are used to give an expanded description of why a GC occurred.
 marker.gcreason.description.API=There was an API call to force garbage collection.
 marker.gcreason.description.EAGER_ALLOC_TRIGGER=JavaScript returned to the event loop and there were enough bytes allocated since the last GC that a new GC cycle was triggered.
 marker.gcreason.description.DESTROY_RUNTIME=Firefox destroyed a JavaScript runtime or context, and this was the final garbage collection before shutting down.
-marker.gcreason.description.DESTROY_CONTEXT=Firefox destroyed a JavaScript runtime or context, and this was the final garbage collection before shutting down.
 marker.gcreason.description.LAST_DITCH=JavaScript attempted to allocate, but there was no memory available. Doing a full compacting garbage collection as an attempt to free up memory for the allocation.
 marker.gcreason.description.TOO_MUCH_MALLOC=JavaScript allocated too many bytes, and forced a garbage collection.
 marker.gcreason.description.ALLOC_TRIGGER=JavaScript allocated too many times, and forced a garbage collection.
 marker.gcreason.description.DEBUG_GC=GC due to Zeal debug settings.
 marker.gcreason.description.COMPARTMENT_REVIVED=A global object that was thought to be dead at the start of the GC cycle was revived by the end of the GC cycle.
 marker.gcreason.description.RESET=The active incremental GC cycle was forced to finish immediately.
 marker.gcreason.description.OUT_OF_NURSERY=JavaScript allocated enough new objects in the nursery that it became full and triggered a minor GC.
 marker.gcreason.description.EVICT_NURSERY=Work needed to be done on the tenured heap, requiring the nursery to be empty.
--- a/js/public/GCAPI.h
+++ b/js/public/GCAPI.h
@@ -49,17 +49,17 @@ typedef enum JSGCInvocationKind {
 
 namespace JS {
 
 #define GCREASONS(D)                            \
     /* Reasons internal to the JS engine */     \
     D(API)                                      \
     D(EAGER_ALLOC_TRIGGER)                      \
     D(DESTROY_RUNTIME)                          \
-    D(DESTROY_CONTEXT)                          \
+    D(UNUSED0)                                  \
     D(LAST_DITCH)                               \
     D(TOO_MUCH_MALLOC)                          \
     D(ALLOC_TRIGGER)                            \
     D(DEBUG_GC)                                 \
     D(COMPARTMENT_REVIVED)                      \
     D(RESET)                                    \
     D(OUT_OF_NURSERY)                           \
     D(EVICT_NURSERY)                            \
--- a/js/src/doc/Debugger/Debugger.Memory.md
+++ b/js/src/doc/Debugger/Debugger.Memory.md
@@ -156,17 +156,16 @@ compartment.
 
     `reason`
     :   A very short string describing the reason why the collection was
         triggered. Known values include the following:
 
         * "API"
         * "EAGER_ALLOC_TRIGGER"
         * "DESTROY_RUNTIME"
-        * "DESTROY_CONTEXT"
         * "LAST_DITCH"
         * "TOO_MUCH_MALLOC"
         * "ALLOC_TRIGGER"
         * "DEBUG_GC"
         * "COMPARTMENT_REVIVED"
         * "RESET"
         * "OUT_OF_NURSERY"
         * "EVICT_NURSERY"
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug1282113.js
@@ -0,0 +1,6 @@
+Object.getOwnPropertyNames(this);
+setGCCallback({
+    action: "majorGC",
+    phases: "begin"
+});
+selectforgc(this);
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -6275,16 +6275,21 @@ GCRuntime::checkCanCallAPI()
 }
 
 bool
 GCRuntime::checkIfGCAllowedInCurrentState(JS::gcreason::Reason reason)
 {
     if (rt->mainThread.suppressGC)
         return false;
 
+    // Only allow shutdown GCs when we're destroying the runtime. This keeps
+    // the GC callback from triggering a nested GC and resetting global state.
+    if (rt->isBeingDestroyed() && !IsShutdownGC(reason))
+        return false;
+
 #ifdef JS_GC_ZEAL
     if (deterministicOnly && !IsDeterministicGCReason(reason))
         return false;
 #endif
 
     return true;
 }