%PDF- %PDF-
Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/wasm/ |
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/wasm/module-compiler.h |
// Copyright 2017 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #if !V8_ENABLE_WEBASSEMBLY #error This header should only be included if WebAssembly is enabled. #endif // !V8_ENABLE_WEBASSEMBLY #ifndef V8_WASM_MODULE_COMPILER_H_ #define V8_WASM_MODULE_COMPILER_H_ #include <atomic> #include <functional> #include <memory> #include "include/v8-metrics.h" #include "src/base/optional.h" #include "src/base/platform/elapsed-timer.h" #include "src/base/platform/mutex.h" #include "src/base/platform/time.h" #include "src/common/globals.h" #include "src/execution/isolate.h" #include "src/logging/counters.h" #include "src/tasks/cancelable-task.h" #include "src/wasm/compilation-environment.h" #include "src/wasm/wasm-features.h" #include "src/wasm/wasm-import-wrapper-cache.h" #include "src/wasm/wasm-module.h" namespace v8 { namespace base { template <typename T> class Vector; } // namespace base namespace internal { class JSArrayBuffer; class JSPromise; class Counters; class WasmModuleObject; class WasmInstanceObject; namespace wasm { struct CompilationEnv; class CompilationResultResolver; class ErrorThrower; class ModuleCompiler; class NativeModule; class ProfileInformation; class StreamingDecoder; class WasmCode; struct WasmModule; V8_EXPORT_PRIVATE std::shared_ptr<NativeModule> CompileToNativeModule( Isolate* isolate, WasmFeatures enabled_features, ErrorThrower* thrower, std::shared_ptr<const WasmModule> module, ModuleWireBytes wire_bytes, int compilation_id, v8::metrics::Recorder::ContextId context_id, ProfileInformation* pgo_info); V8_EXPORT_PRIVATE void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* module); // Compiles the wrapper for this (kind, sig) pair and sets the corresponding // cache entry. Assumes the key already exists in the cache but has not been // compiled yet. V8_EXPORT_PRIVATE WasmCode* CompileImportWrapper( NativeModule* native_module, Counters* counters, ImportCallKind kind, const FunctionSig* sig, uint32_t canonical_type_index, int expected_arity, Suspend suspend, WasmImportWrapperCache::ModificationScope* cache_scope); // Triggered by the WasmCompileLazy builtin. The return value indicates whether // compilation was successful. Lazy compilation can fail only if validation is // also lazy. bool CompileLazy(Isolate*, Tagged<WasmInstanceObject>, int func_index); // Throws the compilation error after failed lazy compilation. void ThrowLazyCompilationError(Isolate* isolate, const NativeModule* native_module, int func_index); // Trigger tier-up of a particular function to TurboFan. If tier-up was already // triggered, we instead increase the priority with exponential back-off. V8_EXPORT_PRIVATE void TriggerTierUp(Tagged<WasmInstanceObject> instance, int func_index); // Synchronous version of the above. void TierUpNowForTesting(Isolate* isolate, Tagged<WasmInstanceObject> instance, int func_index); template <typename Key, typename KeyInfo, typename Hash> class WrapperQueue { public: // Removes an arbitrary key from the queue and returns it. // If the queue is empty, returns nullopt. // Thread-safe. base::Optional<std::pair<Key, KeyInfo>> pop() { base::Optional<std::pair<Key, KeyInfo>> key = base::nullopt; base::MutexGuard lock(&mutex_); auto it = queue_.begin(); if (it != queue_.end()) { key = *it; queue_.erase(it); } return key; } // Add the given key to the queue and returns true iff the insert was // successful. // Not thread-safe. bool insert(const Key& key, KeyInfo key_info) { return queue_.insert({key, key_info}).second; } size_t size() { base::MutexGuard lock(&mutex_); return queue_.size(); } private: base::Mutex mutex_; std::unordered_map<Key, KeyInfo, Hash> queue_; }; // Encapsulates all the state and steps of an asynchronous compilation. // An asynchronous compile job consists of a number of tasks that are executed // as foreground and background tasks. Any phase that touches the V8 heap or // allocates on the V8 heap (e.g. creating the module object) must be a // foreground task. All other tasks (e.g. decoding and validating, the majority // of the work of compilation) can be background tasks. // TODO(wasm): factor out common parts of this with the synchronous pipeline. class AsyncCompileJob { public: AsyncCompileJob(Isolate* isolate, WasmFeatures enabled_features, base::OwnedVector<const uint8_t> bytes, Handle<Context> context, Handle<NativeContext> incumbent_context, const char* api_method_name, std::shared_ptr<CompilationResultResolver> resolver, int compilation_id); ~AsyncCompileJob(); void Start(); std::shared_ptr<StreamingDecoder> CreateStreamingDecoder(); void Abort(); void CancelPendingForegroundTask(); Isolate* isolate() const { return isolate_; } Handle<NativeContext> context() const { return native_context_; } v8::metrics::Recorder::ContextId context_id() const { return context_id_; } private: class CompileTask; class CompileStep; class CompilationStateCallback; // States of the AsyncCompileJob. // Step 1 (async). Decodes the wasm module. // --> Fail on decoding failure, // --> PrepareAndStartCompile on success. class DecodeModule; // Step 2 (sync). Prepares runtime objects and starts background compilation. // --> finish directly on native module cache hit, // --> finish directly on validation error, // --> trigger eager compilation, if any; FinishCompile is triggered when // done. class PrepareAndStartCompile; // Step 3 (sync). Compilation finished. Finalize the module and resolve the // promise. class FinishCompilation; // Step 4 (sync). Decoding, validation or compilation failed. Reject the // promise. class Fail; friend class AsyncStreamingProcessor; enum FinishingComponent { kStreamingDecoder, kCompilation }; // Decrements the number of outstanding finishers. The last caller of this // function should finish the asynchronous compilation, see the comment on // {outstanding_finishers_}. V8_WARN_UNUSED_RESULT bool DecrementAndCheckFinisherCount( FinishingComponent component) { base::MutexGuard guard(&check_finisher_mutex_); DCHECK_LT(0, outstanding_finishers_); if (outstanding_finishers_-- == 2) { // The first component finished, we just start a timer for a histogram. streaming_until_finished_timer_.Start(); return false; } // The timer has only been started above in the case of streaming // compilation. if (streaming_until_finished_timer_.IsStarted()) { // We measure the time delta from when the StreamingDecoder finishes until // when module compilation finishes. Depending on whether streaming or // compilation finishes first we add the delta to the according histogram. int elapsed = static_cast<int>( streaming_until_finished_timer_.Elapsed().InMilliseconds()); if (component == kStreamingDecoder) { isolate_->counters() ->wasm_compilation_until_streaming_finished() ->AddSample(elapsed); } else { isolate_->counters() ->wasm_streaming_until_compilation_finished() ->AddSample(elapsed); } } DCHECK_EQ(0, outstanding_finishers_); return true; } void CreateNativeModule(std::shared_ptr<const WasmModule> module, size_t code_size_estimate); // Return true for cache hit, false for cache miss. bool GetOrCreateNativeModule(std::shared_ptr<const WasmModule> module, size_t code_size_estimate); void PrepareRuntimeObjects(); void FinishCompile(bool is_after_cache_hit); void Failed(); void AsyncCompileSucceeded(Handle<WasmModuleObject> result); void FinishSuccessfully(); void StartForegroundTask(); void ExecuteForegroundTaskImmediately(); void StartBackgroundTask(); enum UseExistingForegroundTask : bool { kUseExistingForegroundTask = true, kAssertNoExistingForegroundTask = false }; // Switches to the compilation step {Step} and starts a foreground task to // execute it. Most of the time we know that there cannot be a running // foreground task. If there might be one, then pass // kUseExistingForegroundTask to avoid spawning a second one. template <typename Step, UseExistingForegroundTask = kAssertNoExistingForegroundTask, typename... Args> void DoSync(Args&&... args); // Switches to the compilation step {Step} and immediately executes that step. template <typename Step, typename... Args> void DoImmediately(Args&&... args); // Switches to the compilation step {Step} and starts a background task to // execute it. template <typename Step, typename... Args> void DoAsync(Args&&... args); // Switches to the compilation step {Step} but does not start a task to // execute it. template <typename Step, typename... Args> void NextStep(Args&&... args); Isolate* const isolate_; const char* const api_method_name_; const WasmFeatures enabled_features_; const DynamicTiering dynamic_tiering_; base::TimeTicks start_time_; // Copy of the module wire bytes, moved into the {native_module_} on its // creation. base::OwnedVector<const uint8_t> bytes_copy_; // Reference to the wire bytes (held in {bytes_copy_} or as part of // {native_module_}). ModuleWireBytes wire_bytes_; Handle<NativeContext> native_context_; Handle<NativeContext> incumbent_context_; v8::metrics::Recorder::ContextId context_id_; v8::metrics::WasmModuleDecoded metrics_event_; const std::shared_ptr<CompilationResultResolver> resolver_; Handle<WasmModuleObject> module_object_; std::shared_ptr<NativeModule> native_module_; std::unique_ptr<CompileStep> step_; CancelableTaskManager background_task_manager_; std::shared_ptr<v8::TaskRunner> foreground_task_runner_; // For async compilation the AsyncCompileJob is the only finisher. For // streaming compilation also the AsyncStreamingProcessor has to finish before // compilation can be finished. int32_t outstanding_finishers_ = 1; base::ElapsedTimer streaming_until_finished_timer_; base::Mutex check_finisher_mutex_; // A reference to a pending foreground task, or {nullptr} if none is pending. CompileTask* pending_foreground_task_ = nullptr; // The AsyncCompileJob owns the StreamingDecoder because the StreamingDecoder // contains data which is needed by the AsyncCompileJob for streaming // compilation. The AsyncCompileJob does not actively use the // StreamingDecoder. std::shared_ptr<StreamingDecoder> stream_; // The compilation id to identify trace events linked to this compilation. const int compilation_id_; }; } // namespace wasm } // namespace internal } // namespace v8 #endif // V8_WASM_MODULE_COMPILER_H_