11cb0ef41Sopenharmony_ci// Copyright 2019 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#ifndef V8_OBJECTS_OSR_OPTIMIZED_CODE_CACHE_H_ 61cb0ef41Sopenharmony_ci#define V8_OBJECTS_OSR_OPTIMIZED_CODE_CACHE_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/objects/fixed-array.h" 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci// Has to be the last include (doesn't have include guards): 111cb0ef41Sopenharmony_ci#include "src/objects/object-macros.h" 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace v8 { 141cb0ef41Sopenharmony_cinamespace internal { 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci// This enum is a performance optimization for accessing the OSR code cache - 171cb0ef41Sopenharmony_ci// we can skip cache iteration in many cases unless there are multiple entries 181cb0ef41Sopenharmony_ci// for a particular SharedFunctionInfo. 191cb0ef41Sopenharmony_cienum OSRCodeCacheStateOfSFI : uint8_t { 201cb0ef41Sopenharmony_ci kNotCached, // Likely state. 211cb0ef41Sopenharmony_ci kCachedOnce, // Unlikely state, one entry. 221cb0ef41Sopenharmony_ci kCachedMultiple, // Very unlikely state, multiple entries. 231cb0ef41Sopenharmony_ci}; 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci// TODO(jgruber): There are a few issues with the current implementation: 261cb0ef41Sopenharmony_ci// 271cb0ef41Sopenharmony_ci// - The cache is a flat list, thus any search operation is O(N). This resulted 281cb0ef41Sopenharmony_ci// in optimization attempts, see OSRCodeCacheStateOfSFI. 291cb0ef41Sopenharmony_ci// - We always iterate up to `length` (== capacity). 301cb0ef41Sopenharmony_ci// - We essentially reimplement WeakArrayList, i.e. growth and shrink logic. 311cb0ef41Sopenharmony_ci// - On overflow, new entries always pick slot 0. 321cb0ef41Sopenharmony_ci// 331cb0ef41Sopenharmony_ci// There are a few alternatives: 341cb0ef41Sopenharmony_ci// 351cb0ef41Sopenharmony_ci// 1) we could reuse WeakArrayList logic (but then we'd still have to 361cb0ef41Sopenharmony_ci// implement custom compaction due to our entry tuple structure). 371cb0ef41Sopenharmony_ci// 2) we could reuse CompilationCacheTable (but then we lose weakness and have 381cb0ef41Sopenharmony_ci// to deal with aging). 391cb0ef41Sopenharmony_ci// 3) we could try to base on a weak HashTable variant (EphemeronHashTable?). 401cb0ef41Sopenharmony_ciclass V8_EXPORT OSROptimizedCodeCache : public WeakFixedArray { 411cb0ef41Sopenharmony_ci public: 421cb0ef41Sopenharmony_ci DECL_CAST(OSROptimizedCodeCache) 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci static Handle<OSROptimizedCodeCache> Empty(Isolate* isolate); 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci // Caches the optimized code |code| corresponding to the shared function 471cb0ef41Sopenharmony_ci // |shared| and bailout id |osr_offset| in the OSROptimized code cache. 481cb0ef41Sopenharmony_ci // If the OSR code cache wasn't created before it creates a code cache with 491cb0ef41Sopenharmony_ci // kOSRCodeCacheInitialLength entries. 501cb0ef41Sopenharmony_ci static void Insert(Isolate* isolate, Handle<NativeContext> context, 511cb0ef41Sopenharmony_ci Handle<SharedFunctionInfo> shared, Handle<CodeT> code, 521cb0ef41Sopenharmony_ci BytecodeOffset osr_offset); 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci // Returns the code corresponding to the shared function |shared| and 551cb0ef41Sopenharmony_ci // BytecodeOffset |offset| if an entry exists in the cache. Returns an empty 561cb0ef41Sopenharmony_ci // object otherwise. 571cb0ef41Sopenharmony_ci CodeT TryGet(SharedFunctionInfo shared, BytecodeOffset osr_offset, 581cb0ef41Sopenharmony_ci Isolate* isolate); 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci std::vector<BytecodeOffset> OsrOffsetsFor(SharedFunctionInfo shared); 611cb0ef41Sopenharmony_ci base::Optional<BytecodeOffset> FirstOsrOffsetFor(SharedFunctionInfo shared); 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci // Remove all code objects marked for deoptimization from OSR code cache. 641cb0ef41Sopenharmony_ci void EvictDeoptimizedCode(Isolate* isolate); 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci // Reduces the size of the OSR code cache if the number of valid entries are 671cb0ef41Sopenharmony_ci // less than the current capacity of the cache. 681cb0ef41Sopenharmony_ci static void Compact(Isolate* isolate, Handle<NativeContext> context); 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci // Sets the OSR optimized code cache to an empty array. 711cb0ef41Sopenharmony_ci static void Clear(Isolate* isolate, NativeContext context); 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci enum OSRCodeCacheConstants { 741cb0ef41Sopenharmony_ci kSharedOffset, 751cb0ef41Sopenharmony_ci kCachedCodeOffset, 761cb0ef41Sopenharmony_ci kOsrIdOffset, 771cb0ef41Sopenharmony_ci kEntryLength 781cb0ef41Sopenharmony_ci }; 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci static constexpr int kInitialLength = OSRCodeCacheConstants::kEntryLength * 4; 811cb0ef41Sopenharmony_ci static constexpr int kMaxLength = OSRCodeCacheConstants::kEntryLength * 1024; 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci // For osr-code-cache-unittest.cc. 841cb0ef41Sopenharmony_ci MaybeObject RawGetForTesting(int index) const; 851cb0ef41Sopenharmony_ci void RawSetForTesting(int index, MaybeObject value); 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci private: 881cb0ef41Sopenharmony_ci // Hide raw accessors to avoid terminology confusion. 891cb0ef41Sopenharmony_ci using WeakFixedArray::Get; 901cb0ef41Sopenharmony_ci using WeakFixedArray::Set; 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci // Functions that implement heuristics on when to grow / shrink the cache. 931cb0ef41Sopenharmony_ci static int CapacityForLength(int curr_capacity); 941cb0ef41Sopenharmony_ci static bool NeedsTrimming(int num_valid_entries, int curr_capacity); 951cb0ef41Sopenharmony_ci static int GrowOSRCache(Isolate* isolate, 961cb0ef41Sopenharmony_ci Handle<NativeContext> native_context, 971cb0ef41Sopenharmony_ci Handle<OSROptimizedCodeCache>* osr_cache); 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci // Helper functions to get individual items from an entry in the cache. 1001cb0ef41Sopenharmony_ci CodeT GetCodeFromEntry(int index); 1011cb0ef41Sopenharmony_ci SharedFunctionInfo GetSFIFromEntry(int index); 1021cb0ef41Sopenharmony_ci BytecodeOffset GetBytecodeOffsetFromEntry(int index); 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci inline int FindEntry(SharedFunctionInfo shared, BytecodeOffset osr_offset); 1051cb0ef41Sopenharmony_ci inline void ClearEntry(int src, Isolate* isolate); 1061cb0ef41Sopenharmony_ci inline void InitializeEntry(int entry, SharedFunctionInfo shared, CodeT code, 1071cb0ef41Sopenharmony_ci BytecodeOffset osr_offset); 1081cb0ef41Sopenharmony_ci inline void MoveEntry(int src, int dst, Isolate* isolate); 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci OBJECT_CONSTRUCTORS(OSROptimizedCodeCache, WeakFixedArray); 1111cb0ef41Sopenharmony_ci}; 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci} // namespace internal 1141cb0ef41Sopenharmony_ci} // namespace v8 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci#include "src/objects/object-macros-undef.h" 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ci#endif // V8_OBJECTS_OSR_OPTIMIZED_CODE_CACHE_H_ 119