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

Side by Side Diff: src/objects.cc

Issue 68343016: [Object.observe] Don't force normalization of elements for observed objects (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 5596 matching lines...) Expand 10 before | Expand all | Expand 10 after
5607 return object; 5607 return object;
5608 } 5608 }
5609 5609
5610 5610
5611 void JSObject::SetObserved(Handle<JSObject> object) { 5611 void JSObject::SetObserved(Handle<JSObject> object) {
5612 Isolate* isolate = object->GetIsolate(); 5612 Isolate* isolate = object->GetIsolate();
5613 5613
5614 if (object->map()->is_observed()) 5614 if (object->map()->is_observed())
5615 return; 5615 return;
5616 5616
5617 if (!object->HasExternalArrayElements()) {
5618 // Go to dictionary mode, so that we don't skip map checks.
5619 NormalizeElements(object);
5620 ASSERT(!object->HasFastElements());
5621 }
5622
5623 LookupResult result(isolate); 5617 LookupResult result(isolate);
5624 object->map()->LookupTransition(*object, 5618 object->map()->LookupTransition(*object,
5625 isolate->heap()->observed_symbol(), 5619 isolate->heap()->observed_symbol(),
5626 &result); 5620 &result);
5627 5621
5628 Handle<Map> new_map; 5622 Handle<Map> new_map;
5629 if (result.IsTransition()) { 5623 if (result.IsTransition()) {
5630 new_map = handle(result.GetTransitionTarget()); 5624 new_map = handle(result.GetTransitionTarget());
5631 ASSERT(new_map->is_observed()); 5625 ASSERT(new_map->is_observed());
5632 } else if (object->map()->CanHaveMoreTransitions()) { 5626 } else if (object->map()->CanHaveMoreTransitions()) {
5633 new_map = Map::CopyForObserved(handle(object->map())); 5627 new_map = Map::CopyForObserved(handle(object->map()));
5634 } else { 5628 } else {
5635 new_map = Map::Copy(handle(object->map())); 5629 new_map = Map::Copy(handle(object->map()));
5636 new_map->set_is_observed(true); 5630 new_map->set_is_observed();
5637 } 5631 }
5638 object->set_map(*new_map); 5632 object->set_map(*new_map);
5639 } 5633 }
5640 5634
5641 5635
5642 Handle<JSObject> JSObject::Copy(Handle<JSObject> object, 5636 Handle<JSObject> JSObject::Copy(Handle<JSObject> object,
5643 Handle<AllocationSite> site) { 5637 Handle<AllocationSite> site) {
5644 Isolate* isolate = object->GetIsolate(); 5638 Isolate* isolate = object->GetIsolate();
5645 CALL_HEAP_FUNCTION(isolate, 5639 CALL_HEAP_FUNCTION(isolate,
5646 isolate->heap()->CopyJSObject(*object, *site), JSObject); 5640 isolate->heap()->CopyJSObject(*object, *site), JSObject);
(...skipping 1317 matching lines...) Expand 10 before | Expand all | Expand 10 after
6964 } else { 6958 } else {
6965 new_map = Map::Copy(map); 6959 new_map = Map::Copy(map);
6966 } 6960 }
6967 6961
6968 Handle<TransitionArray> transitions = 6962 Handle<TransitionArray> transitions =
6969 Map::AddTransition(map, isolate->factory()->observed_symbol(), new_map, 6963 Map::AddTransition(map, isolate->factory()->observed_symbol(), new_map,
6970 FULL_TRANSITION); 6964 FULL_TRANSITION);
6971 6965
6972 map->set_transitions(*transitions); 6966 map->set_transitions(*transitions);
6973 6967
6974 new_map->set_is_observed(true); 6968 new_map->set_is_observed();
6975 6969
6976 if (map->owns_descriptors()) { 6970 if (map->owns_descriptors()) {
6977 new_map->InitializeDescriptors(map->instance_descriptors()); 6971 new_map->InitializeDescriptors(map->instance_descriptors());
6978 map->set_owns_descriptors(false); 6972 map->set_owns_descriptors(false);
6979 } 6973 }
6980 6974
6981 new_map->SetBackPointer(*map); 6975 new_map->SetBackPointer(*map);
6982 return new_map; 6976 return new_map;
6983 } 6977 }
6984 6978
(...skipping 4229 matching lines...) Expand 10 before | Expand all | Expand 10 after
11214 #endif // ENABLE_DISASSEMBLER 11208 #endif // ENABLE_DISASSEMBLER
11215 11209
11216 11210
11217 MaybeObject* JSObject::SetFastElementsCapacityAndLength( 11211 MaybeObject* JSObject::SetFastElementsCapacityAndLength(
11218 int capacity, 11212 int capacity,
11219 int length, 11213 int length,
11220 SetFastElementsCapacitySmiMode smi_mode) { 11214 SetFastElementsCapacitySmiMode smi_mode) {
11221 Heap* heap = GetHeap(); 11215 Heap* heap = GetHeap();
11222 // We should never end in here with a pixel or external array. 11216 // We should never end in here with a pixel or external array.
11223 ASSERT(!HasExternalArrayElements()); 11217 ASSERT(!HasExternalArrayElements());
11224 ASSERT(!map()->is_observed());
11225 11218
11226 // Allocate a new fast elements backing store. 11219 // Allocate a new fast elements backing store.
11227 FixedArray* new_elements; 11220 FixedArray* new_elements;
11228 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity); 11221 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity);
11229 if (!maybe->To(&new_elements)) return maybe; 11222 if (!maybe->To(&new_elements)) return maybe;
11230 11223
11231 ElementsKind elements_kind = GetElementsKind(); 11224 ElementsKind elements_kind = GetElementsKind();
11232 ElementsKind new_elements_kind; 11225 ElementsKind new_elements_kind;
11233 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, 11226 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it,
11234 // or if it's allowed and the old elements array contained only SMIs. 11227 // or if it's allowed and the old elements array contained only SMIs.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
11299 11292
11300 return false; 11293 return false;
11301 } 11294 }
11302 11295
11303 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( 11296 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
11304 int capacity, 11297 int capacity,
11305 int length) { 11298 int length) {
11306 Heap* heap = GetHeap(); 11299 Heap* heap = GetHeap();
11307 // We should never end in here with a pixel or external array. 11300 // We should never end in here with a pixel or external array.
11308 ASSERT(!HasExternalArrayElements()); 11301 ASSERT(!HasExternalArrayElements());
11309 ASSERT(!map()->is_observed());
11310 11302
11311 FixedArrayBase* elems; 11303 FixedArrayBase* elems;
11312 { MaybeObject* maybe_obj = 11304 { MaybeObject* maybe_obj =
11313 heap->AllocateUninitializedFixedDoubleArray(capacity); 11305 heap->AllocateUninitializedFixedDoubleArray(capacity);
11314 if (!maybe_obj->To(&elems)) return maybe_obj; 11306 if (!maybe_obj->To(&elems)) return maybe_obj;
11315 } 11307 }
11316 11308
11317 ElementsKind elements_kind = GetElementsKind(); 11309 ElementsKind elements_kind = GetElementsKind();
11318 ElementsKind new_elements_kind = elements_kind; 11310 ElementsKind new_elements_kind = elements_kind;
11319 if (IsHoleyElementsKind(elements_kind)) { 11311 if (IsHoleyElementsKind(elements_kind)) {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
11448 List<uint32_t> indices; 11440 List<uint32_t> indices;
11449 List<Handle<Object> > old_values; 11441 List<Handle<Object> > old_values;
11450 Handle<Object> old_length_handle(self->length(), isolate); 11442 Handle<Object> old_length_handle(self->length(), isolate);
11451 Handle<Object> new_length_handle(len, isolate); 11443 Handle<Object> new_length_handle(len, isolate);
11452 uint32_t old_length = 0; 11444 uint32_t old_length = 0;
11453 CHECK(old_length_handle->ToArrayIndex(&old_length)); 11445 CHECK(old_length_handle->ToArrayIndex(&old_length));
11454 uint32_t new_length = 0; 11446 uint32_t new_length = 0;
11455 if (!new_length_handle->ToArrayIndex(&new_length)) 11447 if (!new_length_handle->ToArrayIndex(&new_length))
11456 return Failure::InternalError(); 11448 return Failure::InternalError();
11457 11449
11458 // Observed arrays should always be in dictionary mode;
11459 // if they were in fast mode, the below is slower than necessary
11460 // as it iterates over the array backing store multiple times.
11461 ASSERT(self->HasDictionaryElements());
11462 static const PropertyAttributes kNoAttrFilter = NONE; 11450 static const PropertyAttributes kNoAttrFilter = NONE;
11463 int num_elements = self->NumberOfLocalElements(kNoAttrFilter); 11451 int num_elements = self->NumberOfLocalElements(kNoAttrFilter);
11464 if (num_elements > 0) { 11452 if (num_elements > 0) {
11465 if (old_length == static_cast<uint32_t>(num_elements)) { 11453 if (old_length == static_cast<uint32_t>(num_elements)) {
11466 // Simple case for arrays without holes. 11454 // Simple case for arrays without holes.
11467 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { 11455 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) {
11468 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break; 11456 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break;
11469 } 11457 }
11470 } else { 11458 } else {
11471 // For sparse arrays, only iterate over existing elements. 11459 // For sparse arrays, only iterate over existing elements.
11460 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over
11461 // the to-be-removed indices twice.
11472 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); 11462 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements);
11473 self->GetLocalElementKeys(*keys, kNoAttrFilter); 11463 self->GetLocalElementKeys(*keys, kNoAttrFilter);
11474 while (num_elements-- > 0) { 11464 while (num_elements-- > 0) {
11475 uint32_t index = NumberToUint32(keys->get(num_elements)); 11465 uint32_t index = NumberToUint32(keys->get(num_elements));
11476 if (index < new_length) break; 11466 if (index < new_length) break;
11477 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break; 11467 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break;
11478 } 11468 }
11479 } 11469 }
11480 } 11470 }
11481 11471
(...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after
12860 ElementsKindToString(to_kind)); 12850 ElementsKindToString(to_kind));
12861 } 12851 }
12862 site->set_transition_info(Smi::FromInt(to_kind)); 12852 site->set_transition_info(Smi::FromInt(to_kind));
12863 } 12853 }
12864 } 12854 }
12865 return this; 12855 return this;
12866 } 12856 }
12867 12857
12868 12858
12869 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { 12859 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) {
12870 ASSERT(!map()->is_observed());
12871 ElementsKind from_kind = map()->elements_kind(); 12860 ElementsKind from_kind = map()->elements_kind();
12872 12861
12873 if (IsFastHoleyElementsKind(from_kind)) { 12862 if (IsFastHoleyElementsKind(from_kind)) {
12874 to_kind = GetHoleyElementsKind(to_kind); 12863 to_kind = GetHoleyElementsKind(to_kind);
12875 } 12864 }
12876 12865
12877 if (from_kind == to_kind) return this; 12866 if (from_kind == to_kind) return this;
12878 // Don't update the site if to_kind isn't fast 12867 // Don't update the site if to_kind isn't fast
12879 if (IsFastElementsKind(to_kind)) { 12868 if (IsFastElementsKind(to_kind)) {
12880 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); 12869 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind);
(...skipping 3649 matching lines...) Expand 10 before | Expand all | Expand 10 after
16530 #define ERROR_MESSAGES_TEXTS(C, T) T, 16519 #define ERROR_MESSAGES_TEXTS(C, T) T,
16531 static const char* error_messages_[] = { 16520 static const char* error_messages_[] = {
16532 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16521 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16533 }; 16522 };
16534 #undef ERROR_MESSAGES_TEXTS 16523 #undef ERROR_MESSAGES_TEXTS
16535 return error_messages_[reason]; 16524 return error_messages_[reason];
16536 } 16525 }
16537 16526
16538 16527
16539 } } // namespace v8::internal 16528 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698