Commit 7b6011c1 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[heap] Introduce Heap::AllocateFixedArrayWithMap().

... and use it for allocation of FixedArray-based objects with custom maps.

Change-Id: Id31d05cf506e3607210fe7fdaf05f55053de5e2a
Reviewed-on: https://chromium-review.googlesource.com/789113Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49622}
parent ecb98b8d
......@@ -620,9 +620,8 @@ Node* CollectionsBuiltinsAssembler::AllocateOrderedHashTable() {
// Allocate the table and add the proper map.
const ElementsKind elements_kind = HOLEY_ELEMENTS;
Node* const length_intptr = IntPtrConstant(kFixedArrayLength);
Heap::RootListIndex map_index =
static_cast<Heap::RootListIndex>(CollectionType::GetMapRootIndex());
Node* const fixed_array_map = LoadRoot(map_index);
Node* const fixed_array_map = LoadRoot(
static_cast<Heap::RootListIndex>(CollectionType::GetMapRootIndex()));
Node* const table =
AllocateFixedArray(elements_kind, length_intptr, INTPTR_PARAMETERS,
kAllowLargeObjectAllocation, fixed_array_map);
......@@ -2041,8 +2040,9 @@ TNode<Object> WeakCollectionsBuiltinsAssembler::AllocateTable(
TNode<Object> table = CAST(AllocateFixedArray(
HOLEY_ELEMENTS, length, INTPTR_PARAMETERS, kAllowLargeObjectAllocation));
// See BaseShape::GetMap().
StoreMapNoWriteBarrier(table, Heap::kHashTableMapRootIndex);
Heap::RootListIndex map_root_index =
static_cast<Heap::RootListIndex>(ObjectHashTableShape::GetMapRootIndex());
StoreMapNoWriteBarrier(table, map_root_index);
StoreFixedArrayElement(table, ObjectHashTable::kNumberOfElementsIndex,
SmiConstant(0), SKIP_WRITE_BARRIER);
StoreFixedArrayElement(table, ObjectHashTable::kNumberOfDeletedElementsIndex,
......
......@@ -169,51 +169,68 @@ Handle<Oddball> Factory::NewOddball(Handle<Map> map, const char* to_string,
return oddball;
}
Handle<FixedArray> Factory::NewFixedArray(int size, PretenureFlag pretenure) {
DCHECK_LE(0, size);
Handle<PropertyArray> Factory::NewPropertyArray(int length,
PretenureFlag pretenure) {
DCHECK_LE(0, length);
if (length == 0) return empty_property_array();
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateFixedArray(size, pretenure),
FixedArray);
isolate(), isolate()->heap()->AllocatePropertyArray(length, pretenure),
PropertyArray);
}
Handle<PropertyArray> Factory::NewPropertyArray(int size,
PretenureFlag pretenure) {
DCHECK_LE(0, size);
if (size == 0) return empty_property_array();
Handle<FixedArray> Factory::NewFixedArrayWithMap(
Heap::RootListIndex map_root_index, int length, PretenureFlag pretenure) {
// Zero-length case must be handled outside, where the knowledge about
// the map is.
DCHECK_LT(0, length);
CALL_HEAP_FUNCTION(isolate(),
isolate()->heap()->AllocateFixedArrayWithMap(
map_root_index, length, pretenure),
FixedArray);
}
Handle<FixedArray> Factory::NewFixedArray(int length, PretenureFlag pretenure) {
DCHECK_LE(0, length);
if (length == 0) return empty_fixed_array();
CALL_HEAP_FUNCTION(isolate(),
isolate()->heap()->AllocatePropertyArray(size, pretenure),
PropertyArray);
isolate()->heap()->AllocateFixedArray(length, pretenure),
FixedArray);
}
MaybeHandle<FixedArray> Factory::TryNewFixedArray(int size,
MaybeHandle<FixedArray> Factory::TryNewFixedArray(int length,
PretenureFlag pretenure) {
DCHECK_LE(0, size);
DCHECK_LE(0, length);
if (length == 0) return empty_fixed_array();
AllocationResult allocation =
isolate()->heap()->AllocateFixedArray(size, pretenure);
isolate()->heap()->AllocateFixedArray(length, pretenure);
Object* array = nullptr;
if (!allocation.To(&array)) return MaybeHandle<FixedArray>();
return Handle<FixedArray>(FixedArray::cast(array), isolate());
}
Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size,
Handle<FixedArray> Factory::NewFixedArrayWithHoles(int length,
PretenureFlag pretenure) {
DCHECK_LE(0, size);
DCHECK_LE(0, length);
if (length == 0) return empty_fixed_array();
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateFixedArrayWithFiller(size,
pretenure,
*the_hole_value()),
isolate()->heap()->AllocateFixedArrayWithFiller(
Heap::kFixedArrayMapRootIndex, length, pretenure, *the_hole_value()),
FixedArray);
}
Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) {
Handle<FixedArray> Factory::NewUninitializedFixedArray(int length) {
DCHECK_LE(0, length);
if (length == 0) return empty_fixed_array();
// TODO(ulan): As an experiment this temporarily returns an initialized fixed
// array. After getting canary/performance coverage, either remove the
// function or revert to returning uninitilized array.
CALL_HEAP_FUNCTION(isolate(),
isolate()->heap()->AllocateFixedArray(size, NOT_TENURED),
isolate()->heap()->AllocateFixedArray(length, NOT_TENURED),
FixedArray);
}
......
......@@ -70,10 +70,15 @@ class V8_EXPORT_PRIVATE Factory final {
Handle<Object> to_number, const char* type_of,
byte kind);
// Allocates a fixed array-like object with given map and initialized with
// undefined values.
Handle<FixedArray> NewFixedArrayWithMap(Heap::RootListIndex map_root_index,
int length, PretenureFlag pretenure);
// Allocates a fixed array initialized with undefined values.
Handle<FixedArray> NewFixedArray(int size,
Handle<FixedArray> NewFixedArray(int length,
PretenureFlag pretenure = NOT_TENURED);
Handle<PropertyArray> NewPropertyArray(int size,
Handle<PropertyArray> NewPropertyArray(int length,
PretenureFlag pretenure = NOT_TENURED);
// Tries allocating a fixed array initialized with undefined values.
// In case of an allocation failure (OOM) an empty handle is returned.
......@@ -82,15 +87,14 @@ class V8_EXPORT_PRIVATE Factory final {
// NewFixedArray as a fallback.
MUST_USE_RESULT
MaybeHandle<FixedArray> TryNewFixedArray(
int size, PretenureFlag pretenure = NOT_TENURED);
int length, PretenureFlag pretenure = NOT_TENURED);
// Allocate a new fixed array with non-existing entries (the hole).
Handle<FixedArray> NewFixedArrayWithHoles(
int size,
PretenureFlag pretenure = NOT_TENURED);
int length, PretenureFlag pretenure = NOT_TENURED);
// Allocates an uninitialized fixed array. It must be filled by the caller.
Handle<FixedArray> NewUninitializedFixedArray(int size);
Handle<FixedArray> NewUninitializedFixedArray(int length);
// Allocates a feedback vector whose slots are initialized with undefined
// values.
......
......@@ -224,8 +224,16 @@ AllocationResult Heap::CopyFixedDoubleArray(FixedDoubleArray* src) {
return CopyFixedDoubleArrayWithMap(src, src->map());
}
AllocationResult Heap::AllocateFixedArrayWithMap(RootListIndex map_root_index,
int length,
PretenureFlag pretenure) {
return AllocateFixedArrayWithFiller(map_root_index, length, pretenure,
undefined_value());
}
AllocationResult Heap::AllocateFixedArray(int length, PretenureFlag pretenure) {
return AllocateFixedArrayWithFiller(length, pretenure, undefined_value());
return AllocateFixedArrayWithFiller(Heap::kFixedArrayMapRootIndex, length,
pretenure, undefined_value());
}
AllocationResult Heap::AllocateRaw(int size_in_bytes, AllocationSpace space,
......
......@@ -3860,22 +3860,21 @@ AllocationResult Heap::AllocateRawFixedArray(int length,
return result;
}
AllocationResult Heap::AllocateFixedArrayWithFiller(int length,
PretenureFlag pretenure,
Object* filler) {
DCHECK_LE(0, length);
DCHECK(empty_fixed_array()->IsFixedArray());
if (length == 0) return empty_fixed_array();
AllocationResult Heap::AllocateFixedArrayWithFiller(
RootListIndex map_root_index, int length, PretenureFlag pretenure,
Object* filler) {
// Zero-length case must be handled outside, where the knowledge about
// the map is.
DCHECK_LT(0, length);
DCHECK(!InNewSpace(filler));
HeapObject* result = nullptr;
{
AllocationResult allocation = AllocateRawFixedArray(length, pretenure);
if (!allocation.To(&result)) return allocation;
}
result->set_map_after_allocation(fixed_array_map(), SKIP_WRITE_BARRIER);
DCHECK(RootIsImmortalImmovable(map_root_index));
Map* map = Map::cast(root(map_root_index));
result->set_map_after_allocation(map, SKIP_WRITE_BARRIER);
FixedArray* array = FixedArray::cast(result);
array->set_length(length);
MemsetPointer(array->data_start(), filler, length);
......
......@@ -2075,6 +2075,12 @@ class Heap {
MUST_USE_RESULT AllocationResult
CopyBytecodeArray(BytecodeArray* bytecode_array);
// Allocates a fixed array-like object with given map and initialized with
// undefined values.
MUST_USE_RESULT inline AllocationResult AllocateFixedArrayWithMap(
RootListIndex map_root_index, int length,
PretenureFlag pretenure = NOT_TENURED);
// Allocates a fixed array initialized with undefined values
MUST_USE_RESULT inline AllocationResult AllocateFixedArray(
int length, PretenureFlag pretenure = NOT_TENURED);
......@@ -2129,8 +2135,8 @@ class Heap {
// Allocate an initialized fixed array with the given filler value.
MUST_USE_RESULT AllocationResult
AllocateFixedArrayWithFiller(int length, PretenureFlag pretenure,
Object* filler);
AllocateFixedArrayWithFiller(RootListIndex map_root_index, int length,
PretenureFlag pretenure, Object* filler);
// Allocate and partially initializes a String. There are two String
// encodings: one-byte and two-byte. These functions allocate a string of
......
......@@ -2434,8 +2434,8 @@ void HashTableBase::SetNumberOfDeletedElements(int nod) {
}
template <typename Key>
Map* BaseShape<Key>::GetMap(Isolate* isolate) {
return isolate->heap()->hash_table_map();
int BaseShape<Key>::GetMapRootIndex() {
return Heap::kHashTableMapRootIndex;
}
template <typename Derived, typename Shape>
......@@ -2512,8 +2512,8 @@ uint32_t StringTableShape::HashForObject(Isolate* isolate, Object* object) {
return String::cast(object)->Hash();
}
Map* StringTableShape::GetMap(Isolate* isolate) {
return isolate->heap()->string_table_map();
int StringTableShape::GetMapRootIndex() {
return Heap::kStringTableMapRootIndex;
}
bool NumberDictionary::requires_slow_elements() {
......@@ -4802,14 +4802,14 @@ Object* GlobalDictionaryShape::Unwrap(Object* object) {
return PropertyCell::cast(object)->name();
}
Map* GlobalDictionaryShape::GetMap(Isolate* isolate) {
return isolate->heap()->global_dictionary_map();
int GlobalDictionaryShape::GetMapRootIndex() {
return Heap::kGlobalDictionaryMapRootIndex;
}
Name* NameDictionary::NameAt(int entry) { return Name::cast(KeyAt(entry)); }
Map* NameDictionaryShape::GetMap(Isolate* isolate) {
return isolate->heap()->name_dictionary_map();
int NameDictionaryShape::GetMapRootIndex() {
return Heap::kNameDictionaryMapRootIndex;
}
PropertyCell* GlobalDictionary::CellAt(int entry) {
......@@ -4857,8 +4857,8 @@ uint32_t NumberDictionaryShape::HashForObject(Isolate* isolate, Object* other) {
isolate->heap()->HashSeed());
}
Map* NumberDictionaryShape::GetMap(Isolate* isolate) {
return isolate->heap()->number_dictionary_map();
int NumberDictionaryShape::GetMapRootIndex() {
return Heap::kNumberDictionaryMapRootIndex;
}
Handle<Object> NumberDictionaryShape::AsHandle(Isolate* isolate, uint32_t key) {
......@@ -4963,8 +4963,8 @@ Handle<Object> WeakHashTableShape::AsHandle(Isolate* isolate,
return key;
}
Map* WeakHashTableShape::GetMap(Isolate* isolate) {
return isolate->heap()->weak_hash_table_map();
int WeakHashTableShape::GetMapRootIndex() {
return Heap::kWeakHashTableMapRootIndex;
}
int Map::SlackForArraySize(int old_size, int size_limit) {
......
......@@ -10367,9 +10367,8 @@ Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
int size = number_of_descriptors + slack;
if (size == 0) return factory->empty_descriptor_array();
// Allocate the array of keys.
Handle<FixedArray> result =
factory->NewFixedArray(LengthFor(size), pretenure);
result->set_map_no_write_barrier(*factory->descriptor_array_map());
Handle<FixedArray> result = factory->NewFixedArrayWithMap(
Heap::kDescriptorArrayMapRootIndex, LengthFor(size), pretenure);
result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
result->set(kEnumCacheIndex, isolate->heap()->empty_enum_cache());
return Handle<DescriptorArray>::cast(result);
......@@ -16131,8 +16130,10 @@ Handle<Derived> HashTable<Derived, Shape>::NewInternal(
Isolate* isolate, int capacity, PretenureFlag pretenure) {
Factory* factory = isolate->factory();
int length = EntryToIndex(capacity);
Handle<FixedArray> array = factory->NewFixedArray(length, pretenure);
array->set_map_no_write_barrier(Shape::GetMap(isolate));
Heap::RootListIndex map_root_index =
static_cast<Heap::RootListIndex>(Shape::GetMapRootIndex());
Handle<FixedArray> array =
factory->NewFixedArrayWithMap(map_root_index, length, pretenure);
Handle<Derived> table = Handle<Derived>::cast(array);
table->SetNumberOfElements(0);
......@@ -17932,11 +17933,9 @@ Handle<Derived> OrderedHashTable<Derived, entrysize>::Allocate(
v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
}
int num_buckets = capacity / kLoadFactor;
Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray(
Handle<FixedArray> backing_store = isolate->factory()->NewFixedArrayWithMap(
static_cast<Heap::RootListIndex>(Derived::GetMapRootIndex()),
kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure);
Map* map = Map::cast(isolate->heap()->root(
static_cast<Heap::RootListIndex>(Derived::GetMapRootIndex())));
backing_store->set_map_no_write_barrier(map);
Handle<Derived> table = Handle<Derived>::cast(backing_store);
for (int i = 0; i < num_buckets; ++i) {
table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound));
......@@ -18061,14 +18060,6 @@ HeapObject* OrderedHashMap::GetEmpty(Isolate* isolate) {
return isolate->heap()->empty_ordered_hash_map();
}
int OrderedHashSet::GetMapRootIndex() {
return Heap::kOrderedHashSetMapRootIndex;
}
int OrderedHashMap::GetMapRootIndex() {
return Heap::kOrderedHashMapMapRootIndex;
}
template <class Derived, int entrysize>
Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash(
Handle<Derived> table, int new_capacity) {
......
......@@ -112,7 +112,7 @@ class NameDictionaryShape : public BaseDictionaryShape<Handle<Name>> {
static inline uint32_t Hash(Isolate* isolate, Handle<Name> key);
static inline uint32_t HashForObject(Isolate* isolate, Object* object);
static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key);
static inline Map* GetMap(Isolate* isolate);
static inline int GetMapRootIndex();
static const int kPrefixSize = 2;
static const int kEntrySize = 3;
static const int kEntryValueIndex = 1;
......@@ -212,7 +212,7 @@ class GlobalDictionaryShape : public NameDictionaryShape {
static inline Object* Unwrap(Object* key);
static inline bool IsKey(Isolate* isolate, Object* k);
static inline bool IsLive(Isolate* isolate, Object* key);
static inline Map* GetMap(Isolate* isolate);
static inline int GetMapRootIndex();
};
class GlobalDictionary
......@@ -239,7 +239,7 @@ class NumberDictionaryShape : public BaseDictionaryShape<uint32_t> {
static inline uint32_t Hash(Isolate* isolate, uint32_t key);
static inline uint32_t HashForObject(Isolate* isolate, Object* object);
static inline Map* GetMap(Isolate* isolate);
static inline int GetMapRootIndex();
};
extern template class EXPORT_TEMPLATE_DECLARE(
......
......@@ -5,6 +5,7 @@
#ifndef V8_OBJECTS_HASH_TABLE_INL_H_
#define V8_OBJECTS_HASH_TABLE_INL_H_
#include "src/heap/heap.h"
#include "src/objects/hash-table.h"
namespace v8 {
......@@ -16,6 +17,14 @@ bool BaseShape<KeyT>::IsLive(Isolate* isolate, Object* k) {
return k != heap->the_hole_value() && k != heap->undefined_value();
}
int OrderedHashSet::GetMapRootIndex() {
return Heap::kOrderedHashSetMapRootIndex;
}
int OrderedHashMap::GetMapRootIndex() {
return Heap::kOrderedHashMapMapRootIndex;
}
} // namespace internal
} // namespace v8
......
......@@ -56,7 +56,7 @@ template <typename KeyT>
class BaseShape {
public:
typedef KeyT Key;
static inline Map* GetMap(Isolate* isolate);
static inline int GetMapRootIndex();
static const bool kNeedsHoleCheck = true;
static Object* Unwrap(Object* key) { return key; }
static bool IsKey(Isolate* isolate, Object* key) {
......@@ -554,7 +554,7 @@ class OrderedHashSet : public OrderedHashTable<OrderedHashSet, 1> {
static Handle<FixedArray> ConvertToKeysArray(Handle<OrderedHashSet> table,
GetKeysConversion convert);
static HeapObject* GetEmpty(Isolate* isolate);
static int GetMapRootIndex();
static inline int GetMapRootIndex();
};
class OrderedHashMap : public OrderedHashTable<OrderedHashMap, 2> {
......@@ -570,7 +570,7 @@ class OrderedHashMap : public OrderedHashTable<OrderedHashMap, 2> {
static Object* GetHash(Isolate* isolate, Object* key);
static HeapObject* GetEmpty(Isolate* isolate);
static int GetMapRootIndex();
static inline int GetMapRootIndex();
static const int kValueOffset = 1;
};
......@@ -581,7 +581,7 @@ class WeakHashTableShape : public BaseShape<Handle<Object>> {
static inline uint32_t Hash(Isolate* isolate, Handle<Object> key);
static inline uint32_t HashForObject(Isolate* isolate, Object* object);
static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
static inline Map* GetMap(Isolate* isolate);
static inline int GetMapRootIndex();
static const int kPrefixSize = 0;
static const int kEntrySize = 2;
static const bool kNeedsHoleCheck = false;
......
......@@ -305,10 +305,6 @@ class ObjectDescriptor {
} else {
descriptor_array_template_ =
DescriptorArray::Allocate(isolate, 0, property_count_ + slack);
// TODO(ishell): remove this code once we use |descriptor_array_map|
// for all descriptor arrays.
descriptor_array_template_->set_map_no_write_barrier(
*factory->descriptor_array_map());
}
}
elements_dictionary_template_ =
......
......@@ -42,7 +42,7 @@ class StringTableShape : public BaseShape<StringTableKey*> {
static inline Handle<Object> AsHandle(Isolate* isolate, Key key);
static inline Map* GetMap(Isolate* isolate);
static inline int GetMapRootIndex();
static const int kPrefixSize = 0;
static const int kEntrySize = 1;
......
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