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 23namespace v8 { 24namespace internal { 25 26class Counters; 27class TurbofanCompilationJob; 28 29namespace wasm { 30 31class NativeModule; 32class WasmCode; 33class WasmEngine; 34struct WasmFunction; 35 36struct WasmCompilationResult { 37 public: 38 MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmCompilationResult); 39 40 enum Kind : int8_t { 41 kFunction, 42 kWasmToJsWrapper, 43 }; 44 45 bool succeeded() const { return code_desc.buffer != nullptr; } 46 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 63class V8_EXPORT_PRIVATE WasmCompilationUnit final { 64 public: 65 static ExecutionTier GetBaselineExecutionTier(const WasmModule*); 66 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 74 ExecutionTier tier() const { return tier_; } 75 ForDebugging for_debugging() const { return for_debugging_; } 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. 97ASSERT_TRIVIALLY_COPYABLE(WasmCompilationUnit); 98STATIC_ASSERT(sizeof(WasmCompilationUnit) <= 2 * kSystemPointerSize); 99 100class 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 112 Isolate* isolate() const { return isolate_; } 113 114 void Execute(); 115 Handle<Code> Finalize(); 116 117 bool is_import() const { return is_import_; } 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