42#if V8_ENABLE_DRUMBRAKE
46#ifdef V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING
52#define TRACE_CODE_GC(...) \
54 if (v8_flags.trace_wasm_code_gc) PrintF("[wasm-gc] " __VA_ARGS__); \
96 Address** location = that->location_.get();
98 that->location_.reset();
100 *that->prev_ptr_ = that->next_;
101 if (that->next_ !=
nullptr) that->next_->prev_ptr_ = that->prev_ptr_;
131 orphan->
next_ = *pointer;
142 while (
start !=
nullptr) {
173void CheckNoArchivedThreads(
Isolate* isolate) {
179 FATAL(
"archived threads in combination with wasm not supported");
181 } archived_threads_visitor;
182 isolate->thread_manager()->IterateArchivedThreads(&archived_threads_visitor);
187 explicit WasmGCForegroundTask(
Isolate* isolate)
190 void RunInternal() final {
200class ClearWeakScriptHandleTask :
public CancelableTask {
202 explicit ClearWeakScriptHandleTask(Isolate* isolate,
203 std::unique_ptr<Address*> location)
204 : CancelableTask(isolate->cancelable_task_manager()) {
205 handle_ = isolate->NewWasmOrphanedGlobalHandle();
206 handle_->InitializeLocation(std::move(location));
214 void RunInternal()
override {
215 WasmOrphanedGlobalHandle::Destroy(
handle_);
224class WeakScriptHandle {
226 WeakScriptHandle(DirectHandle<Script> script, Isolate* isolate)
228 DCHECK(IsString(script->name()) || IsUndefined(script->name()));
229 if (IsString(script->name())) {
230 source_url_ = Cast<String>(script->name())->ToCString();
232 auto global_handle = isolate->global_handles()->Create(*script);
233 location_ = std::make_unique<Address*>(global_handle.location());
234 GlobalHandles::MakeWeak(
location_.get());
237 ~WeakScriptHandle() {
251 WeakScriptHandle(WeakScriptHandle&&)
V8_NOEXCEPT = default;
253 DirectHandle<Script> handle()
const {
254 return DirectHandle<Script>::FromSlot(*
location_);
263 const std::shared_ptr<const char[]>& source_url()
const {
291std::vector<std::shared_ptr<NativeModule>>* native_modules_kept_alive_for_pgo;
298 if (!
v8_flags.wasm_native_module_cache)
return nullptr;
305 if (it ==
map_.end()) {
315 [[maybe_unused]]
auto [iterator, inserted] =
316 map_.emplace(
key, std::nullopt);
320 if (it->second.has_value()) {
321 if (
auto shared_native_module = it->second.value().lock()) {
323 shared_native_module->compile_imports().compare(compile_imports),
325 DCHECK_EQ(shared_native_module->wire_bytes(), wire_bytes);
326 return shared_native_module;
337 if (!
v8_flags.wasm_native_module_cache)
return true;
339 auto it =
map_.lower_bound(
Key{prefix_hash, compile_imports, {}});
340 if (it !=
map_.end() && it->first.prefix_hash == prefix_hash) {
345 Key key{prefix_hash, compile_imports, {}};
347 map_.emplace(
key, std::nullopt);
353 if (!
v8_flags.wasm_native_module_cache)
return;
355 Key key{prefix_hash, compile_imports, {}};
361 std::shared_ptr<NativeModule> native_module,
bool error) {
363 if (!
v8_flags.wasm_native_module_cache)
return native_module;
364 if (native_module->module()->origin !=
kWasmOrigin)
return native_module;
367 size_t prefix_hash =
PrefixHash(native_module->wire_bytes());
370 map_.erase(
Key{prefix_hash, compile_imports, {}});
371 const Key key{prefix_hash, compile_imports, wire_bytes};
373 if (it !=
map_.end()) {
374 if (it->second.has_value()) {
375 auto conflicting_module = it->second.value().lock();
376 if (conflicting_module !=
nullptr) {
377 DCHECK_EQ(conflicting_module->wire_bytes(), wire_bytes);
382 return conflicting_module;
391 [[maybe_unused]]
auto [iterator, inserted] =
map_.emplace(
392 key, std::optional<std::weak_ptr<NativeModule>>(native_module));
396 return native_module;
400 if (!
v8_flags.wasm_native_module_cache)
return;
419 while (decoder.
ok() && decoder.
more()) {
421 uint32_t section_size = decoder.
consume_u32v(
"section size");
423 hasher.
Add(section_size);
426 const uint8_t* payload_start = decoder.
pc();
430 return hasher.
hash();
484 for (
auto& [native_module, script_handle] :
scripts) {
485 script_handle.Clear();
493 std::unordered_map<NativeModule*, WeakScriptHandle>
scripts;
522 std::unique_ptr<Address*> location) {
528 runner->
PostTask(std::make_unique<ClearWeakScriptHandleTask>(
529 isolate, std::move(location)));
546#ifdef V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING
557 if (
V8_UNLIKELY(native_modules_kept_alive_for_pgo)) {
558 delete native_modules_kept_alive_for_pgo;
568 code->DcheckRefCountIsOne();
589 if (bytes.empty())
return false;
593 enabled, bytes,
true,
kWasmOrigin, isolate->counters(),
594 isolate->metrics_recorder(),
595 isolate->GetOrRegisterRecorderContextId(isolate->native_context()),
597 if (
result.failed())
return false;
599 result.value().get(), bytes, compile_imports, &unused_detected_features);
600 return !error.has_error();
609 TRACE_EVENT1(
"v8.wasm",
"wasm.SyncCompileTranslatedAsmJs",
"id",
621 isolate->counters(), isolate->metrics_recorder(), context_id,
626 std::cout <<
result.error().message();
630 result.value()->asm_js_offset_information =
631 std::make_unique<AsmJsOffsetInformation>(asm_js_offset_table_bytes);
639 std::move(bytes), compilation_id, context_id, kNoProfileInformation);
640 if (!native_module)
return {};
642 native_module->LogWasmCodes(isolate, *script);
651 if (scripts.count(native_module.get()) == 0) {
652 scripts.emplace(native_module.get(), WeakScriptHandle(script, isolate));
662 std::shared_ptr<NativeModule> native_module =
663 asm_wasm_data->managed_native_module()->get();
666 return module_object;
674 TRACE_EVENT1(
"v8.wasm",
"wasm.SyncCompile",
"id", compilation_id);
676 isolate->GetOrRegisterRecorderContextId(isolate->native_context());
677 std::shared_ptr<WasmModule> module;
682 bool validate_module =
v8_flags.wasm_jitless;
684 enabled_features, bytes.as_vector(), validate_module,
kWasmOrigin,
685 isolate->counters(), isolate->metrics_recorder(), context_id,
691 module = std::move(result).value();
694 compile_imports, &detected_features)) {
695 thrower->CompileError(
"%s @+%u", error.message().c_str(), error.offset());
701 std::unique_ptr<ProfileInformation> pgo_info;
709 isolate, enabled_features, detected_features, std::move(compile_imports),
710 thrower, std::move(module), std::move(bytes), compilation_id, context_id,
712 if (!native_module)
return {};
729 native_module->LogWasmCodes(isolate, *script);
739 isolate->debug()->OnAfterCompile(script);
740 return module_object;
754 Isolate* isolate, std::unique_ptr<InstantiationResultResolver> resolver,
757 ErrorThrower thrower(isolate,
"WebAssembly.instantiate()");
776 if (isolate->has_exception()) {
778 if (isolate->is_execution_terminating())
return;
782 isolate->clear_exception();
783 resolver->OnInstantiationFailed(exception);
786 resolver->OnInstantiationFailed(thrower.
Reify());
793 std::shared_ptr<CompilationResultResolver> resolver,
795 const char* api_method_name_for_errors) {
797 TRACE_EVENT1(
"v8.wasm",
"wasm.AsyncCompile",
"id", compilation_id);
801 ErrorThrower thrower(isolate, api_method_name_for_errors);
803 module_object =
SyncCompile(isolate, enabled, std::move(compile_imports),
804 &thrower, std::move(bytes));
805 if (thrower.
error()) {
806 resolver->OnCompilationFailed(thrower.
Reify());
810 resolver->OnCompilationSucceeded(module);
815 std::shared_ptr<StreamingDecoder> streaming_decoder =
818 api_method_name_for_errors,
819 std::move(resolver));
821 auto* rng = isolate->random_number_generator();
823 if (!bytes.empty()) ranges.
push_back(bytes.as_vector());
825 for (
int round = 0; round < 4; ++round) {
826 for (
auto it = ranges.begin(); it != ranges.end(); ++it) {
828 if (range.size() < 2 || !rng->NextBool())
continue;
832 1 + rng->NextInt(
static_cast<int>(range.size() - 1));
834 it = ranges.insert(it, range.SubVector(0, split_point)) + 1;
835 *it = range.SubVectorFrom(split_point);
838 for (
auto range : ranges) {
839 streaming_decoder->OnBytesReceived(range);
841 streaming_decoder->Finish();
846 isolate, enabled, std::move(compile_imports), std::move(bytes),
847 isolate->native_context(), api_method_name_for_errors,
848 std::move(resolver), compilation_id);
855 const char* api_method_name,
856 std::shared_ptr<CompilationResultResolver> resolver) {
858 TRACE_EVENT1(
"v8.wasm",
"wasm.StartStreamingCompilation",
"id",
860 if (
v8_flags.wasm_async_compilation) {
862 isolate, enabled, std::move(compile_imports), {},
context,
863 api_method_name, std::move(resolver), compilation_id);
867 isolate, enabled, std::move(compile_imports), context, api_method_name,
868 std::move(resolver));
879 counters, native_module, &detected,
880 &native_module->
module()->functions[function_index], tier);
886 std::vector<std::shared_ptr<NativeModule>> native_modules;
892 if (
isolates_[isolate]->keep_in_debug_state)
return;
894 for (
auto* native_module :
isolates_[isolate]->native_modules) {
896 if (
auto shared_ptr =
native_modules_[native_module]->weak_ptr.lock()) {
897 native_modules.emplace_back(std::move(shared_ptr));
903 for (
auto& native_module : native_modules) {
904 native_module->RemoveCompiledCode(
913 std::vector<std::pair<std::shared_ptr<NativeModule>,
bool>> native_modules;
917 auto can_remove_debug_code = [
this](
NativeModule* native_module) {
921 if (
isolates_[isolate]->keep_in_debug_state)
return false;
925 for (
auto* native_module :
isolates_[isolate]->native_modules) {
928 if (!shared_ptr)
continue;
929 if (!native_module->IsInDebugState())
continue;
932 bool remove_debug_code = can_remove_debug_code(native_module);
933 if (remove_debug_code) native_module->SetDebugState(
kNotDebugging);
934 native_modules.emplace_back(std::move(shared_ptr), remove_debug_code);
937 for (
auto& entry : native_modules) {
938 auto& native_module = entry.first;
939 bool remove_debug_code = entry.second;
941 if (native_module->HasDebugInfo()) {
942 native_module->GetDebugInfo()->RemoveIsolate(isolate);
944 if (remove_debug_code) {
946 native_module->RemoveCompiledCode(
954 Isolate* isolate, std::shared_ptr<NativeModule> native_module,
962 const WasmModule* module = native_module->module();
964 if (!source_url.
empty()) {
965 url_str = isolate->factory()
974 int url_len = SNPrintF(buffer,
"wasm://wasm/%08x", hash);
976 url_str = isolate->factory()
977 ->NewStringFromUtf8(buffer.
SubVector(0, url_len),
982 int hash_len = SNPrintF(buffer,
"-%08x", hash);
984 DirectHandle<String> prefix =
985 isolate->factory()->NewStringFromStaticChars(
"wasm://wasm/");
986 DirectHandle<String> module_name =
989 DirectHandle<String> hash_str =
991 ->NewStringFromUtf8(buffer.
SubVector(0, hash_len))
994 url_str = isolate->factory()
995 ->NewConsString(prefix, module_name)
997 url_str = isolate->factory()
998 ->NewConsString(url_str, hash_str)
1002 DirectHandle<PrimitiveHeapObject> source_map_url =
1003 isolate->factory()->undefined_value();
1006 auto source_map_symbols =
1007 module->debug_symbols[WasmDebugSymbols::Type::SourceMap];
1008 base::Vector<const char> external_url =
1009 ModuleWireBytes(wire_bytes)
1010 .GetNameOrNull(source_map_symbols.external_url);
1011 MaybeDirectHandle<String> src_map_str =
1012 isolate->factory()->NewStringFromUtf8(external_url,
1014 source_map_url = src_map_str.ToHandleChecked();
1019 size_t code_size_estimate = native_module->committed_code_space();
1020 size_t memory_estimate =
1021 code_size_estimate +
1023 DirectHandle<Managed<wasm::NativeModule>> managed_native_module =
1025 std::move(native_module));
1027 DirectHandle<Script> script =
1028 isolate->factory()->NewScript(isolate->factory()->undefined_value());
1033 raw_script->set_context_data(isolate->native_context()->debug_context_id());
1034 raw_script->set_name(*url_str);
1035 raw_script->set_type(Script::Type::kWasm);
1036 raw_script->set_source_mapping_url(*source_map_url);
1037 raw_script->set_line_ends(ReadOnlyRoots(isolate).empty_fixed_array(),
1039 raw_script->set_wasm_managed_native_module(*managed_native_module);
1040 raw_script->set_wasm_breakpoint_infos(
1042 raw_script->set_wasm_weak_instance_list(
1051 static constexpr bool kIsSharedCrossOrigin =
true;
1052 static constexpr bool kIsOpaque =
false;
1053 static constexpr bool kIsWasm =
true;
1054 static constexpr bool kIsModule =
false;
1055 raw_script->set_origin_options(ScriptOriginOptions(
1056 kIsSharedCrossOrigin, kIsOpaque, kIsWasm, kIsModule));
1064 Isolate* isolate, std::shared_ptr<NativeModule> shared_native_module,
1066 NativeModule* native_module = shared_native_module.get();
1086 isolate->debug()->OnAfterCompile(script);
1087 return module_object;
1094 std::vector<std::shared_ptr<NativeModule>> native_modules_with_dead_code;
1097 size_t removed_code_size = 0;
1098 size_t removed_metadata_size = 0;
1100 std::shared_ptr<NativeModule> shared = info->weak_ptr.lock();
1101 if (!shared)
continue;
1102 auto [code_size, metadata_size] = native_module->RemoveCompiledCode(
1104 DCHECK_EQ(code_size == 0, metadata_size == 0);
1105 if (code_size == 0)
continue;
1106 native_modules_with_dead_code.emplace_back(std::move(shared));
1107 removed_code_size += code_size;
1108 removed_metadata_size += metadata_size;
1110 return {removed_code_size, removed_metadata_size};
1115 size_t codesize_liftoff = 0;
1117 codesize_liftoff += native_module->SumLiftoffCodeSizeForTesting();
1119 return codesize_liftoff;
1122std::shared_ptr<CompilationStatistics>
1160 std::shared_ptr<CompilationResultResolver> resolver,
int compilation_id) {
1162 isolate->GetIncumbentContext();
1164 isolate, enabled, std::move(compile_imports), std::move(bytes), context,
1165 incumbent_context, api_method_name, std::move(resolver), compilation_id);
1177 std::unique_ptr<AsyncCompileJob>
result = std::move(item->second);
1186 if (entry.first->isolate() == isolate)
return true;
1194 std::vector<std::unique_ptr<AsyncCompileJob>> jobs_to_delete;
1199 if (!it->first->context().is_identical_to(context)) {
1203 jobs_to_delete.push_back(std::move(it->second));
1212 std::vector<std::unique_ptr<AsyncCompileJob>> jobs_to_delete;
1213 std::vector<std::weak_ptr<NativeModule>> modules_in_isolate;
1218 if (it->first->isolate() != isolate) {
1222 jobs_to_delete.push_back(std::move(it->second));
1227 for (
auto* native_module : isolate_info->native_modules) {
1229 modules_in_isolate.emplace_back(
native_modules_[native_module]->weak_ptr);
1237 for (
auto& weak_module : modules_in_isolate) {
1238 if (
auto shared_module = weak_module.lock()) {
1239 shared_module->compilation_state()->CancelInitialCompilation();
1250 auto isolate_info = std::make_unique<IsolateInfo>(isolate, log_code);
1253 isolates_.emplace(isolate, std::move(isolate_info));
1267 Counters* counters = isolate->counters();
1271 DCHECK_EQ(1, engine->isolates_.count(isolate));
1272 for (
auto* native_module : engine->isolates_[isolate]->native_modules) {
1273 native_module->SampleCodeSize(counters);
1281 Histogram* metadata_histogram = counters->wasm_engine_metadata_size_kb();
1282 if (metadata_histogram->
Enabled()) {
1283 size_t engine_meta_data = engine->EstimateCurrentMemoryConsumption();
1284 metadata_histogram->
AddSample(
static_cast<int>(engine_meta_data / KB));
1290#ifdef V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING
1292 gdb_server_->AddIsolate(isolate);
1298#ifdef V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING
1300 gdb_server_->RemoveIsolate(isolate);
1308 std::set<std::shared_ptr<NativeModule>> native_modules_with_code_to_log;
1314 auto isolates_it =
isolates_.find(isolate);
1316 IsolateInfo* isolate_info = isolates_it->second.get();
1327 auto has_isolate_with_code_logging = [
this, native_module_info] {
1328 return std::any_of(native_module_info->
isolates.begin(),
1329 native_module_info->
isolates.end(),
1331 return isolates_.find(isolate)->second->log_codes;
1334 DCHECK_EQ(native_module->log_code(), has_isolate_with_code_logging());
1336 native_module_info->
isolates.erase(isolate);
1337 if (native_module->log_code() && !has_isolate_with_code_logging()) {
1342 if (native_module->HasDebugInfo()) {
1343 native_module->GetDebugInfo()->RemoveIsolate(isolate);
1353 for (
auto& [script_id, code_to_log] : isolate_info->
code_to_log) {
1354 if (code_to_log.native_module ==
nullptr) {
1359 native_modules_with_code_to_log.insert(code_to_log.native_module);
1360 for (
WasmCode* code : code_to_log.code) {
1364 code->DecRefOnLiveCode();
1374 if (code_vec.
empty())
return;
1375 NativeModule* native_module = code_vec[0]->native_module();
1376 if (!native_module->
log_code())
return;
1377 using TaskToSchedule =
1378 std::pair<std::shared_ptr<v8::TaskRunner>, std::unique_ptr<LogCodesTask>>;
1379 std::vector<TaskToSchedule> to_schedule;
1385 std::shared_ptr<NativeModule> shared_native_module =
1386 native_module_info->
weak_ptr.lock();
1392 if (info->log_codes ==
false)
continue;
1394 auto script_it = info->
scripts.find(native_module);
1397 if (script_it == info->scripts.end())
continue;
1402 if (info->code_to_log.empty()) {
1403 isolate->stack_guard()->RequestLogWasmCode();
1404 to_schedule.emplace_back(info->foreground_task_runner,
1405 std::make_unique<LogCodesTask>(isolate));
1408 WeakScriptHandle& weak_script_handle = script_it->second;
1409 auto& log_entry = info->code_to_log[weak_script_handle.script_id()];
1410 if (!log_entry.native_module) {
1411 log_entry.native_module = shared_native_module;
1413 if (!log_entry.source_url) {
1414 log_entry.source_url = weak_script_handle.source_url();
1416 log_entry.code.insert(log_entry.code.end(), code_vec.
begin(),
1421 DCHECK_EQ(native_module, code->native_module());
1426 for (
auto& [runner, task] : to_schedule) {
1427 runner->PostTask(std::move(task));
1439 using TaskToSchedule =
1440 std::pair<std::shared_ptr<v8::TaskRunner>, std::unique_ptr<LogCodesTask>>;
1441 std::vector<TaskToSchedule> to_schedule;
1442 bool did_trigger_code_logging =
false;
1446 Isolate* isolate = entry.first;
1448 if (info->log_codes ==
false)
continue;
1449 did_trigger_code_logging =
true;
1453 if (info->code_to_log.empty()) {
1454 isolate->stack_guard()->RequestLogWasmCode();
1455 to_schedule.emplace_back(info->foreground_task_runner,
1456 std::make_unique<LogCodesTask>(isolate));
1459 constexpr int kNoScriptId = -1;
1461 log_entry.code.push_back(code);
1469 std::memory_order_relaxed) > 0);
1471 for (
auto& [runner, task] : to_schedule) {
1472 runner->PostTask(std::move(task));
1475 return did_trigger_code_logging;
1483 if (info->log_codes)
return;
1487 for (
NativeModule* native_module : info->native_modules) {
1503 [](std::pair<
NativeModule*
const, std::unique_ptr<NativeModuleInfo>>&
1504 pair) { return pair.first->log_code(); }));
1518 [](std::pair<
NativeModule*
const, std::unique_ptr<NativeModuleInfo>>&
1519 pair) { return pair.first->log_code(); }));
1525 std::unordered_map<int, IsolateInfo::CodeToLogPerScript> code_to_log_map;
1529 code_to_log_map.swap(
isolates_[isolate]->code_to_log);
1536 for (
auto& [script_id, code_to_log] : code_to_log_map) {
1538 for (
WasmCode* code : code_to_log.code) {
1539 const char* source_url = code_to_log.source_url.get();
1541 if (!source_url) source_url =
"";
1542 code->LogCode(isolate, source_url, script_id);
1552 std::shared_ptr<const WasmModule> module,
size_t code_size_estimate) {
1554 "wasm.NewNativeModule");
1555#ifdef V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING
1556 if (
v8_flags.wasm_gdb_remote && !gdb_server_) {
1558 gdb_server_->AddIsolate(isolate);
1567 std::shared_ptr<NativeModule> native_module =
1569 isolate, enabled_features, detected_features,
1570 std::move(compile_imports), code_size_estimate, std::move(module));
1573 if (!native_modules_kept_alive_for_pgo) {
1574 native_modules_kept_alive_for_pgo =
1575 new std::vector<std::shared_ptr<NativeModule>>;
1577 native_modules_kept_alive_for_pgo->emplace_back(native_module);
1580 native_module.get(), std::make_unique<NativeModuleInfo>(native_module)));
1583 native_module_info->
isolates.insert(isolate);
1598 isolate->counters()->wasm_memory_protection_keys_support();
1600 histogram->AddSample(has_mpk ? 1 : 0);
1603 isolate->counters()->wasm_modules_per_isolate()->AddSample(
1605 isolate->counters()->wasm_modules_per_engine()->AddSample(
1607 return native_module;
1613 TRACE_EVENT1(
"v8.wasm",
"wasm.GetNativeModuleFromCache",
"wire_bytes",
1615 std::shared_ptr<NativeModule> native_module =
1618 bool remove_all_code =
false;
1619 if (native_module) {
1623 if (!native_module_info) {
1624 native_module_info = std::make_unique<NativeModuleInfo>(native_module);
1626 native_module_info->isolates.insert(isolate);
1628 isolate_data->native_modules.insert(native_module.get());
1629 if (isolate_data->keep_in_debug_state && !native_module->IsInDebugState()) {
1630 remove_all_code =
true;
1633 if (isolate_data->log_codes && !native_module->log_code()) {
1637 if (remove_all_code) {
1639 native_module->RemoveCompiledCode(
1642 return native_module;
1646 bool has_error, std::shared_ptr<NativeModule> native_module,
1650 void* prev = native_module.get();
1653 if (prev == native_module.get())
return native_module;
1654 bool remove_all_code =
false;
1661 isolate_data->native_modules.insert(native_module.get());
1662 if (isolate_data->keep_in_debug_state && !native_module->IsInDebugState()) {
1663 remove_all_code =
true;
1666 if (isolate_data->log_codes && !native_module->log_code()) {
1670 if (remove_all_code) {
1672 native_module->RemoveCompiledCode(
1675 return native_module;
1680 TRACE_EVENT0(
"v8.wasm",
"wasm.GetStreamingCompilationOwnership");
1699 auto module = native_modules_.find(native_module);
1701 auto part_of_native_module = [native_module](
WasmCode*
code) {
1702 return code->native_module() == native_module;
1704 for (
Isolate* isolate : module->second->isolates) {
1707 DCHECK_EQ(1, info->native_modules.count(native_module));
1708 info->native_modules.erase(native_module);
1709 info->scripts.erase(native_module);
1719 for (
auto& log_entry : info->code_to_log) {
1720 for (
WasmCode* code : log_entry.second.code) {
1721 DCHECK_NE(native_module, code->native_module());
1732 if ((*it)->native_module() == native_module) {
1738 TRACE_CODE_GC(
"Native module %p died, reducing dead code objects to %zu.\n",
1752 std::unordered_set<WasmCode*>& live_code) {
1754 TRACE_CODE_GC(
"Isolate %d reporting %zu live code objects.\n", isolate->id(),
1761 isolate->counters()->wasm_module_num_triggered_code_gcs()->AddSample(
1768void ReportLiveCodeFromFrameForGC(
1770 std::unordered_set<wasm::WasmCode*>& live_wasm_code) {
1771 if (frame->
type() == StackFrame::WASM) {
1772 WasmFrame* wasm_frame = WasmFrame::cast(frame);
1773 WasmCode* code = wasm_frame->wasm_code();
1774 live_wasm_code.insert(code);
1775#if V8_TARGET_ARCH_X64
1776 if (code->for_debugging()) {
1783 live_wasm_code.insert(osr_code);
1787 }
else if (frame->
type() == StackFrame::WASM_TO_JS) {
1788 live_wasm_code.insert(
static_cast<WasmToJsFrame*
>(frame)->wasm_code());
1795 std::unordered_set<wasm::WasmCode*> live_wasm_code;
1797 for (
const std::unique_ptr<StackMemory>& stack : isolate->wasm_stacks()) {
1798 if (stack->IsActive()) {
1806 ReportLiveCodeFromFrameForGC(isolate, frame, live_wasm_code);
1811 StackFrameIterator::FirstStackOnly{});
1812 !it.
done(); it.Advance()) {
1814 ReportLiveCodeFromFrameForGC(isolate, frame, live_wasm_code);
1817 CheckNoArchivedThreads(isolate);
1828 DCHECK(code->is_dying());
1835 size_t dead_code_limit =
1847 num_code_gcs_triggered_ < std::numeric_limits<int8_t>::max();
1851 "Triggering GC (potentially dead: %zu bytes; limit: %zu bytes).\n",
1857 "Scheduling another GC after the current one (potentially dead: "
1858 "%zu bytes; limit: %zu bytes).\n",
1866 if (!
v8_flags.wasm_code_gc)
return;
1868 TRACE_CODE_GC(
"Wasm Code GC explicitly requested for testing:\n");
1879 std::vector<WasmCode*>& dead_wrappers) {
1885 std::vector<WasmCode*>& dead_wrappers) {
1888 for (
auto& dead_code_entry : dead_code) {
1890 const std::vector<WasmCode*>& code_vec = dead_code_entry.second;
1891 TRACE_CODE_GC(
"Freeing %zu code object%s of module %p.\n", code_vec.size(),
1892 code_vec.size() == 1 ?
"" :
"s", native_module);
1895 if (dead_wrappers.size()) {
1896 TRACE_CODE_GC(
"Freeing %zu wrapper%s.\n", dead_wrappers.size(),
1897 dead_wrappers.size() == 1 ?
"" :
"s");
1903 Isolate* isolate,
const std::shared_ptr<NativeModule>& native_module,
1909 auto it = scripts.find(native_module.get());
1910 if (it != scripts.end()) {
1912 if (weak_global_handle.
is_null()) {
1920 auto script = CreateWasmScript(isolate, native_module, source_url);
1925 DCHECK_EQ(0, scripts.count(native_module.get()));
1926 scripts.emplace(native_module.get(), WeakScriptHandle(script, isolate));
1931std::shared_ptr<OperationsBarrier>
1950 Isolate* isolate = entry.first;
1953 auto new_task = std::make_unique<WasmGCForegroundTask>(isolate);
1954 gc_task = new_task.get();
1961 "Starting GC (nr %d). Number of potentially dead code objects: %zu\n",
1979 "Remaining dead code objects: %zu; outstanding isolates: %zu.\n",
1989 size_t num_freed = 0;
1991 std::vector<WasmCode*> dead_wrappers;
1994 DCHECK(code->is_dying());
1996 if (code->DecRefOnDeadCode()) {
1998 if (native_module) {
1999 dead_code[native_module].push_back(code);
2001 dead_wrappers.push_back(code);
2015 if (next_gc_sequence_index != 0)
TriggerGC(next_gc_sequence_index);
2020 for (
const auto& [native_module, native_module_info] :
native_modules_) {
2021 target->DecodeNames(native_module);
2044 for (
const auto& [isolate, isolate_info] :
isolates_) {
2052 for (
const auto& [native_module, native_module_info] :
native_modules_) {
2053 result += native_module->EstimateCurrentMemoryConsumption();
2063 if (
v8_flags.trace_wasm_offheap_memory) {
2071 PrintF(
"Off-heap memory size of WasmEngine: %zu\n",
2080 int previous_value =
deopts_executed_.fetch_add(1, std::memory_order_relaxed);
2081 return previous_value + 1;
2086struct GlobalWasmState {
2096GlobalWasmState* global_wasm_state =
nullptr;
2103 global_wasm_state =
new GlobalWasmState();
2105#ifdef V8_ENABLE_DRUMBRAKE
2116#ifdef V8_ENABLE_DRUMBRAKE
2125 delete global_wasm_state;
2126 global_wasm_state =
nullptr;
2133 return &global_wasm_state->engine;
2138 return &global_wasm_state->code_manager;
2143 return &global_wasm_state->import_wrapper_cache;
2148 return &global_wasm_state->type_names_provider;
2155 "Wasm memories must not be bigger than JSArrayBuffers");
2158 v8_flags.wasm_max_mem_pages.value());
2164 "Wasm memories must not be bigger than JSArrayBuffers");
2167 v8_flags.wasm_max_mem_pages.value());
2173 v8_flags.wasm_max_table_size.value());
2179 v8_flags.wasm_max_table_size.value());
2186 constexpr size_t kMin = 16;
RegisterAllocator * allocator_
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
void PostTask(std::unique_ptr< Task > task, const SourceLocation &location=SourceLocation::Current())
void SetVerbose(bool value)
void SetCaptureMessage(bool value)
Hasher & AddRange(Iterator first, Iterator last)
constexpr size_t hash() const
V8_INLINE void AssertHeld() const
Vector< T > SubVector(size_t from, size_t to) const
constexpr bool empty() const
constexpr size_t size() const
constexpr T * begin() const
constexpr T * end() const
static Handle< AsmWasmData > New(Isolate *isolate, std::shared_ptr< wasm::NativeModule > native_module, DirectHandle< HeapNumber > uses_bitset)
V8_INLINE bool is_null() const
static V8_INLINE DirectHandle< T > New(Tagged< T > object, Isolate *isolate)
static void Destroy(Address *location)
V8_EXPORT_PRIVATE void AddSample(int sample)
StackGuard * stack_guard()
static constexpr size_t kMaxByteLength
static DirectHandle< Managed< CppType > > From(Isolate *isolate, size_t estimated_size, std::shared_ptr< CppType > shared_ptr, AllocationType allocation_type=AllocationType::kYoung)
V8_INLINE DirectHandle< T > ToHandleChecked() const
virtual Type type() const =0
static V8_EXPORT_PRIVATE v8::Platform * GetCurrentPlatform()
static V8_EXPORT_PRIVATE DirectHandle< WasmModuleObject > New(Isolate *isolate, std::shared_ptr< wasm::NativeModule > native_module, DirectHandle< Script > script)
static DirectHandle< String > ExtractUtf8StringFromModuleBytes(Isolate *, DirectHandle< WasmModuleObject >, wasm::WireBytesRef, InternalizeString)
std::shared_ptr< StreamingDecoder > CreateStreamingDecoder()
size_t EstimateCurrentMemoryConsumption() const
const uint8_t * pc() const
void consume_bytes(uint32_t size, const char *name="skip")
uint32_t consume_u32v(const char *name="var_uint32")
uint8_t consume_u8(const char *name="uint8_t")
void CompileFailed(const WasmError &error)
V8_WARN_UNUSED_RESULT DirectHandle< JSObject > Reify()
void StreamingCompilationFailed(size_t prefix_hash, const CompileTimeImports &compile_imports)
void Erase(NativeModule *native_module)
std::shared_ptr< NativeModule > MaybeGetNativeModule(ModuleOrigin origin, base::Vector< const uint8_t > wire_bytes, const CompileTimeImports &compile_imports)
std::map< Key, std::optional< std::weak_ptr< NativeModule > > > map_
base::ConditionVariable cache_cv_
static size_t PrefixHash(base::Vector< const uint8_t > wire_bytes)
std::shared_ptr< NativeModule > Update(std::shared_ptr< NativeModule > native_module, bool error)
bool GetStreamingCompilationOwnership(size_t prefix_hash, const CompileTimeImports &compile_imports)
void DisableCodeLogging()
void FreeCode(base::Vector< WasmCode *const >)
const WasmModule * module() const
base::Vector< const uint8_t > wire_bytes() const
void LogWasmCodes(Isolate *, Tagged< Script >)
const CompileTimeImports & compile_imports() const
static std::unique_ptr< StreamingDecoder > CreateSyncStreamingDecoder(Isolate *isolate, WasmEnabledFeatures enabled, CompileTimeImports compile_imports, DirectHandle< Context > context, const char *api_method_name_for_errors, std::shared_ptr< CompilationResultResolver > resolver)
size_t EstimateCurrentMemoryConsumption() const
static size_t EstimateNativeModuleMetaDataSize(const WasmModule *)
static bool HasMemoryProtectionKeySupport()
WasmCode * LookupCode(Isolate *isolate, Address pc) const
std::shared_ptr< NativeModule > NewNativeModule(Isolate *isolate, WasmEnabledFeatures enabled_features, WasmDetectedFeatures detected_features, CompileTimeImports compile_imports, size_t code_size_estimate, std::shared_ptr< const WasmModule > module)
void FlushCodeLookupCache(Isolate *isolate)
size_t committed_code_space() const
static void AddRef(WasmCode *)
static void DecrementRefCount(base::Vector< WasmCode *const >)
static bool ShouldBeLogged(Isolate *isolate)
static void CompileWasmFunction(Counters *, NativeModule *, WasmDetectedFeatures *detected, const WasmFunction *, ExecutionTier)
static constexpr WasmEnabledFeatures ForAsmjs()
LogCodesTask(Isolate *isolate)
void RunInternal() override
std::atomic< size_t > num_modules_with_code_logging_
std::unique_ptr< CurrentGCInfo > current_gc_info_
static void InitializeOncePerProcess()
int IncrementDeoptsExecutedCount()
void DisableCodeLogging(NativeModule *)
std::unordered_set< WasmCode * > potentially_dead_code_
std::shared_ptr< NativeModule > MaybeGetNativeModule(ModuleOrigin origin, base::Vector< const uint8_t > wire_bytes, const CompileTimeImports &compile_imports, Isolate *isolate)
void LogCode(base::Vector< WasmCode * >)
std::shared_ptr< OperationsBarrier > GetBarrierForBackgroundCompile()
void PrintCurrentMemoryConsumptionEstimate() const
void TriggerCodeGCForTesting()
size_t GetLiftoffCodeSizeForTesting()
static void FreeAllOrphanedGlobalHandles(WasmOrphanedGlobalHandle *start)
static void GlobalTearDown()
bool GetStreamingCompilationOwnership(size_t prefix_hash, const CompileTimeImports &compile_imports)
MaybeDirectHandle< WasmModuleObject > SyncCompile(Isolate *isolate, WasmEnabledFeatures enabled, CompileTimeImports compile_imports, ErrorThrower *thrower, base::OwnedVector< const uint8_t > bytes)
bool LogWrapperCode(WasmCode *)
void ReportLiveCodeFromStackForGC(Isolate *)
size_t new_potentially_dead_code_size_
std::atomic< int > deopts_executed_
int GetDeoptsExecutedCount() const
void DumpAndResetTurboStatistics()
void PotentiallyFinishCurrentGC()
int8_t num_code_gcs_triggered_
DirectHandle< WasmModuleObject > ImportNativeModule(Isolate *isolate, std::shared_ptr< NativeModule > shared_module, base::Vector< const char > source_url)
size_t NativeModuleCount() const
void AddPotentiallyDeadCode(WasmCode *)
static std::atomic< int32_t > had_nondeterminism_
void FreeDeadCode(const DeadCodeMap &, std::vector< WasmCode * > &)
std::unordered_map< Isolate *, std::unique_ptr< IsolateInfo > > isolates_
std::unique_ptr< CodeTracer > code_tracer_
void ReportLiveCodeForGC(Isolate *, std::unordered_set< WasmCode * > &live_code)
void EnableCodeLogging(Isolate *)
void LogOutstandingCodesForIsolate(Isolate *)
std::unique_ptr< AsyncCompileJob > RemoveCompileJob(AsyncCompileJob *job)
DirectHandle< Script > GetOrCreateScript(Isolate *, const std::shared_ptr< NativeModule > &, base::Vector< const char > source_url)
AsyncCompileJob * CreateAsyncCompileJob(Isolate *isolate, WasmEnabledFeatures enabled, CompileTimeImports compile_imports, base::OwnedVector< const uint8_t > bytes, DirectHandle< Context > context, const char *api_method_name, std::shared_ptr< CompilationResultResolver > resolver, int compilation_id)
std::shared_ptr< OperationsBarrier > operations_barrier_
void CompileFunction(Counters *counters, NativeModule *native_module, uint32_t function_index, ExecutionTier tier)
CodeTracer * GetCodeTracer()
std::unordered_map< NativeModule *, std::unique_ptr< NativeModuleInfo > > native_modules_
static WasmOrphanedGlobalHandle * NewOrphanedGlobalHandle(WasmOrphanedGlobalHandle **pointer)
void StreamingCompilationFailed(size_t prefix_hash, const CompileTimeImports &compile_imports)
void DeleteCompileJobsOnContext(DirectHandle< Context > context)
void DeleteCompileJobsOnIsolate(Isolate *isolate)
void AsyncCompile(Isolate *isolate, WasmEnabledFeatures enabled, CompileTimeImports compile_imports, std::shared_ptr< CompilationResultResolver > resolver, base::OwnedVector< const uint8_t > bytes, const char *api_method_name_for_errors)
std::unordered_map< AsyncCompileJob *, std::unique_ptr< AsyncCompileJob > > async_compile_jobs_
void EnterDebuggingForIsolate(Isolate *isolate)
bool SyncValidate(Isolate *isolate, WasmEnabledFeatures enabled, CompileTimeImports compile_imports, base::Vector< const uint8_t > bytes)
void TriggerCodeGC_Locked(size_t dead_code_limit)
void FreeNativeModule(NativeModule *)
void DecodeAllNameSections(CanonicalTypeNamesProvider *target)
DirectHandle< WasmModuleObject > FinalizeTranslatedAsmJs(Isolate *isolate, DirectHandle< AsmWasmData > asm_wasm_data, DirectHandle< Script > script)
std::atomic< int > next_compilation_id_
size_t EstimateCurrentMemoryConsumption() const
bool HasRunningCompileJob(Isolate *isolate)
std::shared_ptr< CompilationStatistics > compilation_stats_
void LeaveDebuggingForIsolate(Isolate *isolate)
std::shared_ptr< NativeModule > NewNativeModule(Isolate *isolate, WasmEnabledFeatures enabled_features, WasmDetectedFeatures detected_features, CompileTimeImports compile_imports, std::shared_ptr< const WasmModule > module, size_t code_size_estimate)
void ClearWeakScriptHandle(Isolate *isolate, std::unique_ptr< Address * > location)
MaybeHandle< AsmWasmData > SyncCompileTranslatedAsmJs(Isolate *isolate, ErrorThrower *thrower, base::OwnedVector< const uint8_t > bytes, DirectHandle< Script > script, base::Vector< const uint8_t > asm_js_offset_table_bytes, DirectHandle< HeapNumber > uses_bitset, LanguageMode language_mode)
NativeModuleCache native_module_cache_
bool RemoveIsolateFromCurrentGC(Isolate *)
void RemoveIsolate(Isolate *isolate)
std::shared_ptr< NativeModule > UpdateNativeModuleCache(bool has_error, std::shared_ptr< NativeModule > native_module, Isolate *isolate)
std::shared_ptr< CompilationStatistics > GetOrCreateTurboStatistics()
std::unordered_map< NativeModule *, std::vector< WasmCode * > > DeadCodeMap
void FreeDeadCodeLocked(const DeadCodeMap &, std::vector< WasmCode * > &)
std::shared_ptr< StreamingDecoder > StartStreamingCompilation(Isolate *isolate, WasmEnabledFeatures enabled, CompileTimeImports compile_imports, DirectHandle< Context > context, const char *api_method_name, std::shared_ptr< CompilationResultResolver > resolver)
void TriggerGC(int8_t gc_sequence_index)
void AsyncInstantiate(Isolate *isolate, std::unique_ptr< InstantiationResultResolver > resolver, DirectHandle< WasmModuleObject > module_object, MaybeDirectHandle< JSReceiver > imports)
void DumpTurboStatistics()
MaybeDirectHandle< WasmInstanceObject > SyncInstantiate(Isolate *isolate, ErrorThrower *thrower, DirectHandle< WasmModuleObject > module_object, MaybeDirectHandle< JSReceiver > imports, MaybeDirectHandle< JSArrayBuffer > memory)
void AddIsolate(Isolate *isolate)
std::pair< size_t, size_t > FlushLiftoffCode()
TypeCanonicalizer type_canonicalizer_
void Free(std::vector< WasmCode * > &wrappers)
void LazyInitialize(Isolate *triggering_isolate)
void LogForIsolate(Isolate *isolate)
static void GlobalTearDown()
static void InitializeOncePerProcess()
static void Destroy(WasmOrphanedGlobalHandle *that)
WasmOrphanedGlobalHandle ** prev_ptr_
void InitializeLocation(std::unique_ptr< Address * > location)
WasmOrphanedGlobalHandle()=default
WasmOrphanedGlobalHandle * next_
std::unique_ptr< Address * > location_
static std::unique_ptr< GdbServer > Create()
static const ContextId Empty()
ZoneVector< RpoNumber > & result
LinkageLocation location_
constexpr Vector< T > VectorOf(T *start, size_t size)
constexpr size_t kV8MaxWasmTableInitEntries
V8_EXPORT_PRIVATE WasmCodePointerTable * GetProcessWideWasmCodePointerTable()
uint32_t max_mem32_pages()
WasmImportWrapperCache * GetWasmImportWrapperCache()
uint32_t max_table_size()
uint32_t max_mem64_pages()
WasmCodeManager * GetWasmCodeManager()
constexpr size_t kV8MaxWasmMemory64Pages
CanonicalTypeNamesProvider * GetCanonicalTypeNamesProvider()
size_t GetWireBytesHash(base::Vector< const uint8_t > wire_bytes)
constexpr size_t kV8MaxWasmModuleSize
MaybeDirectHandle< WasmInstanceObject > InstantiateToInstanceObject(Isolate *isolate, ErrorThrower *thrower, DirectHandle< WasmModuleObject > module_object, MaybeDirectHandle< JSReceiver > imports, MaybeDirectHandle< JSArrayBuffer > memory_buffer)
ModuleResult DecodeWasmModule(WasmEnabledFeatures enabled_features, base::Vector< const uint8_t > wire_bytes, bool validate_functions, ModuleOrigin origin, Counters *counters, std::shared_ptr< metrics::Recorder > metrics_recorder, v8::metrics::Recorder::ContextId context_id, DecodingMethod decoding_method, WasmDetectedFeatures *detected_features)
std::shared_ptr< NativeModule > CompileToNativeModule(Isolate *isolate, WasmEnabledFeatures enabled_features, WasmDetectedFeatures detected_features, CompileTimeImports compile_imports, ErrorThrower *thrower, std::shared_ptr< const WasmModule > module, base::OwnedVector< const uint8_t > wire_bytes, int compilation_id, v8::metrics::Recorder::ContextId context_id, ProfileInformation *pgo_info)
WasmError ValidateAndSetBuiltinImports(const WasmModule *module, base::Vector< const uint8_t > wire_bytes, const CompileTimeImports &imports, WasmDetectedFeatures *detected)
uint32_t max_table_init_entries()
size_t ContentSize(const std::vector< T > &vector)
WasmEngine * GetWasmEngine()
constexpr size_t kWasmPageSize
std::unique_ptr< ProfileInformation > LoadProfileFromFile(const WasmModule *module, base::Vector< const uint8_t > wire_bytes)
constexpr size_t kV8MaxWasmTableSize
constexpr size_t kV8MaxWasmMemory32Pages
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
void PrintF(const char *format,...)
Tagged(T object) -> Tagged< T >
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
V8_EXPORT_PRIVATE FlagValues v8_flags
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset instance_object
constexpr uint32_t kMaxUInt32
kInterpreterTrampolineOffset script
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
@ kGCTypeMarkSweepCompact
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define UPDATE_WHEN_CLASS_CHANGES(classname, size)
base::TimeTicks start_time
const int8_t gc_sequence_index
std::unordered_map< Isolate *, WasmGCForegroundTask * > outstanding_isolates
CurrentGCInfo(int8_t gc_sequence_index)
std::unordered_set< WasmCode * > dead_code
int8_t next_gc_sequence_index
std::shared_ptr< const char[]> source_url
std::vector< WasmCode * > code
std::shared_ptr< NativeModule > native_module
std::unordered_set< NativeModule * > native_modules
const std::shared_ptr< Counters > async_counters
IsolateInfo(Isolate *isolate, bool log_code)
std::unordered_map< NativeModule *, WeakScriptHandle > scripts
std::shared_ptr< v8::TaskRunner > foreground_task_runner
std::unordered_map< int, CodeToLogPerScript > code_to_log
NativeModuleInfo(std::weak_ptr< NativeModule > native_module)
std::unordered_set< Isolate * > isolates
std::weak_ptr< NativeModule > weak_ptr
std::array< WasmDebugSymbols, WasmDebugSymbols::kNumTypes > debug_symbols
#define TRACE_EVENT0(category_group, name)
#define TRACE_DISABLED_BY_DEFAULT(name)
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
#define V8_UNLIKELY(condition)
CanonicalTypeNamesProvider type_names_provider
WasmImportWrapperCache import_wrapper_cache
WasmCodeManager code_manager
std::shared_ptr< const char[]> source_url_
#define TRACE_CODE_GC(...)
WasmOrphanedGlobalHandle * handle_