Commit 0c25403c authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Move code logging to the WasmEngine

The compilation state should have no notion of Isolates. Move code
logging and management of the corresponding foreground task to the
WasmEngine.

R=mstarzinger@chromium.org

Bug: v8:8689
Change-Id: Ib690317139d0754731b9f0e71d06e7a722082eed
Reviewed-on: https://chromium-review.googlesource.com/c/1434035
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59093}
parent a1ff298d
......@@ -216,41 +216,6 @@ class CompilationStateImpl {
: func_index(func_index), error(std::move(error)) {}
};
class LogCodesTask : public CancelableTask {
public:
LogCodesTask(CancelableTaskManager* manager,
CompilationStateImpl* compilation_state, Isolate* isolate)
: CancelableTask(manager),
compilation_state_(compilation_state),
isolate_(isolate) {
// This task should only be created if we should actually log code.
DCHECK(WasmCode::ShouldBeLogged(isolate));
}
// Hold the compilation state {mutex_} when calling this method.
void AddCode(WasmCode* code) { code_to_log_.push_back(code); }
void RunInternal() override {
// Remove this task from the {CompilationStateImpl}. The next compilation
// that finishes will allocate and schedule a new task.
{
base::MutexGuard guard(&compilation_state_->mutex_);
DCHECK_EQ(this, compilation_state_->log_codes_task_);
compilation_state_->log_codes_task_ = nullptr;
}
// If by now we shouldn't log code any more, don't log it.
if (!WasmCode::ShouldBeLogged(isolate_)) return;
for (WasmCode* code : code_to_log_) {
code->LogCode(isolate_);
}
}
private:
CompilationStateImpl* const compilation_state_;
Isolate* const isolate_;
std::vector<WasmCode*> code_to_log_;
};
void NotifyOnEvent(CompilationEvent event, const WasmError* error);
std::vector<std::unique_ptr<WasmCompilationUnit>>& finish_units() {
......@@ -296,10 +261,6 @@ class CompilationStateImpl {
// as a module is being compiled.
WasmFeatures detected_features_ = kNoWasmFeatures;
// The foreground task to log finished wasm code. Is {nullptr} if no such task
// is currently scheduled.
LogCodesTask* log_codes_task_ = nullptr;
// Abstraction over the storage of the wire bytes. Held in a shared_ptr so
// that background compilation jobs can keep the storage alive while
// compiling.
......@@ -1799,13 +1760,7 @@ void CompilationStateImpl::OnFinishedUnit(ExecutionTier tier, WasmCode* code) {
}
if (should_log_code_ && code != nullptr) {
if (log_codes_task_ == nullptr) {
auto new_task = base::make_unique<LogCodesTask>(&foreground_task_manager_,
this, isolate_);
log_codes_task_ = new_task.get();
foreground_task_runner_->PostTask(std::move(new_task));
}
log_codes_task_->AddCode(code);
engine_->LogCode(code);
}
}
......
......@@ -22,10 +22,65 @@ namespace v8 {
namespace internal {
namespace wasm {
namespace {
class LogCodesTask : public Task {
public:
explicit LogCodesTask(base::Mutex* mutex, LogCodesTask** task_slot,
Isolate* isolate)
: mutex_(mutex), task_slot_(task_slot), isolate_(isolate) {}
// Hold the {mutex_} when calling this method.
void AddCode(WasmCode* code) { code_to_log_.push_back(code); }
void Run() override {
if (isolate_ == nullptr) return; // Cancelled.
// Remove this task from the {IsolateInfo} in the engine. The next
// logging request will allocate and schedule a new task.
{
base::MutexGuard guard(mutex_);
DCHECK_EQ(this, *task_slot_);
*task_slot_ = nullptr;
}
// If by now we should not log code any more, do not log it.
if (!WasmCode::ShouldBeLogged(isolate_)) return;
for (WasmCode* code : code_to_log_) {
code->LogCode(isolate_);
}
}
void Cancel() {
// Cancel will only be called on Isolate shutdown, which happens on the
// Isolate's foreground thread. Thus no synchronization needed.
isolate_ = nullptr;
}
private:
// The mutex of the WasmEngine.
base::Mutex* const mutex_;
// The slot in the WasmEngine where this LogCodesTask is stored. This is
// cleared by this task before execution.
LogCodesTask** const task_slot_;
Isolate* isolate_;
std::vector<WasmCode*> code_to_log_;
};
} // namespace
struct WasmEngine::IsolateInfo {
explicit IsolateInfo(Isolate* isolate) {
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
v8::Platform* platform = V8::GetCurrentPlatform();
foreground_task_runner = platform->GetForegroundTaskRunner(v8_isolate);
}
// All native modules that are being used by this Isolate (currently only
// grows, never shrinks).
std::set<NativeModule*> native_modules;
// The currently scheduled LogCodesTask.
LogCodesTask* log_codes_task = nullptr;
// The foreground task runner of the isolate (can be called from background).
std::shared_ptr<v8::TaskRunner> foreground_task_runner;
};
WasmEngine::WasmEngine()
......@@ -352,7 +407,7 @@ void WasmEngine::DeleteCompileJobsOnIsolate(Isolate* isolate) {
void WasmEngine::AddIsolate(Isolate* isolate) {
base::MutexGuard guard(&mutex_);
DCHECK_EQ(0, isolates_.count(isolate));
isolates_.emplace(isolate, base::make_unique<IsolateInfo>());
isolates_.emplace(isolate, base::make_unique<IsolateInfo>(isolate));
// Install sampling GC callback.
// TODO(v8:7424): For now we sample module sizes in a GC callback. This will
......@@ -383,9 +438,27 @@ void WasmEngine::RemoveIsolate(Isolate* isolate) {
DCHECK_EQ(1, isolates_per_native_module_[native_module].count(isolate));
isolates_per_native_module_[native_module].erase(isolate);
}
if (auto* task = it->second->log_codes_task) task->Cancel();
isolates_.erase(it);
}
void WasmEngine::LogCode(WasmCode* code) {
base::MutexGuard guard(&mutex_);
NativeModule* native_module = code->native_module();
DCHECK_EQ(1, isolates_per_native_module_.count(native_module));
for (Isolate* isolate : isolates_per_native_module_[native_module]) {
DCHECK_EQ(1, isolates_.count(isolate));
IsolateInfo* info = isolates_[isolate].get();
if (info->log_codes_task == nullptr) {
auto new_task = base::make_unique<LogCodesTask>(
&mutex_, &info->log_codes_task, isolate);
info->log_codes_task = new_task.get();
info->foreground_task_runner->PostTask(std::move(new_task));
}
info->log_codes_task->AddCode(code);
}
}
std::unique_ptr<NativeModule> WasmEngine::NewNativeModule(
Isolate* isolate, const WasmFeatures& enabled, size_t code_size_estimate,
bool can_request_more, std::shared_ptr<const WasmModule> module) {
......
......@@ -153,6 +153,11 @@ class V8_EXPORT_PRIVATE WasmEngine {
std::forward<Args>(args)...);
}
// Trigger code logging for this WasmCode in all Isolates which have access to
// the NativeModule containing this code. This method can be called from
// background threads.
void LogCode(WasmCode*);
// Create a new NativeModule. The caller is responsible for its
// lifetime. The native module will be given some memory for code,
// which will be page size aligned. The size of the initial memory
......
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