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

Side by Side Diff: src/objects.cc

Issue 66933003: Reland [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 4234 matching lines...) Expand 10 before | Expand all | Expand 10 after
11219 #endif // ENABLE_DISASSEMBLER 11213 #endif // ENABLE_DISASSEMBLER
11220 11214
11221 11215
11222 MaybeObject* JSObject::SetFastElementsCapacityAndLength( 11216 MaybeObject* JSObject::SetFastElementsCapacityAndLength(
11223 int capacity, 11217 int capacity,
11224 int length, 11218 int length,
11225 SetFastElementsCapacitySmiMode smi_mode) { 11219 SetFastElementsCapacitySmiMode smi_mode) {
11226 Heap* heap = GetHeap(); 11220 Heap* heap = GetHeap();
11227 // We should never end in here with a pixel or external array. 11221 // We should never end in here with a pixel or external array.
11228 ASSERT(!HasExternalArrayElements()); 11222 ASSERT(!HasExternalArrayElements());
11229 ASSERT(!map()->is_observed());
11230 11223
11231 // Allocate a new fast elements backing store. 11224 // Allocate a new fast elements backing store.
11232 FixedArray* new_elements; 11225 FixedArray* new_elements;
11233 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity); 11226 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity);
11234 if (!maybe->To(&new_elements)) return maybe; 11227 if (!maybe->To(&new_elements)) return maybe;
11235 11228
11236 ElementsKind elements_kind = GetElementsKind(); 11229 ElementsKind elements_kind = GetElementsKind();
11237 ElementsKind new_elements_kind; 11230 ElementsKind new_elements_kind;
11238 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, 11231 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it,
11239 // or if it's allowed and the old elements array contained only SMIs. 11232 // 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
11304 11297
11305 return false; 11298 return false;
11306 } 11299 }
11307 11300
11308 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( 11301 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
11309 int capacity, 11302 int capacity,
11310 int length) { 11303 int length) {
11311 Heap* heap = GetHeap(); 11304 Heap* heap = GetHeap();
11312 // We should never end in here with a pixel or external array. 11305 // We should never end in here with a pixel or external array.
11313 ASSERT(!HasExternalArrayElements()); 11306 ASSERT(!HasExternalArrayElements());
11314 ASSERT(!map()->is_observed());
11315 11307
11316 FixedArrayBase* elems; 11308 FixedArrayBase* elems;
11317 { MaybeObject* maybe_obj = 11309 { MaybeObject* maybe_obj =
11318 heap->AllocateUninitializedFixedDoubleArray(capacity); 11310 heap->AllocateUninitializedFixedDoubleArray(capacity);
11319 if (!maybe_obj->To(&elems)) return maybe_obj; 11311 if (!maybe_obj->To(&elems)) return maybe_obj;
11320 } 11312 }
11321 11313
11322 ElementsKind elements_kind = GetElementsKind(); 11314 ElementsKind elements_kind = GetElementsKind();
11323 ElementsKind new_elements_kind = elements_kind; 11315 ElementsKind new_elements_kind = elements_kind;
11324 if (IsHoleyElementsKind(elements_kind)) { 11316 if (IsHoleyElementsKind(elements_kind)) {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
11453 List<uint32_t> indices; 11445 List<uint32_t> indices;
11454 List<Handle<Object> > old_values; 11446 List<Handle<Object> > old_values;
11455 Handle<Object> old_length_handle(self->length(), isolate); 11447 Handle<Object> old_length_handle(self->length(), isolate);
11456 Handle<Object> new_length_handle(len, isolate); 11448 Handle<Object> new_length_handle(len, isolate);
11457 uint32_t old_length = 0; 11449 uint32_t old_length = 0;
11458 CHECK(old_length_handle->ToArrayIndex(&old_length)); 11450 CHECK(old_length_handle->ToArrayIndex(&old_length));
11459 uint32_t new_length = 0; 11451 uint32_t new_length = 0;
11460 if (!new_length_handle->ToArrayIndex(&new_length)) 11452 if (!new_length_handle->ToArrayIndex(&new_length))
11461 return Failure::InternalError(); 11453 return Failure::InternalError();
11462 11454
11463 // Observed arrays should always be in dictionary mode;
11464 // if they were in fast mode, the below is slower than necessary
11465 // as it iterates over the array backing store multiple times.
11466 ASSERT(self->HasDictionaryElements());
11467 static const PropertyAttributes kNoAttrFilter = NONE; 11455 static const PropertyAttributes kNoAttrFilter = NONE;
11468 int num_elements = self->NumberOfLocalElements(kNoAttrFilter); 11456 int num_elements = self->NumberOfLocalElements(kNoAttrFilter);
11469 if (num_elements > 0) { 11457 if (num_elements > 0) {
11470 if (old_length == static_cast<uint32_t>(num_elements)) { 11458 if (old_length == static_cast<uint32_t>(num_elements)) {
11471 // Simple case for arrays without holes. 11459 // Simple case for arrays without holes.
11472 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { 11460 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) {
11473 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break; 11461 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break;
11474 } 11462 }
11475 } else { 11463 } else {
11476 // For sparse arrays, only iterate over existing elements. 11464 // For sparse arrays, only iterate over existing elements.
11465 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over
11466 // the to-be-removed indices twice.
11477 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); 11467 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements);
11478 self->GetLocalElementKeys(*keys, kNoAttrFilter); 11468 self->GetLocalElementKeys(*keys, kNoAttrFilter);
11479 while (num_elements-- > 0) { 11469 while (num_elements-- > 0) {
11480 uint32_t index = NumberToUint32(keys->get(num_elements)); 11470 uint32_t index = NumberToUint32(keys->get(num_elements));
11481 if (index < new_length) break; 11471 if (index < new_length) break;
11482 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break; 11472 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break;
11483 } 11473 }
11484 } 11474 }
11485 } 11475 }
11486 11476
(...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after
12865 ElementsKindToString(to_kind)); 12855 ElementsKindToString(to_kind));
12866 } 12856 }
12867 site->set_transition_info(Smi::FromInt(to_kind)); 12857 site->set_transition_info(Smi::FromInt(to_kind));
12868 } 12858 }
12869 } 12859 }
12870 return this; 12860 return this;
12871 } 12861 }
12872 12862
12873 12863
12874 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { 12864 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) {
12875 ASSERT(!map()->is_observed());
12876 ElementsKind from_kind = map()->elements_kind(); 12865 ElementsKind from_kind = map()->elements_kind();
12877 12866
12878 if (IsFastHoleyElementsKind(from_kind)) { 12867 if (IsFastHoleyElementsKind(from_kind)) {
12879 to_kind = GetHoleyElementsKind(to_kind); 12868 to_kind = GetHoleyElementsKind(to_kind);
12880 } 12869 }
12881 12870
12882 if (from_kind == to_kind) return this; 12871 if (from_kind == to_kind) return this;
12883 // Don't update the site if to_kind isn't fast 12872 // Don't update the site if to_kind isn't fast
12884 if (IsFastElementsKind(to_kind)) { 12873 if (IsFastElementsKind(to_kind)) {
12885 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); 12874 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind);
(...skipping 3649 matching lines...) Expand 10 before | Expand all | Expand 10 after
16535 #define ERROR_MESSAGES_TEXTS(C, T) T, 16524 #define ERROR_MESSAGES_TEXTS(C, T) T,
16536 static const char* error_messages_[] = { 16525 static const char* error_messages_[] = {
16537 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16526 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16538 }; 16527 };
16539 #undef ERROR_MESSAGES_TEXTS 16528 #undef ERROR_MESSAGES_TEXTS
16540 return error_messages_[reason]; 16529 return error_messages_[reason];
16541 } 16530 }
16542 16531
16543 16532
16544 } } // namespace v8::internal 16533 } } // 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