Commit bffc2ab6 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Move top-tier-finished callback to CompilationState

The AsyncCompileJob should be decoupled from tiering, hence the
top-tier-finished callback should not be delivered via the
AsyncCompileJob. Instead, store it directly on the CompilationState.

R=ahaas@chromium.org

Bug: v8:8050, v8:7921, chromium:912031
Change-Id: Iebd64655667a8078c34caea4edeb6cf5f40833fd
Reviewed-on: https://chromium-review.googlesource.com/c/1371604Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58165}
parent 152bc72b
...@@ -73,10 +73,20 @@ class WireBytesStorage { ...@@ -73,10 +73,20 @@ class WireBytesStorage {
virtual Vector<const uint8_t> GetCode(WireBytesRef) const = 0; virtual Vector<const uint8_t> GetCode(WireBytesRef) const = 0;
}; };
// Callbacks will receive either {kFailedCompilation} or both
// {kFinishedBaselineCompilation} and {kFinishedTopTierCompilation}, in that
// order. If tier up is off, both events are delivered right after each other.
enum class CompilationEvent : uint8_t {
kFinishedBaselineCompilation,
kFinishedTopTierCompilation,
kFailedCompilation
};
// The implementation of {CompilationState} lives in module-compiler.cc. // The implementation of {CompilationState} lives in module-compiler.cc.
// This is the PIMPL interface to that private class. // This is the PIMPL interface to that private class.
class CompilationState { class CompilationState {
public: public:
using callback_t = std::function<void(CompilationEvent, const ResultBase*)>;
~CompilationState(); ~CompilationState();
void CancelAndWait(); void CancelAndWait();
...@@ -87,6 +97,8 @@ class CompilationState { ...@@ -87,6 +97,8 @@ class CompilationState {
std::shared_ptr<WireBytesStorage> GetWireBytesStorage(); std::shared_ptr<WireBytesStorage> GetWireBytesStorage();
void AddCallback(callback_t);
private: private:
friend class NativeModule; friend class NativeModule;
CompilationState() = delete; CompilationState() = delete;
......
...@@ -53,15 +53,6 @@ namespace wasm { ...@@ -53,15 +53,6 @@ namespace wasm {
namespace { namespace {
// Callbacks will receive either {kFailedCompilation} or both
// {kFinishedBaselineCompilation} and {kFinishedTopTierCompilation}, in that
// order. If tier up is off, both events are delivered right after each other.
enum class CompilationEvent : uint8_t {
kFinishedBaselineCompilation,
kFinishedTopTierCompilation,
kFailedCompilation
};
enum class CompileMode : uint8_t { kRegular, kTiering }; enum class CompileMode : uint8_t { kRegular, kTiering };
// The {CompilationStateImpl} keeps track of the compilation state of the // The {CompilationStateImpl} keeps track of the compilation state of the
...@@ -71,8 +62,6 @@ enum class CompileMode : uint8_t { kRegular, kTiering }; ...@@ -71,8 +62,6 @@ enum class CompileMode : uint8_t { kRegular, kTiering };
// It's public interface {CompilationState} lives in compilation-environment.h. // It's public interface {CompilationState} lives in compilation-environment.h.
class CompilationStateImpl { class CompilationStateImpl {
public: public:
using callback_t = std::function<void(CompilationEvent, const VoidResult*)>;
CompilationStateImpl(internal::Isolate*, NativeModule*); CompilationStateImpl(internal::Isolate*, NativeModule*);
~CompilationStateImpl(); ~CompilationStateImpl();
...@@ -85,9 +74,9 @@ class CompilationStateImpl { ...@@ -85,9 +74,9 @@ class CompilationStateImpl {
// compilation. // compilation.
void SetNumberOfFunctionsToCompile(size_t num_functions); void SetNumberOfFunctionsToCompile(size_t num_functions);
// Set the callback function to be called on compilation events. Needs to be // Add the callback function to be called on compilation events. Needs to be
// set before {AddCompilationUnits} is run. // set before {AddCompilationUnits} is run.
void SetCallback(callback_t callback); void AddCallback(CompilationState::callback_t);
// Inserts new functions to compile and kicks off compilation. // Inserts new functions to compile and kicks off compilation.
void AddCompilationUnits( void AddCompilationUnits(
...@@ -268,8 +257,8 @@ class CompilationStateImpl { ...@@ -268,8 +257,8 @@ class CompilationStateImpl {
// End of fields protected by {mutex_}. // End of fields protected by {mutex_}.
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Callback function to be called on compilation events. // Callback functions to be called on compilation events.
callback_t callback_; std::vector<CompilationState::callback_t> callbacks_;
CancelableTaskManager background_task_manager_; CancelableTaskManager background_task_manager_;
CancelableTaskManager foreground_task_manager_; CancelableTaskManager foreground_task_manager_;
...@@ -457,6 +446,10 @@ std::shared_ptr<WireBytesStorage> CompilationState::GetWireBytesStorage() { ...@@ -457,6 +446,10 @@ std::shared_ptr<WireBytesStorage> CompilationState::GetWireBytesStorage() {
return Impl(this)->GetWireBytesStorage(); return Impl(this)->GetWireBytesStorage();
} }
void CompilationState::AddCallback(CompilationState::callback_t callback) {
return Impl(this)->AddCallback(std::move(callback));
}
CompilationState::~CompilationState() { Impl(this)->~CompilationStateImpl(); } CompilationState::~CompilationState() { Impl(this)->~CompilationStateImpl(); }
// static // static
...@@ -2401,6 +2394,8 @@ void AsyncCompileJob::PrepareRuntimeObjects( ...@@ -2401,6 +2394,8 @@ void AsyncCompileJob::PrepareRuntimeObjects(
module_object_ = handle(*module_object_, isolate_); module_object_ = handle(*module_object_, isolate_);
deferred_handles_.push_back(deferred.Detach()); deferred_handles_.push_back(deferred.Detach());
} }
if (stream_) stream_->NotifyRuntimeObjectsCreated(module_object_);
} }
// This function assumes that it is executed in a HandleScope, and that a // This function assumes that it is executed in a HandleScope, and that a
...@@ -2447,7 +2442,7 @@ class AsyncCompileJob::CompilationStateCallback { ...@@ -2447,7 +2442,7 @@ class AsyncCompileJob::CompilationStateCallback {
public: public:
explicit CompilationStateCallback(AsyncCompileJob* job) : job_(job) {} explicit CompilationStateCallback(AsyncCompileJob* job) : job_(job) {}
void operator()(CompilationEvent event, const VoidResult* error_result) { void operator()(CompilationEvent event, const ResultBase* error_result) {
// This callback is only being called from a foreground task. // This callback is only being called from a foreground task.
switch (event) { switch (event) {
case CompilationEvent::kFinishedBaselineCompilation: case CompilationEvent::kFinishedBaselineCompilation:
...@@ -2460,10 +2455,6 @@ class AsyncCompileJob::CompilationStateCallback { ...@@ -2460,10 +2455,6 @@ class AsyncCompileJob::CompilationStateCallback {
break; break;
case CompilationEvent::kFinishedTopTierCompilation: case CompilationEvent::kFinishedTopTierCompilation:
DCHECK_EQ(CompilationEvent::kFinishedBaselineCompilation, last_event_); DCHECK_EQ(CompilationEvent::kFinishedBaselineCompilation, last_event_);
// Notify embedder that compilation is finished.
if (job_->stream_ && job_->stream_->module_compiled_callback()) {
job_->stream_->module_compiled_callback()(job_->module_object_);
}
// If a foreground task or a finisher is pending, we rely on // If a foreground task or a finisher is pending, we rely on
// FinishModule to remove the job. // FinishModule to remove the job.
if (!job_->pending_foreground_task_ && if (!job_->pending_foreground_task_ &&
...@@ -2716,7 +2707,7 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep { ...@@ -2716,7 +2707,7 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep {
CompilationStateImpl* compilation_state = CompilationStateImpl* compilation_state =
Impl(job->native_module_->compilation_state()); Impl(job->native_module_->compilation_state());
compilation_state->SetCallback(CompilationStateCallback{job}); compilation_state->AddCallback(CompilationStateCallback{job});
if (start_compilation_) { if (start_compilation_) {
// TODO(ahaas): Try to remove the {start_compilation_} check when // TODO(ahaas): Try to remove the {start_compilation_} check when
// streaming decoding is done in the background. If // streaming decoding is done in the background. If
...@@ -3022,9 +3013,8 @@ void CompilationStateImpl::SetNumberOfFunctionsToCompile(size_t num_functions) { ...@@ -3022,9 +3013,8 @@ void CompilationStateImpl::SetNumberOfFunctionsToCompile(size_t num_functions) {
} }
} }
void CompilationStateImpl::SetCallback(callback_t callback) { void CompilationStateImpl::AddCallback(CompilationState::callback_t callback) {
DCHECK_NULL(callback_); callbacks_.emplace_back(std::move(callback));
callback_ = std::move(callback);
} }
void CompilationStateImpl::AddCompilationUnits( void CompilationStateImpl::AddCompilationUnits(
...@@ -3237,7 +3227,7 @@ void CompilationStateImpl::SetError(uint32_t func_index, ...@@ -3237,7 +3227,7 @@ void CompilationStateImpl::SetError(uint32_t func_index,
void CompilationStateImpl::NotifyOnEvent(CompilationEvent event, void CompilationStateImpl::NotifyOnEvent(CompilationEvent event,
const VoidResult* error_result) { const VoidResult* error_result) {
HandleScope scope(isolate_); HandleScope scope(isolate_);
if (callback_) callback_(event, error_result); for (auto& callback : callbacks_) callback(event, error_result);
} }
void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* module, void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* module,
......
...@@ -119,6 +119,48 @@ bool StreamingDecoder::SetCompiledModuleBytes( ...@@ -119,6 +119,48 @@ bool StreamingDecoder::SetCompiledModuleBytes(
return true; return true;
} }
namespace {
class TopTierCompiledCallback {
public:
TopTierCompiledCallback(std::shared_ptr<NativeModule> native_module,
StreamingDecoder::ModuleCompiledCallback callback)
: native_module_(std::move(native_module)),
callback_(std::move(callback)) {}
void operator()(CompilationEvent event,
const ResultBase* error_result) const {
if (event != CompilationEvent::kFinishedTopTierCompilation) return;
DCHECK_NULL(error_result);
callback_(native_module_);
#ifdef DEBUG
DCHECK(!called_);
called_ = true;
#endif
}
private:
const std::shared_ptr<NativeModule> native_module_;
const StreamingDecoder::ModuleCompiledCallback callback_;
#ifdef DEBUG
mutable bool called_ = false;
#endif
};
} // namespace
void StreamingDecoder::NotifyRuntimeObjectsCreated(
Handle<WasmModuleObject> module_object) {
if (!module_compiled_callback_) return;
std::shared_ptr<NativeModule> native_module =
module_object->shared_native_module();
auto* comp_state = module_object->native_module()->compilation_state();
comp_state->AddCallback(TopTierCompiledCallback{
std::move(native_module), std::move(module_compiled_callback_)});
// The callback took ownership of the callback:
DCHECK_NULL(module_compiled_callback_);
}
// An abstract class to share code among the states which decode VarInts. This // An abstract class to share code among the states which decode VarInts. This
// class takes over the decoding of the VarInt and then calls the actual decode // class takes over the decoding of the VarInt and then calls the actual decode
// code with the decoded value. // code with the decoded value.
......
...@@ -84,15 +84,13 @@ class V8_EXPORT_PRIVATE StreamingDecoder { ...@@ -84,15 +84,13 @@ class V8_EXPORT_PRIVATE StreamingDecoder {
// Caching support. // Caching support.
// Sets the callback that is called after the module is fully compiled. // Sets the callback that is called after the module is fully compiled.
using ModuleCompiledCallback = std::function<void(Handle<WasmModuleObject>)>; using ModuleCompiledCallback =
std::function<void(const std::shared_ptr<NativeModule>&)>;
void SetModuleCompiledCallback(ModuleCompiledCallback callback); void SetModuleCompiledCallback(ModuleCompiledCallback callback);
// Passes previously compiled module bytes from the embedder's cache. // Passes previously compiled module bytes from the embedder's cache.
bool SetCompiledModuleBytes(Vector<const uint8_t> compiled_module_bytes); bool SetCompiledModuleBytes(Vector<const uint8_t> compiled_module_bytes);
// The callback is stored on the StreamingDecoder so it can be called by the
// AsyncCompileJob. void NotifyRuntimeObjectsCreated(Handle<WasmModuleObject>);
ModuleCompiledCallback module_compiled_callback() const {
return module_compiled_callback_;
}
private: private:
// TODO(ahaas): Put the whole private state of the StreamingDecoder into the // TODO(ahaas): Put the whole private state of the StreamingDecoder into the
......
...@@ -64,8 +64,9 @@ class WasmStreaming::WasmStreamingImpl { ...@@ -64,8 +64,9 @@ class WasmStreaming::WasmStreamingImpl {
// Wrap the embedder callback here so we can also wrap the result as a // Wrap the embedder callback here so we can also wrap the result as a
// Local<WasmModuleObject> here. // Local<WasmModuleObject> here.
streaming_decoder_->SetModuleCompiledCallback( streaming_decoder_->SetModuleCompiledCallback(
[callback, data](i::Handle<i::WasmModuleObject> module_object) { [callback,
callback(data, Utils::Convert(module_object->shared_native_module())); data](const std::shared_ptr<i::wasm::NativeModule>& native_module) {
callback(data, Utils::Convert(native_module));
}); });
} }
......
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