1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved. 2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file. 4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_IDENTITY_MAP_H_ 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_IDENTITY_MAP_H_ 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#include "src/base/functional.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/handles.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 { 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal { 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Forward declarations. 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Heap; 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Zone; 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Base class of identity maps contains shared code for all template 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// instantions. 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass IdentityMapBase { 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected: 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allow Tester to access internals, including changing the address of objects 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // within the {keys_} array in order to simulate a moving GC. 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class IdentityMapTester; 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch typedef void** RawEntry; 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IdentityMapBase(Heap* heap, Zone* zone) 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : heap_(heap), 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch zone_(zone), 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch gc_counter_(-1), 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_(0), 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mask_(0), 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch keys_(nullptr), 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values_(nullptr) {} 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~IdentityMapBase(); 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawEntry GetEntry(Object* key); 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawEntry FindEntry(Object* key); 40342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch void Clear(); 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Internal implementation should not be called directly by subclasses. 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int LookupIndex(Object* address); 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int InsertIndex(Object* address); 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Rehash(); 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Resize(); 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawEntry Lookup(Object* key); 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawEntry Insert(Object* key); 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int Hash(Object* address); 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 52342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch base::hash<uintptr_t> hasher_; 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Heap* heap_; 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Zone* zone_; 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int gc_counter_; 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int size_; 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int mask_; 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object** keys_; 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void** values_; 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Implements an identity map from object addresses to a given value type {V}. 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The map is robust w.r.t. garbage collection by synchronization with the 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// supplied {heap}. 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// * Keys are treated as strong roots. 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// * SMIs are valid keys, except SMI #0. 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// * The value type {V} must be reinterpret_cast'able to {void*} 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// * The value type {V} must not be a heap type. 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <typename V> 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass IdentityMap : public IdentityMapBase { 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IdentityMap(Heap* heap, Zone* zone) : IdentityMapBase(heap, zone) {} 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Searches this map for the given key using the object's address 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // as the identity, returning: 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // found => a pointer to the storage location for the value 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // not found => a pointer to a new storage location for the value 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V* Get(Handle<Object> key) { return Get(*key); } 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V* Get(Object* key) { return reinterpret_cast<V*>(GetEntry(key)); } 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Searches this map for the given key using the object's address 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // as the identity, returning: 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // found => a pointer to the storage location for the value 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // not found => {nullptr} 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V* Find(Handle<Object> key) { return Find(*key); } 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V* Find(Object* key) { return reinterpret_cast<V*>(FindEntry(key)); } 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Set the value for the given key. 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Set(Handle<Object> key, V v) { Set(*key, v); } 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Set(Object* key, V v) { *(reinterpret_cast<V*>(GetEntry(key))) = v; } 91342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 92342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch // Removes all elements from the map. 93342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch void Clear() { IdentityMapBase::Clear(); } 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif // V8_IDENTITY_MAP_H_ 99