Bug 1345177 - Give RegExpShared a finalizer r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 28 Mar 2017 11:51:18 +0100
changeset 350108 4fd1e9b734b931691a5a849482bff0b05fe1ef4f
parent 350107 9fdc31fe714ad67bb66ec2613429d8519624fbb0
child 350109 9fd2650f5db0f9c28070fb570cc987045d4db9f3
push id31568
push userkwierso@gmail.com
push dateTue, 28 Mar 2017 20:31:07 +0000
treeherdermozilla-central@272ce6c25721 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1345177
milestone55.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 1345177 - Give RegExpShared a finalizer r=sfink
js/src/gc/Heap.h
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpObject.h
--- a/js/src/gc/Heap.h
+++ b/js/src/gc/Heap.h
@@ -310,19 +310,16 @@ class TenuredCell : public Cell
     }
 
     static MOZ_ALWAYS_INLINE void readBarrier(TenuredCell* thing);
     static MOZ_ALWAYS_INLINE void writeBarrierPre(TenuredCell* thing);
 
     static MOZ_ALWAYS_INLINE void writeBarrierPost(void* cellp, TenuredCell* prior,
                                                    TenuredCell* next);
 
-    // Default implementation for kinds that don't require finalization.
-    void finalize(FreeOp* fop) {}
-
     // Default implementation for kinds that don't require fixup.
     void fixupAfterMovingGC() {}
 
 #ifdef DEBUG
     inline bool isAligned() const;
 #endif
 };
 
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -942,22 +942,16 @@ js::StringHasRegExpMetaChars(JSLinearStr
 }
 
 /* RegExpShared */
 
 RegExpShared::RegExpShared(JSAtom* source, RegExpFlag flags)
   : source(source), flags(flags), canStringMatch(false), parenCount(0)
 {}
 
-RegExpShared::~RegExpShared()
-{
-    for (size_t i = 0; i < tables.length(); i++)
-        js_delete(tables[i]);
-}
-
 void
 RegExpShared::traceChildren(JSTracer* trc)
 {
     // Discard code to avoid holding onto ExecutablePools.
     if (IsMarkingTrace(trc) && trc->runtime()->gc.isShrinkingGC())
         discardJitCode();
 
     TraceNullableEdge(trc, &source, "RegExpShared source");
@@ -967,16 +961,24 @@ RegExpShared::traceChildren(JSTracer* tr
 
 void
 RegExpShared::discardJitCode()
 {
     for (auto& comp : compilationArray)
         comp.jitCode = nullptr;
 }
 
+void
+RegExpShared::finalize(FreeOp* fop)
+{
+    for (size_t i = 0; i < tables.length(); i++)
+        js_free(tables[i]);
+    tables.~JitCodeTables();
+}
+
 /* static */ bool
 RegExpShared::compile(JSContext* cx, MutableHandleRegExpShared re, HandleLinearString input,
                       CompilationMode mode, ForceByteCodeEnum force)
 {
     TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx);
     AutoTraceLog logCompile(logger, TraceLogger_IrregexpCompile);
 
     RootedAtom pattern(cx, re->source);
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -139,17 +139,18 @@ class RegExpShared : public gc::TenuredC
         switch (mode) {
           case Normal:    return latin1 ? 0 : 1;
           case MatchOnly: return latin1 ? 2 : 3;
         }
         MOZ_CRASH();
     }
 
     // Tables referenced by JIT code.
-    Vector<uint8_t*, 0, SystemAllocPolicy> tables;
+    using JitCodeTables = Vector<uint8_t*, 0, SystemAllocPolicy>;
+    JitCodeTables tables;
 
     /* Internal functions. */
     RegExpShared(JSAtom* source, RegExpFlag flags);
 
     static bool compile(JSContext* cx, MutableHandleRegExpShared res, HandleLinearString input,
                         CompilationMode mode, ForceByteCodeEnum force);
     static bool compile(JSContext* cx, MutableHandleRegExpShared res, HandleAtom pattern,
                         HandleLinearString input, CompilationMode mode, ForceByteCodeEnum force);
@@ -162,17 +163,17 @@ class RegExpShared : public gc::TenuredC
         return compilationArray[CompilationIndex(mode, latin1)];
     }
 
     RegExpCompilation& compilation(CompilationMode mode, bool latin1) {
         return compilationArray[CompilationIndex(mode, latin1)];
     }
 
   public:
-    ~RegExpShared();
+    ~RegExpShared() = delete;
 
     // Execute this RegExp on input starting from searchIndex, filling in
     // matches if specified and otherwise only determining if there is a match.
     static RegExpRunStatus execute(JSContext* cx, MutableHandleRegExpShared res,
                                    HandleLinearString input, size_t searchIndex,
                                    MatchPairs* matches, size_t* endIndex);
 
     // Register a table with this RegExpShared, and take ownership.
@@ -204,16 +205,17 @@ class RegExpShared : public gc::TenuredC
     }
     bool isCompiled() const {
         return isCompiled(Normal, true) || isCompiled(Normal, false)
             || isCompiled(MatchOnly, true) || isCompiled(MatchOnly, false);
     }
 
     void traceChildren(JSTracer* trc);
     void discardJitCode();
+    void finalize(FreeOp* fop);
 
     static size_t offsetOfSource() {
         return offsetof(RegExpShared, source);
     }
 
     static size_t offsetOfFlags() {
         return offsetof(RegExpShared, flags);
     }