Commit 9aab9f13 authored by adamk's avatar adamk Committed by Commit bot

Create optimized versions of the Map/Set clear method

This completes the first round of optimizations for Map and Set.
All non-key-dependent methods now have a Hydrogen version, and
for keyed methods, string versions are optimized.

Review URL: https://codereview.chromium.org/796503002

Cr-Commit-Position: refs/heads/master@{#25763}
parent 33f0cf5a
......@@ -92,7 +92,7 @@ function SetClearJS() {
throw MakeTypeError('incompatible_method_receiver',
['Set.prototype.clear', this]);
}
%SetClear(this);
%_SetClear(this);
}
......@@ -245,7 +245,7 @@ function MapClearJS() {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.clear', this]);
}
%MapClear(this);
%_MapClear(this);
}
......
......@@ -6367,6 +6367,11 @@ class HObjectAccess FINAL {
Representation::Smi());
}
template <typename CollectionType>
static HObjectAccess ForOrderedHashTableNextTable() {
return HObjectAccess(kInobject, CollectionType::kNextTableOffset);
}
template <typename CollectionType>
static HObjectAccess ForOrderedHashTableBucket(int bucket) {
return HObjectAccess(kInobject, CollectionType::kHashTableStartOffset +
......
......@@ -12727,6 +12727,46 @@ void HOptimizedGraphBuilder::GenerateMapInitialize(CallRuntime* call) {
}
template <typename CollectionType>
void HOptimizedGraphBuilder::BuildOrderedHashTableClear(HValue* receiver) {
HValue* old_table =
Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
HObjectAccess::ForJSCollectionTable());
HValue* new_table = BuildAllocateOrderedHashTable<CollectionType>();
Add<HStoreNamedField>(
old_table, HObjectAccess::ForOrderedHashTableNextTable<CollectionType>(),
new_table);
Add<HStoreNamedField>(
old_table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
CollectionType>(),
Add<HConstant>(CollectionType::kClearedTableSentinel));
Add<HStoreNamedField>(receiver, HObjectAccess::ForJSCollectionTable(),
new_table);
}
void HOptimizedGraphBuilder::GenerateSetClear(CallRuntime* call) {
DCHECK(call->arguments()->length() == 1);
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
HValue* receiver = Pop();
NoObservableSideEffectsScope no_effects(this);
BuildOrderedHashTableClear<OrderedHashSet>(receiver);
return ast_context()->ReturnValue(graph()->GetConstantUndefined());
}
void HOptimizedGraphBuilder::GenerateMapClear(CallRuntime* call) {
DCHECK(call->arguments()->length() == 1);
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
HValue* receiver = Pop();
NoObservableSideEffectsScope no_effects(this);
BuildOrderedHashTableClear<OrderedHashMap>(receiver);
return ast_context()->ReturnValue(graph()->GetConstantUndefined());
}
void HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) {
DCHECK(call->arguments()->length() == 1);
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
......
......@@ -2434,6 +2434,8 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
template <typename CollectionType>
HValue* BuildAllocateOrderedHashTable();
template <typename CollectionType>
void BuildOrderedHashTableClear(HValue* receiver);
template <typename CollectionType>
void BuildJSCollectionDelete(CallRuntime* call,
const Runtime::Function* c_function);
template <typename CollectionType>
......
......@@ -16025,7 +16025,7 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear(
table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
table->SetNextTable(*new_table);
table->SetNumberOfDeletedElements(-1);
table->SetNumberOfDeletedElements(kClearedTableSentinel);
return new_table;
}
......@@ -16270,8 +16270,7 @@ void OrderedHashTableIterator<Derived, TableType>::Transition() {
if (index > 0) {
int nod = table->NumberOfDeletedElements();
// When we clear the table we set the number of deleted elements to -1.
if (nod == -1) {
if (nod == TableType::kClearedTableSentinel) {
index = 0;
} else {
int old_index = index;
......
......@@ -3933,6 +3933,7 @@ class OrderedHashTable: public FixedArray {
static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1;
static const int kNextTableIndex = kNumberOfElementsIndex;
static const int kNumberOfBucketsOffset =
kHeaderSize + kNumberOfBucketsIndex * kPointerSize;
......@@ -3942,12 +3943,19 @@ class OrderedHashTable: public FixedArray {
kHeaderSize + kNumberOfDeletedElementsIndex * kPointerSize;
static const int kHashTableStartOffset =
kHeaderSize + kHashTableStartIndex * kPointerSize;
static const int kNextTableOffset =
kHeaderSize + kNextTableIndex * kPointerSize;
static const int kEntrySize = entrysize + 1;
static const int kChainOffset = entrysize;
static const int kLoadFactor = 2;
// NumberOfDeletedElements is set to kClearedTableSentinel when
// the table is cleared, which allows iterator transitions to
// optimize that case.
static const int kClearedTableSentinel = -1;
private:
static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
......@@ -3989,7 +3997,6 @@ class OrderedHashTable: public FixedArray {
return set(kRemovedHolesIndex + index, Smi::FromInt(removed_index));
}
static const int kNextTableIndex = kNumberOfElementsIndex;
static const int kRemovedHolesIndex = kHashTableStartIndex;
static const int kMaxCapacity =
......
......@@ -300,17 +300,11 @@ namespace internal {
F(GetConstructTrap, 1, 1) \
F(Fix, 1, 1) \
\
/* Harmony sets */ \
F(SetClear, 1, 1) \
\
/* ES6 collection iterators */ \
F(SetIteratorInitialize, 3, 1) \
F(SetIteratorClone, 1, 1) \
F(SetIteratorNext, 2, 1) \
F(SetIteratorDetails, 1, 1) \
\
/* Harmony maps */ \
F(MapClear, 1, 1) \
\
F(MapIteratorInitialize, 3, 1) \
F(MapIteratorClone, 1, 1) \
F(MapIteratorNext, 2, 1) \
......@@ -721,6 +715,7 @@ namespace internal {
F(MathSqrtRT, 1, 1) \
F(MathLogRT, 1, 1) \
/* ES6 Collections */ \
F(MapClear, 1, 1) \
F(MapDelete, 2, 1) \
F(MapGet, 2, 1) \
F(MapGetSize, 1, 1) \
......@@ -728,6 +723,7 @@ namespace internal {
F(MapInitialize, 1, 1) \
F(MapSet, 3, 1) \
F(SetAdd, 2, 1) \
F(SetClear, 1, 1) \
F(SetDelete, 2, 1) \
F(SetGetSize, 1, 1) \
F(SetHas, 2, 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