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

Unified Diff: src/elements.cc

Issue 2014523002: Reland of [keys] Simplify KeyAccumulator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fixing wrong handle dereferencing Created 4 years, 7 months 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
« no previous file with comments | « src/debug/debug-scopes.cc ('k') | src/json-stringifier.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/elements.cc
diff --git a/src/elements.cc b/src/elements.cc
index 6c257ac63f3424b4dd531d1c936e0ff12e38bebd..398466509ce490b2f35cbe9f9740cc3301a6d168 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -445,6 +445,26 @@ static void TraceTopFrame(Isolate* isolate) {
JavaScriptFrame::PrintTop(isolate, stdout, false, true);
}
+static void SortIndices(
+ Handle<FixedArray> indices, uint32_t sort_size,
+ WriteBarrierMode write_barrier_mode = UPDATE_WRITE_BARRIER) {
+ struct {
+ bool operator()(Object* a, Object* b) {
+ if (!a->IsUndefined()) {
+ if (b->IsUndefined()) return true;
+ return a->Number() < b->Number();
+ }
+ return b->IsUndefined();
+ }
+ } cmp;
+ Object** start =
+ reinterpret_cast<Object**>(indices->GetFirstElementAddress());
+ std::sort(start, start + sort_size, cmp);
+ if (write_barrier_mode != SKIP_WRITE_BARRIER) {
+ FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(indices->GetIsolate()->heap(), *indices,
+ 0, sort_size);
+ }
+}
// Base class for element handler implementations. Contains the
// the common logic for objects with different ElementsKinds.
@@ -709,8 +729,7 @@ class ElementsAccessorBase : public ElementsAccessor {
JSObject::ValidateElements(array);
}
- static uint32_t GetIterationLength(JSObject* receiver,
- FixedArrayBase* elements) {
+ static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) {
if (receiver->IsJSArray()) {
DCHECK(JSArray::cast(receiver)->length()->IsSmi());
return static_cast<uint32_t>(
@@ -719,6 +738,11 @@ class ElementsAccessorBase : public ElementsAccessor {
return Subclass::GetCapacityImpl(receiver, elements);
}
+ static uint32_t GetMaxNumberOfEntries(JSObject* receiver,
+ FixedArrayBase* elements) {
+ return Subclass::GetMaxIndex(receiver, elements);
+ }
+
static Handle<FixedArrayBase> ConvertElementsWithCapacity(
Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
ElementsKind from_kind, uint32_t capacity) {
@@ -863,7 +887,6 @@ class ElementsAccessorBase : public ElementsAccessor {
PropertyFilter filter) {
int count = 0;
KeyAccumulator accumulator(isolate, OWN_ONLY, ALL_PROPERTIES);
- accumulator.NextPrototype();
Subclass::CollectElementIndicesImpl(
object, handle(object->elements(), isolate), &accumulator);
Handle<FixedArray> keys = accumulator.GetKeys();
@@ -909,11 +932,12 @@ class ElementsAccessorBase : public ElementsAccessor {
KeyAccumulator* keys) {
DCHECK_NE(DICTIONARY_ELEMENTS, kind());
// Non-dictionary elements can't have all-can-read accessors.
- uint32_t length = GetIterationLength(*object, *backing_store);
+ uint32_t length = Subclass::GetMaxIndex(*object, *backing_store);
PropertyFilter filter = keys->filter();
+ Factory* factory = keys->isolate()->factory();
for (uint32_t i = 0; i < length; i++) {
if (Subclass::HasElementImpl(object, i, backing_store, filter)) {
- keys->AddKey(i);
+ keys->AddKey(factory->NewNumberFromUint(i));
}
}
}
@@ -923,7 +947,7 @@ class ElementsAccessorBase : public ElementsAccessor {
Handle<FixedArrayBase> backing_store, GetKeysConversion convert,
PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices,
uint32_t insertion_index = 0) {
- uint32_t length = Subclass::GetIterationLength(*object, *backing_store);
+ uint32_t length = Subclass::GetMaxIndex(*object, *backing_store);
for (uint32_t i = 0; i < length; i++) {
if (Subclass::HasElementImpl(object, i, backing_store, filter)) {
if (convert == CONVERT_TO_STRING) {
@@ -968,18 +992,7 @@ class ElementsAccessorBase : public ElementsAccessor {
// Sort the indices list if necessary.
if (IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind())) {
- struct {
- bool operator()(Object* a, Object* b) {
- if (!a->IsUndefined()) {
- if (b->IsUndefined()) return true;
- return a->Number() < b->Number();
- }
- return !b->IsUndefined();
- }
- } cmp;
- Object** start =
- reinterpret_cast<Object**>(combined_keys->GetFirstElementAddress());
- std::sort(start, start + nof_indices, cmp);
+ SortIndices(combined_keys, nof_indices, SKIP_WRITE_BARRIER);
uint32_t array_length = 0;
// Indices from dictionary elements should only be converted after
// sorting.
@@ -1044,7 +1057,7 @@ class ElementsAccessorBase : public ElementsAccessor {
? index
: kMaxUInt32;
} else {
- uint32_t length = GetIterationLength(holder, backing_store);
+ uint32_t length = Subclass::GetMaxIndex(holder, backing_store);
return index < length ? index : kMaxUInt32;
}
}
@@ -1081,17 +1094,15 @@ class DictionaryElementsAccessor
: ElementsAccessorBase<DictionaryElementsAccessor,
ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
- static uint32_t GetIterationLength(JSObject* receiver,
- FixedArrayBase* elements) {
- uint32_t length;
- if (receiver->IsJSArray()) {
- // Special-case GetIterationLength for dictionary elements since the
- // length of the array might be a HeapNumber.
- JSArray::cast(receiver)->length()->ToArrayLength(&length);
- } else {
- length = GetCapacityImpl(receiver, elements);
- }
- return length;
+ static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) {
+ // We cannot properly estimate this for dictionaries.
+ UNREACHABLE();
+ }
+
+ static uint32_t GetMaxNumberOfEntries(JSObject* receiver,
+ FixedArrayBase* backing_store) {
+ SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store);
+ return dict->NumberOfElements();
}
static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array,
@@ -1313,21 +1324,28 @@ class DictionaryElementsAccessor
Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) {
if (keys->filter() & SKIP_STRINGS) return;
- Isolate* isolate = keys->isolate();
- Handle<Object> undefined = isolate->factory()->undefined_value();
- Handle<Object> the_hole = isolate->factory()->the_hole_value();
+ Factory* factory = keys->isolate()->factory();
+ Handle<Object> undefined = factory->undefined_value();
+ Handle<Object> the_hole = factory->the_hole_value();
Handle<SeededNumberDictionary> dictionary =
Handle<SeededNumberDictionary>::cast(backing_store);
int capacity = dictionary->Capacity();
+ Handle<FixedArray> elements =
+ factory->NewFixedArray(GetMaxNumberOfEntries(*object, *backing_store));
+ int insertion_index = 0;
PropertyFilter filter = keys->filter();
for (int i = 0; i < capacity; i++) {
uint32_t key =
GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole);
if (key == kMaxUInt32) continue;
- keys->AddKey(key);
+ Handle<Object> key_handle = factory->NewNumberFromUint(key);
+ elements->set(insertion_index, *key_handle);
+ insertion_index++;
+ }
+ SortIndices(elements, insertion_index);
+ for (int i = 0; i < insertion_index; i++) {
+ keys->AddKey(elements->get(i));
}
-
- keys->SortCurrentElementsList();
}
static Handle<FixedArray> DirectCollectElementIndicesImpl(
@@ -1552,8 +1570,8 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
KeyAccumulator* accumulator,
AddKeyConversion convert) {
Handle<FixedArrayBase> elements(receiver->elements(),
- receiver->GetIsolate());
- uint32_t length = Subclass::GetIterationLength(*receiver, *elements);
+ accumulator->isolate());
+ uint32_t length = Subclass::GetMaxNumberOfEntries(*receiver, *elements);
for (uint32_t i = 0; i < length; i++) {
if (IsFastPackedElementsKind(KindTraits::Kind) ||
HasEntryImpl(*elements, i)) {
@@ -2386,18 +2404,16 @@ class SloppyArgumentsElementsAccessor
static void CollectElementIndicesImpl(Handle<JSObject> object,
Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) {
- FixedArray* parameter_map = FixedArray::cast(*backing_store);
- uint32_t length = parameter_map->length() - 2;
- for (uint32_t i = 0; i < length; ++i) {
- if (!parameter_map->get(i + 2)->IsTheHole()) {
- keys->AddKey(i);
- }
- }
-
- Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1)));
- ArgumentsAccessor::CollectElementIndicesImpl(object, store, keys);
- if (Subclass::kind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS) {
- keys->SortCurrentElementsList();
+ Isolate* isolate = keys->isolate();
+ uint32_t nof_indices = 0;
+ Handle<FixedArray> indices = isolate->factory()->NewFixedArray(
+ GetCapacityImpl(*object, *backing_store));
+ DirectCollectElementIndicesImpl(isolate, object, backing_store,
+ KEEP_NUMBERS, ENUMERABLE_STRINGS, indices,
+ &nof_indices);
+ SortIndices(indices, nof_indices);
+ for (uint32_t i = 0; i < nof_indices; i++) {
+ keys->AddKey(indices->get(i));
}
}
@@ -2745,8 +2761,9 @@ class StringWrapperElementsAccessor
Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) {
uint32_t length = GetString(*object)->length();
+ Factory* factory = keys->isolate()->factory();
for (uint32_t i = 0; i < length; i++) {
- keys->AddKey(i);
+ keys->AddKey(factory->NewNumberFromUint(i));
}
BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store,
keys);
« no previous file with comments | « src/debug/debug-scopes.cc ('k') | src/json-stringifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698