// Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "third_party/blink/renderer/platform/heap/address_cache.h" #include "third_party/blink/renderer/platform/heap/heap_page.h" namespace blink { AddressCache::EnabledScope::EnabledScope(AddressCache* address_cache) : address_cache_(address_cache) { address_cache_->FlushIfDirty(); address_cache_->EnableLookup(); } AddressCache::EnabledScope::~EnabledScope() { address_cache_->DisableLookup(); } void AddressCache::Flush() { if (has_entries_) { for (size_t i = 0; i < kNumberOfEntries; ++i) entries_[i] = nullptr; has_entries_ = false; } dirty_ = false; } void AddressCache::FlushIfDirty() { if (dirty_) { Flush(); dirty_ = false; } } size_t AddressCache::GetHash(Address address) { size_t value = (reinterpret_cast(address) >> kBlinkPageSizeLog2); value ^= value >> kNumberOfEntriesLog2; value ^= value >> (kNumberOfEntriesLog2 * 2); value &= kNumberOfEntries - 1; return value & ~1; // Returns only even number. } bool AddressCache::Lookup(Address address) { DCHECK(enabled_); DCHECK(!dirty_); size_t index = GetHash(address); DCHECK(!(index & 1)); Address cache_page = RoundToBlinkPageStart(address); if (entries_[index] == cache_page) return entries_[index]; if (entries_[index + 1] == cache_page) return entries_[index + 1]; return false; } void AddressCache::AddEntry(Address address) { has_entries_ = true; size_t index = GetHash(address); DCHECK(!(index & 1)); Address cache_page = RoundToBlinkPageStart(address); entries_[index + 1] = entries_[index]; entries_[index] = cache_page; } } // namespace blink