Commit 2b99d09e authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[elements] Support dictionary-mode in initialize_elements and remove ResetElements

Bug: 
Change-Id: I240356157c71a544d94f8898029d54010b2f4d37
Reviewed-on: https://chromium-review.googlesource.com/544309
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46173}
parent 88222199
...@@ -1361,43 +1361,44 @@ class DictionaryElementsAccessor ...@@ -1361,43 +1361,44 @@ class DictionaryElementsAccessor
int capacity = dict->Capacity(); int capacity = dict->Capacity();
uint32_t old_length = 0; uint32_t old_length = 0;
CHECK(array->length()->ToArrayLength(&old_length)); CHECK(array->length()->ToArrayLength(&old_length));
if (length < old_length) { {
if (dict->requires_slow_elements()) { DisallowHeapAllocation no_gc;
// Find last non-deletable element in range of elements to be if (length < old_length) {
// deleted and adjust range accordingly. if (dict->requires_slow_elements()) {
for (int entry = 0; entry < capacity; entry++) { // Find last non-deletable element in range of elements to be
DisallowHeapAllocation no_gc; // deleted and adjust range accordingly.
Object* index = dict->KeyAt(entry); for (int entry = 0; entry < capacity; entry++) {
if (index->IsNumber()) { Object* index = dict->KeyAt(entry);
uint32_t number = static_cast<uint32_t>(index->Number()); if (dict->IsKey(isolate, index)) {
if (length <= number && number < old_length) { uint32_t number = static_cast<uint32_t>(index->Number());
PropertyDetails details = dict->DetailsAt(entry); if (length <= number && number < old_length) {
if (!details.IsConfigurable()) length = number + 1; PropertyDetails details = dict->DetailsAt(entry);
if (!details.IsConfigurable()) length = number + 1;
}
} }
} }
} }
}
if (length == 0) { if (length == 0) {
// Flush the backing store. // Flush the backing store.
JSObject::ResetElements(array); array->initialize_elements();
} else { } else {
DisallowHeapAllocation no_gc; // Remove elements that should be deleted.
// Remove elements that should be deleted. int removed_entries = 0;
int removed_entries = 0; for (int entry = 0; entry < capacity; entry++) {
for (int entry = 0; entry < capacity; entry++) { Object* index = dict->KeyAt(entry);
Object* index = dict->KeyAt(entry); if (dict->IsKey(isolate, index)) {
if (index->IsNumber()) { uint32_t number = static_cast<uint32_t>(index->Number());
uint32_t number = static_cast<uint32_t>(index->Number()); if (length <= number && number < old_length) {
if (length <= number && number < old_length) { dict->ClearEntry(entry);
dict->ClearEntry(entry); removed_entries++;
removed_entries++; }
} }
} }
}
// Update the number of elements. // Update the number of elements.
dict->ElementsRemoved(removed_entries); dict->ElementsRemoved(removed_entries);
}
} }
} }
...@@ -1714,15 +1715,18 @@ class DictionaryElementsAccessor ...@@ -1714,15 +1715,18 @@ class DictionaryElementsAccessor
if (*dictionary == receiver->elements()) continue; if (*dictionary == receiver->elements()) continue;
// Otherwise, bailout or update elements // Otherwise, bailout or update elements
// If switched to initial elements, return true if searching for
// undefined, and false otherwise.
if (receiver->map()->GetInitialElements() == receiver->elements()) {
return Just(search_for_hole);
}
// If switched to fast elements, continue with the correct accessor.
if (receiver->GetElementsKind() != DICTIONARY_ELEMENTS) { if (receiver->GetElementsKind() != DICTIONARY_ELEMENTS) {
if (receiver->map()->GetInitialElements() == receiver->elements()) { ElementsAccessor* accessor = receiver->GetElementsAccessor();
// If switched to initial elements, return true if searching for return accessor->IncludesValue(isolate, receiver, value, k + 1,
// undefined, and false otherwise. length);
return Just(search_for_hole);
}
// Otherwise, switch to slow path.
return IncludesValueSlowPath(isolate, receiver, value, k + 1,
length);
} }
dictionary = handle( dictionary = handle(
SeededNumberDictionary::cast(receiver->elements()), isolate); SeededNumberDictionary::cast(receiver->elements()), isolate);
......
...@@ -2402,6 +2402,8 @@ FixedArrayBase* Map::GetInitialElements() { ...@@ -2402,6 +2402,8 @@ FixedArrayBase* Map::GetInitialElements() {
result = GetHeap()->empty_sloppy_arguments_elements(); result = GetHeap()->empty_sloppy_arguments_elements();
} else if (has_fixed_typed_array_elements()) { } else if (has_fixed_typed_array_elements()) {
result = GetHeap()->EmptyFixedTypedArrayForMap(this); result = GetHeap()->EmptyFixedTypedArrayForMap(this);
} else if (has_dictionary_elements()) {
result = GetHeap()->empty_slow_element_dictionary();
} else { } else {
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -5835,20 +5835,6 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object, ...@@ -5835,20 +5835,6 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
DCHECK(object->HasFastProperties()); DCHECK(object->HasFastProperties());
} }
void JSObject::ResetElements(Handle<JSObject> object) {
Isolate* isolate = object->GetIsolate();
CHECK(object->map() != isolate->heap()->sloppy_arguments_elements_map());
if (object->map()->has_dictionary_elements()) {
Handle<SeededNumberDictionary> new_elements =
SeededNumberDictionary::New(isolate, 0);
object->set_elements(*new_elements);
} else {
object->set_elements(object->map()->GetInitialElements());
}
}
void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) { void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) {
if (dictionary->requires_slow_elements()) return; if (dictionary->requires_slow_elements()) return;
dictionary->set_requires_slow_elements(); dictionary->set_requires_slow_elements();
......
...@@ -2149,7 +2149,6 @@ class JSObject: public JSReceiver { ...@@ -2149,7 +2149,6 @@ class JSObject: public JSReceiver {
// FixedArray parameter map for a (sloppy) arguments object. // FixedArray parameter map for a (sloppy) arguments object.
DECL_ACCESSORS(elements, FixedArrayBase) DECL_ACCESSORS(elements, FixedArrayBase)
inline void initialize_elements(); inline void initialize_elements();
static void ResetElements(Handle<JSObject> object);
static inline void SetMapAndElements(Handle<JSObject> object, static inline void SetMapAndElements(Handle<JSObject> object,
Handle<Map> map, Handle<Map> map,
Handle<FixedArrayBase> elements); Handle<FixedArrayBase> elements);
......
...@@ -132,7 +132,7 @@ RUNTIME_FUNCTION(Runtime_MoveArrayContents) { ...@@ -132,7 +132,7 @@ RUNTIME_FUNCTION(Runtime_MoveArrayContents) {
JSObject::SetMapAndElements(to, new_map, new_elements); JSObject::SetMapAndElements(to, new_map, new_elements);
to->set_length(from->length()); to->set_length(from->length());
JSObject::ResetElements(from); from->initialize_elements();
from->set_length(Smi::kZero); from->set_length(Smi::kZero);
JSObject::ValidateElements(to); JSObject::ValidateElements(to);
......
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