Commit 0f90a2aa authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[wasm] Provide a global WasmCodeManager

The WasmCodeManager was part of the WasmEngine so far, but there is only
exactly one WasmEngine. Hence we can pull it out, and also remove the
pointer in the WasmCodeAllocator.

The argument passed from the single constructor call is now inlined in
the constructor itself.

Drive-by: Replace "GetPlatformPageAllocator()->CommitPageSize()" by just
"CommitPageSize()".

R=jkummerow@chromium.org

Bug: v8:11879
Change-Id: I6c0e74cea308f5806d1aa479945d90b6ef8d1613
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2972909
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75270}
parent 764fa7e3
......@@ -99,7 +99,7 @@ const char* V8NameConverter::NameOfAddress(byte* pc) const {
#if V8_ENABLE_WEBASSEMBLY
wasm::WasmCodeRefScope wasm_code_ref_scope;
if (auto* wasm_code = wasm::GetWasmEngine()->code_manager()->LookupCode(
if (auto* wasm_code = wasm::GetWasmCodeManager()->LookupCode(
reinterpret_cast<Address>(pc))) {
SNPrintF(v8_buffer_, "%p (%s)", static_cast<void*>(pc),
wasm::GetWasmCodeKindAsString(wasm_code->kind()));
......
......@@ -2862,8 +2862,7 @@ V8_EXPORT_PRIVATE extern void _v8_internal_Print_Code(void* object) {
#if V8_ENABLE_WEBASSEMBLY
{
i::wasm::WasmCodeRefScope scope;
if (auto* wasm_code =
i::wasm::GetWasmEngine()->code_manager()->LookupCode(address)) {
if (auto* wasm_code = i::wasm::GetWasmCodeManager()->LookupCode(address)) {
i::StdoutStream os;
wasm_code->Disassemble(nullptr, os, address);
return;
......
......@@ -571,7 +571,7 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
// returned {wasm_code} to be null and fall back to {GetContainingCode}.
wasm::WasmCodeRefScope code_ref_scope;
if (wasm::WasmCode* wasm_code =
wasm::GetWasmEngine()->code_manager()->LookupCode(pc)) {
wasm::GetWasmCodeManager()->LookupCode(pc)) {
switch (wasm_code->kind()) {
case wasm::WasmCode::kFunction:
return WASM;
......@@ -944,8 +944,7 @@ void CommonFrame::IterateCompiledFrame(RootVisitor* v) const {
bool is_wasm = false;
#if V8_ENABLE_WEBASSEMBLY
if (auto* wasm_code =
wasm::GetWasmEngine()->code_manager()->LookupCode(inner_pointer)) {
if (auto* wasm_code = wasm::GetWasmCodeManager()->LookupCode(inner_pointer)) {
is_wasm = true;
SafepointTable table(wasm_code);
safepoint_entry = table.FindEntry(inner_pointer);
......@@ -981,7 +980,7 @@ void CommonFrame::IterateCompiledFrame(RootVisitor* v) const {
// directly call a Wasm function from JavaScript. In this case the
// parameters we pass to the callee are not tagged.
wasm::WasmCode* wasm_callee =
wasm::GetWasmEngine()->code_manager()->LookupCode(callee_pc());
wasm::GetWasmCodeManager()->LookupCode(callee_pc());
bool is_wasm_call = (wasm_callee != nullptr);
if (is_wasm_call) has_tagged_outgoing_params = false;
#endif // V8_ENABLE_WEBASSEMBLY
......@@ -1861,10 +1860,7 @@ void WasmFrame::Print(StringStream* accumulator, PrintMode mode,
wasm::WasmCodeRefScope code_ref_scope;
accumulator->Add("WASM [");
accumulator->PrintName(script().name());
Address instruction_start = wasm::GetWasmEngine()
->code_manager()
->LookupCode(pc())
->instruction_start();
Address instruction_start = wasm_code()->instruction_start();
base::Vector<const uint8_t> raw_func_name =
module_object().GetRawFunctionName(function_index());
const int kMaxPrintedFunctionName = 64;
......@@ -1884,7 +1880,7 @@ void WasmFrame::Print(StringStream* accumulator, PrintMode mode,
}
wasm::WasmCode* WasmFrame::wasm_code() const {
return wasm::GetWasmEngine()->code_manager()->LookupCode(pc());
return wasm::GetWasmCodeManager()->LookupCode(pc());
}
WasmInstanceObject WasmFrame::wasm_instance() const {
......@@ -1946,7 +1942,7 @@ bool WasmFrame::at_to_number_conversion() const {
// ToNumber conversion call.
wasm::WasmCode* code =
callee_pc() != kNullAddress
? wasm::GetWasmEngine()->code_manager()->LookupCode(callee_pc())
? wasm::GetWasmCodeManager()->LookupCode(callee_pc())
: nullptr;
if (!code || code->kind() != wasm::WasmCode::kWasmToJsWrapper) return false;
int offset = static_cast<int>(callee_pc() - code->instruction_start());
......@@ -1958,8 +1954,7 @@ bool WasmFrame::at_to_number_conversion() const {
}
int WasmFrame::LookupExceptionHandlerInTable() {
wasm::WasmCode* code =
wasm::GetWasmEngine()->code_manager()->LookupCode(pc());
wasm::WasmCode* code = wasm::GetWasmCodeManager()->LookupCode(pc());
if (!code->IsAnonymous() && code->handler_table_size() > 0) {
HandlerTable table(code);
int pc_offset = static_cast<int>(pc() - code->instruction_start());
......@@ -1970,8 +1965,7 @@ int WasmFrame::LookupExceptionHandlerInTable() {
void WasmDebugBreakFrame::Iterate(RootVisitor* v) const {
DCHECK(caller_pc());
wasm::WasmCode* code =
wasm::GetWasmEngine()->code_manager()->LookupCode(caller_pc());
wasm::WasmCode* code = wasm::GetWasmCodeManager()->LookupCode(caller_pc());
DCHECK(code);
SafepointTable table(code);
SafepointEntry safepoint_entry = table.FindEntry(caller_pc());
......
......@@ -1793,7 +1793,7 @@ Object Isolate::UnwindAndFindHandler() {
wasm::WasmCodeRefScope code_ref_scope;
WasmFrame* wasm_frame = static_cast<WasmFrame*>(frame);
wasm::WasmCode* wasm_code =
wasm::GetWasmEngine()->code_manager()->LookupCode(frame->pc());
wasm::GetWasmCodeManager()->LookupCode(frame->pc());
int offset = wasm_frame->LookupExceptionHandlerInTable();
if (offset < 0) break;
wasm::GetWasmEngine()->SampleCatchEvent(this);
......@@ -1854,8 +1854,7 @@ Object Isolate::UnwindAndFindHandler() {
StubFrame* stub_frame = static_cast<StubFrame*>(frame);
#if defined(DEBUG) && V8_ENABLE_WEBASSEMBLY
wasm::WasmCodeRefScope code_ref_scope;
DCHECK_NULL(
wasm::GetWasmEngine()->code_manager()->LookupCode(frame->pc()));
DCHECK_NULL(wasm::GetWasmCodeManager()->LookupCode(frame->pc()));
#endif // defined(DEBUG) && V8_ENABLE_WEBASSEMBLY
Code code = stub_frame->LookupCode();
if (!code.IsCode() || code.kind() != CodeKind::BUILTIN ||
......
......@@ -515,16 +515,14 @@ int WasmCode::GetSourcePositionBefore(int offset) {
// static
constexpr size_t WasmCodeAllocator::kMaxCodeSpaceSize;
WasmCodeAllocator::WasmCodeAllocator(WasmCodeManager* code_manager,
std::shared_ptr<Counters> async_counters)
: code_manager_(code_manager),
async_counters_(std::move(async_counters)) {
WasmCodeAllocator::WasmCodeAllocator(std::shared_ptr<Counters> async_counters)
: async_counters_(std::move(async_counters)) {
owned_code_space_.reserve(4);
}
WasmCodeAllocator::~WasmCodeAllocator() {
code_manager_->FreeNativeModule(base::VectorOf(owned_code_space_),
committed_code_space());
GetWasmCodeManager()->FreeNativeModule(base::VectorOf(owned_code_space_),
committed_code_space());
}
void WasmCodeAllocator::Init(VirtualMemory code_space) {
......@@ -636,9 +634,8 @@ base::Vector<byte> WasmCodeAllocator::AllocateForCode(
base::Vector<byte> WasmCodeAllocator::AllocateForCodeInRegion(
NativeModule* native_module, size_t size, base::AddressRegion region) {
DCHECK_EQ(code_manager_, native_module->engine()->code_manager());
DCHECK_LT(0, size);
v8::PageAllocator* page_allocator = GetPlatformPageAllocator();
auto* code_manager = GetWasmCodeManager();
size = RoundUp<kCodeAlignment>(size);
base::AddressRegion code_space =
free_code_space_.AllocateInRegion(size, region);
......@@ -658,14 +655,14 @@ base::Vector<byte> WasmCodeAllocator::AllocateForCodeInRegion(
std::tie(min_reservation, reserve_size) = ReservationSize(
size, native_module->module()->num_declared_functions, total_reserved);
VirtualMemory new_mem =
code_manager_->TryAllocate(reserve_size, reinterpret_cast<void*>(hint));
code_manager->TryAllocate(reserve_size, reinterpret_cast<void*>(hint));
if (!new_mem.IsReserved() || new_mem.size() < min_reservation) {
V8::FatalProcessOutOfMemory(nullptr, "wasm code reservation");
UNREACHABLE();
}
base::AddressRegion new_region = new_mem.region();
code_manager_->AssignRange(new_region, native_module);
code_manager->AssignRange(new_region, native_module);
free_code_space_.Merge(new_region);
owned_code_space_.emplace_back(std::move(new_mem));
native_module->AddCodeSpaceLocked(new_region);
......@@ -675,7 +672,7 @@ base::Vector<byte> WasmCodeAllocator::AllocateForCodeInRegion(
async_counters_->wasm_module_num_code_spaces()->AddSample(
static_cast<int>(owned_code_space_.size()));
}
const Address commit_page_size = page_allocator->CommitPageSize();
const Address commit_page_size = CommitPageSize();
Address commit_start = RoundUp(code_space.begin(), commit_page_size);
Address commit_end = RoundUp(code_space.end(), commit_page_size);
// {commit_start} will be either code_space.start or the start of the next
......@@ -689,7 +686,7 @@ base::Vector<byte> WasmCodeAllocator::AllocateForCodeInRegion(
if (commit_start < commit_end) {
for (base::AddressRegion split_range : SplitRangeByReservationsIfNeeded(
{commit_start, commit_end - commit_start}, owned_code_space_)) {
code_manager_->Commit(split_range);
code_manager->Commit(split_range);
}
committed_code_space_.fetch_add(commit_end - commit_start);
// Committed code cannot grow bigger than maximum code space size.
......@@ -781,7 +778,7 @@ bool WasmCodeAllocator::SetThreadWritable(bool writable) {
}
writable = writable_nesting_level > 0;
int key = code_manager_->memory_protection_key_;
int key = GetWasmCodeManager()->memory_protection_key_;
MemoryProtectionKeyPermission permissions =
writable ? kNoRestrictions : kDisableWrite;
......@@ -809,8 +806,7 @@ void WasmCodeAllocator::FreeCode(base::Vector<WasmCode* const> codes) {
// pages to decommit into {regions_to_decommit} (decommitting is expensive,
// so try to merge regions before decommitting).
DisjointAllocationPool regions_to_decommit;
PageAllocator* allocator = GetPlatformPageAllocator();
size_t commit_page_size = allocator->CommitPageSize();
size_t commit_page_size = CommitPageSize();
for (auto region : freed_regions.regions()) {
auto merged_region = freed_code_space_.Merge(region);
Address discard_start =
......@@ -823,13 +819,14 @@ void WasmCodeAllocator::FreeCode(base::Vector<WasmCode* const> codes) {
regions_to_decommit.Merge({discard_start, discard_end - discard_start});
}
auto* code_manager = GetWasmCodeManager();
for (auto region : regions_to_decommit.regions()) {
size_t old_committed = committed_code_space_.fetch_sub(region.size());
DCHECK_GE(old_committed, region.size());
USE(old_committed);
for (base::AddressRegion split_range :
SplitRangeByReservationsIfNeeded(region, owned_code_space_)) {
code_manager_->Decommit(split_range);
code_manager->Decommit(split_range);
}
}
}
......@@ -848,7 +845,7 @@ NativeModule::NativeModule(WasmEngine* engine, const WasmFeatures& enabled,
std::shared_ptr<NativeModule>* shared_this)
: engine_(engine),
engine_scope_(engine->GetBarrierForBackgroundCompile()->TryLock()),
code_allocator_(engine->code_manager(), async_counters),
code_allocator_(async_counters),
enabled_features_(enabled),
module_(std::move(module)),
import_wrapper_cache_(std::unique_ptr<WasmImportWrapperCache>(
......@@ -1723,14 +1720,12 @@ NativeModule::~NativeModule() {
import_wrapper_cache_.reset();
}
WasmCodeManager::WasmCodeManager(size_t max_committed)
: max_committed_code_space_(max_committed),
critical_committed_code_space_(max_committed / 2),
WasmCodeManager::WasmCodeManager()
: max_committed_code_space_(FLAG_wasm_max_code_space * MB),
critical_committed_code_space_(max_committed_code_space_ / 2),
memory_protection_key_(FLAG_wasm_memory_protection_keys
? AllocateMemoryProtectionKey()
: kNoMemoryProtectionKey) {
DCHECK_LE(max_committed, FLAG_wasm_max_code_space * MB);
}
: kNoMemoryProtectionKey) {}
WasmCodeManager::~WasmCodeManager() {
// No more committed code space.
......@@ -1982,7 +1977,6 @@ size_t WasmCodeManager::EstimateNativeModuleMetaDataSize(
std::shared_ptr<NativeModule> WasmCodeManager::NewNativeModule(
WasmEngine* engine, Isolate* isolate, const WasmFeatures& enabled,
size_t code_size_estimate, std::shared_ptr<const WasmModule> module) {
DCHECK_EQ(this, GetWasmEngine()->code_manager());
if (total_committed_code_space_.load() >
critical_committed_code_space_.load()) {
(reinterpret_cast<v8::Isolate*>(isolate))
......
......@@ -43,7 +43,6 @@ namespace wasm {
class DebugInfo;
class NativeModule;
class WasmCodeManager;
struct WasmCompilationResult;
class WasmEngine;
class WasmImportWrapperCache;
......@@ -481,7 +480,7 @@ class WasmCodeAllocator {
static constexpr size_t kMaxCodeSpaceSize = 1024 * MB;
#endif
WasmCodeAllocator(WasmCodeManager*, std::shared_ptr<Counters> async_counters);
explicit WasmCodeAllocator(std::shared_ptr<Counters> async_counters);
~WasmCodeAllocator();
// Call before use, after the {NativeModule} is set up completely.
......@@ -532,9 +531,6 @@ class WasmCodeAllocator {
static constexpr base::AddressRegion kUnrestrictedRegion{
kNullAddress, std::numeric_limits<size_t>::max()};
// The engine-wide wasm code manager.
WasmCodeManager* const code_manager_;
//////////////////////////////////////////////////////////////////////////////
// These fields are protected by the mutex in {NativeModule}.
......@@ -938,7 +934,7 @@ class V8_EXPORT_PRIVATE NativeModule final {
class V8_EXPORT_PRIVATE WasmCodeManager final {
public:
explicit WasmCodeManager(size_t max_committed);
WasmCodeManager();
WasmCodeManager(const WasmCodeManager&) = delete;
WasmCodeManager& operator=(const WasmCodeManager&) = delete;
......
......@@ -529,8 +529,7 @@ class DebugInfoImpl {
private:
struct FrameInspectionScope {
FrameInspectionScope(DebugInfoImpl* debug_info, Address pc)
: code(debug_info->native_module_->engine()->code_manager()->LookupCode(
pc)),
: code(wasm::GetWasmCodeManager()->LookupCode(pc)),
pc_offset(static_cast<int>(pc - code->instruction_start())),
debug_side_table(code->is_inspectable()
? debug_info->GetDebugSideTable(code)
......
......@@ -438,7 +438,7 @@ struct WasmEngine::NativeModuleInfo {
int8_t num_code_gcs_triggered = 0;
};
WasmEngine::WasmEngine() : code_manager_(FLAG_wasm_max_code_space * MB) {}
WasmEngine::WasmEngine() = default;
WasmEngine::~WasmEngine() {
#ifdef V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING
......@@ -1135,8 +1135,9 @@ std::shared_ptr<NativeModule> WasmEngine::NewNativeModule(
}
#endif // V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING
std::shared_ptr<NativeModule> native_module = code_manager_.NewNativeModule(
this, isolate, enabled, code_size_estimate, std::move(module));
std::shared_ptr<NativeModule> native_module =
GetWasmCodeManager()->NewNativeModule(
this, isolate, enabled, code_size_estimate, std::move(module));
base::MutexGuard lock(&mutex_);
auto pair = native_modules_.insert(std::make_pair(
native_module.get(), std::make_unique<NativeModuleInfo>(native_module)));
......@@ -1154,7 +1155,7 @@ std::shared_ptr<NativeModule> WasmEngine::NewNativeModule(
auto* histogram =
isolate->counters()->wasm_memory_protection_keys_support();
bool has_mpk =
code_manager_.memory_protection_key_ != kNoMemoryProtectionKey;
GetWasmCodeManager()->memory_protection_key_ != kNoMemoryProtectionKey;
histogram->AddSample(has_mpk ? 1 : 0);
}
......@@ -1339,8 +1340,7 @@ void WasmEngine::ReportLiveCodeFromStackForGC(Isolate* isolate) {
Address osr_target = base::Memory<Address>(WasmFrame::cast(frame)->fp() -
kOSRTargetOffset);
if (osr_target) {
WasmCode* osr_code =
GetWasmEngine()->code_manager()->LookupCode(osr_target);
WasmCode* osr_code = GetWasmCodeManager()->LookupCode(osr_target);
DCHECK_NOT_NULL(osr_code);
live_wasm_code.insert(osr_code);
}
......@@ -1368,7 +1368,7 @@ bool WasmEngine::AddPotentiallyDeadCode(WasmCode* code) {
size_t dead_code_limit =
FLAG_stress_wasm_code_gc
? 0
: 64 * KB + code_manager_.committed_code_space() / 10;
: 64 * KB + GetWasmCodeManager()->committed_code_space() / 10;
if (new_potentially_dead_code_size_ > dead_code_limit) {
bool inc_gc_count =
info->num_code_gcs_triggered < std::numeric_limits<int8_t>::max();
......@@ -1579,14 +1579,19 @@ void WasmEngine::PotentiallyFinishCurrentGC() {
namespace {
WasmEngine* global_wasm_engine = nullptr;
struct GlobalWasmState {
WasmEngine engine;
WasmCodeManager code_manager;
};
GlobalWasmState* global_wasm_state = nullptr;
} // namespace
// static
void WasmEngine::InitializeOncePerProcess() {
DCHECK_NULL(global_wasm_engine);
global_wasm_engine = new WasmEngine();
DCHECK_NULL(global_wasm_state);
global_wasm_state = new GlobalWasmState();
}
// static
......@@ -1594,13 +1599,18 @@ void WasmEngine::GlobalTearDown() {
// Note: This can be called multiple times in a row (see
// test-api/InitializeAndDisposeMultiple). This is fine, as
// {global_wasm_engine} will be nullptr then.
delete global_wasm_engine;
global_wasm_engine = nullptr;
delete global_wasm_state;
global_wasm_state = nullptr;
}
WasmEngine* GetWasmEngine() {
DCHECK_NOT_NULL(global_wasm_engine);
return global_wasm_engine;
DCHECK_NOT_NULL(global_wasm_state);
return &global_wasm_state->engine;
}
WasmCodeManager* GetWasmCodeManager() {
DCHECK_NOT_NULL(global_wasm_state);
return &global_wasm_state->code_manager;
}
// {max_mem_pages} is declared in wasm-limits.h.
......
......@@ -216,8 +216,6 @@ class V8_EXPORT_PRIVATE WasmEngine {
Isolate* isolate, std::shared_ptr<NativeModule> shared_module,
base::Vector<const char> source_url);
WasmCodeManager* code_manager() { return &code_manager_; }
AccountingAllocator* allocator() { return &allocator_; }
// Compilation statistics for TurboFan compilations.
......@@ -380,7 +378,6 @@ class V8_EXPORT_PRIVATE WasmEngine {
// calling this method.
void PotentiallyFinishCurrentGC();
WasmCodeManager code_manager_;
AccountingAllocator allocator_;
#ifdef V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING
......@@ -432,6 +429,9 @@ class V8_EXPORT_PRIVATE WasmEngine {
// Returns a reference to the WasmEngine shared by the entire process.
V8_EXPORT_PRIVATE WasmEngine* GetWasmEngine();
// Returns a reference to the WasmCodeManager shared by the entire process.
V8_EXPORT_PRIVATE WasmCodeManager* GetWasmCodeManager();
} // namespace wasm
} // namespace internal
} // namespace v8
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment