Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index 3a1a625b1b20334fde3f0e3c606c3053e4060273..7109342902bd6d6bbbd64dc1cb98ba1988023769 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -428,6 +428,7 @@ |
} |
} |
+ |
static void TraceTopFrame(Isolate* isolate) { |
StackFrameIterator it(isolate); |
if (it.done()) { |
@@ -729,16 +730,6 @@ |
JSObject::ValidateElements(array); |
} |
- static uint32_t GetIterationLength(JSObject* receiver, |
- FixedArrayBase* elements) { |
- if (receiver->IsJSArray()) { |
- return static_cast<uint32_t>( |
- Smi::cast(JSArray::cast(receiver)->length())->value()); |
- } else { |
- return ElementsAccessorSubclass::GetCapacityImpl(receiver, elements); |
- } |
- } |
- |
static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
ElementsKind from_kind, uint32_t capacity) { |
@@ -855,14 +846,6 @@ |
from, from_start, *to, from_kind, to_start, packed_size, copy_size); |
} |
- void CollectElementIndices(Handle<JSObject> object, |
- Handle<FixedArrayBase> backing_store, |
- KeyAccumulator* keys, uint32_t range, |
- PropertyFilter filter, uint32_t offset) final { |
- ElementsAccessorSubclass::CollectElementIndicesImpl( |
- object, backing_store, keys, range, filter, offset); |
- } |
- |
static void CollectElementIndicesImpl(Handle<JSObject> object, |
Handle<FixedArrayBase> backing_store, |
KeyAccumulator* keys, uint32_t range, |
@@ -873,102 +856,30 @@ |
// Non-dictionary elements can't have all-can-read accessors. |
return; |
} |
- uint32_t length = GetIterationLength(*object, *backing_store); |
+ uint32_t length = 0; |
+ if (object->IsJSArray()) { |
+ length = Smi::cast(JSArray::cast(*object)->length())->value(); |
+ } else { |
+ length = |
+ ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store); |
+ } |
if (range < length) length = range; |
for (uint32_t i = offset; i < length; i++) { |
- if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, |
- filter)) { |
- keys->AddKey(i); |
- } |
- } |
- } |
- |
- static Handle<FixedArray> DirectCollectElementIndicesImpl( |
- Isolate* isolate, Handle<JSObject> object, |
- Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
- PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices) { |
- uint32_t length = |
- ElementsAccessorSubclass::GetIterationLength(*object, *backing_store); |
- uint32_t insertion_index = 0; |
- for (uint32_t i = 0; i < length; i++) { |
- if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, |
- filter)) { |
- if (convert == CONVERT_TO_STRING) { |
- list->set(insertion_index, *isolate->factory()->Uint32ToString(i)); |
- } else { |
- list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); |
- } |
- insertion_index++; |
- } |
- } |
- *nof_indices = insertion_index; |
- return list; |
- } |
- |
- Handle<FixedArray> PrependElementIndices(Handle<JSObject> object, |
- Handle<FixedArrayBase> backing_store, |
- Handle<FixedArray> keys, |
- GetKeysConversion convert, |
- PropertyFilter filter) final { |
- return ElementsAccessorSubclass::PrependElementIndicesImpl( |
- object, backing_store, keys, convert, filter); |
- } |
- |
- static Handle<FixedArray> PrependElementIndicesImpl( |
- Handle<JSObject> object, Handle<FixedArrayBase> backing_store, |
- Handle<FixedArray> keys, GetKeysConversion convert, |
- PropertyFilter filter) { |
- Isolate* isolate = object->GetIsolate(); |
- uint32_t nof_property_keys = keys->length(); |
- uint32_t initial_list_length = |
- ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store); |
- initial_list_length += nof_property_keys; |
- |
- // Collect the element indices into a new list. |
- uint32_t nof_indices = 0; |
- Handle<FixedArray> combined_keys = |
- isolate->factory()->NewFixedArray(initial_list_length); |
- combined_keys = ElementsAccessorSubclass::DirectCollectElementIndicesImpl( |
- isolate, object, backing_store, convert, filter, combined_keys, |
- &nof_indices); |
- |
- // Sort the indices list if necessary. |
- if (IsDictionaryElementsKind(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); |
- // Indices from dictionary elements should only be converted after |
- // sorting. |
- if (convert == CONVERT_TO_STRING) { |
- for (uint32_t i = 0; i < nof_indices; i++) { |
- combined_keys->set(i, *isolate->factory()->Uint32ToString( |
- combined_keys->get(i)->Number())); |
- } |
- } |
- } |
- |
- // Copy over the passed-in property keys. |
- CopyObjectToObjectElements(*keys, FAST_ELEMENTS, 0, *combined_keys, |
- FAST_ELEMENTS, nof_indices, nof_property_keys); |
- |
- if (IsHoleyElementsKind(kind())) { |
- // Shrink combined_keys to the final size. |
- int final_size = nof_indices + nof_property_keys; |
- DCHECK_LE(final_size, combined_keys->length()); |
- combined_keys->Shrink(final_size); |
- } |
- |
- return combined_keys; |
- } |
+ if (!ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, |
+ filter)) { |
+ continue; |
+ } |
+ keys->AddKey(i); |
+ } |
+ } |
+ |
+ void CollectElementIndices(Handle<JSObject> object, |
+ Handle<FixedArrayBase> backing_store, |
+ KeyAccumulator* keys, uint32_t range, |
+ PropertyFilter filter, uint32_t offset) final { |
+ ElementsAccessorSubclass::CollectElementIndicesImpl( |
+ object, backing_store, keys, range, filter, offset); |
+ }; |
void AddElementsToKeyAccumulator(Handle<JSObject> receiver, |
KeyAccumulator* accumulator, |
@@ -1001,7 +912,12 @@ |
? index |
: kMaxUInt32; |
} else { |
- uint32_t length = GetIterationLength(holder, backing_store); |
+ uint32_t length = |
+ holder->IsJSArray() |
+ ? static_cast<uint32_t>( |
+ Smi::cast(JSArray::cast(holder)->length())->value()) |
+ : ElementsAccessorSubclass::GetCapacityImpl(holder, |
+ backing_store); |
return index < length ? index : kMaxUInt32; |
} |
} |
@@ -1203,28 +1119,6 @@ |
return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); |
} |
- static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary, |
- int entry, PropertyFilter filter) { |
- DisallowHeapAllocation no_gc; |
- Object* raw_key = dictionary->KeyAt(entry); |
- if (!dictionary->IsKey(raw_key)) return kMaxUInt32; |
- if (raw_key->FilterKey(filter)) return kMaxUInt32; |
- if (dictionary->IsDeleted(entry)) return kMaxUInt32; |
- DCHECK(raw_key->IsNumber()); |
- DCHECK_LE(raw_key->Number(), kMaxUInt32); |
- uint32_t key = static_cast<uint32_t>(raw_key->Number()); |
- PropertyDetails details = dictionary->DetailsAt(entry); |
- if (filter & ONLY_ALL_CAN_READ) { |
- if (details.kind() != kAccessor) return kMaxUInt32; |
- Object* accessors = dictionary->ValueAt(entry); |
- if (!accessors->IsAccessorInfo()) return kMaxUInt32; |
- if (!AccessorInfo::cast(accessors)->all_can_read()) return kMaxUInt32; |
- } |
- PropertyAttributes attr = details.attributes(); |
- if ((attr & filter) != 0) return kMaxUInt32; |
- return key; |
- } |
- |
static void CollectElementIndicesImpl(Handle<JSObject> object, |
Handle<FixedArrayBase> backing_store, |
KeyAccumulator* keys, uint32_t range, |
@@ -1234,30 +1128,27 @@ |
Handle<SeededNumberDictionary>::cast(backing_store); |
int capacity = dictionary->Capacity(); |
for (int i = 0; i < capacity; i++) { |
- uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); |
- if (key == kMaxUInt32) continue; |
- keys->AddKey(key); |
+ Object* k = dictionary->KeyAt(i); |
+ if (!dictionary->IsKey(k)) continue; |
+ if (k->FilterKey(filter)) continue; |
+ if (dictionary->IsDeleted(i)) continue; |
+ DCHECK(k->IsNumber()); |
+ DCHECK_LE(k->Number(), kMaxUInt32); |
+ uint32_t index = static_cast<uint32_t>(k->Number()); |
+ if (index < offset) continue; |
+ PropertyDetails details = dictionary->DetailsAt(i); |
+ if (filter & ONLY_ALL_CAN_READ) { |
+ if (details.kind() != kAccessor) continue; |
+ Object* accessors = dictionary->ValueAt(i); |
+ if (!accessors->IsAccessorInfo()) continue; |
+ if (!AccessorInfo::cast(accessors)->all_can_read()) continue; |
+ } |
+ PropertyAttributes attr = details.attributes(); |
+ if ((attr & filter) != 0) continue; |
+ keys->AddKey(index); |
} |
keys->SortCurrentElementsList(); |
- } |
- |
- static Handle<FixedArray> DirectCollectElementIndicesImpl( |
- Isolate* isolate, Handle<JSObject> object, |
- Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
- PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices) { |
- Handle<SeededNumberDictionary> dictionary = |
- Handle<SeededNumberDictionary>::cast(backing_store); |
- uint32_t capacity = dictionary->Capacity(); |
- uint32_t insertion_index = 0; |
- for (uint32_t i = 0; i < capacity; i++) { |
- uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); |
- if (key == kMaxUInt32) continue; |
- list->set(insertion_index, *isolate->factory()->NewNumberFromUint(key)); |
- insertion_index++; |
- } |
- *nof_indices = insertion_index; |
- return list; |
} |
static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
@@ -1424,10 +1315,15 @@ |
static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
KeyAccumulator* accumulator, |
AddKeyConversion convert) { |
+ uint32_t length = 0; |
Handle<FixedArrayBase> elements(receiver->elements(), |
receiver->GetIsolate()); |
- uint32_t length = |
- FastElementsAccessorSubclass::GetIterationLength(*receiver, *elements); |
+ if (receiver->IsJSArray()) { |
+ length = Smi::cast(JSArray::cast(*receiver)->length())->value(); |
+ } else { |
+ length = |
+ FastElementsAccessorSubclass::GetCapacityImpl(*receiver, *elements); |
+ } |
for (uint32_t i = 0; i < length; i++) { |
if (IsFastPackedElementsKind(KindTraits::Kind) || |
HasEntryImpl(*elements, i)) { |