Bug 1320374: Rename IonCompileTask to CompileTask and {Compile,Instantiate}Task to {1}PromiseTask; r=luke
authorBenjamin Bouvier <benj@benj.me>
Fri, 25 Nov 2016 17:52:44 +0100
changeset 324707 40642c7dbe9a33d27d987b4d568244c519423f2a
parent 324706 636dbc0dc25613fb6b6f8ee670323f950b885942
child 324708 9d270fe2298bc780b33b76093bc0e87a4bd94fae
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersluke
bugs1320374
milestone53.0a1
Bug 1320374: Rename IonCompileTask to CompileTask and {Compile,Instantiate}Task to {1}PromiseTask; r=luke MozReview-Commit-ID: 1KtWxpjGWxv
js/src/vm/HelperThreads.cpp
js/src/vm/HelperThreads.h
js/src/wasm/WasmBaselineCompile.cpp
js/src/wasm/WasmBaselineCompile.h
js/src/wasm/WasmGenerator.cpp
js/src/wasm/WasmGenerator.h
js/src/wasm/WasmIonCompile.cpp
js/src/wasm/WasmIonCompile.h
js/src/wasm/WasmJS.cpp
js/src/wasm/WasmStubs.cpp
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -15,17 +15,16 @@
 #include "builtin/Promise.h"
 #include "frontend/BytecodeCompiler.h"
 #include "gc/GCInternals.h"
 #include "jit/IonBuilder.h"
 #include "vm/Debugger.h"
 #include "vm/SharedImmutableStringsCache.h"
 #include "vm/Time.h"
 #include "vm/TraceLogging.h"
-#include "wasm/WasmIonCompile.h"
 
 #include "jscntxtinlines.h"
 #include "jscompartmentinlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 using namespace js;
 
@@ -79,17 +78,17 @@ js::SetFakeCPUCount(size_t count)
     // This must be called before the threads have been initialized.
     MOZ_ASSERT(!HelperThreadState().threads);
 
     HelperThreadState().cpuCount = count;
     HelperThreadState().threadCount = ThreadCountForCPUCount(count);
 }
 
 bool
-js::StartOffThreadWasmCompile(wasm::IonCompileTask* task)
+js::StartOffThreadWasmCompile(wasm::CompileTask* task)
 {
     AutoLockHelperThreadState lock;
 
     // Don't append this task if another failed.
     if (HelperThreadState().wasmFailed(lock))
         return false;
 
     if (!HelperThreadState().wasmWorklist(lock).append(task))
@@ -915,17 +914,17 @@ bool
 GlobalHelperThreadState::canStartWasmCompile(const AutoLockHelperThreadState& lock)
 {
     // Don't execute an wasm job if an earlier one failed.
     if (wasmWorklist(lock).empty() || numWasmFailedJobs)
         return false;
 
     // Honor the maximum allowed threads to compile wasm jobs at once,
     // to avoid oversaturating the machine.
-    if (!checkTaskThreadLimit<wasm::IonCompileTask*>(maxWasmCompilationThreads()))
+    if (!checkTaskThreadLimit<wasm::CompileTask*>(maxWasmCompilationThreads()))
         return false;
 
     return true;
 }
 
 bool
 GlobalHelperThreadState::canStartPromiseTask(const AutoLockHelperThreadState& lock)
 {
@@ -1414,17 +1413,17 @@ void
 HelperThread::handleWasmWorkload(AutoLockHelperThreadState& locked)
 {
     MOZ_ASSERT(HelperThreadState().canStartWasmCompile(locked));
     MOZ_ASSERT(idle());
 
     currentTask.emplace(HelperThreadState().wasmWorklist(locked).popCopy());
     bool success = false;
 
-    wasm::IonCompileTask* task = wasmTask();
+    wasm::CompileTask* task = wasmTask();
     {
         AutoUnlockHelperThreadState unlock(locked);
         success = wasm::CompileFunction(task);
     }
 
     // On success, try to move work to the finished list.
     if (success)
         success = HelperThreadState().wasmFinishedList(locked).append(task);
--- a/js/src/vm/HelperThreads.h
+++ b/js/src/vm/HelperThreads.h
@@ -8,16 +8,17 @@
  * Definitions for managing off-main-thread work using a process wide list
  * of worklist items and pool of threads. Worklist items are engine internal,
  * and are distinct from e.g. web workers.
  */
 
 #ifndef vm_HelperThreads_h
 #define vm_HelperThreads_h
 
+#include "mozilla/Attributes.h"
 #include "mozilla/GuardObjects.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Variant.h"
 
 #include "jscntxt.h"
 
 #include "frontend/TokenStream.h"
@@ -37,18 +38,18 @@ class PromiseTask;
 struct HelperThread;
 struct ParseTask;
 namespace jit {
   class IonBuilder;
 } // namespace jit
 namespace wasm {
   class FuncIR;
   class FunctionCompileResults;
-  class IonCompileTask;
-  typedef Vector<IonCompileTask*, 0, SystemAllocPolicy> IonCompileTaskPtrVector;
+  class CompileTask;
+  typedef Vector<CompileTask*, 0, SystemAllocPolicy> CompileTaskPtrVector;
 } // namespace wasm
 
 enum class ParseTaskKind
 {
     Script,
     Module
 };
 
@@ -79,17 +80,17 @@ class GlobalHelperThreadState
 
   private:
     // The lists below are all protected by |lock|.
 
     // Ion compilation worklist and finished jobs.
     IonBuilderVector ionWorklist_, ionFinishedList_;
 
     // wasm worklist and finished jobs.
-    wasm::IonCompileTaskPtrVector wasmWorklist_, wasmFinishedList_;
+    wasm::CompileTaskPtrVector wasmWorklist_, wasmFinishedList_;
 
   public:
     // For now, only allow a single parallel wasm compilation to happen at a
     // time. This avoids race conditions on wasmWorklist/wasmFinishedList/etc.
     mozilla::Atomic<bool> wasmCompilationInProgress;
 
   private:
     // Async tasks that, upon completion, are dispatched back to the JSContext's
@@ -158,20 +159,20 @@ class GlobalHelperThreadState
 
     IonBuilderVector& ionWorklist(const AutoLockHelperThreadState&) {
         return ionWorklist_;
     }
     IonBuilderVector& ionFinishedList(const AutoLockHelperThreadState&) {
         return ionFinishedList_;
     }
 
-    wasm::IonCompileTaskPtrVector& wasmWorklist(const AutoLockHelperThreadState&) {
+    wasm::CompileTaskPtrVector& wasmWorklist(const AutoLockHelperThreadState&) {
         return wasmWorklist_;
     }
-    wasm::IonCompileTaskPtrVector& wasmFinishedList(const AutoLockHelperThreadState&) {
+    wasm::CompileTaskPtrVector& wasmFinishedList(const AutoLockHelperThreadState&) {
         return wasmFinishedList_;
     }
 
     PromiseTaskVector& promiseTasks(const AutoLockHelperThreadState&) {
         return promiseTasks_;
     }
 
     ParseTaskVector& parseWorklist(const AutoLockHelperThreadState&) {
@@ -303,35 +304,35 @@ struct HelperThread
      * Indicate to a thread that it should pause execution. This is only
      * written with the helper thread state lock held, but may be read from
      * without the lock held.
      */
     mozilla::Atomic<bool, mozilla::Relaxed> pause;
 
     /* The current task being executed by this thread, if any. */
     mozilla::Maybe<mozilla::Variant<jit::IonBuilder*,
-                                    wasm::IonCompileTask*,
+                                    wasm::CompileTask*,
                                     PromiseTask*,
                                     ParseTask*,
                                     SourceCompressionTask*,
                                     GCHelperState*,
                                     GCParallelTask*>> currentTask;
 
     bool idle() const {
         return currentTask.isNothing();
     }
 
     /* Any builder currently being compiled by Ion on this thread. */
     jit::IonBuilder* ionBuilder() {
         return maybeCurrentTaskAs<jit::IonBuilder*>();
     }
 
     /* Any wasm data currently being optimized on this thread. */
-    wasm::IonCompileTask* wasmTask() {
-        return maybeCurrentTaskAs<wasm::IonCompileTask*>();
+    wasm::CompileTask* wasmTask() {
+        return maybeCurrentTaskAs<wasm::CompileTask*>();
     }
 
     /* Any source being parsed/emitted on this thread. */
     ParseTask* parseTask() {
         return maybeCurrentTaskAs<ParseTask*>();
     }
 
     /* Any source being compressed on this thread. */
@@ -390,19 +391,27 @@ EnsureHelperThreadsInitialized();
 // --thread-count=N option.
 void
 SetFakeCPUCount(size_t count);
 
 // Pause the current thread until it's pause flag is unset.
 void
 PauseCurrentHelperThread();
 
-/* Perform MIR optimization and LIR generation on a single function. */
+// Enqueues a wasm compilation task.
 bool
-StartOffThreadWasmCompile(wasm::IonCompileTask* task);
+StartOffThreadWasmCompile(wasm::CompileTask* task);
+
+namespace wasm {
+
+// Performs MIR optimization and LIR generation on one or several functions.
+MOZ_MUST_USE bool
+CompileFunction(CompileTask* task);
+
+}
 
 /*
  * If helper threads are available, start executing the given PromiseTask on a
  * helper thread, finishing back on the originating JSContext's owner thread. If
  * no helper threads are available, the PromiseTask is synchronously executed
  * and finished.
  */
 bool
--- a/js/src/wasm/WasmBaselineCompile.cpp
+++ b/js/src/wasm/WasmBaselineCompile.cpp
@@ -7597,19 +7597,19 @@ js::wasm::BaselineCanCompile(const Funct
 
     return true;
 #else
     return false;
 #endif
 }
 
 bool
-js::wasm::BaselineCompileFunction(IonCompileTask* task)
-{
-    MOZ_ASSERT(task->mode() == IonCompileTask::CompileMode::Baseline);
+js::wasm::BaselineCompileFunction(CompileTask* task)
+{
+    MOZ_ASSERT(task->mode() == CompileTask::CompileMode::Baseline);
 
     const FuncBytes& func = task->func();
     FuncCompileResults& results = task->results();
 
     Decoder d(func.bytes());
 
     // Build the local types vector.
 
--- a/js/src/wasm/WasmBaselineCompile.h
+++ b/js/src/wasm/WasmBaselineCompile.h
@@ -14,35 +14,34 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 #ifndef asmjs_wasm_baseline_compile_h
 #define asmjs_wasm_baseline_compile_h
 
-#include "wasm/WasmIonCompile.h"
-
 namespace js {
 namespace wasm {
 
 class FunctionGenerator;
+class CompileTask;
 
 // Return true if BaselineCompileFunction can generate code for the
 // function held in the FunctionGenerator.  If false is returned a
 // different compilation strategy must be chosen.
 //
 // This allows the baseline compiler to have different capabilities on
 // different platforms and defer to the full Ion compiler if
 // capabilities are missing.  The FunctionGenerator and other data
 // structures contain information about the capabilities that are
 // required to compile the function.
 bool
 BaselineCanCompile(const FunctionGenerator* fg);
 
 // Generate adequate code quickly.
 bool
-BaselineCompileFunction(IonCompileTask* task);
+BaselineCompileFunction(CompileTask* task);
 
 } // namespace wasm
 } // namespace js
 
 #endif // asmjs_wasm_baseline_compile_h
--- a/js/src/wasm/WasmGenerator.cpp
+++ b/js/src/wasm/WasmGenerator.cpp
@@ -65,22 +65,22 @@ ModuleGenerator::ModuleGenerator()
 
 ModuleGenerator::~ModuleGenerator()
 {
     if (parallel_) {
         // Wait for any outstanding jobs to fail or complete.
         if (outstanding_) {
             AutoLockHelperThreadState lock;
             while (true) {
-                IonCompileTaskPtrVector& worklist = HelperThreadState().wasmWorklist(lock);
+                CompileTaskPtrVector& worklist = HelperThreadState().wasmWorklist(lock);
                 MOZ_ASSERT(outstanding_ >= worklist.length());
                 outstanding_ -= worklist.length();
                 worklist.clear();
 
-                IonCompileTaskPtrVector& finished = HelperThreadState().wasmFinishedList(lock);
+                CompileTaskPtrVector& finished = HelperThreadState().wasmFinishedList(lock);
                 MOZ_ASSERT(outstanding_ >= finished.length());
                 outstanding_ -= finished.length();
                 finished.clear();
 
                 uint32_t numFailed = HelperThreadState().harvestFailedWasmJobs(lock);
                 MOZ_ASSERT(outstanding_ >= numFailed);
                 outstanding_ -= numFailed;
 
@@ -219,17 +219,17 @@ ModuleGenerator::init(UniqueModuleEnviro
     return true;
 }
 
 bool
 ModuleGenerator::finishOutstandingTask()
 {
     MOZ_ASSERT(parallel_);
 
-    IonCompileTask* task = nullptr;
+    CompileTask* task = nullptr;
     {
         AutoLockHelperThreadState lock;
         while (true) {
             MOZ_ASSERT(outstanding_ > 0);
 
             if (HelperThreadState().wasmFailed(lock))
                 return false;
 
@@ -380,17 +380,17 @@ ModuleGenerator::patchFarJumps(const Tra
 
     for (const TrapFarJump& farJump : masm_.trapFarJumps())
         masm_.patchFarJump(farJump.jump, trapExits[farJump.trap].begin);
 
     return true;
 }
 
 bool
-ModuleGenerator::finishTask(IonCompileTask* task)
+ModuleGenerator::finishTask(CompileTask* task)
 {
     const FuncBytes& func = task->func();
     FuncCompileResults& results = task->results();
 
     masm_.haltingAlign(CodeAlignment);
 
     // Before merging in the new function's code, if calls in a prior function
     // body might go out of range, insert far jumps to extend the range.
@@ -896,23 +896,23 @@ ModuleGenerator::finishFuncDef(uint32_t 
                                           funcIndex,
                                           funcSig(funcIndex),
                                           fg->lineOrBytecode_,
                                           Move(fg->callSiteLineNums_));
     if (!func)
         return false;
 
     auto mode = alwaysBaseline_ && BaselineCanCompile(fg)
-                ? IonCompileTask::CompileMode::Baseline
-                : IonCompileTask::CompileMode::Ion;
+                ? CompileTask::CompileMode::Baseline
+                : CompileTask::CompileMode::Ion;
 
     if (freeTasks_.empty() && !finishOutstandingTask())
         return false;
 
-    IonCompileTask* task = freeTasks_.popCopy();
+    CompileTask* task = freeTasks_.popCopy();
     task->init(Move(func), mode);
 
     if (parallel_) {
         if (!StartOffThreadWasmCompile(task))
             return false;
         outstanding_++;
     } else {
         if (!CompileFunction(task))
@@ -1122,8 +1122,26 @@ ModuleGenerator::finish(const ShareableB
                                        Move(linkData_),
                                        Move(env_->imports),
                                        Move(env_->exports),
                                        Move(dataSegments),
                                        Move(env_->elemSegments),
                                        *metadata_,
                                        bytecode));
 }
+
+bool
+wasm::CompileFunction(CompileTask* task)
+{
+    TraceLoggerThread* logger = TraceLoggerForCurrentThread();
+    AutoTraceLog logCompile(logger, TraceLogger_WasmCompilation);
+
+    switch (task->mode()) {
+      case wasm::CompileTask::CompileMode::Ion:
+        return wasm::IonCompileFunction(task);
+      case wasm::CompileTask::CompileMode::Baseline:
+        return wasm::BaselineCompileFunction(task);
+      case wasm::CompileTask::CompileMode::None:
+        break;
+    }
+
+    MOZ_CRASH("Uninitialized task");
+}
--- a/js/src/wasm/WasmGenerator.h
+++ b/js/src/wasm/WasmGenerator.h
@@ -21,33 +21,158 @@
 
 #include "jit/MacroAssembler.h"
 #include "wasm/WasmModule.h"
 #include "wasm/WasmValidate.h"
 
 namespace js {
 namespace wasm {
 
+struct ModuleEnvironment;
+
+typedef Vector<jit::MIRType, 8, SystemAllocPolicy> MIRTypeVector;
+typedef jit::ABIArgIter<MIRTypeVector> ABIArgMIRTypeIter;
+typedef jit::ABIArgIter<ValTypeVector> ABIArgValTypeIter;
+
 struct CompileArgs;
 
 class FunctionGenerator;
 
 typedef Vector<UniqueBytes, 0, SystemAllocPolicy> UniqueBytesVector;
 
+// 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
+{
+    UniqueBytes      bytes_;
+    uint32_t         index_;
+    const SigWithId& sig_;
+    uint32_t         lineOrBytecode_;
+    Uint32Vector     callSiteLineNums_;
+
+  public:
+    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_; }
+    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;
+
+// The FuncCompileResults class contains the results of compiling a single
+// function body, ready to be merged into the whole-module MacroAssembler.
+
+class FuncCompileResults
+{
+    jit::TempAllocator alloc_;
+    jit::MacroAssembler masm_;
+    FuncOffsets offsets_;
+
+    FuncCompileResults(const FuncCompileResults&) = delete;
+    FuncCompileResults& operator=(const FuncCompileResults&) = delete;
+
+  public:
+    explicit FuncCompileResults(LifoAlloc& lifo)
+      : alloc_(&lifo),
+        masm_(jit::MacroAssembler::WasmToken(), alloc_)
+    {}
+
+    jit::TempAllocator& alloc() { return alloc_; }
+    jit::MacroAssembler& masm() { return masm_; }
+    FuncOffsets& offsets() { return offsets_; }
+};
+
+// A CompileTask represents the task of compiling a single function body. An
+// CompileTask is filled with the wasm code to be compiled on the main
+// validation thread, sent off to a compilation helper thread which creates
+// the FuncCompileResults, and finally sent back to the validation thread. To
+// save time allocating and freeing memory, CompileTasks are reset() and
+// reused.
+
+class CompileTask
+{
+  public:
+    enum class CompileMode { None, Baseline, Ion };
+
+  private:
+    const ModuleEnvironment&  env_;
+    LifoAlloc                 lifo_;
+    UniqueFuncBytes           func_;
+    CompileMode               mode_;
+    Maybe<FuncCompileResults> results_;
+
+    CompileTask(const CompileTask&) = delete;
+    CompileTask& operator=(const CompileTask&) = delete;
+
+  public:
+    CompileTask(const ModuleEnvironment& env, size_t defaultChunkSize)
+      : env_(env), lifo_(defaultChunkSize), func_(nullptr), mode_(CompileMode::None)
+    {}
+    LifoAlloc& lifo() {
+        return lifo_;
+    }
+    const ModuleEnvironment& env() const {
+        return env_;
+    }
+    void init(UniqueFuncBytes func, CompileMode mode) {
+        MOZ_ASSERT(!func_);
+        func_ = Move(func);
+        results_.emplace(lifo_);
+        mode_ = mode;
+    }
+    CompileMode mode() const {
+        return mode_;
+    }
+    const FuncBytes& func() const {
+        MOZ_ASSERT(func_);
+        return *func_;
+    }
+    FuncCompileResults& results() {
+        return *results_;
+    }
+    void reset(UniqueBytes* recycled) {
+        if (func_) {
+            *recycled = Move(func_->recycle());
+            (*recycled)->clear();
+        }
+        func_.reset(nullptr);
+        results_.reset();
+        lifo_.releaseAll();
+        mode_ = CompileMode::None;
+    }
+};
+
 // 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
 {
     typedef HashSet<uint32_t, DefaultHasher<uint32_t>, SystemAllocPolicy> Uint32Set;
-    typedef Vector<IonCompileTask, 0, SystemAllocPolicy> IonCompileTaskVector;
-    typedef Vector<IonCompileTask*, 0, SystemAllocPolicy> IonCompileTaskPtrVector;
+    typedef Vector<CompileTask, 0, SystemAllocPolicy> CompileTaskVector;
+    typedef Vector<CompileTask*, 0, SystemAllocPolicy> CompileTaskPtrVector;
     typedef EnumeratedArray<Trap, Trap::Limit, ProfilingOffsets> TrapExitOffsetArray;
 
     // Constant parameters
     bool                            alwaysBaseline_;
 
     // Data that is moved into the result of finish()
     Assumptions                     assumptions_;
     LinkData                        linkData_;
@@ -64,31 +189,31 @@ class MOZ_STACK_CLASS ModuleGenerator
     Uint32Vector                    funcToCodeRange_;
     Uint32Set                       exportedFuncs_;
     uint32_t                        lastPatchedCallsite_;
     uint32_t                        startOfUnpatchedCallsites_;
 
     // Parallel compilation
     bool                            parallel_;
     uint32_t                        outstanding_;
-    IonCompileTaskVector            tasks_;
-    IonCompileTaskPtrVector         freeTasks_;
+    CompileTaskVector               tasks_;
+    CompileTaskPtrVector            freeTasks_;
     UniqueBytesVector               freeBytes_;
 
     // Assertions
     DebugOnly<FunctionGenerator*>   activeFuncDef_;
     DebugOnly<bool>                 startedFuncDefs_;
     DebugOnly<bool>                 finishedFuncDefs_;
     DebugOnly<uint32_t>             numFinishedFuncDefs_;
 
     bool funcIsCompiled(uint32_t funcIndex) const;
     const CodeRange& funcCodeRange(uint32_t funcIndex) const;
     MOZ_MUST_USE bool patchCallSites(TrapExitOffsetArray* maybeTrapExits = nullptr);
     MOZ_MUST_USE bool patchFarJumps(const TrapExitOffsetArray& trapExits);
-    MOZ_MUST_USE bool finishTask(IonCompileTask* task);
+    MOZ_MUST_USE bool finishTask(CompileTask* task);
     MOZ_MUST_USE bool finishOutstandingTask();
     MOZ_MUST_USE bool finishFuncExports();
     MOZ_MUST_USE bool finishCodegen();
     MOZ_MUST_USE bool finishLinkData(Bytes& code);
     MOZ_MUST_USE bool addFuncImport(const Sig& sig, uint32_t globalDataOffset);
     MOZ_MUST_USE bool allocateGlobalBytes(uint32_t bytes, uint32_t align, uint32_t* globalDataOff);
     MOZ_MUST_USE bool allocateGlobal(GlobalDesc* global);
 
--- a/js/src/wasm/WasmIonCompile.cpp
+++ b/js/src/wasm/WasmIonCompile.cpp
@@ -3692,19 +3692,19 @@ EmitExpr(FunctionCompiler& f)
         return EmitCurrentMemory(f);
       case Op::Limit:;
     }
 
     MOZ_CRASH("unexpected wasm opcode");
 }
 
 bool
-wasm::IonCompileFunction(IonCompileTask* task)
+wasm::IonCompileFunction(CompileTask* task)
 {
-    MOZ_ASSERT(task->mode() == IonCompileTask::CompileMode::Ion);
+    MOZ_ASSERT(task->mode() == CompileTask::CompileMode::Ion);
 
     const FuncBytes& func = task->func();
     FuncCompileResults& results = task->results();
 
     Decoder d(func.bytes());
 
     // Build the local types vector.
 
@@ -3774,26 +3774,8 @@ wasm::IonCompileFunction(IonCompileTask*
 
         CodeGenerator codegen(&mir, lir, &results.masm());
         if (!codegen.generateWasm(sigId, prologueTrapOffset, &results.offsets()))
             return false;
     }
 
     return true;
 }
-
-bool
-wasm::CompileFunction(IonCompileTask* task)
-{
-    TraceLoggerThread* logger = TraceLoggerForCurrentThread();
-    AutoTraceLog logCompile(logger, TraceLogger_WasmCompilation);
-
-    switch (task->mode()) {
-      case wasm::IonCompileTask::CompileMode::Ion:
-        return wasm::IonCompileFunction(task);
-      case wasm::IonCompileTask::CompileMode::Baseline:
-        return wasm::BaselineCompileFunction(task);
-      case wasm::IonCompileTask::CompileMode::None:
-        break;
-    }
-
-    MOZ_CRASH("Uninitialized task");
-}
--- a/js/src/wasm/WasmIonCompile.h
+++ b/js/src/wasm/WasmIonCompile.h
@@ -14,149 +14,23 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 #ifndef wasm_ion_compile_h
 #define wasm_ion_compile_h
 
-#include "jit/MacroAssembler.h"
-#include "wasm/WasmTypes.h"
+#include "mozilla/Attributes.h"
 
 namespace js {
 namespace wasm {
 
-struct ModuleEnvironment;
-
-typedef Vector<jit::MIRType, 8, SystemAllocPolicy> MIRTypeVector;
-typedef jit::ABIArgIter<MIRTypeVector> ABIArgMIRTypeIter;
-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
-{
-    UniqueBytes      bytes_;
-    uint32_t         index_;
-    const SigWithId& sig_;
-    uint32_t         lineOrBytecode_;
-    Uint32Vector     callSiteLineNums_;
-
-  public:
-    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_; }
-    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;
-
-// The FuncCompileResults class contains the results of compiling a single
-// function body, ready to be merged into the whole-module MacroAssembler.
-
-class FuncCompileResults
-{
-    jit::TempAllocator alloc_;
-    jit::MacroAssembler masm_;
-    FuncOffsets offsets_;
-
-    FuncCompileResults(const FuncCompileResults&) = delete;
-    FuncCompileResults& operator=(const FuncCompileResults&) = delete;
-
-  public:
-    explicit FuncCompileResults(LifoAlloc& lifo)
-      : alloc_(&lifo),
-        masm_(jit::MacroAssembler::WasmToken(), alloc_)
-    {}
-
-    jit::TempAllocator& alloc() { return alloc_; }
-    jit::MacroAssembler& masm() { return masm_; }
-    FuncOffsets& offsets() { return offsets_; }
-};
+class CompileTask;
 
-// An IonCompileTask represents the task of compiling a single function body. An
-// IonCompileTask is filled with the wasm code to be compiled on the main
-// validation thread, sent off to an Ion compilation helper thread which creates
-// the FuncCompileResults, and finally sent back to the validation thread. To
-// save time allocating and freeing memory, IonCompileTasks are reset() and
-// reused.
-
-class IonCompileTask
-{
-  public:
-    enum class CompileMode { None, Baseline, Ion };
-
-  private:
-    const ModuleEnvironment&  env_;
-    LifoAlloc                 lifo_;
-    UniqueFuncBytes           func_;
-    CompileMode               mode_;
-    Maybe<FuncCompileResults> results_;
-
-    IonCompileTask(const IonCompileTask&) = delete;
-    IonCompileTask& operator=(const IonCompileTask&) = delete;
-
-  public:
-    IonCompileTask(const ModuleEnvironment& env, size_t defaultChunkSize)
-      : env_(env), lifo_(defaultChunkSize), func_(nullptr), mode_(CompileMode::None)
-    {}
-    LifoAlloc& lifo() {
-        return lifo_;
-    }
-    const ModuleEnvironment& env() const {
-        return env_;
-    }
-    void init(UniqueFuncBytes func, CompileMode mode) {
-        MOZ_ASSERT(!func_);
-        func_ = Move(func);
-        results_.emplace(lifo_);
-        mode_ = mode;
-    }
-    CompileMode mode() const {
-        return mode_;
-    }
-    const FuncBytes& func() const {
-        MOZ_ASSERT(func_);
-        return *func_;
-    }
-    FuncCompileResults& results() {
-        return *results_;
-    }
-    void reset(UniqueBytes* recycled) {
-        if (func_) {
-            *recycled = Move(func_->recycle());
-            (*recycled)->clear();
-        }
-        func_.reset(nullptr);
-        results_.reset();
-        lifo_.releaseAll();
-        mode_ = CompileMode::None;
-    }
-};
-
+// Generates very fast code at the expense of compilation time.
 MOZ_MUST_USE bool
-IonCompileFunction(IonCompileTask* task);
-
-bool
-CompileFunction(IonCompileTask* task);
+IonCompileFunction(CompileTask* task);
 
 } // namespace wasm
 } // namespace js
 
 #endif // wasm_ion_compile_h
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -1678,24 +1678,24 @@ ResolveCompilation(JSContext* cx, Module
     RootedObject moduleObj(cx, WasmModuleObject::create(cx, module, proto));
     if (!moduleObj)
         return false;
 
     RootedValue resolutionValue(cx, ObjectValue(*moduleObj));
     return promise->resolve(cx, resolutionValue);
 }
 
-struct CompileTask : PromiseTask
+struct CompilePromiseTask : PromiseTask
 {
     MutableBytes bytecode;
     CompileArgs  compileArgs;
     UniqueChars  error;
     SharedModule module;
 
-    CompileTask(JSContext* cx, Handle<PromiseObject*> promise)
+    CompilePromiseTask(JSContext* cx, Handle<PromiseObject*> promise)
       : PromiseTask(cx, promise)
     {}
 
     void execute() override {
         module = Compile(*bytecode, compileArgs, &error);
     }
 
     bool finishPromise(JSContext* cx, Handle<PromiseObject*> promise) override {
@@ -1753,17 +1753,17 @@ WebAssembly_compile(JSContext* cx, unsig
     RootedFunction nopFun(cx, NewNativeFunction(cx, Nop, 0, nullptr));
     if (!nopFun)
         return false;
 
     Rooted<PromiseObject*> promise(cx, PromiseObject::create(cx, nopFun));
     if (!promise)
         return false;
 
-    auto task = cx->make_unique<CompileTask>(cx, promise);
+    auto task = cx->make_unique<CompilePromiseTask>(cx, promise);
     if (!task)
         return false;
 
     CallArgs callArgs = CallArgsFromVp(argc, vp);
 
     if (!GetBufferSource(cx, callArgs, "WebAssembly.compile", &task->bytecode))
         return RejectWithPendingException(cx, promise, callArgs);
 
@@ -1801,22 +1801,22 @@ ResolveInstantiation(JSContext* cx, Modu
     val = ObjectValue(*instanceObj);
     if (!JS_DefineProperty(cx, resultObj, "instance", val, JSPROP_ENUMERATE))
         return false;
 
     val = ObjectValue(*resultObj);
     return promise->resolve(cx, val);
 }
 
-struct InstantiateTask : CompileTask
+struct InstantiatePromiseTask : CompilePromiseTask
 {
     PersistentRootedObject importObj;
 
-    InstantiateTask(JSContext* cx, Handle<PromiseObject*> promise, HandleObject importObj)
-      : CompileTask(cx, promise),
+    InstantiatePromiseTask(JSContext* cx, Handle<PromiseObject*> promise, HandleObject importObj)
+      : CompilePromiseTask(cx, promise),
         importObj(cx, importObj)
     {}
 
     bool finishPromise(JSContext* cx, Handle<PromiseObject*> promise) override {
         return module
                ? ResolveInstantiation(cx, *module, importObj, promise)
                : Reject(cx, compileArgs, Move(error), promise);
     }
@@ -1873,17 +1873,17 @@ WebAssembly_instantiate(JSContext* cx, u
         RootedWasmInstanceObject instanceObj(cx);
         if (!Instantiate(cx, *module, importObj, &instanceObj))
             return RejectWithPendingException(cx, promise, callArgs);
 
         RootedValue resolutionValue(cx, ObjectValue(*instanceObj));
         if (!promise->resolve(cx, resolutionValue))
             return false;
     } else {
-        auto task = cx->make_unique<InstantiateTask>(cx, promise, importObj);
+        auto task = cx->make_unique<InstantiatePromiseTask>(cx, promise, importObj);
         if (!task)
             return false;
 
         if (!GetBufferSource(cx, firstArg, JSMSG_WASM_BAD_BUF_MOD_ARG, &task->bytecode))
             return RejectWithPendingException(cx, promise, callArgs);
 
         if (!InitCompileArgs(cx, &task->compileArgs))
             return false;
--- a/js/src/wasm/WasmStubs.cpp
+++ b/js/src/wasm/WasmStubs.cpp
@@ -16,17 +16,17 @@
  * limitations under the License.
  */
 
 #include "wasm/WasmStubs.h"
 
 #include "mozilla/ArrayUtils.h"
 
 #include "wasm/WasmCode.h"
-#include "wasm/WasmIonCompile.h"
+#include "wasm/WasmGenerator.h"
 
 #include "jit/MacroAssembler-inl.h"
 
 using namespace js;
 using namespace js::jit;
 using namespace js::wasm;
 
 using mozilla::ArrayLength;