v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
function-compiler.h
Go to the documentation of this file.
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#if !V8_ENABLE_WEBASSEMBLY
9#error This header should only be included if WebAssembly is enabled.
10#endif // !V8_ENABLE_WEBASSEMBLY
11
12#include <memory>
13
22#include "src/wasm/wasm-tier.h"
23
24namespace v8 {
25namespace internal {
26
27class Counters;
28class TurbofanCompilationJob;
29
30namespace wasm {
31
32class NativeModule;
33class WasmCode;
34class WasmEngine;
35struct WasmFunction;
36
37// Stores assumptions that a Wasm compilation job made while executing,
38// so they can be checked for continued validity when the job finishes.
40 public:
41 AssumptionsJournal() = default;
42
43 void RecordAssumption(uint32_t func_index, WellKnownImport status) {
44 imports_.push_back(std::make_pair(func_index, status));
45 }
46
47 const std::vector<std::pair<uint32_t, WellKnownImport>>& import_statuses() {
48 return imports_;
49 }
50
51 bool empty() const { return imports_.empty(); }
52
53 private:
54 // This is not particularly efficient, but it's probably good enough.
55 // For most compilations, this won't hold any entries. If it does
56 // hold entries, their number is expected to be small, because most
57 // functions don't call many imports, and many imports won't be
58 // specially recognized.
59 std::vector<std::pair<uint32_t, WellKnownImport>> imports_;
60};
61
63 public:
65
66 enum Kind : int8_t {
69#if V8_ENABLE_DRUMBRAKE
70 kInterpreterEntry,
71#endif // V8_ENABLE_DRUMBRAKE
72 };
73
74 bool succeeded() const { return code_desc.buffer != nullptr; }
75 bool failed() const { return !succeeded(); }
76 explicit operator bool() const { return succeeded(); }
77
79 std::unique_ptr<AssemblerBuffer> instr_buffer;
80 uint32_t frame_slot_count = 0;
81 uint32_t ool_spill_count = 0;
87 std::unique_ptr<AssumptionsJournal> assumptions;
88 std::unique_ptr<LiftoffFrameDescriptionForDeopt> liftoff_frame_descriptions;
94};
95
97 public:
98 WasmCompilationUnit(int index, ExecutionTier tier, ForDebugging for_debugging)
99 : func_index_(index), tier_(tier), for_debugging_(for_debugging) {
100 DCHECK_IMPLIES(for_debugging != ForDebugging::kNotForDebugging,
101 tier_ == ExecutionTier::kLiftoff);
102 }
103
104 WasmCompilationResult ExecuteCompilation(CompilationEnv*,
105 const WireBytesStorage*, Counters*,
106 WasmDetectedFeatures* detected);
107
108 ExecutionTier tier() const { return tier_; }
110 int func_index() const { return func_index_; }
111
112 static void CompileWasmFunction(Counters*, NativeModule*,
113 WasmDetectedFeatures* detected,
115
116 private:
120};
121
122// {WasmCompilationUnit} should be trivially copyable and small enough so we can
123// efficiently pass it by value.
125static_assert(sizeof(WasmCompilationUnit) <= 2 * kSystemPointerSize);
126
128 public:
130 CanonicalTypeIndex sig_index);
132
133 // Allow move construction and assignment, for putting units in a std::vector.
135 V8_NOEXCEPT = default;
137 V8_NOEXCEPT = default;
138
139 Isolate* isolate() const { return isolate_; }
140
141 void Execute();
142 DirectHandle<Code> Finalize();
143
144 const CanonicalSig* sig() const { return sig_; }
145 CanonicalTypeIndex sig_index() const { return sig_index_; }
146
147 // Run a compilation unit synchronously.
148 static DirectHandle<Code> CompileJSToWasmWrapper(
149 Isolate* isolate, const CanonicalSig* sig, CanonicalTypeIndex sig_index);
150
151 private:
152 // Wrapper compilation is bound to an isolate. Concurrent accesses to the
153 // isolate (during the "Execute" phase) must be audited carefully, i.e. we
154 // should only access immutable information (like the root table). The isolate
155 // is guaranteed to be alive when this unit executes.
159 std::unique_ptr<OptimizedCompilationJob> job_;
160};
161
162inline bool CanUseGenericJsToWasmWrapper(const WasmModule* module,
163 const CanonicalSig* sig) {
164#if (V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 || \
165 V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_S390X || V8_TARGET_ARCH_PPC64 || \
166 V8_TARGET_ARCH_LOONG64)
167 // We don't use the generic wrapper for asm.js, because it creates invalid
168 // stack traces.
169 return !is_asmjs_module(module) && v8_flags.wasm_generic_wrapper &&
171#else
172 return false;
173#endif
174}
175
176} // namespace wasm
177} // namespace internal
178} // namespace v8
179
180#endif // V8_WASM_FUNCTION_COMPILER_H_
Isolate * isolate_
void RecordAssumption(uint32_t func_index, WellKnownImport status)
const std::vector< std::pair< uint32_t, WellKnownImport > > & import_statuses()
std::vector< std::pair< uint32_t, WellKnownImport > > imports_
JSToWasmWrapperCompilationUnit(JSToWasmWrapperCompilationUnit &&) V8_NOEXCEPT=default
std::unique_ptr< OptimizedCompilationJob > job_
WasmCompilationUnit(int index, ExecutionTier tier, ForDebugging for_debugging)
const ForDebugging for_debugging_
const int func_index_
const CompilationTier tier_
constexpr int kAnonymousFuncIndex
bool is_asmjs_module(const WasmModule *module)
bool IsJSCompatibleSignature(const CanonicalSig *sig)
bool CanUseGenericJsToWasmWrapper(const WasmModule *module, const CanonicalSig *sig)
kWasmInternalFunctionIndirectPointerTag kProtectedInstanceDataOffset sig
constexpr int kSystemPointerSize
Definition globals.h:410
V8_EXPORT_PRIVATE FlagValues v8_flags
wasm::WasmFunction WasmFunction
Definition c-api.cc:87
#define V8_NOEXCEPT
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define ASSERT_TRIVIALLY_COPYABLE(T)
Definition macros.h:267
#define V8_EXPORT_PRIVATE
Definition macros.h:460
base::OwnedVector< uint8_t > source_positions
base::OwnedVector< uint8_t > protected_instructions_data
std::unique_ptr< AssumptionsJournal > assumptions
MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmCompilationResult)
std::unique_ptr< LiftoffFrameDescriptionForDeopt > liftoff_frame_descriptions
base::OwnedVector< uint8_t > inlining_positions
std::unique_ptr< AssemblerBuffer > instr_buffer
base::OwnedVector< uint8_t > deopt_data