• 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 #ifndef V8_WASM_FUNCTION_COMPILER_H_
6 #define V8_WASM_FUNCTION_COMPILER_H_
7 
8 #include <memory>
9 
10 #include "src/codegen/code-desc.h"
11 #include "src/trap-handler/trap-handler.h"
12 #include "src/wasm/compilation-environment.h"
13 #include "src/wasm/function-body-decoder.h"
14 #include "src/wasm/wasm-limits.h"
15 #include "src/wasm/wasm-module.h"
16 #include "src/wasm/wasm-tier.h"
17 
18 namespace v8 {
19 namespace internal {
20 
21 class AssemblerBuffer;
22 class Counters;
23 class OptimizedCompilationJob;
24 
25 namespace wasm {
26 
27 class NativeModule;
28 class WasmCode;
29 class WasmEngine;
30 struct WasmFunction;
31 
32 class WasmInstructionBuffer final {
33  public:
34   WasmInstructionBuffer() = delete;
35   WasmInstructionBuffer(const WasmInstructionBuffer&) = delete;
36   WasmInstructionBuffer& operator=(const WasmInstructionBuffer&) = delete;
37   ~WasmInstructionBuffer();
38   std::unique_ptr<AssemblerBuffer> CreateView();
39   std::unique_ptr<uint8_t[]> ReleaseBuffer();
40 
41   // Allocate a new {WasmInstructionBuffer}. The size is the maximum of {size}
42   // and {AssemblerBase::kMinimalSize}.
43   static std::unique_ptr<WasmInstructionBuffer> New(size_t size = 0);
44 
45   // Override {operator delete} to avoid implicit instantiation of {operator
46   // delete} with {size_t} argument. The {size_t} argument would be incorrect.
delete(void * ptr)47   void operator delete(void* ptr) { ::operator delete(ptr); }
48 };
49 
50 struct WasmCompilationResult {
51  public:
52   MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmCompilationResult);
53 
54   enum Kind : int8_t {
55     kFunction,
56     kWasmToJsWrapper,
57   };
58 
succeededWasmCompilationResult59   bool succeeded() const { return code_desc.buffer != nullptr; }
failedWasmCompilationResult60   bool failed() const { return !succeeded(); }
61   operator bool() const { return succeeded(); }
62 
63   CodeDesc code_desc;
64   std::unique_ptr<uint8_t[]> instr_buffer;
65   uint32_t frame_slot_count = 0;
66   uint32_t tagged_parameter_slots = 0;
67   OwnedVector<byte> source_positions;
68   OwnedVector<byte> protected_instructions_data;
69   int func_index = kAnonymousFuncIndex;
70   ExecutionTier requested_tier;
71   ExecutionTier result_tier;
72   Kind kind = kFunction;
73   ForDebugging for_debugging = kNoDebugging;
74 };
75 
76 class V8_EXPORT_PRIVATE WasmCompilationUnit final {
77  public:
78   static ExecutionTier GetBaselineExecutionTier(const WasmModule*);
79 
WasmCompilationUnit(int index,ExecutionTier tier,ForDebugging for_debugging)80   WasmCompilationUnit(int index, ExecutionTier tier, ForDebugging for_debugging)
81       : func_index_(index), tier_(tier), for_debugging_(for_debugging) {}
82 
83   WasmCompilationResult ExecuteCompilation(
84       WasmEngine*, CompilationEnv*, const std::shared_ptr<WireBytesStorage>&,
85       Counters*, WasmFeatures* detected);
86 
tier()87   ExecutionTier tier() const { return tier_; }
func_index()88   int func_index() const { return func_index_; }
89 
90   static void CompileWasmFunction(Isolate*, NativeModule*,
91                                   WasmFeatures* detected, const WasmFunction*,
92                                   ExecutionTier);
93 
94  private:
95   WasmCompilationResult ExecuteFunctionCompilation(
96       WasmEngine* wasm_engine, CompilationEnv* env,
97       const std::shared_ptr<WireBytesStorage>& wire_bytes_storage,
98       Counters* counters, WasmFeatures* detected);
99 
100   WasmCompilationResult ExecuteImportWrapperCompilation(WasmEngine* engine,
101                                                         CompilationEnv* env);
102 
103   int func_index_;
104   ExecutionTier tier_;
105   ForDebugging for_debugging_;
106 };
107 
108 // {WasmCompilationUnit} should be trivially copyable and small enough so we can
109 // efficiently pass it by value.
110 ASSERT_TRIVIALLY_COPYABLE(WasmCompilationUnit);
111 STATIC_ASSERT(sizeof(WasmCompilationUnit) <= 2 * kSystemPointerSize);
112 
113 class V8_EXPORT_PRIVATE JSToWasmWrapperCompilationUnit final {
114  public:
115   // A flag to mark whether the compilation unit can skip the compilation
116   // and return the builtin (generic) wrapper, when available.
117   enum AllowGeneric : bool { kAllowGeneric = true, kDontAllowGeneric = false };
118 
119   JSToWasmWrapperCompilationUnit(Isolate* isolate, WasmEngine* wasm_engine,
120                                  const FunctionSig* sig,
121                                  const wasm::WasmModule* module, bool is_import,
122                                  const WasmFeatures& enabled_features,
123                                  AllowGeneric allow_generic);
124   ~JSToWasmWrapperCompilationUnit();
125 
126   void Execute();
127   Handle<Code> Finalize(Isolate* isolate);
128 
is_import()129   bool is_import() const { return is_import_; }
sig()130   const FunctionSig* sig() const { return sig_; }
131 
132   // Run a compilation unit synchronously.
133   static Handle<Code> CompileJSToWasmWrapper(Isolate* isolate,
134                                              const FunctionSig* sig,
135                                              const WasmModule* module,
136                                              bool is_import);
137 
138   // Run a compilation unit synchronously, but ask for the specific
139   // wrapper.
140   static Handle<Code> CompileSpecificJSToWasmWrapper(Isolate* isolate,
141                                                      const FunctionSig* sig,
142                                                      const WasmModule* module);
143 
144  private:
145   bool is_import_;
146   const FunctionSig* sig_;
147   bool use_generic_wrapper_;
148   std::unique_ptr<OptimizedCompilationJob> job_;
149 };
150 
151 }  // namespace wasm
152 }  // namespace internal
153 }  // namespace v8
154 
155 #endif  // V8_WASM_FUNCTION_COMPILER_H_
156