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

Side by Side Diff: src/objects.cc

Issue 1608523002: [runtime] Do not use the enum-cache for non-prototype objects. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: pass filter along Created 4 years, 11 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 8081 matching lines...) Expand 10 before | Expand all | Expand 10 after
8092 } 8092 }
8093 } 8093 }
8094 } else { 8094 } else {
8095 // Only deep copy fields from the object literal expression. 8095 // Only deep copy fields from the object literal expression.
8096 // In particular, don't try to copy the length attribute of 8096 // In particular, don't try to copy the length attribute of
8097 // an array. 8097 // an array.
8098 PropertyFilter filter = static_cast<PropertyFilter>( 8098 PropertyFilter filter = static_cast<PropertyFilter>(
8099 ONLY_WRITABLE | ONLY_ENUMERABLE | ONLY_CONFIGURABLE); 8099 ONLY_WRITABLE | ONLY_ENUMERABLE | ONLY_CONFIGURABLE);
8100 KeyAccumulator accumulator(isolate, filter); 8100 KeyAccumulator accumulator(isolate, filter);
8101 accumulator.NextPrototype(); 8101 accumulator.NextPrototype();
8102 copy->CollectOwnPropertyNames(&accumulator, filter); 8102 copy->CollectOwnPropertyKeys(&accumulator, filter);
8103 Handle<FixedArray> names = accumulator.GetKeys(); 8103 Handle<FixedArray> names = accumulator.GetKeys();
8104 for (int i = 0; i < names->length(); i++) { 8104 for (int i = 0; i < names->length(); i++) {
8105 DCHECK(names->get(i)->IsName()); 8105 DCHECK(names->get(i)->IsName());
8106 Handle<Name> name(Name::cast(names->get(i))); 8106 Handle<Name> name(Name::cast(names->get(i)));
8107 Handle<Object> value = 8107 Handle<Object> value =
8108 Object::GetProperty(copy, name).ToHandleChecked(); 8108 Object::GetProperty(copy, name).ToHandleChecked();
8109 if (value->IsJSObject()) { 8109 if (value->IsJSObject()) {
8110 Handle<JSObject> result; 8110 Handle<JSObject> result;
8111 ASSIGN_RETURN_ON_EXCEPTION( 8111 ASSIGN_RETURN_ON_EXCEPTION(
8112 isolate, result, 8112 isolate, result,
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
8615 } 8615 }
8616 8616
8617 JSObject::CollectOwnElementKeys(object, accumulator, *filter); 8617 JSObject::CollectOwnElementKeys(object, accumulator, *filter);
8618 8618
8619 // Add the element keys from the interceptor. 8619 // Add the element keys from the interceptor.
8620 Maybe<bool> success = 8620 Maybe<bool> success =
8621 GetKeysFromInterceptor<v8::IndexedPropertyEnumeratorCallback, kIndexed>( 8621 GetKeysFromInterceptor<v8::IndexedPropertyEnumeratorCallback, kIndexed>(
8622 isolate, receiver, object, *filter, accumulator); 8622 isolate, receiver, object, *filter, accumulator);
8623 MAYBE_RETURN(success, Nothing<bool>()); 8623 MAYBE_RETURN(success, Nothing<bool>());
8624 8624
8625 if (*filter == ENUMERABLE_STRINGS) { 8625 object->CollectOwnPropertyKeys(accumulator, *filter, type);
8626 // We can cache the computed property keys if access checks are
8627 // not needed and no interceptors are involved.
8628 //
8629 // We do not use the cache if the object has elements and
8630 // therefore it does not make sense to cache the property names
8631 // for arguments objects. Arguments objects will always have
8632 // elements.
8633 // Wrapped strings have elements, but don't have an elements
8634 // array or dictionary. So the fast inline test for whether to
8635 // use the cache says yes, so we should not create a cache.
8636 Handle<JSFunction> arguments_function(
8637 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor()));
8638 bool cache_enum_length =
8639 ((object->map()->GetConstructor() != *arguments_function) &&
8640 !object->IsJSValue() && !object->IsAccessCheckNeeded() &&
8641 !object->HasNamedInterceptor() && !object->HasIndexedInterceptor());
8642 // Compute the property keys and cache them if possible.
8643 Handle<FixedArray> enum_keys =
8644 JSObject::GetEnumPropertyKeys(object, cache_enum_length);
8645 accumulator->AddKeys(enum_keys);
8646 } else {
8647 object->CollectOwnPropertyNames(accumulator, *filter);
8648 }
8649 8626
8650 // Add the property keys from the interceptor. 8627 // Add the property keys from the interceptor.
8651 success = GetKeysFromInterceptor<v8::GenericNamedPropertyEnumeratorCallback, 8628 success = GetKeysFromInterceptor<v8::GenericNamedPropertyEnumeratorCallback,
8652 kNamed>(isolate, receiver, object, *filter, 8629 kNamed>(isolate, receiver, object, *filter,
8653 accumulator); 8630 accumulator);
8654 MAYBE_RETURN(success, Nothing<bool>()); 8631 MAYBE_RETURN(success, Nothing<bool>());
8655 return Just(true); 8632 return Just(true);
8656 } 8633 }
8657 8634
8658 8635
(...skipping 7715 matching lines...) Expand 10 before | Expand all | Expand 10 after
16374 SwapPairs(numbers, i, p); 16351 SwapPairs(numbers, i, p);
16375 } 16352 }
16376 } 16353 }
16377 } else { 16354 } else {
16378 HeapSortPairs(this, numbers, len); 16355 HeapSortPairs(this, numbers, len);
16379 return; 16356 return;
16380 } 16357 }
16381 } 16358 }
16382 16359
16383 16360
16384 void JSObject::CollectOwnPropertyNames(KeyAccumulator* keys, 16361 void JSObject::CollectOwnPropertyKeys(KeyAccumulator* keys,
16385 PropertyFilter filter) { 16362 PropertyFilter filter,
16363 JSReceiver::KeyCollectionType type) {
16386 if (HasFastProperties()) { 16364 if (HasFastProperties()) {
16387 int real_size = map()->NumberOfOwnDescriptors(); 16365 int real_size = map()->NumberOfOwnDescriptors();
16388 Handle<DescriptorArray> descs(map()->instance_descriptors()); 16366 Handle<DescriptorArray> descs(map()->instance_descriptors());
16389 for (int i = 0; i < real_size; i++) { 16367 for (int i = 0; i < real_size; i++) {
16390 PropertyDetails details = descs->GetDetails(i); 16368 PropertyDetails details = descs->GetDetails(i);
16391 if ((details.attributes() & filter) != 0) continue; 16369 if ((details.attributes() & filter) != 0) {
16370 if (type == JSReceiver::OWN_ONLY) continue;
16371 if (details.attributes() & DONT_ENUM) {
16372 keys->HideKey(descs->GetKey(i));
16373 }
16374 continue;
16375 }
16392 if (filter & ONLY_ALL_CAN_READ) { 16376 if (filter & ONLY_ALL_CAN_READ) {
16393 if (details.kind() != kAccessor) continue; 16377 if (details.kind() != kAccessor) continue;
16394 Object* accessors = descs->GetValue(i); 16378 Object* accessors = descs->GetValue(i);
16395 if (!accessors->IsAccessorInfo()) continue; 16379 if (!accessors->IsAccessorInfo()) continue;
16396 if (!AccessorInfo::cast(accessors)->all_can_read()) continue; 16380 if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
16397 } 16381 }
16398 Name* key = descs->GetKey(i); 16382 Name* key = descs->GetKey(i);
16399 if (key->FilterKey(filter)) continue; 16383 if (key->FilterKey(filter)) continue;
16400 keys->AddKey(key); 16384 keys->AddKey(key);
16401 } 16385 }
(...skipping 2023 matching lines...) Expand 10 before | Expand all | Expand 10 after
18425 } 18409 }
18426 DCHECK(storage->length() >= index); 18410 DCHECK(storage->length() >= index);
18427 return index - start_index; 18411 return index - start_index;
18428 } 18412 }
18429 18413
18430 18414
18431 template <typename Derived, typename Shape, typename Key> 18415 template <typename Derived, typename Shape, typename Key>
18432 void Dictionary<Derived, Shape, Key>::CollectKeysTo( 18416 void Dictionary<Derived, Shape, Key>::CollectKeysTo(
18433 Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys, 18417 Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys,
18434 PropertyFilter filter) { 18418 PropertyFilter filter) {
18419 if (dictionary->NumberOfElements() == 0) return;
18435 int capacity = dictionary->Capacity(); 18420 int capacity = dictionary->Capacity();
18436 Handle<FixedArray> array = 18421 Handle<FixedArray> array =
18437 keys->isolate()->factory()->NewFixedArray(dictionary->NumberOfElements()); 18422 keys->isolate()->factory()->NewFixedArray(dictionary->NumberOfElements());
18438 int array_size = 0; 18423 int array_size = 0;
18424 std::vector<int> hidden_key_indices;
18439 18425
18440 { 18426 {
18441 DisallowHeapAllocation no_gc; 18427 DisallowHeapAllocation no_gc;
18442 Dictionary<Derived, Shape, Key>* raw_dict = *dictionary; 18428 Dictionary<Derived, Shape, Key>* raw_dict = *dictionary;
18443 for (int i = 0; i < capacity; i++) { 18429 for (int i = 0; i < capacity; i++) {
18444 Object* k = raw_dict->KeyAt(i); 18430 Object* key = raw_dict->KeyAt(i);
18445 if (!raw_dict->IsKey(k) || k->FilterKey(filter)) continue; 18431 if (!raw_dict->IsKey(key) || key->FilterKey(filter)) continue;
18446 if (raw_dict->IsDeleted(i)) continue; 18432 if (raw_dict->IsDeleted(i)) continue;
18447 PropertyDetails details = raw_dict->DetailsAt(i); 18433 PropertyDetails details = raw_dict->DetailsAt(i);
18448 if ((details.attributes() & filter) != 0) continue; 18434 if ((details.attributes() & filter) != 0) {
18435 if (details.attributes() & DONT_ENUM) {
18436 hidden_key_indices.push_back(i);
18437 }
18438 continue;
18439 }
18449 if (filter & ONLY_ALL_CAN_READ) { 18440 if (filter & ONLY_ALL_CAN_READ) {
18450 if (details.kind() != kAccessor) continue; 18441 if (details.kind() != kAccessor) continue;
18451 Object* accessors = raw_dict->ValueAt(i); 18442 Object* accessors = raw_dict->ValueAt(i);
18452 if (accessors->IsPropertyCell()) { 18443 if (accessors->IsPropertyCell()) {
18453 accessors = PropertyCell::cast(accessors)->value(); 18444 accessors = PropertyCell::cast(accessors)->value();
18454 } 18445 }
18455 if (!accessors->IsAccessorInfo()) continue; 18446 if (!accessors->IsAccessorInfo()) continue;
18456 if (!AccessorInfo::cast(accessors)->all_can_read()) continue; 18447 if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
18457 } 18448 }
18458 array->set(array_size++, Smi::FromInt(i)); 18449 array->set(array_size++, Smi::FromInt(i));
18459 } 18450 }
18460 18451
18461 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(raw_dict)); 18452 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(raw_dict));
18462 Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress()); 18453 Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress());
18463 std::sort(start, start + array_size, cmp); 18454 std::sort(start, start + array_size, cmp);
18464 } 18455 }
18465 18456 for (int i = 0; i < hidden_key_indices.size(); i++) {
18457 keys->HideKey(dictionary->KeyAt(hidden_key_indices[i]));
18458 }
18466 for (int i = 0; i < array_size; i++) { 18459 for (int i = 0; i < array_size; i++) {
18467 int index = Smi::cast(array->get(i))->value(); 18460 int index = Smi::cast(array->get(i))->value();
18468 keys->AddKey(dictionary->KeyAt(index)); 18461 keys->AddKey(dictionary->KeyAt(index));
18469 } 18462 }
18470 } 18463 }
18471 18464
18472 18465
18473 // Backwards lookup (slow). 18466 // Backwards lookup (slow).
18474 template<typename Derived, typename Shape, typename Key> 18467 template<typename Derived, typename Shape, typename Key>
18475 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { 18468 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) {
(...skipping 1239 matching lines...) Expand 10 before | Expand all | Expand 10 after
19715 if (cell->value() != *new_value) { 19708 if (cell->value() != *new_value) {
19716 cell->set_value(*new_value); 19709 cell->set_value(*new_value);
19717 Isolate* isolate = cell->GetIsolate(); 19710 Isolate* isolate = cell->GetIsolate();
19718 cell->dependent_code()->DeoptimizeDependentCodeGroup( 19711 cell->dependent_code()->DeoptimizeDependentCodeGroup(
19719 isolate, DependentCode::kPropertyCellChangedGroup); 19712 isolate, DependentCode::kPropertyCellChangedGroup);
19720 } 19713 }
19721 } 19714 }
19722 19715
19723 } // namespace internal 19716 } // namespace internal
19724 } // namespace v8 19717 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698