| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 15c12db4e02ddf9c26f55938775fe750cb105bbe..a2bece97f16382f8d552dd5b147c8d63cf239600 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -2625,6 +2625,8 @@ Map* Map::FindUpdatedMap(int verbatim,
|
| current->instance_descriptors()->GetValue(i)) {
|
| return NULL;
|
| }
|
| + } else if (target_details.type() == CALLBACKS) {
|
| + return NULL;
|
| }
|
| }
|
|
|
| @@ -5913,9 +5915,9 @@ bool JSReceiver::IsSimpleEnum() {
|
| JSObject* curr = JSObject::cast(o);
|
| int enum_length = curr->map()->EnumLength();
|
| if (enum_length == kInvalidEnumCacheSentinel) return false;
|
| + if (curr->IsAccessCheckNeeded()) return false;
|
| ASSERT(!curr->HasNamedInterceptor());
|
| ASSERT(!curr->HasIndexedInterceptor());
|
| - ASSERT(!curr->IsAccessCheckNeeded());
|
| if (curr->NumberOfEnumElements() > 0) return false;
|
| if (curr != this && enum_length != 0) return false;
|
| }
|
| @@ -15531,7 +15533,7 @@ int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes(
|
| template<typename Shape, typename Key>
|
| int Dictionary<Shape, Key>::NumberOfEnumElements() {
|
| return NumberOfElementsFilterAttributes(
|
| - static_cast<PropertyAttributes>(DONT_ENUM));
|
| + static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC));
|
| }
|
|
|
|
|
| @@ -15559,45 +15561,38 @@ void Dictionary<Shape, Key>::CopyKeysTo(
|
| }
|
|
|
|
|
| -FixedArray* NameDictionary::CopyEnumKeysTo(FixedArray* storage) {
|
| +struct EnumIndexComparator {
|
| + explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { }
|
| + bool operator() (Smi* a, Smi* b) {
|
| + PropertyDetails da(dict->DetailsAt(a->value()));
|
| + PropertyDetails db(dict->DetailsAt(b->value()));
|
| + return da.dictionary_index() < db.dictionary_index();
|
| + }
|
| + NameDictionary* dict;
|
| +};
|
| +
|
| +
|
| +void NameDictionary::CopyEnumKeysTo(FixedArray* storage) {
|
| int length = storage->length();
|
| - ASSERT(length >= NumberOfEnumElements());
|
| - Heap* heap = GetHeap();
|
| - Object* undefined_value = heap->undefined_value();
|
| int capacity = Capacity();
|
| int properties = 0;
|
| -
|
| - // Fill in the enumeration array by assigning enumerable keys at their
|
| - // enumeration index. This will leave holes in the array if there are keys
|
| - // that are deleted or not enumerable.
|
| for (int i = 0; i < capacity; i++) {
|
| Object* k = KeyAt(i);
|
| if (IsKey(k) && !k->IsSymbol()) {
|
| PropertyDetails details = DetailsAt(i);
|
| if (details.IsDeleted() || details.IsDontEnum()) continue;
|
| + storage->set(properties, Smi::FromInt(i));
|
| properties++;
|
| - storage->set(details.dictionary_index() - 1, k);
|
| if (properties == length) break;
|
| }
|
| }
|
| -
|
| - // There are holes in the enumeration array if less properties were assigned
|
| - // than the length of the array. If so, crunch all the existing properties
|
| - // together by shifting them to the left (maintaining the enumeration order),
|
| - // and trimming of the right side of the array.
|
| - if (properties < length) {
|
| - if (properties == 0) return heap->empty_fixed_array();
|
| - properties = 0;
|
| - for (int i = 0; i < length; ++i) {
|
| - Object* value = storage->get(i);
|
| - if (value != undefined_value) {
|
| - storage->set(properties, value);
|
| - ++properties;
|
| - }
|
| - }
|
| - RightTrimFixedArray<FROM_MUTATOR>(heap, storage, length - properties);
|
| + EnumIndexComparator cmp(this);
|
| + Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress());
|
| + std::sort(start, start + length, cmp);
|
| + for (int i = 0; i < length; i++) {
|
| + int index = Smi::cast(storage->get(i))->value();
|
| + storage->set(i, KeyAt(index));
|
| }
|
| - return storage;
|
| }
|
|
|
|
|
|
|