11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#if !V8_ENABLE_WEBASSEMBLY 61cb0ef41Sopenharmony_ci#error This header should only be included if WebAssembly is enabled. 71cb0ef41Sopenharmony_ci#endif // !V8_ENABLE_WEBASSEMBLY 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ci#ifndef V8_WASM_COMPILATION_ENVIRONMENT_H_ 101cb0ef41Sopenharmony_ci#define V8_WASM_COMPILATION_ENVIRONMENT_H_ 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci#include <memory> 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ci#include "src/wasm/wasm-features.h" 151cb0ef41Sopenharmony_ci#include "src/wasm/wasm-limits.h" 161cb0ef41Sopenharmony_ci#include "src/wasm/wasm-module.h" 171cb0ef41Sopenharmony_ci#include "src/wasm/wasm-tier.h" 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_cinamespace v8 { 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ciclass JobHandle; 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_cinamespace internal { 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ciclass Counters; 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_cinamespace wasm { 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ciclass NativeModule; 301cb0ef41Sopenharmony_ciclass WasmCode; 311cb0ef41Sopenharmony_ciclass WasmEngine; 321cb0ef41Sopenharmony_ciclass WasmError; 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_cienum RuntimeExceptionSupport : bool { 351cb0ef41Sopenharmony_ci kRuntimeExceptionSupport = true, 361cb0ef41Sopenharmony_ci kNoRuntimeExceptionSupport = false 371cb0ef41Sopenharmony_ci}; 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_cienum BoundsCheckStrategy : int8_t { 401cb0ef41Sopenharmony_ci // Emit protected instructions, use the trap handler for OOB detection. 411cb0ef41Sopenharmony_ci kTrapHandler, 421cb0ef41Sopenharmony_ci // Emit explicit bounds checks. 431cb0ef41Sopenharmony_ci kExplicitBoundsChecks, 441cb0ef41Sopenharmony_ci // Emit no bounds checks at all (for testing only). 451cb0ef41Sopenharmony_ci kNoBoundsChecks 461cb0ef41Sopenharmony_ci}; 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_cienum class DynamicTiering { kEnabled, kDisabled }; 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci// The {CompilationEnv} encapsulates the module data that is used during 511cb0ef41Sopenharmony_ci// compilation. CompilationEnvs are shareable across multiple compilations. 521cb0ef41Sopenharmony_cistruct CompilationEnv { 531cb0ef41Sopenharmony_ci // A pointer to the decoded module's static representation. 541cb0ef41Sopenharmony_ci const WasmModule* const module; 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci // The bounds checking strategy to use. 571cb0ef41Sopenharmony_ci const BoundsCheckStrategy bounds_checks; 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci // If the runtime doesn't support exception propagation, 601cb0ef41Sopenharmony_ci // we won't generate stack checks, and trap handling will also 611cb0ef41Sopenharmony_ci // be generated differently. 621cb0ef41Sopenharmony_ci const RuntimeExceptionSupport runtime_exception_support; 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci // The smallest size of any memory that could be used with this module, in 651cb0ef41Sopenharmony_ci // bytes. 661cb0ef41Sopenharmony_ci const uintptr_t min_memory_size; 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci // The largest size of any memory that could be used with this module, in 691cb0ef41Sopenharmony_ci // bytes. 701cb0ef41Sopenharmony_ci const uintptr_t max_memory_size; 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci // Features enabled for this compilation. 731cb0ef41Sopenharmony_ci const WasmFeatures enabled_features; 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci const DynamicTiering dynamic_tiering; 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci constexpr CompilationEnv(const WasmModule* module, 781cb0ef41Sopenharmony_ci BoundsCheckStrategy bounds_checks, 791cb0ef41Sopenharmony_ci RuntimeExceptionSupport runtime_exception_support, 801cb0ef41Sopenharmony_ci const WasmFeatures& enabled_features, 811cb0ef41Sopenharmony_ci DynamicTiering dynamic_tiering) 821cb0ef41Sopenharmony_ci : module(module), 831cb0ef41Sopenharmony_ci bounds_checks(bounds_checks), 841cb0ef41Sopenharmony_ci runtime_exception_support(runtime_exception_support), 851cb0ef41Sopenharmony_ci // During execution, the memory can never be bigger than what fits in a 861cb0ef41Sopenharmony_ci // uintptr_t. 871cb0ef41Sopenharmony_ci min_memory_size( 881cb0ef41Sopenharmony_ci std::min(kV8MaxWasmMemoryPages, 891cb0ef41Sopenharmony_ci uintptr_t{module ? module->initial_pages : 0}) * 901cb0ef41Sopenharmony_ci kWasmPageSize), 911cb0ef41Sopenharmony_ci max_memory_size((module && module->has_maximum_pages 921cb0ef41Sopenharmony_ci ? std::min(kV8MaxWasmMemoryPages, 931cb0ef41Sopenharmony_ci uintptr_t{module->maximum_pages}) 941cb0ef41Sopenharmony_ci : kV8MaxWasmMemoryPages) * 951cb0ef41Sopenharmony_ci kWasmPageSize), 961cb0ef41Sopenharmony_ci enabled_features(enabled_features), 971cb0ef41Sopenharmony_ci dynamic_tiering(dynamic_tiering) {} 981cb0ef41Sopenharmony_ci}; 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci// The wire bytes are either owned by the StreamingDecoder, or (after streaming) 1011cb0ef41Sopenharmony_ci// by the NativeModule. This class abstracts over the storage location. 1021cb0ef41Sopenharmony_ciclass WireBytesStorage { 1031cb0ef41Sopenharmony_ci public: 1041cb0ef41Sopenharmony_ci virtual ~WireBytesStorage() = default; 1051cb0ef41Sopenharmony_ci virtual base::Vector<const uint8_t> GetCode(WireBytesRef) const = 0; 1061cb0ef41Sopenharmony_ci // Returns the ModuleWireBytes corresponding to the underlying module if 1071cb0ef41Sopenharmony_ci // available. Not supported if the wire bytes are owned by a StreamingDecoder. 1081cb0ef41Sopenharmony_ci virtual base::Optional<ModuleWireBytes> GetModuleBytes() const = 0; 1091cb0ef41Sopenharmony_ci}; 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci// Callbacks will receive either {kFailedCompilation} or both 1121cb0ef41Sopenharmony_ci// {kFinishedBaselineCompilation} and {kFinishedTopTierCompilation}, in that 1131cb0ef41Sopenharmony_ci// order. If tier up is off, both events are delivered right after each other. 1141cb0ef41Sopenharmony_cienum class CompilationEvent : uint8_t { 1151cb0ef41Sopenharmony_ci kFinishedBaselineCompilation, 1161cb0ef41Sopenharmony_ci kFinishedExportWrappers, 1171cb0ef41Sopenharmony_ci kFinishedCompilationChunk, 1181cb0ef41Sopenharmony_ci kFinishedTopTierCompilation, 1191cb0ef41Sopenharmony_ci kFailedCompilation, 1201cb0ef41Sopenharmony_ci kFinishedRecompilation 1211cb0ef41Sopenharmony_ci}; 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE CompilationEventCallback { 1241cb0ef41Sopenharmony_ci public: 1251cb0ef41Sopenharmony_ci virtual ~CompilationEventCallback() = default; 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci virtual void call(CompilationEvent event) = 0; 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci enum class ReleaseAfterFinalEvent { kRelease, kKeep }; 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci // Tells the module compiler whether to keep or to release a callback when the 1321cb0ef41Sopenharmony_ci // compilation state finishes all compilation units. Most callbacks should be 1331cb0ef41Sopenharmony_ci // released, that's why there is a default implementation, but the callback 1341cb0ef41Sopenharmony_ci // for code caching with dynamic tiering has to stay alive. 1351cb0ef41Sopenharmony_ci virtual ReleaseAfterFinalEvent release_after_final_event() { 1361cb0ef41Sopenharmony_ci return ReleaseAfterFinalEvent::kRelease; 1371cb0ef41Sopenharmony_ci } 1381cb0ef41Sopenharmony_ci}; 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci// The implementation of {CompilationState} lives in module-compiler.cc. 1411cb0ef41Sopenharmony_ci// This is the PIMPL interface to that private class. 1421cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE CompilationState { 1431cb0ef41Sopenharmony_ci public: 1441cb0ef41Sopenharmony_ci ~CompilationState(); 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci void InitCompileJob(); 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ci void CancelCompilation(); 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci void CancelInitialCompilation(); 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci void SetError(); 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci void SetWireBytesStorage(std::shared_ptr<WireBytesStorage>); 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ci std::shared_ptr<WireBytesStorage> GetWireBytesStorage() const; 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci void AddCallback(std::unique_ptr<CompilationEventCallback> callback); 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci void InitializeAfterDeserialization( 1611cb0ef41Sopenharmony_ci base::Vector<const int> lazy_functions, 1621cb0ef41Sopenharmony_ci base::Vector<const int> liftoff_functions); 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ci // Wait until top tier compilation finished, or compilation failed. 1651cb0ef41Sopenharmony_ci void WaitForTopTierFinished(); 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci // Set a higher priority for the compilation job. 1681cb0ef41Sopenharmony_ci void SetHighPriority(); 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci bool failed() const; 1711cb0ef41Sopenharmony_ci bool baseline_compilation_finished() const; 1721cb0ef41Sopenharmony_ci bool top_tier_compilation_finished() const; 1731cb0ef41Sopenharmony_ci bool recompilation_finished() const; 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci void set_compilation_id(int compilation_id); 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci DynamicTiering dynamic_tiering() const; 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci // Override {operator delete} to avoid implicit instantiation of {operator 1801cb0ef41Sopenharmony_ci // delete} with {size_t} argument. The {size_t} argument would be incorrect. 1811cb0ef41Sopenharmony_ci void operator delete(void* ptr) { ::operator delete(ptr); } 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci CompilationState() = delete; 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci private: 1861cb0ef41Sopenharmony_ci // NativeModule is allowed to call the static {New} method. 1871cb0ef41Sopenharmony_ci friend class NativeModule; 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ci // The CompilationState keeps a {std::weak_ptr} back to the {NativeModule} 1901cb0ef41Sopenharmony_ci // such that it can keep it alive (by regaining a {std::shared_ptr}) in 1911cb0ef41Sopenharmony_ci // certain scopes. 1921cb0ef41Sopenharmony_ci static std::unique_ptr<CompilationState> New( 1931cb0ef41Sopenharmony_ci const std::shared_ptr<NativeModule>&, std::shared_ptr<Counters>, 1941cb0ef41Sopenharmony_ci DynamicTiering dynamic_tiering); 1951cb0ef41Sopenharmony_ci}; 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci} // namespace wasm 1981cb0ef41Sopenharmony_ci} // namespace internal 1991cb0ef41Sopenharmony_ci} // namespace v8 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ci#endif // V8_WASM_COMPILATION_ENVIRONMENT_H_ 202