Bug 1289610 - Don't discard Baseline code in ~AutoClearTypeInferenceStateOnOOM. r=bhackett, a=gchang
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 17 Nov 2016 10:30:49 +0100
changeset 352611 10a8d1be0861e5b39aa1a78624a7b66e72a66719
parent 352610 08b67f1167751fd9cde52cd0f3da8da46e65426e
child 352612 2e61912b522799a315b45da0f648f76ad4874287
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett, gchang
bugs1289610
milestone52.0a2
Bug 1289610 - Don't discard Baseline code in ~AutoClearTypeInferenceStateOnOOM. r=bhackett, a=gchang
js/src/gc/Zone.cpp
js/src/gc/Zone.h
js/src/vm/TypeInference.cpp
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -199,45 +199,48 @@ Zone::sweepBreakpoints(FreeOp* fop)
 void
 Zone::sweepWeakMaps()
 {
     /* Finalize unreachable (key,value) pairs in all weak maps. */
     WeakMapBase::sweepZone(this);
 }
 
 void
-Zone::discardJitCode(FreeOp* fop)
+Zone::discardJitCode(FreeOp* fop, bool discardBaselineCode)
 {
     if (!jitZone())
         return;
 
     if (isPreservingCode()) {
         PurgeJITCaches(this);
     } else {
 
+        if (discardBaselineCode) {
 #ifdef DEBUG
-        /* Assert no baseline scripts are marked as active. */
-        for (auto script = cellIter<JSScript>(); !script.done(); script.next())
-            MOZ_ASSERT_IF(script->hasBaselineScript(), !script->baselineScript()->active());
+            /* Assert no baseline scripts are marked as active. */
+            for (auto script = cellIter<JSScript>(); !script.done(); script.next())
+                MOZ_ASSERT_IF(script->hasBaselineScript(), !script->baselineScript()->active());
 #endif
 
-        /* Mark baseline scripts on the stack as active. */
-        jit::MarkActiveBaselineScripts(this);
+            /* Mark baseline scripts on the stack as active. */
+            jit::MarkActiveBaselineScripts(this);
+        }
 
         /* Only mark OSI points if code is being discarded. */
         jit::InvalidateAll(fop, this);
 
         for (auto script = cellIter<JSScript>(); !script.done(); script.next())  {
             jit::FinishInvalidation(fop, script);
 
             /*
              * Discard baseline script if it's not marked as active. Note that
              * this also resets the active flag.
              */
-            jit::FinishDiscardBaselineScript(fop, script);
+            if (discardBaselineCode)
+                jit::FinishDiscardBaselineScript(fop, script);
 
             /*
              * Warm-up counter for scripts are reset on GC. After discarding code we
              * need to let it warm back up to get information such as which
              * opcodes are setting array holes or accessing getter properties.
              */
             script->resetWarmUpCounter();
         }
@@ -245,17 +248,18 @@ Zone::discardJitCode(FreeOp* fop)
         /*
          * When scripts contains pointers to nursery things, the store buffer
          * can contain entries that point into the optimized stub space. Since
          * this method can be called outside the context of a GC, this situation
          * could result in us trying to mark invalid store buffer entries.
          *
          * Defer freeing any allocated blocks until after the next minor GC.
          */
-        jitZone()->optimizedStubSpace()->freeAllAfterMinorGC(fop->runtime());
+        if (discardBaselineCode)
+            jitZone()->optimizedStubSpace()->freeAllAfterMinorGC(fop->runtime());
     }
 }
 
 #ifdef JSGC_HASH_TABLE_CHECKS
 void
 JS::Zone::checkUniqueIdTableAfterMovingGC()
 {
     for (UniqueIdMap::Enum e(uniqueIds_); !e.empty(); e.popFront())
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -140,17 +140,17 @@ struct Zone : public JS::shadow::Zone,
               public js::MallocProvider<JS::Zone>
 {
     explicit Zone(JSRuntime* rt);
     ~Zone();
     MOZ_MUST_USE bool init(bool isSystem);
 
     void findOutgoingEdges(js::gc::ZoneComponentFinder& finder);
 
-    void discardJitCode(js::FreeOp* fop);
+    void discardJitCode(js::FreeOp* fop, bool discardBaselineCode = true);
 
     void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
                                 size_t* typePool,
                                 size_t* baselineStubsOptimized,
                                 size_t* uniqueIdMap,
                                 size_t* shapeTables);
 
     void resetGCMallocBytes();
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -4516,17 +4516,17 @@ TypeZone::clearAllNewScriptsOnOOM()
 }
 
 AutoClearTypeInferenceStateOnOOM::~AutoClearTypeInferenceStateOnOOM()
 {
     if (oom) {
         JSRuntime* rt = zone->runtimeFromMainThread();
         js::CancelOffThreadIonCompile(rt);
         zone->setPreservingCode(false);
-        zone->discardJitCode(rt->defaultFreeOp());
+        zone->discardJitCode(rt->defaultFreeOp(), /* discardBaselineCode = */ false);
         zone->types.clearAllNewScriptsOnOOM();
     }
 }
 
 #ifdef DEBUG
 void
 TypeScript::printTypes(JSContext* cx, HandleScript script) const
 {