Bug 1325200 part 3 - Discard regexp/constructor code on GC. r=bhackett
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 12 Jan 2017 17:06:45 +0100
changeset 329157 ee94a9d6cc1c13b82d58bc2198d5e61ddf9311fb
parent 329156 daa9f9d628b6fbaac647a344b4d91d0bdbb16724
child 329158 c1cc2ba83430b30483bc764b96c8a94e5a12e0a2
push id31199
push userkwierso@gmail.com
push dateFri, 13 Jan 2017 00:03:35 +0000
treeherdermozilla-central@b1c31c4a0a67 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs1325200
milestone53.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 1325200 part 3 - Discard regexp/constructor code on GC. r=bhackett
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpObject.h
js/src/vm/TypeInference.cpp
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -1287,26 +1287,37 @@ RegExpShared::needsSweep(JSRuntime* rt)
         clearMarked();
         return false;
     }
 
     return true;
 }
 
 void
+RegExpShared::discardJitCode()
+{
+    for (size_t i = 0; i < ArrayLength(compilationArray); i++)
+        compilationArray[i].jitCode = nullptr;
+}
+
+void
 RegExpCompartment::sweep(JSRuntime* rt)
 {
     if (!set_.initialized())
         return;
 
     for (Set::Enum e(set_); !e.empty(); e.popFront()) {
         RegExpShared* shared = e.front();
         if (shared->needsSweep(rt)) {
             js_delete(shared);
             e.removeFront();
+        } else {
+            // Discard code to avoid holding onto ExecutablePools.
+            if (rt->gc.isHeapCompacting())
+                shared->discardJitCode();
         }
     }
 
     if (matchResultTemplateObject_ &&
         IsAboutToBeFinalized(&matchResultTemplateObject_))
     {
         matchResultTemplateObject_.set(nullptr);
     }
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -200,16 +200,17 @@ class RegExpShared
     }
     bool isCompiled() const {
         return isCompiled(Normal, true) || isCompiled(Normal, false)
             || isCompiled(MatchOnly, true) || isCompiled(MatchOnly, false);
     }
 
     void trace(JSTracer* trc);
     bool needsSweep(JSRuntime* rt);
+    void discardJitCode();
 
     bool marked() const { return marked_; }
     void clearMarked() { marked_ = false; }
 
     static size_t offsetOfSource() {
         return offsetof(RegExpShared, source);
     }
 
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -4282,16 +4282,20 @@ ObjectGroup::sweep(AutoClearTypeInferenc
         // Remove unboxed layouts that are about to be finalized from the
         // compartment wide list while we are still on the main thread.
         ObjectGroup* group = this;
         if (IsAboutToBeFinalizedUnbarriered(&group))
             unboxedLayout().detachFromCompartment();
 
         if (unboxedLayout().newScript())
             unboxedLayout().newScript()->sweep();
+
+        // Discard constructor code to avoid holding onto ExecutablePools.
+        if (zone()->isGCCompacting())
+            unboxedLayout().setConstructorCode(nullptr);
     }
 
     if (maybePreliminaryObjects())
         maybePreliminaryObjects()->sweep();
 
     if (newScript())
         newScript()->sweep();