• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 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 #if !V8_ENABLE_WEBASSEMBLY
6 #error This header should only be included if WebAssembly is enabled.
7 #endif  // !V8_ENABLE_WEBASSEMBLY
8 
9 #ifndef V8_WASM_FUNCTION_COMPILER_H_
10 #define V8_WASM_FUNCTION_COMPILER_H_
11 
12 #include <memory>
13 
14 #include "src/codegen/assembler.h"
15 #include "src/codegen/code-desc.h"
16 #include "src/trap-handler/trap-handler.h"
17 #include "src/wasm/compilation-environment.h"
18 #include "src/wasm/function-body-decoder.h"
19 #include "src/wasm/wasm-limits.h"
20 #include "src/wasm/wasm-module.h"
21 #include "src/wasm/wasm-tier.h"
22 
23 namespace v8 {
24 namespace internal {
25 
26 class Counters;
27 class TurbofanCompilationJob;
28 
29 namespace wasm {
30 
31 class NativeModule;
32 class WasmCode;
33 class WasmEngine;
34 struct WasmFunction;
35 
36 struct WasmCompilationResult {
37  public:
38   MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmCompilationResult);
39 
40   enum Kind : int8_t {
41     kFunction,
42     kWasmToJsWrapper,
43   };
44 
succeededWasmCompilationResult45   bool succeeded() const { return code_desc.buffer != nullptr; }
failedWasmCompilationResult46   bool failed() const { return !succeeded(); }
47   operator bool() const { return succeeded(); }
48 
49   CodeDesc code_desc;
50   std::unique_ptr<AssemblerBuffer> instr_buffer;
51   uint32_t frame_slot_count = 0;
52   uint32_t tagged_parameter_slots = 0;
53   base::OwnedVector<byte> source_positions;
54   base::OwnedVector<byte> protected_instructions_data;
55   int func_index = kAnonymousFuncIndex;
56   ExecutionTier requested_tier;
57   ExecutionTier result_tier;
58   Kind kind = kFunction;
59   ForDebugging for_debugging = kNoDebugging;
60   int feedback_vector_slots = 0;
61 };
62 
63 class V8_EXPORT_PRIVATE WasmCompilationUnit final {
64  public:
65   static ExecutionTier GetBaselineExecutionTier(const WasmModule*);
66 
WasmCompilationUnit(int index,ExecutionTier tier,ForDebugging for_debugging)67   WasmCompilationUnit(int index, ExecutionTier tier, ForDebugging for_debugging)
68       : func_index_(index), tier_(tier), for_debugging_(for_debugging) {}
69 
70   WasmCompilationResult ExecuteCompilation(CompilationEnv*,
71                                            const WireBytesStorage*, Counters*,
72                                            WasmFeatures* detected);
73 
tier()74   ExecutionTier tier() const { return tier_; }
for_debugging()75   ForDebugging for_debugging() const { return for_debugging_; }
func_index()76   int func_index() const { return func_index_; }
77 
78   static void CompileWasmFunction(Isolate*, NativeModule*,
79                                   WasmFeatures* detected, const WasmFunction*,
80                                   ExecutionTier);
81 
82  private:
83   WasmCompilationResult ExecuteFunctionCompilation(CompilationEnv*,
84                                                    const WireBytesStorage*,
85                                                    Counters*,
86                                                    WasmFeatures* detected);
87 
88   WasmCompilationResult ExecuteImportWrapperCompilation(CompilationEnv*);
89 
90   int func_index_;
91   ExecutionTier tier_;
92   ForDebugging for_debugging_;
93 };
94 
95 // {WasmCompilationUnit} should be trivially copyable and small enough so we can
96 // efficiently pass it by value.
97 ASSERT_TRIVIALLY_COPYABLE(WasmCompilationUnit);
98 STATIC_ASSERT(sizeof(WasmCompilationUnit) <= 2 * kSystemPointerSize);
99 
100 class V8_EXPORT_PRIVATE JSToWasmWrapperCompilationUnit final {
101  public:
102   // A flag to mark whether the compilation unit can skip the compilation
103   // and return the builtin (generic) wrapper, when available.
104   enum AllowGeneric : bool { kAllowGeneric = true, kDontAllowGeneric = false };
105 
106   JSToWasmWrapperCompilationUnit(Isolate* isolate, const FunctionSig* sig,
107                                  const wasm::WasmModule* module, bool is_import,
108                                  const WasmFeatures& enabled_features,
109                                  AllowGeneric allow_generic);
110   ~JSToWasmWrapperCompilationUnit();
111 
isolate()112   Isolate* isolate() const { return isolate_; }
113 
114   void Execute();
115   Handle<Code> Finalize();
116 
is_import()117   bool is_import() const { return is_import_; }
sig()118   const FunctionSig* sig() const { return sig_; }
119 
120   // Run a compilation unit synchronously.
121   static Handle<Code> CompileJSToWasmWrapper(Isolate* isolate,
122                                              const FunctionSig* sig,
123                                              const WasmModule* module,
124                                              bool is_import);
125 
126   // Run a compilation unit synchronously, but ask for the specific
127   // wrapper.
128   static Handle<Code> CompileSpecificJSToWasmWrapper(Isolate* isolate,
129                                                      const FunctionSig* sig,
130                                                      const WasmModule* module);
131 
132  private:
133   // Wrapper compilation is bound to an isolate. Concurrent accesses to the
134   // isolate (during the "Execute" phase) must be audited carefully, i.e. we
135   // should only access immutable information (like the root table). The isolate
136   // is guaranteed to be alive when this unit executes.
137   Isolate* isolate_;
138   bool is_import_;
139   const FunctionSig* sig_;
140   bool use_generic_wrapper_;
141   std::unique_ptr<TurbofanCompilationJob> job_;
142 };
143 
144 }  // namespace wasm
145 }  // namespace internal
146 }  // namespace v8
147 
148 #endif  // V8_WASM_FUNCTION_COMPILER_H_
149