Bug 1320374: wasm: move IonCompileTask out of FunctionGenerator; r=luke
authorBenjamin Bouvier <benj@benj.me>
Tue, 29 Nov 2016 11:56:46 +0100
changeset 324706 636dbc0dc25613fb6b6f8ee670323f950b885942
parent 324705 3e47198ee2eb8a03205e0817f6dea6151c5266f1
child 324707 40642c7dbe9a33d27d987b4d568244c519423f2a
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersluke
bugs1320374
milestone53.0a1
Bug 1320374: wasm: move IonCompileTask out of FunctionGenerator; r=luke
js/src/wasm/WasmGenerator.cpp
js/src/wasm/WasmGenerator.h
js/src/wasm/WasmIonCompile.h
js/src/wasm/WasmTypes.h
--- a/js/src/wasm/WasmGenerator.cpp
+++ b/js/src/wasm/WasmGenerator.cpp
@@ -414,18 +414,20 @@ ModuleGenerator::finishTask(IonCompileTa
     funcToCodeRange_[func.index()] = funcCodeRangeIndex;
 
     // Merge the compiled results into the whole-module masm.
     mozilla::DebugOnly<size_t> sizeBefore = masm_.size();
     if (!masm_.asmMergeWith(results.masm()))
         return false;
     MOZ_ASSERT(masm_.size() == offsetInWhole + results.masm().size());
 
+    UniqueBytes recycled;
+    task->reset(&recycled);
     freeTasks_.infallibleAppend(task);
-    return true;
+    return freeBytes_.emplaceBack(Move(recycled));
 }
 
 bool
 ModuleGenerator::finishFuncExports()
 {
     // In addition to all the functions that were explicitly exported, any
     // element of an exported table is also exported.
 
@@ -850,38 +852,42 @@ ModuleGenerator::startFuncDefs()
     for (size_t i = 0; i < numTasks; i++)
         tasks_.infallibleEmplaceBack(*env_, COMPILATION_LIFO_DEFAULT_CHUNK_SIZE);
 
     if (!freeTasks_.reserve(numTasks))
         return false;
     for (size_t i = 0; i < numTasks; i++)
         freeTasks_.infallibleAppend(&tasks_[i]);
 
+    if (!freeBytes_.reserve(numTasks))
+        return false;
+    for (size_t i = 0; i < numTasks; i++)
+        freeBytes_.infallibleAppend(js::MakeUnique<Bytes>());
+
     startedFuncDefs_ = true;
     MOZ_ASSERT(!finishedFuncDefs_);
     return true;
 }
 
 bool
 ModuleGenerator::startFuncDef(uint32_t lineOrBytecode, FunctionGenerator* fg)
 {
     MOZ_ASSERT(startedFuncDefs_);
     MOZ_ASSERT(!activeFuncDef_);
     MOZ_ASSERT(!finishedFuncDefs_);
 
-    if (freeTasks_.empty() && !finishOutstandingTask())
-        return false;
+    if (!freeBytes_.empty()) {
+        fg->bytes_ = Move(freeBytes_.back());
+        freeBytes_.popBack();
+    } else {
+        fg->bytes_ = js::MakeUnique<Bytes>();
+    }
 
-    IonCompileTask* task = freeTasks_.popCopy();
-
-    task->reset(&fg->bytes_);
-    fg->bytes_.clear();
     fg->lineOrBytecode_ = lineOrBytecode;
     fg->m_ = this;
-    fg->task_ = task;
     activeFuncDef_ = fg;
     return true;
 }
 
 bool
 ModuleGenerator::finishFuncDef(uint32_t funcIndex, FunctionGenerator* fg)
 {
     MOZ_ASSERT(activeFuncDef_ == fg);
@@ -893,31 +899,34 @@ ModuleGenerator::finishFuncDef(uint32_t 
                                           Move(fg->callSiteLineNums_));
     if (!func)
         return false;
 
     auto mode = alwaysBaseline_ && BaselineCanCompile(fg)
                 ? IonCompileTask::CompileMode::Baseline
                 : IonCompileTask::CompileMode::Ion;
 
-    fg->task_->init(Move(func), mode);
+    if (freeTasks_.empty() && !finishOutstandingTask())
+        return false;
+
+    IonCompileTask* task = freeTasks_.popCopy();
+    task->init(Move(func), mode);
 
     if (parallel_) {
-        if (!StartOffThreadWasmCompile(fg->task_))
+        if (!StartOffThreadWasmCompile(task))
             return false;
         outstanding_++;
     } else {
-        if (!CompileFunction(fg->task_))
+        if (!CompileFunction(task))
             return false;
-        if (!finishTask(fg->task_))
+        if (!finishTask(task))
             return false;
     }
 
     fg->m_ = nullptr;
-    fg->task_ = nullptr;
     activeFuncDef_ = nullptr;
     numFinishedFuncDefs_++;
     return true;
 }
 
 bool
 ModuleGenerator::finishFuncDefs()
 {
--- a/js/src/wasm/WasmGenerator.h
+++ b/js/src/wasm/WasmGenerator.h
@@ -25,16 +25,18 @@
 
 namespace js {
 namespace wasm {
 
 struct CompileArgs;
 
 class FunctionGenerator;
 
+typedef Vector<UniqueBytes, 0, SystemAllocPolicy> UniqueBytesVector;
+
 // A ModuleGenerator encapsulates the creation of a wasm module. During the
 // lifetime of a ModuleGenerator, a sequence of FunctionGenerators are created
 // and destroyed to compile the individual function bodies. After generating all
 // functions, ModuleGenerator::finish() must be called to complete the
 // compilation and extract the resulting wasm module.
 
 class MOZ_STACK_CLASS ModuleGenerator
 {
@@ -64,16 +66,17 @@ class MOZ_STACK_CLASS ModuleGenerator
     uint32_t                        lastPatchedCallsite_;
     uint32_t                        startOfUnpatchedCallsites_;
 
     // Parallel compilation
     bool                            parallel_;
     uint32_t                        outstanding_;
     IonCompileTaskVector            tasks_;
     IonCompileTaskPtrVector         freeTasks_;
+    UniqueBytesVector               freeBytes_;
 
     // Assertions
     DebugOnly<FunctionGenerator*>   activeFuncDef_;
     DebugOnly<bool>                 startedFuncDefs_;
     DebugOnly<bool>                 finishedFuncDefs_;
     DebugOnly<uint32_t>             numFinishedFuncDefs_;
 
     bool funcIsCompiled(uint32_t funcIndex) const;
@@ -154,30 +157,29 @@ class MOZ_STACK_CLASS ModuleGenerator
 // be called before the FunctionGenerator is destroyed and the next function is
 // started.
 
 class MOZ_STACK_CLASS FunctionGenerator
 {
     friend class ModuleGenerator;
 
     ModuleGenerator* m_;
-    IonCompileTask*  task_;
     bool             usesSimd_;
     bool             usesAtomics_;
 
     // Data created during function generation, then handed over to the
     // FuncBytes in ModuleGenerator::finishFunc().
-    Bytes            bytes_;
+    UniqueBytes      bytes_;
     Uint32Vector     callSiteLineNums_;
 
     uint32_t lineOrBytecode_;
 
   public:
     FunctionGenerator()
-      : m_(nullptr), task_(nullptr), usesSimd_(false), usesAtomics_(false), lineOrBytecode_(0)
+      : m_(nullptr), usesSimd_(false), usesAtomics_(false), bytes_(nullptr), lineOrBytecode_(0)
     {}
 
     bool usesSimd() const {
         return usesSimd_;
     }
     void setUsesSimd() {
         usesSimd_ = true;
     }
@@ -185,17 +187,17 @@ class MOZ_STACK_CLASS FunctionGenerator
     bool usesAtomics() const {
         return usesAtomics_;
     }
     void setUsesAtomics() {
         usesAtomics_ = true;
     }
 
     Bytes& bytes() {
-        return bytes_;
+        return *bytes_;
     }
     MOZ_MUST_USE bool addCallSiteLineNum(uint32_t lineno) {
         return callSiteLineNums_.append(lineno);
     }
 };
 
 } // namespace wasm
 } // namespace js
--- a/js/src/wasm/WasmIonCompile.h
+++ b/js/src/wasm/WasmIonCompile.h
@@ -32,37 +32,38 @@ typedef jit::ABIArgIter<MIRTypeVector> A
 typedef jit::ABIArgIter<ValTypeVector> ABIArgValTypeIter;
 
 // The FuncBytes class represents a single, concurrently-compilable function.
 // A FuncBytes object is composed of the wasm function body bytes along with the
 // ambient metadata describing the function necessary to compile it.
 
 class FuncBytes
 {
-    Bytes            bytes_;
+    UniqueBytes      bytes_;
     uint32_t         index_;
     const SigWithId& sig_;
     uint32_t         lineOrBytecode_;
     Uint32Vector     callSiteLineNums_;
 
   public:
-    FuncBytes(Bytes&& bytes,
+    FuncBytes(UniqueBytes bytes,
               uint32_t index,
               const SigWithId& sig,
               uint32_t lineOrBytecode,
               Uint32Vector&& callSiteLineNums)
       : bytes_(Move(bytes)),
         index_(index),
         sig_(sig),
         lineOrBytecode_(lineOrBytecode),
         callSiteLineNums_(Move(callSiteLineNums))
     {}
 
-    Bytes& bytes() { return bytes_; }
-    const Bytes& bytes() const { return bytes_; }
+    Bytes& bytes() { return *bytes_; }
+    const Bytes& bytes() const { return *bytes_; }
+    UniqueBytes recycle() { return Move(bytes_); }
     uint32_t index() const { return index_; }
     const SigWithId& sig() const { return sig_; }
     uint32_t lineOrBytecode() const { return lineOrBytecode_; }
     const Uint32Vector& callSiteLineNums() const { return callSiteLineNums_; }
 };
 
 typedef UniquePtr<FuncBytes> UniqueFuncBytes;
 
@@ -132,19 +133,21 @@ class IonCompileTask
     }
     const FuncBytes& func() const {
         MOZ_ASSERT(func_);
         return *func_;
     }
     FuncCompileResults& results() {
         return *results_;
     }
-    void reset(Bytes* recycled) {
-        if (func_)
-            *recycled = Move(func_->bytes());
+    void reset(UniqueBytes* recycled) {
+        if (func_) {
+            *recycled = Move(func_->recycle());
+            (*recycled)->clear();
+        }
         func_.reset(nullptr);
         results_.reset();
         lifo_.releaseAll();
         mode_ = CompileMode::None;
     }
 };
 
 MOZ_MUST_USE bool
--- a/js/src/wasm/WasmTypes.h
+++ b/js/src/wasm/WasmTypes.h
@@ -78,16 +78,17 @@ using mozilla::PodZero;
 using mozilla::PodCopy;
 using mozilla::PodEqual;
 using mozilla::RefCounted;
 using mozilla::Some;
 using mozilla::Unused;
 
 typedef Vector<uint32_t, 0, SystemAllocPolicy> Uint32Vector;
 typedef Vector<uint8_t, 0, SystemAllocPolicy> Bytes;
+typedef UniquePtr<Bytes> UniqueBytes;
 
 typedef int8_t I8x16[16];
 typedef int16_t I16x8[8];
 typedef int32_t I32x4[4];
 typedef float F32x4[4];
 
 class Code;
 class CodeRange;