// 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.

#ifndef V8_WASM_WASM_ENGINE_H_
#define V8_WASM_WASM_ENGINE_H_

#include <algorithm>
#include <map>
#include <memory>
#include <unordered_map>
#include <unordered_set>

#include "src/base/platform/condition-variable.h"
#include "src/base/platform/mutex.h"
#include "src/tasks/cancelable-task.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-tier.h"
#include "src/zone/accounting-allocator.h"

namespace v8 {
namespace internal {

class AsmWasmData;
class CodeTracer;
class CompilationStatistics;
class HeapNumber;
class WasmInstanceObject;
class WasmModuleObject;
class JSArrayBuffer;

namespace wasm {

#ifdef V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING
namespace gdb_server {
class GdbServer;
}  // namespace gdb_server
#endif  // V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING

class AsyncCompileJob;
class ErrorThrower;
struct ModuleWireBytes;
class WasmFeatures;

class V8_EXPORT_PRIVATE CompilationResultResolver {
 public:
  virtual void OnCompilationSucceeded(Handle<WasmModuleObject> result) = 0;
  virtual void OnCompilationFailed(Handle<Object> error_reason) = 0;
  virtual ~CompilationResultResolver() = default;
};

class V8_EXPORT_PRIVATE InstantiationResultResolver {
 public:
  virtual void OnInstantiationSucceeded(Handle<WasmInstanceObject> result) = 0;
  virtual void OnInstantiationFailed(Handle<Object> error_reason) = 0;
  virtual ~InstantiationResultResolver() = default;
};

// Native modules cached by their wire bytes.
class NativeModuleCache {
 public:
  struct Key {
    // Store the prefix hash as part of the key for faster lookup, and to
    // quickly check existing prefixes for streaming compilation.
    size_t prefix_hash;
    Vector<const uint8_t> bytes;

    bool operator==(const Key& other) const {
      bool eq = bytes == other.bytes;
      DCHECK_IMPLIES(eq, prefix_hash == other.prefix_hash);
      return eq;
    }

    bool operator<(const Key& other) const {
      if (prefix_hash != other.prefix_hash) {
        DCHECK_IMPLIES(!bytes.empty() && !other.bytes.empty(),
                       bytes != other.bytes);
        return prefix_hash < other.prefix_hash;
      }
      if (bytes.size() != other.bytes.size()) {
        return bytes.size() < other.bytes.size();
      }
      // Fast path when the base pointers are the same.
      // Also handles the {nullptr} case which would be UB for memcmp.
      if (bytes.begin() == other.bytes.begin()) {
        DCHECK_EQ(prefix_hash, other.prefix_hash);
        return false;
      }
      DCHECK_NOT_NULL(bytes.begin());
      DCHECK_NOT_NULL(other.bytes.begin());
      return memcmp(bytes.begin(), other.bytes.begin(), bytes.size()) < 0;
    }
  };

  std::shared_ptr<NativeModule> MaybeGetNativeModule(
      ModuleOrigin origin, Vector<const uint8_t> wire_bytes);
  bool GetStreamingCompilationOwnership(size_t prefix_hash);
  void StreamingCompilationFailed(size_t prefix_hash);
  std::shared_ptr<NativeModule> Update(
      std::shared_ptr<NativeModule> native_module, bool error);
  void Erase(NativeModule* native_module);

  bool empty() { return map_.empty(); }

  static size_t WireBytesHash(Vector<const uint8_t> bytes);

  // Hash the wire bytes up to the code section header. Used as a heuristic to
  // avoid streaming compilation of modules that are likely already in the
  // cache. See {GetStreamingCompilationOwnership}. Assumes that the bytes have
  // already been validated.
  static size_t PrefixHash(Vector<const uint8_t> wire_bytes);

 private:
  // Each key points to the corresponding native module's wire bytes, so they
  // should always be valid as long as the native module is alive.  When
  // the native module dies, {FreeNativeModule} deletes the entry from the
  // map, so that we do not leave any dangling key pointing to an expired
  // weak_ptr. This also serves as a way to regularly clean up the map, which
  // would otherwise accumulate expired entries.
  // A {nullopt} value is inserted to indicate that this native module is
  // currently being created in some thread, and that other threads should wait
  // before trying to get it from the cache.
  // By contrast, an expired {weak_ptr} indicates that the native module died
  // and will soon be cleaned up from the cache.
  std::map<Key, base::Optional<std::weak_ptr<NativeModule>>> map_;

  base::Mutex mutex_;

  // This condition variable is used to synchronize threads compiling the same
  // module. Only one thread will create the {NativeModule}. Other threads
  // will wait on this variable until the first thread wakes them up.
  base::ConditionVariable cache_cv_;
};

// The central data structure that represents an engine instance capable of
// loading, instantiating, and executing Wasm code.
class V8_EXPORT_PRIVATE WasmEngine {
 public:
  WasmEngine();
  WasmEngine(const WasmEngine&) = delete;
  WasmEngine& operator=(const WasmEngine&) = delete;
  ~WasmEngine();

  // Synchronously validates the given bytes that represent an encoded Wasm
  // module.
  bool SyncValidate(Isolate* isolate, const WasmFeatures& enabled,
                    const ModuleWireBytes& bytes);

  // Synchronously compiles the given bytes that represent a translated
  // asm.js module.
  MaybeHandle<AsmWasmData> SyncCompileTranslatedAsmJs(
      Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
      Vector<const byte> asm_js_offset_table_bytes,
      Handle<HeapNumber> uses_bitset, LanguageMode language_mode);
  Handle<WasmModuleObject> FinalizeTranslatedAsmJs(
      Isolate* isolate, Handle<AsmWasmData> asm_wasm_data,
      Handle<Script> script);

  // Synchronously compiles the given bytes that represent an encoded Wasm
  // module.
  MaybeHandle<WasmModuleObject> SyncCompile(Isolate* isolate,
                                            const WasmFeatures& enabled,
                                            ErrorThrower* thrower,
                                            const ModuleWireBytes& bytes);

  // Synchronously instantiate the given Wasm module with the given imports.
  // If the module represents an asm.js module, then the supplied {memory}
  // should be used as the memory of the instance.
  MaybeHandle<WasmInstanceObject> SyncInstantiate(
      Isolate* isolate, ErrorThrower* thrower,
      Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
      MaybeHandle<JSArrayBuffer> memory);

  // Begin an asynchronous compilation of the given bytes that represent an
  // encoded Wasm module.
  // The {is_shared} flag indicates if the bytes backing the module could
  // be shared across threads, i.e. could be concurrently modified.
  void AsyncCompile(Isolate* isolate, const WasmFeatures& enabled,
                    std::shared_ptr<CompilationResultResolver> resolver,
                    const ModuleWireBytes& bytes, bool is_shared,
                    const char* api_method_name_for_errors);

  // Begin an asynchronous instantiation of the given Wasm module.
  void AsyncInstantiate(Isolate* isolate,
                        std::unique_ptr<InstantiationResultResolver> resolver,
                        Handle<WasmModuleObject> module_object,
                        MaybeHandle<JSReceiver> imports);

  std::shared_ptr<StreamingDecoder> StartStreamingCompilation(
      Isolate* isolate, const WasmFeatures& enabled, Handle<Context> context,
      const char* api_method_name,
      std::shared_ptr<CompilationResultResolver> resolver);

  // Compiles the function with the given index at a specific compilation tier.
  // Errors are stored internally in the CompilationState.
  // This is mostly used for testing to force a function into a specific tier.
  void CompileFunction(Isolate* isolate, NativeModule* native_module,
                       uint32_t function_index, ExecutionTier tier);

  void TierDownAllModulesPerIsolate(Isolate* isolate);
  void TierUpAllModulesPerIsolate(Isolate* isolate);

  // Exports the sharable parts of the given module object so that they can be
  // transferred to a different Context/Isolate using the same engine.
  std::shared_ptr<NativeModule> ExportNativeModule(
      Handle<WasmModuleObject> module_object);

  // Imports the shared part of a module from a different Context/Isolate using
  // the the same engine, recreating a full module object in the given Isolate.
  Handle<WasmModuleObject> ImportNativeModule(
      Isolate* isolate, std::shared_ptr<NativeModule> shared_module,
      Vector<const char> source_url);

  WasmCodeManager* code_manager() { return &code_manager_; }

  AccountingAllocator* allocator() { return &allocator_; }

  // Compilation statistics for TurboFan compilations.
  CompilationStatistics* GetOrCreateTurboStatistics();

  // Prints the gathered compilation statistics, then resets them.
  void DumpAndResetTurboStatistics();

  // Used to redirect tracing output from {stdout} to a file.
  CodeTracer* GetCodeTracer();

  // Remove {job} from the list of active compile jobs.
  std::unique_ptr<AsyncCompileJob> RemoveCompileJob(AsyncCompileJob* job);

  // Returns true if at least one AsyncCompileJob that belongs to the given
  // Isolate is currently running.
  bool HasRunningCompileJob(Isolate* isolate);

  // Deletes all AsyncCompileJobs that belong to the given context. All
  // compilation is aborted, no more callbacks will be triggered. This is used
  // when a context is disposed, e.g. because of browser navigation.
  void DeleteCompileJobsOnContext(Handle<Context> context);

  // Deletes all AsyncCompileJobs that belong to the given Isolate. All
  // compilation is aborted, no more callbacks will be triggered. This is used
  // for tearing down an isolate, or to clean it up to be reused.
  void DeleteCompileJobsOnIsolate(Isolate* isolate);

  // Manage the set of Isolates that use this WasmEngine.
  void AddIsolate(Isolate* isolate);
  void RemoveIsolate(Isolate* isolate);

  // Trigger code logging for the given code objects in all Isolates which have
  // access to the NativeModule containing this code. This method can be called
  // from background threads.
  void LogCode(Vector<WasmCode*>);

  // Enable code logging for the given Isolate. Initially, code logging is
  // enabled if {WasmCode::ShouldBeLogged(Isolate*)} returns true during
  // {AddIsolate}.
  void EnableCodeLogging(Isolate*);

  // This is called from the foreground thread of the Isolate to log all
  // outstanding code objects (added via {LogCode}).
  void LogOutstandingCodesForIsolate(Isolate*);

  // 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
  // is determined by {code_size_estimate}. The native module may later request
  // more memory.
  // TODO(wasm): isolate is only required here for CompilationState.
  std::shared_ptr<NativeModule> NewNativeModule(
      Isolate* isolate, const WasmFeatures& enabled_features,
      std::shared_ptr<const WasmModule> module, size_t code_size_estimate);

  // Try getting a cached {NativeModule}, or get ownership for its creation.
  // Return {nullptr} if no {NativeModule} exists for these bytes. In this case,
  // a {nullopt} entry is added to let other threads know that a {NativeModule}
  // for these bytes is currently being created. The caller should eventually
  // call {UpdateNativeModuleCache} to update the entry and wake up other
  // threads. The {wire_bytes}' underlying array should be valid at least until
  // the call to {UpdateNativeModuleCache}.
  std::shared_ptr<NativeModule> MaybeGetNativeModule(
      ModuleOrigin origin, Vector<const uint8_t> wire_bytes, Isolate* isolate);

  // Replace the temporary {nullopt} with the new native module, or
  // erase it if any error occurred. Wake up blocked threads waiting for this
  // module.
  // To avoid a deadlock on the main thread between synchronous and streaming
  // compilation, two compilation jobs might compile the same native module at
  // the same time. In this case the first call to {UpdateNativeModuleCache}
  // will insert the native module in the cache, and the last call will discard
  // its {native_module} argument and replace it with the existing entry.
  // Return true in the former case, and false in the latter.
  bool UpdateNativeModuleCache(bool error,
                               std::shared_ptr<NativeModule>* native_module,
                               Isolate* isolate);

  // Register this prefix hash for a streaming compilation job.
  // If the hash is not in the cache yet, the function returns true and the
  // caller owns the compilation of this module.
  // Otherwise another compilation job is currently preparing or has already
  // prepared a module with the same prefix hash. The caller should wait until
  // the stream is finished and call {MaybeGetNativeModule} to either get the
  // module from the cache or get ownership for the compilation of these bytes.
  bool GetStreamingCompilationOwnership(size_t prefix_hash);

  // Remove the prefix hash from the cache when compilation failed. If
  // compilation succeeded, {UpdateNativeModuleCache} should be called instead.
  void StreamingCompilationFailed(size_t prefix_hash);

  void FreeNativeModule(NativeModule*);

  // Sample the code size of the given {NativeModule} in all isolates that have
  // access to it. Call this after top-tier compilation finished.
  // This will spawn foreground tasks that do *not* keep the NativeModule alive.
  void SampleTopTierCodeSizeInAllIsolates(const std::shared_ptr<NativeModule>&);

  // Called by each Isolate to report its live code for a GC cycle. First
  // version reports an externally determined set of live code (might be empty),
  // second version gets live code from the execution stack of that isolate.
  void ReportLiveCodeForGC(Isolate*, Vector<WasmCode*>);
  void ReportLiveCodeFromStackForGC(Isolate*);

  // Add potentially dead code. The occurrence in the set of potentially dead
  // code counts as a reference, and is decremented on the next GC.
  // Returns {true} if the code was added to the set of potentially dead code,
  // {false} if an entry already exists. The ref count is *unchanged* in any
  // case.
  V8_WARN_UNUSED_RESULT bool AddPotentiallyDeadCode(WasmCode*);

  // Free dead code.
  using DeadCodeMap = std::unordered_map<NativeModule*, std::vector<WasmCode*>>;
  void FreeDeadCode(const DeadCodeMap&);
  void FreeDeadCodeLocked(const DeadCodeMap&);

  Handle<Script> GetOrCreateScript(Isolate*,
                                   const std::shared_ptr<NativeModule>&,
                                   Vector<const char> source_url = {});

  // Take shared ownership of a compile job handle, such that we can synchronize
  // on that before the engine dies.
  void ShepherdCompileJobHandle(std::shared_ptr<JobHandle>);

  // Call on process start and exit.
  static void InitializeOncePerProcess();
  static void GlobalTearDown();

  // Returns a reference to the WasmEngine shared by the entire process. Try to
  // use {Isolate::wasm_engine} instead if it is available, which encapsulates
  // engine lifetime decisions during Isolate bootstrapping.
  static std::shared_ptr<WasmEngine> GetWasmEngine();

 private:
  struct CurrentGCInfo;
  struct IsolateInfo;
  struct NativeModuleInfo;

  AsyncCompileJob* CreateAsyncCompileJob(
      Isolate* isolate, const WasmFeatures& enabled,
      std::unique_ptr<byte[]> bytes_copy, size_t length,
      Handle<Context> context, const char* api_method_name,
      std::shared_ptr<CompilationResultResolver> resolver);

  void TriggerGC(int8_t gc_sequence_index);

  // Remove an isolate from the outstanding isolates of the current GC. Returns
  // true if the isolate was still outstanding, false otherwise. Hold {mutex_}
  // when calling this method.
  bool RemoveIsolateFromCurrentGC(Isolate*);

  // Finish a GC if there are no more outstanding isolates. Hold {mutex_} when
  // calling this method.
  void PotentiallyFinishCurrentGC();

  WasmCodeManager code_manager_;
  AccountingAllocator allocator_;

#ifdef V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING
  // Implements a GDB-remote stub for WebAssembly debugging.
  std::unique_ptr<gdb_server::GdbServer> gdb_server_;
#endif  // V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING

  // This mutex protects all information which is mutated concurrently or
  // fields that are initialized lazily on the first access.
  base::Mutex mutex_;

  //////////////////////////////////////////////////////////////////////////////
  // Protected by {mutex_}:

  // We use an AsyncCompileJob as the key for itself so that we can delete the
  // job from the map when it is finished.
  std::unordered_map<AsyncCompileJob*, std::unique_ptr<AsyncCompileJob>>
      async_compile_jobs_;

  std::unique_ptr<CompilationStatistics> compilation_stats_;
  std::unique_ptr<CodeTracer> code_tracer_;

  // Set of isolates which use this WasmEngine.
  std::unordered_map<Isolate*, std::unique_ptr<IsolateInfo>> isolates_;

  // Set of native modules managed by this engine.
  std::unordered_map<NativeModule*, std::unique_ptr<NativeModuleInfo>>
      native_modules_;

  // Background compile jobs that are still running. We need to join them before
  // the engine gets deleted. Otherwise we don't care when exactly they finish.
  std::vector<std::shared_ptr<JobHandle>> compile_job_handles_;

  // Size of code that became dead since the last GC. If this exceeds a certain
  // threshold, a new GC is triggered.
  size_t new_potentially_dead_code_size_ = 0;

  // If an engine-wide GC is currently running, this pointer stores information
  // about that.
  std::unique_ptr<CurrentGCInfo> current_gc_info_;

  NativeModuleCache native_module_cache_;

  // End of fields protected by {mutex_}.
  //////////////////////////////////////////////////////////////////////////////
};

}  // namespace wasm
}  // namespace internal
}  // namespace v8

#endif  // V8_WASM_WASM_ENGINE_H_
