function-compiler.h 5.36 KB
Newer Older
1 2 3 4
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6 7 8
#if !V8_ENABLE_WEBASSEMBLY
#error This header should only be included if WebAssembly is enabled.
#endif  // !V8_ENABLE_WEBASSEMBLY

9 10 11
#ifndef V8_WASM_FUNCTION_COMPILER_H_
#define V8_WASM_FUNCTION_COMPILER_H_

12 13
#include <memory>

14
#include "src/codegen/code-desc.h"
15
#include "src/trap-handler/trap-handler.h"
16
#include "src/wasm/compilation-environment.h"
17
#include "src/wasm/function-body-decoder.h"
18 19
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-module.h"
20
#include "src/wasm/wasm-tier.h"
21 22 23 24

namespace v8 {
namespace internal {

25
class AssemblerBuffer;
26
class Counters;
27
class OptimizedCompilationJob;
28

29 30 31 32
namespace wasm {

class NativeModule;
class WasmCode;
33
class WasmEngine;
34 35
struct WasmFunction;

36 37
class WasmInstructionBuffer final {
 public:
38
  WasmInstructionBuffer() = delete;
39 40
  WasmInstructionBuffer(const WasmInstructionBuffer&) = delete;
  WasmInstructionBuffer& operator=(const WasmInstructionBuffer&) = delete;
41 42 43 44
  ~WasmInstructionBuffer();
  std::unique_ptr<AssemblerBuffer> CreateView();
  std::unique_ptr<uint8_t[]> ReleaseBuffer();

45 46 47
  // Allocate a new {WasmInstructionBuffer}. The size is the maximum of {size}
  // and {AssemblerBase::kMinimalSize}.
  static std::unique_ptr<WasmInstructionBuffer> New(size_t size = 0);
48

49 50 51
  // Override {operator delete} to avoid implicit instantiation of {operator
  // delete} with {size_t} argument. The {size_t} argument would be incorrect.
  void operator delete(void* ptr) { ::operator delete(ptr); }
52 53 54 55 56 57
};

struct WasmCompilationResult {
 public:
  MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmCompilationResult);

58 59 60 61 62
  enum Kind : int8_t {
    kFunction,
    kWasmToJsWrapper,
  };

63
  bool succeeded() const { return code_desc.buffer != nullptr; }
64
  bool failed() const { return !succeeded(); }
65 66 67 68 69
  operator bool() const { return succeeded(); }

  CodeDesc code_desc;
  std::unique_ptr<uint8_t[]> instr_buffer;
  uint32_t frame_slot_count = 0;
70
  uint32_t tagged_parameter_slots = 0;
71
  OwnedVector<byte> source_positions;
72
  OwnedVector<byte> protected_instructions_data;
73
  int func_index = kAnonymousFuncIndex;
74 75
  ExecutionTier requested_tier;
  ExecutionTier result_tier;
76
  Kind kind = kFunction;
77
  ForDebugging for_debugging = kNoDebugging;
78 79
};

80
class V8_EXPORT_PRIVATE WasmCompilationUnit final {
81
 public:
82
  static ExecutionTier GetBaselineExecutionTier(const WasmModule*);
83

84 85
  WasmCompilationUnit(int index, ExecutionTier tier, ForDebugging for_debugging)
      : func_index_(index), tier_(tier), for_debugging_(for_debugging) {}
86

87
  WasmCompilationResult ExecuteCompilation(
88 89
      WasmEngine*, CompilationEnv*, const std::shared_ptr<WireBytesStorage>&,
      Counters*, WasmFeatures* detected);
90

91
  ExecutionTier tier() const { return tier_; }
92
  int func_index() const { return func_index_; }
93

94 95 96
  static void CompileWasmFunction(Isolate*, NativeModule*,
                                  WasmFeatures* detected, const WasmFunction*,
                                  ExecutionTier);
97 98

 private:
99 100 101 102 103 104 105 106
  WasmCompilationResult ExecuteFunctionCompilation(
      WasmEngine* wasm_engine, CompilationEnv* env,
      const std::shared_ptr<WireBytesStorage>& wire_bytes_storage,
      Counters* counters, WasmFeatures* detected);

  WasmCompilationResult ExecuteImportWrapperCompilation(WasmEngine* engine,
                                                        CompilationEnv* env);

107 108
  int func_index_;
  ExecutionTier tier_;
109
  ForDebugging for_debugging_;
110 111
};

112 113 114 115 116
// {WasmCompilationUnit} should be trivially copyable and small enough so we can
// efficiently pass it by value.
ASSERT_TRIVIALLY_COPYABLE(WasmCompilationUnit);
STATIC_ASSERT(sizeof(WasmCompilationUnit) <= 2 * kSystemPointerSize);

117 118
class V8_EXPORT_PRIVATE JSToWasmWrapperCompilationUnit final {
 public:
119 120 121 122
  // A flag to mark whether the compilation unit can skip the compilation
  // and return the builtin (generic) wrapper, when available.
  enum AllowGeneric : bool { kAllowGeneric = true, kDontAllowGeneric = false };

123
  JSToWasmWrapperCompilationUnit(Isolate* isolate, WasmEngine* wasm_engine,
124 125
                                 const FunctionSig* sig,
                                 const wasm::WasmModule* module, bool is_import,
126 127
                                 const WasmFeatures& enabled_features,
                                 AllowGeneric allow_generic);
128 129 130 131 132
  ~JSToWasmWrapperCompilationUnit();

  void Execute();
  Handle<Code> Finalize(Isolate* isolate);

133
  bool is_import() const { return is_import_; }
134
  const FunctionSig* sig() const { return sig_; }
135

136
  // Run a compilation unit synchronously.
137 138
  static Handle<Code> CompileJSToWasmWrapper(Isolate* isolate,
                                             const FunctionSig* sig,
139
                                             const WasmModule* module,
140 141
                                             bool is_import);

142 143 144 145 146 147
  // Run a compilation unit synchronously, but ask for the specific
  // wrapper.
  static Handle<Code> CompileSpecificJSToWasmWrapper(Isolate* isolate,
                                                     const FunctionSig* sig,
                                                     const WasmModule* module);

148
 private:
149
  bool is_import_;
150
  const FunctionSig* sig_;
151
  bool use_generic_wrapper_;
152 153 154
  std::unique_ptr<OptimizedCompilationJob> job_;
};

155 156 157 158 159
}  // namespace wasm
}  // namespace internal
}  // namespace v8

#endif  // V8_WASM_FUNCTION_COMPILER_H_