Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Unified Diff: src/code-stub-assembler.cc

Issue 2504403005: [stubs] KeyedStoreGeneric: inline dictionary property stores (Closed)
Patch Set: ready for review Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/code-stub-assembler.cc
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
index b03007755e5ee12c68c7a7747f02f13d67c197b1..e3b3e17c9c84579dcc3ad55e26e71ea647d148b3 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -1335,13 +1335,15 @@ Node* CodeStubAssembler::StoreObjectFieldRoot(Node* object, int offset,
Node* CodeStubAssembler::StoreFixedArrayElement(Node* object, Node* index_node,
Node* value,
+ int additional_offset,
rmcilroy 2016/11/21 17:25:18 Would it be worth reordering these so that you don
Igor Sheludko 2016/11/22 12:05:07 +1. And if you put additional parameter after Writ
Jakob Kummerow 2016/11/22 13:47:57 Done.
WriteBarrierMode barrier_mode,
ParameterMode parameter_mode) {
DCHECK(barrier_mode == SKIP_WRITE_BARRIER ||
barrier_mode == UPDATE_WRITE_BARRIER);
- Node* offset =
- ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS, parameter_mode,
- FixedArray::kHeaderSize - kHeapObjectTag);
+ int header_size =
+ FixedArray::kHeaderSize + additional_offset - kHeapObjectTag;
+ Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS,
+ parameter_mode, header_size);
MachineRepresentation rep = MachineRepresentation::kTagged;
if (barrier_mode == SKIP_WRITE_BARRIER) {
return StoreNoWriteBarrier(rep, object, offset, value);
@@ -4036,19 +4038,57 @@ Node* CodeStubAssembler::IntPtrMax(Node* left, Node* right) {
MachineType::PointerRepresentation());
}
+template <class Dictionary>
+Node* CodeStubAssembler::GetNumberOfElements(Node* dictionary) {
+ return LoadFixedArrayElement(
+ dictionary, IntPtrConstant(Dictionary::kNumberOfElementsIndex), 0,
+ INTPTR_PARAMETERS);
+}
+
+template <class Dictionary>
+void CodeStubAssembler::SetNumberOfElements(Node* dictionary,
+ Node* num_elements_smi) {
+ StoreFixedArrayElement(
+ dictionary, IntPtrConstant(Dictionary::kNumberOfElementsIndex),
+ num_elements_smi, 0, SKIP_WRITE_BARRIER, INTPTR_PARAMETERS);
+}
+
+template <class Dictionary>
+Node* CodeStubAssembler::GetCapacity(Node* dictionary) {
+ return LoadFixedArrayElement(dictionary,
+ IntPtrConstant(Dictionary::kCapacityIndex), 0,
+ INTPTR_PARAMETERS);
+}
+
+template <class Dictionary>
+Node* CodeStubAssembler::GetNextEnumerationIndex(Node* dictionary) {
+ return LoadFixedArrayElement(
+ dictionary, IntPtrConstant(Dictionary::kNextEnumerationIndexIndex), 0,
+ INTPTR_PARAMETERS);
+}
+
+template <class Dictionary>
+void CodeStubAssembler::SetNextEnumerationIndex(Node* dictionary,
+ Node* next_enum_index_smi) {
+ StoreFixedArrayElement(
+ dictionary, IntPtrConstant(Dictionary::kNextEnumerationIndexIndex),
+ next_enum_index_smi, 0, SKIP_WRITE_BARRIER, INTPTR_PARAMETERS);
+}
+
template <typename Dictionary>
void CodeStubAssembler::NameDictionaryLookup(Node* dictionary,
Node* unique_name, Label* if_found,
Variable* var_name_index,
Label* if_not_found,
- int inlined_probes) {
+ int inlined_probes,
+ LookupMode mode) {
CSA_ASSERT(this, IsDictionary(dictionary));
DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep());
+ DCHECK_IMPLIES(mode == kFindInsertionIndex,
+ inlined_probes == 0 && if_found == nullptr);
Comment("NameDictionaryLookup");
- Node* capacity = SmiUntag(LoadFixedArrayElement(
- dictionary, IntPtrConstant(Dictionary::kCapacityIndex), 0,
- INTPTR_PARAMETERS));
+ Node* capacity = SmiUntag(GetCapacity<Dictionary>(dictionary));
Node* mask = IntPtrSub(capacity, IntPtrConstant(1));
Node* hash = ChangeUint32ToWord(LoadNameHash(unique_name));
@@ -4068,8 +4108,13 @@ void CodeStubAssembler::NameDictionaryLookup(Node* dictionary,
count = IntPtrConstant(i + 1);
entry = WordAnd(IntPtrAdd(entry, count), mask);
}
+ if (mode == kFindInsertionIndex) {
+ // Appease the variable merging algorithm for "Goto(&loop)" below.
+ var_name_index->Bind(IntPtrConstant(0));
+ }
Node* undefined = UndefinedConstant();
+ Node* the_hole = mode == kFindExisting ? nullptr : TheHoleConstant();
Variable var_count(this, MachineType::PointerRepresentation());
Variable var_entry(this, MachineType::PointerRepresentation());
@@ -4089,7 +4134,12 @@ void CodeStubAssembler::NameDictionaryLookup(Node* dictionary,
Node* current =
LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS);
GotoIf(WordEqual(current, undefined), if_not_found);
- GotoIf(WordEqual(current, unique_name), if_found);
+ if (mode == kFindExisting) {
+ GotoIf(WordEqual(current, unique_name), if_found);
+ } else {
+ DCHECK(mode == kFindInsertionIndex);
Igor Sheludko 2016/11/22 12:05:08 DCHECK_EQ
Jakob Kummerow 2016/11/22 13:47:57 Done. (FWIW, I disagree with the preference -- I t
+ GotoIf(WordEqual(current, the_hole), if_not_found);
+ }
// See Dictionary::NextProbe().
count = IntPtrAdd(count, IntPtrConstant(1));
@@ -4103,9 +4153,9 @@ void CodeStubAssembler::NameDictionaryLookup(Node* dictionary,
// Instantiate template methods to workaround GCC compilation issue.
template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>(
- Node*, Node*, Label*, Variable*, Label*, int);
+ Node*, Node*, Label*, Variable*, Label*, int, LookupMode);
template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>(
- Node*, Node*, Label*, Variable*, Label*, int);
+ Node*, Node*, Label*, Variable*, Label*, int, LookupMode);
Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) {
// See v8::internal::ComputeIntegerHash()
@@ -4131,9 +4181,7 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
DCHECK_EQ(MachineType::PointerRepresentation(), var_entry->rep());
Comment("NumberDictionaryLookup");
- Node* capacity = SmiUntag(LoadFixedArrayElement(
- dictionary, IntPtrConstant(Dictionary::kCapacityIndex), 0,
- INTPTR_PARAMETERS));
+ Node* capacity = SmiUntag(GetCapacity<Dictionary>(dictionary));
Node* mask = IntPtrSub(capacity, IntPtrConstant(1));
Node* int32_seed;
@@ -4197,6 +4245,80 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
}
}
+template <class Dictionary>
+void CodeStubAssembler::FindInsertionEntry(Node* dictionary, Node* key,
+ Variable* var_key_index) {
+ UNREACHABLE();
+}
+
+template <>
+void CodeStubAssembler::FindInsertionEntry<NameDictionary>(
+ Node* dictionary, Node* key, Variable* var_key_index) {
+ Label done(this);
+ NameDictionaryLookup<NameDictionary>(dictionary, key, nullptr, var_key_index,
+ &done, 0, kFindInsertionIndex);
+ Bind(&done);
+}
+
+template <class Dictionary>
+void CodeStubAssembler::Add(Node* dictionary, Node* key, Node* value,
Igor Sheludko 2016/11/22 12:05:07 This implementation is not fully applicable for Gl
Jakob Kummerow 2016/11/22 13:47:57 Done. (Pulled out the second half as "InsertEntry<
+ Label* bailout) {
+ Node* capacity = GetCapacity<Dictionary>(dictionary);
+ Node* nof = GetNumberOfElements<Dictionary>(dictionary);
+ Node* new_nof = SmiAdd(nof, SmiConstant(1));
+ // Require 33% to still be free after adding additional_elements.
+ // This is a simplification of the C++ implementation's behavior, which
+ // also rehashes the dictionary when there are too many deleted elements.
+ // Computing "x + (x >> 1)" on a Smi x does not return a valid Smi!
+ // But that's OK here because it's only used for a comparison.
+ Node* required_capacity_pseudo_smi = SmiAdd(new_nof, WordShr(new_nof, 1));
+ GotoIf(UintPtrLessThan(capacity, required_capacity_pseudo_smi), bailout);
+ Node* enum_index = nullptr;
+ if (Dictionary::kIsEnumerable) {
+ enum_index = GetNextEnumerationIndex<Dictionary>(dictionary);
+ Node* new_enum_index = SmiAdd(enum_index, SmiConstant(1));
+ Node* max_enum_index = SmiConstant(
+ Smi::FromInt(PropertyDetails::DictionaryStorageField::kMax));
Igor Sheludko 2016/11/22 12:05:07 Can you drop Smi::FromInt?
Jakob Kummerow 2016/11/22 13:47:57 Done.
+ GotoIf(UintPtrGreaterThan(new_enum_index, max_enum_index), bailout);
+
+ // No more bailouts after this point.
+ // Operations from here on can have side effects.
+
+ SetNextEnumerationIndex<Dictionary>(dictionary, new_enum_index);
+ } else {
+ USE(enum_index);
+ }
+ SetNumberOfElements<Dictionary>(dictionary, new_nof);
+
+ Variable var_key_index(this, MachineType::PointerRepresentation());
+ FindInsertionEntry<Dictionary>(dictionary, key, &var_key_index);
+ Node* index = var_key_index.value();
+ StoreFixedArrayElement(dictionary, index, key, 0, UPDATE_WRITE_BARRIER,
+ INTPTR_PARAMETERS);
+ const int kNameToValueOffset =
+ (Dictionary::kEntryValueIndex - Dictionary::kEntryKeyIndex) *
+ kPointerSize;
+ StoreFixedArrayElement(dictionary, index, value, kNameToValueOffset,
+ UPDATE_WRITE_BARRIER, INTPTR_PARAMETERS);
+ if (Dictionary::kIsEnumerable) {
Igor Sheludko 2016/11/22 12:05:07 Shoudn't we also set details if the dictionary is
Jakob Kummerow 2016/11/22 13:47:57 Oops, good point. Done.
+ const int kInitialIndex = 0;
+ PropertyDetails d(NONE, DATA, kInitialIndex, PropertyCellType::kNoCell);
+ Node* details = SmiConstant(d.AsSmi());
+ enum_index =
+ WordShl(enum_index, PropertyDetails::DictionaryStorageField::kShift);
+ STATIC_ASSERT(kInitialIndex == 0);
+ details = WordOr(details, enum_index);
+ const int kNameToDetailsOffset =
+ (Dictionary::kEntryDetailsIndex - Dictionary::kEntryKeyIndex) *
+ kPointerSize;
+ StoreFixedArrayElement(dictionary, index, details, kNameToDetailsOffset,
+ SKIP_WRITE_BARRIER, INTPTR_PARAMETERS);
+ }
+}
+
+template void CodeStubAssembler::Add<NameDictionary>(Node*, Node*, Node*,
+ Label*);
+
void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name,
Node* descriptors, Node* nof,
Label* if_found,
@@ -4982,7 +5104,7 @@ void CodeStubAssembler::UpdateFeedback(compiler::Node* feedback,
Node* previous_feedback =
LoadFixedArrayElement(type_feedback_vector, slot_id);
Node* combined_feedback = SmiOr(previous_feedback, SmiFromWord32(feedback));
- StoreFixedArrayElement(type_feedback_vector, slot_id, combined_feedback,
+ StoreFixedArrayElement(type_feedback_vector, slot_id, combined_feedback, 0,
SKIP_WRITE_BARRIER);
}
@@ -5193,7 +5315,7 @@ Node* CodeStubAssembler::EmitKeyedSloppyArguments(Node* receiver, Node* key,
CSA_ASSERT(this, WordNotEqual(result, TheHoleConstant()));
var_result.Bind(result);
} else {
- StoreFixedArrayElement(the_context, mapped_index, value,
+ StoreFixedArrayElement(the_context, mapped_index, value, 0,
UPDATE_WRITE_BARRIER, INTPTR_PARAMETERS);
}
Goto(&end);
@@ -5217,7 +5339,7 @@ Node* CodeStubAssembler::EmitKeyedSloppyArguments(Node* receiver, Node* key,
GotoIf(WordEqual(result, TheHoleConstant()), bailout);
var_result.Bind(result);
} else {
- StoreFixedArrayElement(backing_store, key, value, UPDATE_WRITE_BARRIER,
+ StoreFixedArrayElement(backing_store, key, value, 0, UPDATE_WRITE_BARRIER,
INTPTR_PARAMETERS);
}
Goto(&end);
@@ -5300,7 +5422,7 @@ void CodeStubAssembler::StoreElement(Node* elements, ElementsKind kind,
value = Float64SilenceNaN(value);
StoreFixedDoubleArrayElement(elements, index, value, mode);
} else {
- StoreFixedArrayElement(elements, index, value, barrier_mode, mode);
+ StoreFixedArrayElement(elements, index, value, 0, barrier_mode, mode);
}
}
@@ -5692,7 +5814,7 @@ Node* CodeStubAssembler::CreateAllocationSiteInFeedbackVector(
StoreObjectField(site, AllocationSite::kWeakNextOffset, next_site);
StoreNoWriteBarrier(MachineRepresentation::kTagged, site_list, site);
- StoreFixedArrayElement(feedback_vector, slot, site, UPDATE_WRITE_BARRIER,
+ StoreFixedArrayElement(feedback_vector, slot, site, 0, UPDATE_WRITE_BARRIER,
CodeStubAssembler::SMI_PARAMETERS);
return site;
}
@@ -5710,7 +5832,7 @@ Node* CodeStubAssembler::CreateWeakCellInFeedbackVector(Node* feedback_vector,
Heap::kTheHoleValueRootIndex);
// Store the WeakCell in the feedback vector.
- StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER,
+ StoreFixedArrayElement(feedback_vector, slot, cell, 0, UPDATE_WRITE_BARRIER,
CodeStubAssembler::SMI_PARAMETERS);
return cell;
}

Powered by Google App Engine
This is Rietveld 408576698