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