summaryrefslogtreecommitdiff
path: root/chromium/v8/src/wasm/function-compiler.h
blob: fa70073291b630a3c156b0bbe50a8971af94affd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// 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.

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

#ifndef V8_WASM_FUNCTION_COMPILER_H_
#define V8_WASM_FUNCTION_COMPILER_H_

#include <memory>

#include "src/codegen/assembler.h"
#include "src/codegen/code-desc.h"
#include "src/wasm/compilation-environment.h"
#include "src/wasm/function-body-decoder.h"
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-tier.h"

namespace v8 {
namespace internal {

class Counters;
class TurbofanCompilationJob;

namespace wasm {

class AssemblerBufferCache;
class NativeModule;
class WasmCode;
class WasmEngine;
struct WasmFunction;

struct WasmCompilationResult {
 public:
  MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmCompilationResult);

  enum Kind : int8_t {
    kFunction,
    kWasmToJsWrapper,
  };

  bool succeeded() const { return code_desc.buffer != nullptr; }
  bool failed() const { return !succeeded(); }
  explicit operator bool() const { return succeeded(); }

  CodeDesc code_desc;
  std::unique_ptr<AssemblerBuffer> instr_buffer;
  uint32_t frame_slot_count = 0;
  uint32_t tagged_parameter_slots = 0;
  base::OwnedVector<byte> source_positions;
  base::OwnedVector<byte> protected_instructions_data;
  int func_index = kAnonymousFuncIndex;
  ExecutionTier requested_tier;
  ExecutionTier result_tier;
  Kind kind = kFunction;
  ForDebugging for_debugging = kNoDebugging;
};

class V8_EXPORT_PRIVATE WasmCompilationUnit final {
 public:
  WasmCompilationUnit(int index, ExecutionTier tier, ForDebugging for_debugging)
      : func_index_(index), tier_(tier), for_debugging_(for_debugging) {}

  WasmCompilationResult ExecuteCompilation(CompilationEnv*,
                                           const WireBytesStorage*, Counters*,
                                           AssemblerBufferCache*,
                                           WasmFeatures* detected);

  ExecutionTier tier() const { return tier_; }
  ForDebugging for_debugging() const { return for_debugging_; }
  int func_index() const { return func_index_; }

  static void CompileWasmFunction(Isolate*, NativeModule*,
                                  WasmFeatures* detected, const WasmFunction*,
                                  ExecutionTier);

 private:
  WasmCompilationResult ExecuteFunctionCompilation(CompilationEnv*,
                                                   const WireBytesStorage*,
                                                   Counters*,
                                                   AssemblerBufferCache*,
                                                   WasmFeatures* detected);

  WasmCompilationResult ExecuteImportWrapperCompilation(CompilationEnv*);

  int func_index_;
  ExecutionTier tier_;
  ForDebugging for_debugging_;
};

// {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);

class V8_EXPORT_PRIVATE JSToWasmWrapperCompilationUnit final {
 public:
  // 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 };

  JSToWasmWrapperCompilationUnit(Isolate* isolate, const FunctionSig* sig,
                                 uint32_t canonical_sig_index,
                                 const wasm::WasmModule* module, bool is_import,
                                 const WasmFeatures& enabled_features,
                                 AllowGeneric allow_generic);
  ~JSToWasmWrapperCompilationUnit();

  Isolate* isolate() const { return isolate_; }

  void Execute();
  Handle<CodeT> Finalize();

  bool is_import() const { return is_import_; }
  const FunctionSig* sig() const { return sig_; }
  uint32_t canonical_sig_index() const { return canonical_sig_index_; }

  // Run a compilation unit synchronously.
  static Handle<CodeT> CompileJSToWasmWrapper(Isolate* isolate,
                                              const FunctionSig* sig,
                                              uint32_t canonical_sig_index,
                                              const WasmModule* module,
                                              bool is_import);

  // Run a compilation unit synchronously, but ask for the specific
  // wrapper.
  static Handle<CodeT> CompileSpecificJSToWasmWrapper(
      Isolate* isolate, const FunctionSig* sig, uint32_t canonical_sig_index,
      const WasmModule* module);

 private:
  // Wrapper compilation is bound to an isolate. Concurrent accesses to the
  // isolate (during the "Execute" phase) must be audited carefully, i.e. we
  // should only access immutable information (like the root table). The isolate
  // is guaranteed to be alive when this unit executes.
  Isolate* isolate_;
  bool is_import_;
  const FunctionSig* sig_;
  uint32_t canonical_sig_index_;
  bool use_generic_wrapper_;
  std::unique_ptr<TurbofanCompilationJob> job_;
};

}  // namespace wasm
}  // namespace internal
}  // namespace v8

#endif  // V8_WASM_FUNCTION_COMPILER_H_