5 #ifndef V8_WASM_WASM_CODE_MANAGER_H_ 6 #define V8_WASM_WASM_CODE_MANAGER_H_ 11 #include <unordered_map> 12 #include <unordered_set> 14 #include "src/base/macros.h" 15 #include "src/builtins/builtins-definitions.h" 16 #include "src/handles.h" 17 #include "src/trap-handler/trap-handler.h" 18 #include "src/vector.h" 19 #include "src/wasm/compilation-environment.h" 20 #include "src/wasm/wasm-features.h" 21 #include "src/wasm/wasm-limits.h" 32 class WasmCodeManager;
34 class WasmMemoryTracker;
35 class WasmImportWrapperCache;
46 : regions_({region}) {}
61 bool IsEmpty()
const {
return regions_.empty(); }
62 const std::list<base::AddressRegion>& regions()
const {
return regions_; }
65 std::list<base::AddressRegion> regions_;
84 #define DEF_ENUM(Name) k##Name, 85 #define DEF_ENUM_TRAP(Name) kThrowWasm##Name, 86 WASM_RUNTIME_STUB_LIST(DEF_ENUM, DEF_ENUM_TRAP)
95 enum Tier : int8_t { kLiftoff, kTurbofan, kOther };
97 Vector<byte> instructions()
const {
return instructions_; }
98 Address instruction_start()
const {
99 return reinterpret_cast<Address>(instructions_.start());
103 return source_position_table_.as_vector();
107 DCHECK(!IsAnonymous());
111 bool IsAnonymous()
const {
return index_ == kAnonymousFuncIndex; }
112 Kind kind()
const {
return kind_; }
113 NativeModule* native_module()
const {
return native_module_; }
114 Tier tier()
const {
return tier_; }
116 size_t constant_pool_offset()
const {
return constant_pool_offset_; }
117 size_t safepoint_table_offset()
const {
return safepoint_table_offset_; }
118 size_t handler_table_offset()
const {
return handler_table_offset_; }
119 uint32_t stack_slots()
const {
return stack_slots_; }
120 bool is_liftoff()
const {
return tier_ == kLiftoff; }
121 bool contains(
Address pc)
const {
122 return reinterpret_cast<Address>(instructions_.start()) <= pc &&
123 pc < reinterpret_cast<Address>(instructions_.end());
128 return protected_instructions_.as_vector();
131 const char* GetRuntimeStubName()
const;
133 void Validate()
const;
134 void Print(
const char* name =
nullptr)
const;
135 void Disassemble(
const char* name, std::ostream& os,
136 Address current_pc = kNullAddress)
const;
138 static bool ShouldBeLogged(
Isolate* isolate);
139 void LogCode(
Isolate* isolate)
const;
143 enum FlushICache :
bool { kFlushICache =
true, kNoFlushICache =
false };
145 static constexpr
uint32_t kAnonymousFuncIndex = 0xffffffff;
146 STATIC_ASSERT(kAnonymousFuncIndex > kV8MaxWasmFunctions);
153 size_t safepoint_table_offset,
size_t handler_table_offset,
154 size_t constant_pool_offset,
156 protected_instructions,
159 : instructions_(instructions),
160 reloc_info_(std::move(reloc_info)),
161 source_position_table_(std::move(source_position_table)),
162 native_module_(native_module),
165 constant_pool_offset_(constant_pool_offset),
166 stack_slots_(stack_slots),
167 safepoint_table_offset_(safepoint_table_offset),
168 handler_table_offset_(handler_table_offset),
169 protected_instructions_(std::move(protected_instructions)),
171 DCHECK_LE(safepoint_table_offset, instructions.size());
172 DCHECK_LE(constant_pool_offset, instructions.size());
173 DCHECK_LE(handler_table_offset, instructions.size());
178 size_t trap_handler_index()
const;
179 void set_trap_handler_index(
size_t);
180 bool HasTrapHandlerIndex()
const;
184 void RegisterTrapHandlerData();
192 size_t constant_pool_offset_ = 0;
197 size_t safepoint_table_offset_ = 0;
198 size_t handler_table_offset_ = 0;
199 intptr_t trap_handler_index_ = -1;
207 const char* GetWasmCodeKindAsString(WasmCode::Kind);
211 #if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_S390X || V8_TARGET_ARCH_ARM64 212 static constexpr
bool kCanAllocateMoreMemory =
false;
214 static constexpr
bool kCanAllocateMoreMemory =
true;
220 size_t safepoint_table_offset,
size_t handler_table_offset,
222 protected_instructions,
224 WasmCode::Kind kind, WasmCode::Tier tier);
228 size_t safepoint_table_offset,
size_t handler_table_offset,
229 size_t constant_pool_offset,
231 protected_instructions,
247 void SetRuntimeStubs(
Isolate* isolate);
261 std::vector<WasmCode*> SnapshotCodeTable()
const;
264 DCHECK_LT(index, num_functions());
265 DCHECK_LE(module_->num_imported_functions, index);
266 return code_table_[index - module_->num_imported_functions];
269 bool has_code(
uint32_t index)
const {
return code(index) !=
nullptr; }
271 WasmCode* runtime_stub(WasmCode::RuntimeStubId index)
const {
272 DCHECK_LT(index, WasmCode::kRuntimeStubCount);
273 WasmCode* code = runtime_stub_table_[index];
274 DCHECK_NOT_NULL(code);
278 Address jump_table_start()
const {
279 return jump_table_ ? jump_table_->instruction_start() : kNullAddress;
282 ptrdiff_t jump_table_offset(
uint32_t func_index)
const {
283 DCHECK_GE(func_index, num_imported_functions());
284 return GetCallTargetForFunction(func_index) - jump_table_start();
287 bool is_jump_table_slot(
Address address)
const {
288 return jump_table_->contains(address);
297 void DisableTrapHandler();
305 uint32_t GetFunctionIndexFromJumpTableSlot(
Address slot_address)
const;
307 bool SetExecutable(
bool executable);
311 void ReserveCodeTableForTesting(
uint32_t max_functions);
313 void LogWasmCodes(
Isolate* isolate);
322 return module_->num_declared_functions + module_->num_imported_functions;
324 uint32_t num_imported_functions()
const {
325 return module_->num_imported_functions;
327 UseTrapHandler use_trap_handler()
const {
return use_trap_handler_; }
328 void set_lazy_compile_frozen(
bool frozen) { lazy_compile_frozen_ = frozen; }
329 bool lazy_compile_frozen()
const {
return lazy_compile_frozen_; }
331 const WasmModule* module()
const {
return module_.get(); }
332 size_t committed_code_space()
const {
return committed_code_space_.load(); }
339 return import_wrapper_cache_.get();
344 const WasmFeatures& enabled_features()
const {
return enabled_features_; }
354 std::shared_ptr<const WasmModule> module);
357 const char* name =
nullptr);
366 uint32_t stack_slots,
size_t safepoint_table_offset,
367 size_t handler_table_offset,
368 size_t constant_pool_offset,
372 WasmCode::Kind, WasmCode::Tier);
380 return {code_table_.get(), module_->num_declared_functions};
384 bool has_interpreter_redirection(
uint32_t func_index) {
385 DCHECK_LT(func_index, num_functions());
386 DCHECK_LE(module_->num_imported_functions, func_index);
387 if (!interpreter_redirections_)
return false;
388 uint32_t bitset_idx = func_index - module_->num_imported_functions;
389 uint8_t byte = interpreter_redirections_[bitset_idx / kBitsPerByte];
390 return byte & (1 << (bitset_idx % kBitsPerByte));
394 void SetInterpreterRedirection(
uint32_t func_index) {
395 DCHECK_LT(func_index, num_functions());
396 DCHECK_LE(module_->num_imported_functions, func_index);
397 if (!interpreter_redirections_) {
398 interpreter_redirections_.reset(
399 new uint8_t[RoundUp<kBitsPerByte>(module_->num_declared_functions) /
402 uint32_t bitset_idx = func_index - module_->num_imported_functions;
403 uint8_t& byte = interpreter_redirections_[bitset_idx / kBitsPerByte];
404 byte |= 1 << (bitset_idx % kBitsPerByte);
414 std::shared_ptr<const WasmModule> module_;
418 WasmCode* runtime_stub_table_[WasmCode::kRuntimeStubCount] = {
nullptr};
426 std::unique_ptr<CompilationState> compilation_state_;
429 std::unique_ptr<WasmImportWrapperCache> import_wrapper_cache_;
439 std::vector<std::unique_ptr<WasmCode>> owned_code_;
441 std::unique_ptr<WasmCode* []> code_table_;
445 std::unique_ptr<uint8_t[]> interpreter_redirections_;
449 std::list<VirtualMemory> owned_code_space_;
455 std::atomic<size_t> committed_code_space_{0};
456 int modification_scope_depth_ = 0;
457 bool can_request_more_memory_;
458 UseTrapHandler use_trap_handler_ = kNoTrapHandler;
459 bool is_executable_ =
false;
460 bool lazy_compile_frozen_ =
false;
468 size_t max_committed);
475 std::unique_ptr<NativeModule> NewNativeModule(
477 size_t code_size_estimate,
bool can_request_more,
478 std::shared_ptr<const WasmModule> module);
482 size_t remaining_uncommitted_code_space()
const;
485 void SampleModuleSizes(
Isolate* isolate)
const;
487 void SetMaxCommittedMemoryForTesting(
size_t limit);
492 static void InstallSamplingGCCallback(
Isolate* isolate);
494 static size_t EstimateNativeModuleCodeSize(
const WasmModule* module);
495 static size_t EstimateNativeModuleNonCodeSize(
const WasmModule* module);
501 void* hint =
nullptr);
510 bool ShouldForceCriticalMemoryPressureNotification();
513 std::atomic<size_t> remaining_uncommitted_code_space_;
519 std::map<Address, std::pair<Address, NativeModule*>> lookup_map_;
520 std::unordered_set<NativeModule*> native_modules_;
551 #endif // V8_WASM_WASM_CODE_MANAGER_H_