[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: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#46173}
This commit is contained in:
parent
8822219978
commit
2b99d09e62
@ -1361,43 +1361,44 @@ class DictionaryElementsAccessor
|
||||
int capacity = dict->Capacity();
|
||||
uint32_t old_length = 0;
|
||||
CHECK(array->length()->ToArrayLength(&old_length));
|
||||
if (length < old_length) {
|
||||
if (dict->requires_slow_elements()) {
|
||||
// Find last non-deletable element in range of elements to be
|
||||
// deleted and adjust range accordingly.
|
||||
for (int entry = 0; entry < capacity; entry++) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
Object* index = dict->KeyAt(entry);
|
||||
if (index->IsNumber()) {
|
||||
uint32_t number = static_cast<uint32_t>(index->Number());
|
||||
if (length <= number && number < old_length) {
|
||||
PropertyDetails details = dict->DetailsAt(entry);
|
||||
if (!details.IsConfigurable()) length = number + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (length == 0) {
|
||||
// Flush the backing store.
|
||||
JSObject::ResetElements(array);
|
||||
} else {
|
||||
DisallowHeapAllocation no_gc;
|
||||
// Remove elements that should be deleted.
|
||||
int removed_entries = 0;
|
||||
for (int entry = 0; entry < capacity; entry++) {
|
||||
Object* index = dict->KeyAt(entry);
|
||||
if (index->IsNumber()) {
|
||||
uint32_t number = static_cast<uint32_t>(index->Number());
|
||||
if (length <= number && number < old_length) {
|
||||
dict->ClearEntry(entry);
|
||||
removed_entries++;
|
||||
{
|
||||
DisallowHeapAllocation no_gc;
|
||||
if (length < old_length) {
|
||||
if (dict->requires_slow_elements()) {
|
||||
// Find last non-deletable element in range of elements to be
|
||||
// deleted and adjust range accordingly.
|
||||
for (int entry = 0; entry < capacity; entry++) {
|
||||
Object* index = dict->KeyAt(entry);
|
||||
if (dict->IsKey(isolate, index)) {
|
||||
uint32_t number = static_cast<uint32_t>(index->Number());
|
||||
if (length <= number && number < old_length) {
|
||||
PropertyDetails details = dict->DetailsAt(entry);
|
||||
if (!details.IsConfigurable()) length = number + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the number of elements.
|
||||
dict->ElementsRemoved(removed_entries);
|
||||
if (length == 0) {
|
||||
// Flush the backing store.
|
||||
array->initialize_elements();
|
||||
} else {
|
||||
// Remove elements that should be deleted.
|
||||
int removed_entries = 0;
|
||||
for (int entry = 0; entry < capacity; entry++) {
|
||||
Object* index = dict->KeyAt(entry);
|
||||
if (dict->IsKey(isolate, index)) {
|
||||
uint32_t number = static_cast<uint32_t>(index->Number());
|
||||
if (length <= number && number < old_length) {
|
||||
dict->ClearEntry(entry);
|
||||
removed_entries++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the number of elements.
|
||||
dict->ElementsRemoved(removed_entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1714,15 +1715,18 @@ class DictionaryElementsAccessor
|
||||
if (*dictionary == receiver->elements()) continue;
|
||||
|
||||
// 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->map()->GetInitialElements() == receiver->elements()) {
|
||||
// If switched to initial elements, return true if searching for
|
||||
// undefined, and false otherwise.
|
||||
return Just(search_for_hole);
|
||||
}
|
||||
// Otherwise, switch to slow path.
|
||||
return IncludesValueSlowPath(isolate, receiver, value, k + 1,
|
||||
length);
|
||||
ElementsAccessor* accessor = receiver->GetElementsAccessor();
|
||||
return accessor->IncludesValue(isolate, receiver, value, k + 1,
|
||||
length);
|
||||
}
|
||||
dictionary = handle(
|
||||
SeededNumberDictionary::cast(receiver->elements()), isolate);
|
||||
|
@ -2402,6 +2402,8 @@ FixedArrayBase* Map::GetInitialElements() {
|
||||
result = GetHeap()->empty_sloppy_arguments_elements();
|
||||
} else if (has_fixed_typed_array_elements()) {
|
||||
result = GetHeap()->EmptyFixedTypedArrayForMap(this);
|
||||
} else if (has_dictionary_elements()) {
|
||||
result = GetHeap()->empty_slow_element_dictionary();
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -5835,20 +5835,6 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
|
||||
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) {
|
||||
if (dictionary->requires_slow_elements()) return;
|
||||
dictionary->set_requires_slow_elements();
|
||||
|
@ -2149,7 +2149,6 @@ class JSObject: public JSReceiver {
|
||||
// FixedArray parameter map for a (sloppy) arguments object.
|
||||
DECL_ACCESSORS(elements, FixedArrayBase)
|
||||
inline void initialize_elements();
|
||||
static void ResetElements(Handle<JSObject> object);
|
||||
static inline void SetMapAndElements(Handle<JSObject> object,
|
||||
Handle<Map> map,
|
||||
Handle<FixedArrayBase> elements);
|
||||
|
@ -132,7 +132,7 @@ RUNTIME_FUNCTION(Runtime_MoveArrayContents) {
|
||||
JSObject::SetMapAndElements(to, new_map, new_elements);
|
||||
to->set_length(from->length());
|
||||
|
||||
JSObject::ResetElements(from);
|
||||
from->initialize_elements();
|
||||
from->set_length(Smi::kZero);
|
||||
|
||||
JSObject::ValidateElements(to);
|
||||
|
Loading…
Reference in New Issue
Block a user