Commit 41a8d9c3 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[base] Store AllocationPolicy object in TemplateHashMapImpl instance

... this will avoid the need to pass AllocationPolicy to every method
that can allocate/deallocate and allows to make deallocation method
implementation stateful.

The latter will also allow implementing accounting of deallocated zone
memory.

Adding one more field is generally fine because usually these hashmap
objects are allocated on the stack or inside other rarely-allocated
long-lived objects.
The only exception is Scope class. The Scope objects are created very
often during parsing and each of them has a VariableMap field.
The Scope object size issue will be addressed in a follow-up CL.

Bug: v8:10572
Change-Id: I63fbd41246cf2e568c8ba80c213d3e9caffc2c87
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2284992Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68877}
parent ebcc39d5
......@@ -335,10 +335,9 @@ void ObjectLiteral::CalculateEmitStore(Zone* zone) {
const auto GETTER = ObjectLiteral::Property::GETTER;
const auto SETTER = ObjectLiteral::Property::SETTER;
ZoneAllocationPolicy allocator(zone);
CustomMatcherZoneHashMap table(
Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, allocator);
CustomMatcherZoneHashMap table(Literal::Match,
ZoneHashMap::kDefaultHashMapCapacity,
ZoneAllocationPolicy(zone));
for (int i = properties()->length() - 1; i >= 0; i--) {
ObjectLiteral::Property* property = properties()->at(i);
if (property->is_computed_name()) continue;
......@@ -347,7 +346,7 @@ void ObjectLiteral::CalculateEmitStore(Zone* zone) {
DCHECK(!literal->IsNullLiteral());
uint32_t hash = literal->Hash();
ZoneHashMap::Entry* entry = table.LookupOrInsert(literal, hash, allocator);
ZoneHashMap::Entry* entry = table.LookupOrInsert(literal, hash);
if (entry->value == nullptr) {
entry->value = property;
} else {
......
......@@ -46,9 +46,8 @@ Variable* VariableMap::Declare(Zone* zone, Scope* scope,
// AstRawStrings are unambiguous, i.e., the same string is always represented
// by the same AstRawString*.
// FIXME(marja): fix the type of Lookup.
Entry* p =
ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
ZoneAllocationPolicy(zone));
Entry* p = ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name),
name->Hash());
*was_added = p->value == nullptr;
if (*was_added) {
// The variable has not been declared yet -> insert it.
......@@ -66,11 +65,10 @@ void VariableMap::Remove(Variable* var) {
ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->Hash());
}
void VariableMap::Add(Zone* zone, Variable* var) {
void VariableMap::Add(Variable* var) {
const AstRawString* name = var->raw_name();
Entry* p =
ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
ZoneAllocationPolicy(zone));
Entry* p = ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name),
name->Hash());
DCHECK_NULL(p->value);
DCHECK_EQ(name, p->key);
p->value = var;
......@@ -682,7 +680,7 @@ Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name,
if (sloppy_eval_can_extend_vars()) {
cache->NonLocal(name, VariableMode::kDynamic);
} else {
cache->variables_.Add(zone(), function_);
cache->variables_.Add(function_);
}
return function_;
}
......
......@@ -50,7 +50,7 @@ class VariableMap : public ZoneHashMap {
V8_EXPORT_PRIVATE Variable* Lookup(const AstRawString* name);
void Remove(Variable* var);
void Add(Zone* zone, Variable* var);
void Add(Variable* var);
};
class Scope;
......
......@@ -54,18 +54,15 @@ class TemplateHashMapImpl {
// If an entry with matching key is found, returns that entry.
// If no matching entry is found, a new entry is inserted with
// corresponding key, key hash, and default initialized value.
Entry* LookupOrInsert(const Key& key, uint32_t hash,
AllocationPolicy allocator = AllocationPolicy());
Entry* LookupOrInsert(const Key& key, uint32_t hash);
// If an entry with matching key is found, returns that entry.
// If no matching entry is found, a new entry is inserted with
// corresponding key, key hash, and value created by func.
template <typename Func>
Entry* LookupOrInsert(const Key& key, uint32_t hash, const Func& value_func,
AllocationPolicy allocator = AllocationPolicy());
Entry* LookupOrInsert(const Key& key, uint32_t hash, const Func& value_func);
Entry* InsertNew(const Key& key, uint32_t hash,
AllocationPolicy allocator = AllocationPolicy());
Entry* InsertNew(const Key& key, uint32_t hash);
// Removes the entry with matching key.
// It returns the value of the deleted entry
......@@ -103,12 +100,12 @@ class TemplateHashMapImpl {
Entry* Next(Entry* entry) const;
void Reset(AllocationPolicy allocator) {
Initialize(capacity_, allocator);
Initialize(capacity_);
occupancy_ = 0;
}
protected:
void Initialize(uint32_t capacity, AllocationPolicy allocator);
void Initialize(uint32_t capacity);
private:
Entry* map_;
......@@ -117,13 +114,14 @@ class TemplateHashMapImpl {
// TODO(leszeks): This takes up space even if it has no state, maybe replace
// with something that does the empty base optimisation e.g. std::tuple
MatchFun match_;
// TODO(ishell): same here.
AllocationPolicy allocator_;
Entry* map_end() const { return map_ + capacity_; }
Entry* Probe(const Key& key, uint32_t hash) const;
Entry* FillEmptyEntry(Entry* entry, const Key& key, const Value& value,
uint32_t hash,
AllocationPolicy allocator = AllocationPolicy());
void Resize(AllocationPolicy allocator);
uint32_t hash);
void Resize();
DISALLOW_COPY_AND_ASSIGN(TemplateHashMapImpl);
};
......@@ -132,8 +130,8 @@ template <typename Key, typename Value, typename MatchFun,
TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::
TemplateHashMapImpl(uint32_t initial_capacity, MatchFun match,
AllocationPolicy allocator)
: match_(match) {
Initialize(initial_capacity, allocator);
: match_(match), allocator_(allocator) {
Initialize(initial_capacity);
}
template <typename Key, typename Value, typename MatchFun,
......@@ -144,8 +142,9 @@ TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::
AllocationPolicy allocator)
: capacity_(original->capacity_),
occupancy_(original->occupancy_),
match_(original->match_) {
map_ = reinterpret_cast<Entry*>(allocator.New(capacity_ * sizeof(Entry)));
match_(original->match_),
allocator_(allocator) {
map_ = reinterpret_cast<Entry*>(allocator_.New(capacity_ * sizeof(Entry)));
memcpy(map_, original->map_, capacity_ * sizeof(Entry));
}
......@@ -169,8 +168,8 @@ template <typename Key, typename Value, typename MatchFun,
class AllocationPolicy>
typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry*
TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::LookupOrInsert(
const Key& key, uint32_t hash, AllocationPolicy allocator) {
return LookupOrInsert(key, hash, []() { return Value(); }, allocator);
const Key& key, uint32_t hash) {
return LookupOrInsert(key, hash, []() { return Value(); });
}
template <typename Key, typename Value, typename MatchFun,
......@@ -178,24 +177,23 @@ template <typename Key, typename Value, typename MatchFun,
template <typename Func>
typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry*
TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::LookupOrInsert(
const Key& key, uint32_t hash, const Func& value_func,
AllocationPolicy allocator) {
const Key& key, uint32_t hash, const Func& value_func) {
// Find a matching entry.
Entry* entry = Probe(key, hash);
if (entry->exists()) {
return entry;
}
return FillEmptyEntry(entry, key, value_func(), hash, allocator);
return FillEmptyEntry(entry, key, value_func(), hash);
}
template <typename Key, typename Value, typename MatchFun,
class AllocationPolicy>
typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry*
TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::InsertNew(
const Key& key, uint32_t hash, AllocationPolicy allocator) {
const Key& key, uint32_t hash) {
Entry* entry = Probe(key, hash);
return FillEmptyEntry(entry, key, Value(), hash, allocator);
return FillEmptyEntry(entry, key, Value(), hash);
}
template <typename Key, typename Value, typename MatchFun,
......@@ -313,8 +311,7 @@ template <typename Key, typename Value, typename MatchFun,
class AllocationPolicy>
typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry*
TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::FillEmptyEntry(
Entry* entry, const Key& key, const Value& value, uint32_t hash,
AllocationPolicy allocator) {
Entry* entry, const Key& key, const Value& value, uint32_t hash) {
DCHECK(!entry->exists());
new (entry) Entry(key, value, hash);
......@@ -322,7 +319,7 @@ TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::FillEmptyEntry(
// Grow the map if we reached >= 80% occupancy.
if (occupancy_ + occupancy_ / 4 >= capacity_) {
Resize(allocator);
Resize();
entry = Probe(key, hash);
}
......@@ -332,9 +329,9 @@ TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::FillEmptyEntry(
template <typename Key, typename Value, typename MatchFun,
class AllocationPolicy>
void TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Initialize(
uint32_t capacity, AllocationPolicy allocator) {
uint32_t capacity) {
DCHECK(base::bits::IsPowerOfTwo(capacity));
map_ = reinterpret_cast<Entry*>(allocator.New(capacity * sizeof(Entry)));
map_ = reinterpret_cast<Entry*>(allocator_.New(capacity * sizeof(Entry)));
if (map_ == nullptr) {
FATAL("Out of memory: HashMap::Initialize");
return;
......@@ -345,20 +342,19 @@ void TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Initialize(
template <typename Key, typename Value, typename MatchFun,
class AllocationPolicy>
void TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Resize(
AllocationPolicy allocator) {
void TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Resize() {
Entry* map = map_;
uint32_t n = occupancy_;
// Allocate larger map.
Initialize(capacity_ * 2, allocator);
Initialize(capacity_ * 2);
// Rehash all current entries.
for (Entry* entry = map; n > 0; entry++) {
if (entry->exists()) {
Entry* new_entry = Probe(entry->key, entry->hash);
new_entry = FillEmptyEntry(new_entry, entry->key, entry->value,
entry->hash, allocator);
new_entry =
FillEmptyEntry(new_entry, entry->key, entry->value, entry->hash);
n--;
}
}
......@@ -484,10 +480,9 @@ class TemplateHashMap
Iterator begin() const { return Iterator(this, this->Start()); }
Iterator end() const { return Iterator(this, nullptr); }
Iterator find(Key* key, bool insert = false,
AllocationPolicy allocator = AllocationPolicy()) {
Iterator find(Key* key, bool insert = false) {
if (insert) {
return Iterator(this, this->LookupOrInsert(key, key->Hash(), allocator));
return Iterator(this, this->LookupOrInsert(key, key->Hash()));
}
return Iterator(this, this->Lookup(key, key->Hash()));
}
......
......@@ -24,8 +24,7 @@ BytecodeLiveness& BytecodeLivenessMap::InitializeLiveness(int offset,
Zone* zone) {
return liveness_map_
.LookupOrInsert(offset, OffsetHash(offset),
[&]() { return BytecodeLiveness(register_count, zone); },
ZoneAllocationPolicy(zone))
[&]() { return BytecodeLiveness(register_count, zone); })
->value;
}
......
......@@ -2707,7 +2707,7 @@ void JSHeapBroker::InitializeAndStartSerializing(
// clang-format off
ObjectData* JSHeapBroker::GetOrCreateData(Handle<Object> object) {
RefsMap::Entry* entry = refs_->LookupOrInsert(object.address(), zone());
RefsMap::Entry* entry = refs_->LookupOrInsert(object.address());
ObjectData** data_storage = &(entry->value);
if (*data_storage == nullptr) {
// TODO(neis): Remove these Allow* once we serialize everything upfront.
......@@ -3987,8 +3987,7 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object,
data_ = broker->GetOrCreateData(object);
break;
case JSHeapBroker::kDisabled: {
RefsMap::Entry* entry =
broker->refs_->LookupOrInsert(object.address(), broker->zone());
RefsMap::Entry* entry = broker->refs_->LookupOrInsert(object.address());
ObjectData** storage = &(entry->value);
if (*storage == nullptr) {
AllowHandleDereferenceIf allow_handle_dereference(
......
......@@ -22,10 +22,9 @@ RefsMap::Entry* RefsMap::Lookup(const Address& key) const {
return UnderlyingMap::Lookup(key, Hash(key));
}
RefsMap::Entry* RefsMap::LookupOrInsert(const Address& key, Zone* zone) {
RefsMap::Entry* RefsMap::LookupOrInsert(const Address& key) {
return UnderlyingMap::LookupOrInsert(key, RefsMap::Hash(key),
[]() { return nullptr; },
ZoneAllocationPolicy(zone));
[]() { return nullptr; });
}
uint32_t RefsMap::Hash(Address addr) { return static_cast<uint32_t>(addr); }
......
......@@ -41,7 +41,7 @@ class RefsMap
// Wrappers around methods from UnderlyingMap
Entry* Lookup(const Address& key) const;
Entry* LookupOrInsert(const Address& key, Zone* zone);
Entry* LookupOrInsert(const Address& key);
private:
static uint32_t Hash(Address addr);
......
......@@ -119,8 +119,7 @@ Node* StateValuesCache::GetValuesNodeFromCache(Node** nodes, size_t count,
SparseInputMask mask) {
StateValuesKey key(count, mask, nodes);
int hash = StateValuesHashKey(nodes, count);
ZoneHashMap::Entry* lookup =
hash_map_.LookupOrInsert(&key, hash, ZoneAllocationPolicy(zone()));
ZoneHashMap::Entry* lookup = hash_map_.LookupOrInsert(&key, hash);
DCHECK_NOT_NULL(lookup);
Node* node;
if (lookup->value == nullptr) {
......
......@@ -1005,7 +1005,7 @@ class AccessorTable
zone_(zone) {}
Accessors<PropertyT>* LookupOrInsert(Literal* key) {
auto it = this->find(key, true, ZoneAllocationPolicy(zone_));
auto it = this->find(key, true);
if (it->second == nullptr) {
it->second = zone_->New<Accessors<PropertyT>>();
ordered_accessors_.push_back({key, it->second});
......
......@@ -134,11 +134,7 @@ ConstantArrayBuilder::ConstantArrayBuilder(Zone* zone)
ZoneAllocationPolicy(zone)),
smi_map_(zone),
smi_pairs_(zone),
heap_number_map_(zone),
#define INIT_SINGLETON_ENTRY_FIELD(NAME, LOWER_NAME) LOWER_NAME##_(-1),
SINGLETON_CONSTANT_ENTRY_TYPES(INIT_SINGLETON_ENTRY_FIELD)
#undef INIT_SINGLETON_ENTRY_FIELD
zone_(zone) {
heap_number_map_(zone) {
idx_slice_[0] =
zone->New<ConstantArraySlice>(zone, 0, k8BitCapacity, OperandSize::kByte);
idx_slice_[1] = zone->New<ConstantArraySlice>(
......@@ -247,8 +243,7 @@ size_t ConstantArrayBuilder::Insert(const AstRawString* raw_string) {
return constants_map_
.LookupOrInsert(reinterpret_cast<intptr_t>(raw_string),
raw_string->Hash(),
[&]() { return AllocateIndex(Entry(raw_string)); },
ZoneAllocationPolicy(zone_))
[&]() { return AllocateIndex(Entry(raw_string)); })
->value;
}
......@@ -256,8 +251,7 @@ size_t ConstantArrayBuilder::Insert(AstBigInt bigint) {
return constants_map_
.LookupOrInsert(reinterpret_cast<intptr_t>(bigint.c_str()),
static_cast<uint32_t>(base::hash_value(bigint.c_str())),
[&]() { return AllocateIndex(Entry(bigint)); },
ZoneAllocationPolicy(zone_))
[&]() { return AllocateIndex(Entry(bigint)); })
->value;
}
......@@ -265,8 +259,7 @@ size_t ConstantArrayBuilder::Insert(const Scope* scope) {
return constants_map_
.LookupOrInsert(reinterpret_cast<intptr_t>(scope),
static_cast<uint32_t>(base::hash_value(scope)),
[&]() { return AllocateIndex(Entry(scope)); },
ZoneAllocationPolicy(zone_))
[&]() { return AllocateIndex(Entry(scope)); })
->value;
}
......
......@@ -239,11 +239,9 @@ class V8_EXPORT_PRIVATE ConstantArrayBuilder final {
ZoneVector<std::pair<Smi, index_t>> smi_pairs_;
ZoneMap<double, index_t> heap_number_map_;
#define SINGLETON_ENTRY_FIELD(NAME, LOWER_NAME) int LOWER_NAME##_;
#define SINGLETON_ENTRY_FIELD(NAME, LOWER_NAME) int LOWER_NAME##_ = -1;
SINGLETON_CONSTANT_ENTRY_TYPES(SINGLETON_ENTRY_FIELD)
#undef SINGLETON_ENTRY_FIELD
Zone* zone_;
};
} // namespace interpreter
......
......@@ -1068,17 +1068,19 @@ Maybe<bool> KeyAccumulator::CollectOwnJSProxyKeys(Handle<JSReceiver> receiver,
// exception. Combine with step 18
// 18. Let uncheckedResultKeys be a new List which is a copy of trapResult.
Zone set_zone(isolate_->allocator(), ZONE_NAME);
ZoneAllocationPolicy alloc(&set_zone);
const int kPresent = 1;
const int kGone = 0;
base::TemplateHashMapImpl<Handle<Name>, int, NameComparator,
ZoneAllocationPolicy>
unchecked_result_keys(ZoneHashMap::kDefaultHashMapCapacity,
NameComparator(isolate_), alloc);
using ZoneHashMapImpl =
base::TemplateHashMapImpl<Handle<Name>, int, NameComparator,
ZoneAllocationPolicy>;
ZoneHashMapImpl unchecked_result_keys(
ZoneHashMapImpl::kDefaultHashMapCapacity, NameComparator(isolate_),
ZoneAllocationPolicy(&set_zone));
int unchecked_result_keys_size = 0;
for (int i = 0; i < trap_result->length(); ++i) {
Handle<Name> key(Name::cast(trap_result->get(i)), isolate_);
auto entry = unchecked_result_keys.LookupOrInsert(key, key->Hash(), alloc);
auto entry = unchecked_result_keys.LookupOrInsert(key, key->Hash());
if (entry->value != kPresent) {
entry->value = kPresent;
unchecked_result_keys_size++;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment