forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfunction-compiler.h
More file actions
180 lines (147 loc) Β· 6.03 KB
/
function-compiler.h
File metadata and controls
180 lines (147 loc) Β· 6.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_FUNCTION_COMPILER_H_
#define V8_WASM_FUNCTION_COMPILER_H_
#if !V8_ENABLE_WEBASSEMBLY
#error This header should only be included if WebAssembly is enabled.
#endif // !V8_ENABLE_WEBASSEMBLY
#include <memory>
#include "src/codegen/assembler.h"
#include "src/codegen/code-desc.h"
#include "src/codegen/compiler.h"
#include "src/wasm/compilation-environment.h"
#include "src/wasm/function-body-decoder.h"
#include "src/wasm/wasm-deopt-data.h"
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-tier.h"
namespace v8 {
namespace internal {
class Counters;
class TurbofanCompilationJob;
namespace wasm {
class NativeModule;
class WasmCode;
class WasmEngine;
struct WasmFunction;
// Stores assumptions that a Wasm compilation job made while executing,
// so they can be checked for continued validity when the job finishes.
class AssumptionsJournal {
public:
AssumptionsJournal() = default;
void RecordAssumption(uint32_t func_index, WellKnownImport status) {
imports_.push_back(std::make_pair(func_index, status));
}
const std::vector<std::pair<uint32_t, WellKnownImport>>& import_statuses() {
return imports_;
}
bool empty() const { return imports_.empty(); }
private:
// This is not particularly efficient, but it's probably good enough.
// For most compilations, this won't hold any entries. If it does
// hold entries, their number is expected to be small, because most
// functions don't call many imports, and many imports won't be
// specially recognized.
std::vector<std::pair<uint32_t, WellKnownImport>> imports_;
};
struct WasmCompilationResult {
public:
MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmCompilationResult);
enum Kind : int8_t {
kFunction,
kWasmToJsWrapper,
#if V8_ENABLE_DRUMBRAKE
kInterpreterEntry,
#endif // V8_ENABLE_DRUMBRAKE
};
bool succeeded() const { return code_desc.buffer != nullptr; }
bool failed() const { return !succeeded(); }
explicit operator bool() const { return succeeded(); }
CodeDesc code_desc;
std::unique_ptr<AssemblerBuffer> instr_buffer;
uint32_t frame_slot_count = 0;
uint32_t ool_spill_count = 0;
uint32_t tagged_parameter_slots = 0;
base::OwnedVector<uint8_t> source_positions;
base::OwnedVector<uint8_t> inlining_positions;
base::OwnedVector<uint8_t> protected_instructions_data;
base::OwnedVector<uint8_t> deopt_data;
std::unique_ptr<AssumptionsJournal> assumptions;
std::unique_ptr<LiftoffFrameDescriptionForDeopt> liftoff_frame_descriptions;
int func_index = kAnonymousFuncIndex;
ExecutionTier result_tier = ExecutionTier::kNone;
Kind kind = kFunction;
ForDebugging for_debugging = kNotForDebugging;
bool frame_has_feedback_slot = false;
};
class V8_EXPORT_PRIVATE WasmCompilationUnit final {
public:
WasmCompilationUnit(int index, ExecutionTier tier, ForDebugging for_debugging)
: func_index_(index), tier_(tier), for_debugging_(for_debugging) {
DCHECK_IMPLIES(for_debugging != ForDebugging::kNotForDebugging,
tier_ == ExecutionTier::kLiftoff);
}
WasmCompilationResult ExecuteCompilation(CompilationEnv*,
const WireBytesStorage*, Counters*,
WasmDetectedFeatures* detected);
ExecutionTier tier() const { return tier_; }
ForDebugging for_debugging() const { return for_debugging_; }
int func_index() const { return func_index_; }
static void CompileWasmFunction(Counters*, NativeModule*,
WasmDetectedFeatures* detected,
const WasmFunction*, ExecutionTier);
private:
int func_index_;
ExecutionTier tier_;
ForDebugging for_debugging_;
};
// {WasmCompilationUnit} should be trivially copyable and small enough so we can
// efficiently pass it by value.
ASSERT_TRIVIALLY_COPYABLE(WasmCompilationUnit);
static_assert(sizeof(WasmCompilationUnit) <= 2 * kSystemPointerSize);
class V8_EXPORT_PRIVATE JSToWasmWrapperCompilationUnit final {
public:
JSToWasmWrapperCompilationUnit(Isolate* isolate, const CanonicalSig* sig,
CanonicalTypeIndex sig_index);
~JSToWasmWrapperCompilationUnit();
// Allow move construction and assignment, for putting units in a std::vector.
JSToWasmWrapperCompilationUnit(JSToWasmWrapperCompilationUnit&&)
V8_NOEXCEPT = default;
JSToWasmWrapperCompilationUnit& operator=(JSToWasmWrapperCompilationUnit&&)
V8_NOEXCEPT = default;
Isolate* isolate() const { return isolate_; }
void Execute();
DirectHandle<Code> Finalize();
const CanonicalSig* sig() const { return sig_; }
CanonicalTypeIndex sig_index() const { return sig_index_; }
// Run a compilation unit synchronously.
static DirectHandle<Code> CompileJSToWasmWrapper(
Isolate* isolate, const CanonicalSig* sig, CanonicalTypeIndex sig_index);
private:
// Wrapper compilation is bound to an isolate. Concurrent accesses to the
// isolate (during the "Execute" phase) must be audited carefully, i.e. we
// should only access immutable information (like the root table). The isolate
// is guaranteed to be alive when this unit executes.
Isolate* isolate_;
const CanonicalSig* sig_;
CanonicalTypeIndex sig_index_;
std::unique_ptr<OptimizedCompilationJob> job_;
};
inline bool CanUseGenericJsToWasmWrapper(const WasmModule* module,
const CanonicalSig* sig) {
#if (V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 || \
V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_S390X || V8_TARGET_ARCH_PPC64 || \
V8_TARGET_ARCH_LOONG64)
// We don't use the generic wrapper for asm.js, because it creates invalid
// stack traces.
return !is_asmjs_module(module) && v8_flags.wasm_generic_wrapper &&
IsJSCompatibleSignature(sig);
#else
return false;
#endif
}
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_FUNCTION_COMPILER_H_