Home | History | Annotate | Download | only in wasm
      1 // Copyright 2017 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_WASM_MODULE_COMPILER_H_
      6 #define V8_WASM_MODULE_COMPILER_H_
      7 
      8 #include <atomic>
      9 #include <functional>
     10 #include <memory>
     11 
     12 #include "src/cancelable-task.h"
     13 #include "src/globals.h"
     14 #include "src/wasm/wasm-features.h"
     15 #include "src/wasm/wasm-module.h"
     16 
     17 namespace v8 {
     18 namespace internal {
     19 
     20 class JSArrayBuffer;
     21 class JSPromise;
     22 class Counters;
     23 class WasmModuleObject;
     24 class WasmInstanceObject;
     25 
     26 template <typename T>
     27 class Vector;
     28 
     29 namespace wasm {
     30 
     31 class CompilationResultResolver;
     32 class CompilationState;
     33 class ErrorThrower;
     34 class ModuleCompiler;
     35 class NativeModule;
     36 class WasmCode;
     37 struct ModuleEnv;
     38 struct WasmModule;
     39 
     40 struct CompilationStateDeleter {
     41   void operator()(CompilationState* compilation_state) const;
     42 };
     43 
     44 // Wrapper to create a CompilationState exists in order to avoid having
     45 // the CompilationState in the header file.
     46 std::unique_ptr<CompilationState, CompilationStateDeleter> NewCompilationState(
     47     Isolate* isolate, const ModuleEnv& env);
     48 
     49 ModuleEnv* GetModuleEnv(CompilationState* compilation_state);
     50 
     51 MaybeHandle<WasmModuleObject> CompileToModuleObject(
     52     Isolate* isolate, const WasmFeatures& enabled, ErrorThrower* thrower,
     53     std::shared_ptr<const WasmModule> module, const ModuleWireBytes& wire_bytes,
     54     Handle<Script> asm_js_script, Vector<const byte> asm_js_offset_table_bytes);
     55 
     56 MaybeHandle<WasmInstanceObject> InstantiateToInstanceObject(
     57     Isolate* isolate, ErrorThrower* thrower,
     58     Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
     59     MaybeHandle<JSArrayBuffer> memory);
     60 
     61 V8_EXPORT_PRIVATE
     62 void CompileJsToWasmWrappers(Isolate* isolate,
     63                              Handle<WasmModuleObject> module_object);
     64 
     65 V8_EXPORT_PRIVATE Handle<Script> CreateWasmScript(
     66     Isolate* isolate, const ModuleWireBytes& wire_bytes);
     67 
     68 // Triggered by the WasmCompileLazy builtin.
     69 // Returns the instruction start of the compiled code object.
     70 Address CompileLazy(Isolate*, NativeModule*, uint32_t func_index);
     71 
     72 // Encapsulates all the state and steps of an asynchronous compilation.
     73 // An asynchronous compile job consists of a number of tasks that are executed
     74 // as foreground and background tasks. Any phase that touches the V8 heap or
     75 // allocates on the V8 heap (e.g. creating the module object) must be a
     76 // foreground task. All other tasks (e.g. decoding and validating, the majority
     77 // of the work of compilation) can be background tasks.
     78 // TODO(wasm): factor out common parts of this with the synchronous pipeline.
     79 class AsyncCompileJob {
     80  public:
     81   AsyncCompileJob(Isolate* isolate, const WasmFeatures& enabled_features,
     82                   std::unique_ptr<byte[]> bytes_copy, size_t length,
     83                   Handle<Context> context,
     84                   std::shared_ptr<CompilationResultResolver> resolver);
     85   ~AsyncCompileJob();
     86 
     87   void Start();
     88 
     89   std::shared_ptr<StreamingDecoder> CreateStreamingDecoder();
     90 
     91   void Abort();
     92   void CancelPendingForegroundTask();
     93 
     94   Isolate* isolate() const { return isolate_; }
     95 
     96  private:
     97   class CompileTask;
     98   class CompileStep;
     99 
    100   // States of the AsyncCompileJob.
    101   class DecodeModule;            // Step 1  (async)
    102   class DecodeFail;              // Step 1b (sync)
    103   class PrepareAndStartCompile;  // Step 2  (sync)
    104   class CompileFailed;           // Step 4b (sync)
    105   class CompileWrappers;         // Step 5  (sync)
    106   class FinishModule;            // Step 6  (sync)
    107 
    108   const std::shared_ptr<Counters>& async_counters() const {
    109     return async_counters_;
    110   }
    111   Counters* counters() const { return async_counters().get(); }
    112 
    113   void FinishCompile();
    114 
    115   void AsyncCompileFailed(Handle<Object> error_reason);
    116 
    117   void AsyncCompileSucceeded(Handle<WasmModuleObject> result);
    118 
    119   void StartForegroundTask();
    120   void ExecuteForegroundTaskImmediately();
    121 
    122   void StartBackgroundTask();
    123 
    124   // Switches to the compilation step {Step} and starts a foreground task to
    125   // execute it.
    126   template <typename Step, typename... Args>
    127   void DoSync(Args&&... args);
    128 
    129   // Switches to the compilation step {Step} and immediately executes that step.
    130   template <typename Step, typename... Args>
    131   void DoImmediately(Args&&... args);
    132 
    133   // Switches to the compilation step {Step} and starts a background task to
    134   // execute it.
    135   template <typename Step, typename... Args>
    136   void DoAsync(Args&&... args);
    137 
    138   // Switches to the compilation step {Step} but does not start a task to
    139   // execute it.
    140   template <typename Step, typename... Args>
    141   void NextStep(Args&&... args);
    142 
    143   friend class AsyncStreamingProcessor;
    144 
    145   Isolate* isolate_;
    146   const WasmFeatures enabled_features_;
    147   const std::shared_ptr<Counters> async_counters_;
    148   // Copy of the module wire bytes, moved into the {native_module_} on its
    149   // creation.
    150   std::unique_ptr<byte[]> bytes_copy_;
    151   // Reference to the wire bytes (hold in {bytes_copy_} or as part of
    152   // {native_module_}).
    153   ModuleWireBytes wire_bytes_;
    154   Handle<Context> native_context_;
    155   std::shared_ptr<CompilationResultResolver> resolver_;
    156 
    157   std::vector<DeferredHandles*> deferred_handles_;
    158   Handle<WasmModuleObject> module_object_;
    159   NativeModule* native_module_ = nullptr;
    160 
    161   std::unique_ptr<CompileStep> step_;
    162   CancelableTaskManager background_task_manager_;
    163 
    164   std::shared_ptr<v8::TaskRunner> foreground_task_runner_;
    165 
    166   // For async compilation the AsyncCompileJob is the only finisher. For
    167   // streaming compilation also the AsyncStreamingProcessor has to finish before
    168   // compilation can be finished.
    169   std::atomic<int32_t> outstanding_finishers_{1};
    170 
    171   // Decrements the number of outstanding finishers. The last caller of this
    172   // function should finish the asynchronous compilation, see the comment on
    173   // {outstanding_finishers_}.
    174   V8_WARN_UNUSED_RESULT bool DecrementAndCheckFinisherCount() {
    175     return outstanding_finishers_.fetch_sub(1) == 1;
    176   }
    177 
    178   // A reference to a pending foreground task, or {nullptr} if none is pending.
    179   CompileTask* pending_foreground_task_ = nullptr;
    180 
    181   // The AsyncCompileJob owns the StreamingDecoder because the StreamingDecoder
    182   // contains data which is needed by the AsyncCompileJob for streaming
    183   // compilation. The AsyncCompileJob does not actively use the
    184   // StreamingDecoder.
    185   std::shared_ptr<StreamingDecoder> stream_;
    186 
    187   bool tiering_completed_ = false;
    188 };
    189 }  // namespace wasm
    190 }  // namespace internal
    191 }  // namespace v8
    192 
    193 #endif  // V8_WASM_MODULE_COMPILER_H_
    194