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

Side by Side Diff: src/objects.cc

Issue 1707743002: [key-accumulator] Starting to reimplement the key-accumulator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: use proper type Created 4 years, 9 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
« no previous file with comments | « src/objects.h ('k') | src/objects-printer.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 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 16 matching lines...) Expand all
27 #include "src/execution.h" 27 #include "src/execution.h"
28 #include "src/field-index-inl.h" 28 #include "src/field-index-inl.h"
29 #include "src/field-index.h" 29 #include "src/field-index.h"
30 #include "src/field-type.h" 30 #include "src/field-type.h"
31 #include "src/full-codegen/full-codegen.h" 31 #include "src/full-codegen/full-codegen.h"
32 #include "src/ic/ic.h" 32 #include "src/ic/ic.h"
33 #include "src/identity-map.h" 33 #include "src/identity-map.h"
34 #include "src/interpreter/bytecodes.h" 34 #include "src/interpreter/bytecodes.h"
35 #include "src/interpreter/source-position-table.h" 35 #include "src/interpreter/source-position-table.h"
36 #include "src/isolate-inl.h" 36 #include "src/isolate-inl.h"
37 #include "src/key-accumulator.h" 37 #include "src/keys.h"
38 #include "src/list.h" 38 #include "src/list.h"
39 #include "src/log.h" 39 #include "src/log.h"
40 #include "src/lookup.h" 40 #include "src/lookup.h"
41 #include "src/macro-assembler.h" 41 #include "src/macro-assembler.h"
42 #include "src/messages.h" 42 #include "src/messages.h"
43 #include "src/objects-inl.h" 43 #include "src/objects-inl.h"
44 #include "src/objects-body-descriptors-inl.h" 44 #include "src/objects-body-descriptors-inl.h"
45 #include "src/profiler/cpu-profiler.h" 45 #include "src/profiler/cpu-profiler.h"
46 #include "src/property-descriptor.h" 46 #include "src/property-descriptor.h"
47 #include "src/prototype.h" 47 #include "src/prototype.h"
(...skipping 8184 matching lines...) Expand 10 before | Expand all | Expand 10 after
8232 if (result->IsPrimitive()) return result; 8232 if (result->IsPrimitive()) return result;
8233 } 8233 }
8234 } 8234 }
8235 THROW_NEW_ERROR(isolate, 8235 THROW_NEW_ERROR(isolate,
8236 NewTypeError(MessageTemplate::kCannotConvertToPrimitive), 8236 NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
8237 Object); 8237 Object);
8238 } 8238 }
8239 8239
8240 8240
8241 // TODO(cbruni/jkummerow): Consider moving this into elements.cc. 8241 // TODO(cbruni/jkummerow): Consider moving this into elements.cc.
8242 bool HasEnumerableElements(JSObject* object) { 8242 bool JSObject::HasEnumerableElements() {
8243 // TODO(cbruni): cleanup
8244 JSObject* object = this;
8243 switch (object->GetElementsKind()) { 8245 switch (object->GetElementsKind()) {
8244 case FAST_SMI_ELEMENTS: 8246 case FAST_SMI_ELEMENTS:
8245 case FAST_ELEMENTS: 8247 case FAST_ELEMENTS:
8246 case FAST_DOUBLE_ELEMENTS: { 8248 case FAST_DOUBLE_ELEMENTS: {
8247 int length = object->IsJSArray() 8249 int length = object->IsJSArray()
8248 ? Smi::cast(JSArray::cast(object)->length())->value() 8250 ? Smi::cast(JSArray::cast(object)->length())->value()
8249 : object->elements()->length(); 8251 : object->elements()->length();
8250 return length > 0; 8252 return length > 0;
8251 } 8253 }
8252 case FAST_HOLEY_SMI_ELEMENTS: 8254 case FAST_HOLEY_SMI_ELEMENTS:
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
8297 return true; 8299 return true;
8298 } 8300 }
8299 return object->elements()->length() > 0; 8301 return object->elements()->length() > 0;
8300 case NO_ELEMENTS: 8302 case NO_ELEMENTS:
8301 return false; 8303 return false;
8302 } 8304 }
8303 UNREACHABLE(); 8305 UNREACHABLE();
8304 return true; 8306 return true;
8305 } 8307 }
8306 8308
8307
8308 // Tests for the fast common case for property enumeration: 8309 // Tests for the fast common case for property enumeration:
8309 // - This object and all prototypes has an enum cache (which means that 8310 // - This object and all prototypes has an enum cache (which means that
8310 // it is no proxy, has no interceptors and needs no access checks). 8311 // it is no proxy, has no interceptors and needs no access checks).
8311 // - This object has no elements. 8312 // - This object has no elements.
8312 // - No prototype has enumerable properties/elements. 8313 // - No prototype has enumerable properties/elements.
8313 bool JSReceiver::IsSimpleEnum() { 8314 bool JSReceiver::IsSimpleEnum() {
8314 for (PrototypeIterator iter(GetIsolate(), this, 8315 for (PrototypeIterator iter(GetIsolate(), this,
8315 PrototypeIterator::START_AT_RECEIVER); 8316 PrototypeIterator::START_AT_RECEIVER);
8316 !iter.IsAtEnd(); iter.Advance()) { 8317 !iter.IsAtEnd(); iter.Advance()) {
8317 if (!iter.GetCurrent()->IsJSObject()) return false; 8318 if (!iter.GetCurrent()->IsJSObject()) return false;
8318 JSObject* current = iter.GetCurrent<JSObject>(); 8319 JSObject* current = iter.GetCurrent<JSObject>();
8319 int enum_length = current->map()->EnumLength(); 8320 int enum_length = current->map()->EnumLength();
8320 if (enum_length == kInvalidEnumCacheSentinel) return false; 8321 if (enum_length == kInvalidEnumCacheSentinel) return false;
8321 if (current->IsAccessCheckNeeded()) return false; 8322 if (current->IsAccessCheckNeeded()) return false;
8322 DCHECK(!current->HasNamedInterceptor()); 8323 DCHECK(!current->HasNamedInterceptor());
8323 DCHECK(!current->HasIndexedInterceptor()); 8324 DCHECK(!current->HasIndexedInterceptor());
8324 if (HasEnumerableElements(current)) return false; 8325 if (current->HasEnumerableElements()) return false;
8325 if (current != this && enum_length != 0) return false; 8326 if (current != this && enum_length != 0) return false;
8326 } 8327 }
8327 return true; 8328 return true;
8328 } 8329 }
8329 8330
8330 8331
8331 int Map::NumberOfDescribedProperties(DescriptorFlag which, 8332 int Map::NumberOfDescribedProperties(DescriptorFlag which,
8332 PropertyFilter filter) { 8333 PropertyFilter filter) {
8333 int result = 0; 8334 int result = 0;
8334 DescriptorArray* descs = instance_descriptors(); 8335 DescriptorArray* descs = instance_descriptors();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
8378 } 8379 }
8379 8380
8380 bool Map::OnlyHasSimpleProperties() { 8381 bool Map::OnlyHasSimpleProperties() {
8381 // Wrapped string elements aren't explicitly stored in the elements backing 8382 // Wrapped string elements aren't explicitly stored in the elements backing
8382 // store, but are loaded indirectly from the underlying string. 8383 // store, but are loaded indirectly from the underlying string.
8383 return !IsStringWrapperElementsKind(elements_kind()) && 8384 return !IsStringWrapperElementsKind(elements_kind()) &&
8384 instance_type() > LAST_SPECIAL_RECEIVER_TYPE && 8385 instance_type() > LAST_SPECIAL_RECEIVER_TYPE &&
8385 !has_hidden_prototype() && !is_dictionary_map(); 8386 !has_hidden_prototype() && !is_dictionary_map();
8386 } 8387 }
8387 8388
8388 namespace { 8389 // static
8389 8390 Handle<FixedArray> JSObject::GetFastEnumPropertyKeys(Isolate* isolate,
8390 Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate, 8391 Handle<JSObject> object) {
8391 Handle<JSObject> object) {
8392 Handle<Map> map(object->map()); 8392 Handle<Map> map(object->map());
8393 bool cache_enum_length = map->OnlyHasSimpleProperties(); 8393 bool cache_enum_length = map->OnlyHasSimpleProperties();
8394 8394
8395 Handle<DescriptorArray> descs = 8395 Handle<DescriptorArray> descs =
8396 Handle<DescriptorArray>(map->instance_descriptors(), isolate); 8396 Handle<DescriptorArray>(map->instance_descriptors(), isolate);
8397 int own_property_count = map->EnumLength(); 8397 int own_property_count = map->EnumLength();
8398 // If the enum length of the given map is set to kInvalidEnumCache, this 8398 // If the enum length of the given map is set to kInvalidEnumCache, this
8399 // means that the map itself has never used the present enum cache. The 8399 // means that the map itself has never used the present enum cache. The
8400 // first step to using the cache is to set the enum length of the map by 8400 // first step to using the cache is to set the enum length of the map by
8401 // counting the number of own descriptors that are ENUMERABLE_STRINGS. 8401 // counting the number of own descriptors that are ENUMERABLE_STRINGS.
(...skipping 30 matching lines...) Expand all
8432 Handle<FixedArray> storage = 8432 Handle<FixedArray> storage =
8433 isolate->factory()->NewFixedArray(own_property_count); 8433 isolate->factory()->NewFixedArray(own_property_count);
8434 Handle<FixedArray> indices = 8434 Handle<FixedArray> indices =
8435 isolate->factory()->NewFixedArray(own_property_count); 8435 isolate->factory()->NewFixedArray(own_property_count);
8436 8436
8437 int size = map->NumberOfOwnDescriptors(); 8437 int size = map->NumberOfOwnDescriptors();
8438 int index = 0; 8438 int index = 0;
8439 8439
8440 for (int i = 0; i < size; i++) { 8440 for (int i = 0; i < size; i++) {
8441 PropertyDetails details = descs->GetDetails(i); 8441 PropertyDetails details = descs->GetDetails(i);
8442 if (details.IsDontEnum()) continue;
8442 Object* key = descs->GetKey(i); 8443 Object* key = descs->GetKey(i);
8443 if (details.IsDontEnum() || key->IsSymbol()) continue; 8444 if (key->IsSymbol()) continue;
8444 storage->set(index, key); 8445 storage->set(index, key);
8445 if (!indices.is_null()) { 8446 if (!indices.is_null()) {
8446 if (details.type() != DATA) { 8447 if (details.type() != DATA) {
8447 indices = Handle<FixedArray>(); 8448 indices = Handle<FixedArray>();
8448 } else { 8449 } else {
8449 FieldIndex field_index = FieldIndex::ForDescriptor(*map, i); 8450 FieldIndex field_index = FieldIndex::ForDescriptor(*map, i);
8450 int load_by_field_index = field_index.GetLoadByFieldIndex(); 8451 int load_by_field_index = field_index.GetLoadByFieldIndex();
8451 indices->set(index, Smi::FromInt(load_by_field_index)); 8452 indices->set(index, Smi::FromInt(load_by_field_index));
8452 } 8453 }
8453 } 8454 }
8454 index++; 8455 index++;
8455 } 8456 }
8456 DCHECK(index == storage->length()); 8457 DCHECK(index == storage->length());
8457 8458
8458 DescriptorArray::SetEnumCache(descs, isolate, storage, indices); 8459 DescriptorArray::SetEnumCache(descs, isolate, storage, indices);
8459 if (cache_enum_length) { 8460 if (cache_enum_length) {
8460 map->SetEnumLength(own_property_count); 8461 map->SetEnumLength(own_property_count);
8461 } 8462 }
8462 return storage; 8463 return storage;
8463 } 8464 }
8464 8465
8465 } // namespace
8466 8466
8467 Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object) { 8467 Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object) {
8468 Isolate* isolate = object->GetIsolate(); 8468 Isolate* isolate = object->GetIsolate();
8469 if (object->HasFastProperties()) { 8469 if (object->HasFastProperties()) {
8470 return GetFastEnumPropertyKeys(isolate, object); 8470 return GetFastEnumPropertyKeys(isolate, object);
8471 } else if (object->IsJSGlobalObject()) { 8471 } else if (object->IsJSGlobalObject()) {
8472 Handle<GlobalDictionary> dictionary(object->global_dictionary()); 8472 Handle<GlobalDictionary> dictionary(object->global_dictionary());
8473 int length = dictionary->NumberOfEnumElements(); 8473 int length = dictionary->NumberOfEnumElements();
8474 if (length == 0) { 8474 if (length == 0) {
8475 return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); 8475 return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
(...skipping 2197 matching lines...) Expand 10 before | Expand all | Expand 10 after
10673 array = EnsureSpace(array, length + 1); 10673 array = EnsureSpace(array, length + 1);
10674 if (mode == kReloadLengthAfterAllocation) { 10674 if (mode == kReloadLengthAfterAllocation) {
10675 DCHECK(array->Length() <= length); 10675 DCHECK(array->Length() <= length);
10676 length = array->Length(); 10676 length = array->Length();
10677 } 10677 }
10678 array->Set(length, *obj); 10678 array->Set(length, *obj);
10679 array->SetLength(length + 1); 10679 array->SetLength(length + 1);
10680 return array; 10680 return array;
10681 } 10681 }
10682 10682
10683
10684 Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj1, 10683 Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj1,
10685 Handle<Object> obj2, AddMode mode) { 10684 Handle<Object> obj2, AddMode mode) {
10686 int length = array->Length(); 10685 int length = array->Length();
10687 array = EnsureSpace(array, length + 2); 10686 array = EnsureSpace(array, length + 2);
10688 if (mode == kReloadLengthAfterAllocation) { 10687 if (mode == kReloadLengthAfterAllocation) {
10689 length = array->Length(); 10688 length = array->Length();
10690 } 10689 }
10691 array->Set(length, *obj1); 10690 array->Set(length, *obj1);
10692 array->Set(length + 1, *obj2); 10691 array->Set(length + 1, *obj2);
10693 array->SetLength(length + 2); 10692 array->SetLength(length + 2);
(...skipping 5741 matching lines...) Expand 10 before | Expand all | Expand 10 after
16435 j++ < len) { 16434 j++ < len) {
16436 SwapPairs(numbers, i, p); 16435 SwapPairs(numbers, i, p);
16437 } 16436 }
16438 } 16437 }
16439 } else { 16438 } else {
16440 HeapSortPairs(this, numbers, len); 16439 HeapSortPairs(this, numbers, len);
16441 return; 16440 return;
16442 } 16441 }
16443 } 16442 }
16444 16443
16445
16446 void JSObject::CollectOwnPropertyNames(KeyAccumulator* keys, 16444 void JSObject::CollectOwnPropertyNames(KeyAccumulator* keys,
16447 PropertyFilter filter) { 16445 PropertyFilter filter) {
16448 if (HasFastProperties()) { 16446 if (HasFastProperties()) {
16449 int real_size = map()->NumberOfOwnDescriptors(); 16447 int real_size = map()->NumberOfOwnDescriptors();
16450 Handle<DescriptorArray> descs(map()->instance_descriptors()); 16448 Handle<DescriptorArray> descs(map()->instance_descriptors());
16451 for (int i = 0; i < real_size; i++) { 16449 for (int i = 0; i < real_size; i++) {
16452 PropertyDetails details = descs->GetDetails(i); 16450 PropertyDetails details = descs->GetDetails(i);
16453 if ((details.attributes() & filter) != 0) continue; 16451 if ((details.attributes() & filter) != 0) continue;
16454 if (filter & ONLY_ALL_CAN_READ) { 16452 if (filter & ONLY_ALL_CAN_READ) {
16455 if (details.kind() != kAccessor) continue; 16453 if (details.kind() != kAccessor) continue;
(...skipping 20 matching lines...) Expand all
16476 IsJSArray() 16474 IsJSArray()
16477 ? static_cast<uint32_t>( 16475 ? static_cast<uint32_t>(
16478 Smi::cast(JSArray::cast(this)->length())->value()) 16476 Smi::cast(JSArray::cast(this)->length())->value())
16479 : static_cast<uint32_t>(FixedArrayBase::cast(elements())->length()); 16477 : static_cast<uint32_t>(FixedArrayBase::cast(elements())->length());
16480 if (length == 0) return 0; 16478 if (length == 0) return 0;
16481 } 16479 }
16482 // Compute the number of enumerable elements. 16480 // Compute the number of enumerable elements.
16483 return GetOwnElementKeys(NULL, filter); 16481 return GetOwnElementKeys(NULL, filter);
16484 } 16482 }
16485 16483
16486
16487 void JSObject::CollectOwnElementKeys(Handle<JSObject> object, 16484 void JSObject::CollectOwnElementKeys(Handle<JSObject> object,
16488 KeyAccumulator* keys, 16485 KeyAccumulator* keys,
16489 PropertyFilter filter) { 16486 PropertyFilter filter) {
16490 if (filter & SKIP_STRINGS) return; 16487 if (filter & SKIP_STRINGS) return;
16491 ElementsAccessor* accessor = object->GetElementsAccessor(); 16488 ElementsAccessor* accessor = object->GetElementsAccessor();
16492 accessor->CollectElementIndices(object, keys, kMaxUInt32, filter, 0); 16489 accessor->CollectElementIndices(object, keys, kMaxUInt32, filter, 0);
16493 } 16490 }
16494 16491
16495 16492
16496 int JSObject::GetOwnElementKeys(FixedArray* storage, PropertyFilter filter) { 16493 int JSObject::GetOwnElementKeys(FixedArray* storage, PropertyFilter filter) {
(...skipping 1987 matching lines...) Expand 10 before | Expand all | Expand 10 after
18484 if ((attr & filter) != 0) continue; 18481 if ((attr & filter) != 0) continue;
18485 storage->set(index++, k); 18482 storage->set(index++, k);
18486 } 18483 }
18487 if (sort_mode == Dictionary::SORTED) { 18484 if (sort_mode == Dictionary::SORTED) {
18488 storage->SortPairs(storage, index); 18485 storage->SortPairs(storage, index);
18489 } 18486 }
18490 DCHECK(storage->length() >= index); 18487 DCHECK(storage->length() >= index);
18491 return index - start_index; 18488 return index - start_index;
18492 } 18489 }
18493 18490
18494
18495 template <typename Derived, typename Shape, typename Key> 18491 template <typename Derived, typename Shape, typename Key>
18496 void Dictionary<Derived, Shape, Key>::CollectKeysTo( 18492 void Dictionary<Derived, Shape, Key>::CollectKeysTo(
18497 Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys, 18493 Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys,
18498 PropertyFilter filter) { 18494 PropertyFilter filter) {
18499 int capacity = dictionary->Capacity(); 18495 int capacity = dictionary->Capacity();
18500 Handle<FixedArray> array = 18496 Handle<FixedArray> array =
18501 keys->isolate()->factory()->NewFixedArray(dictionary->NumberOfElements()); 18497 keys->isolate()->factory()->NewFixedArray(dictionary->NumberOfElements());
18502 int array_size = 0; 18498 int array_size = 0;
18503 18499
18504 { 18500 {
(...skipping 1266 matching lines...) Expand 10 before | Expand all | Expand 10 after
19771 if (cell->value() != *new_value) { 19767 if (cell->value() != *new_value) {
19772 cell->set_value(*new_value); 19768 cell->set_value(*new_value);
19773 Isolate* isolate = cell->GetIsolate(); 19769 Isolate* isolate = cell->GetIsolate();
19774 cell->dependent_code()->DeoptimizeDependentCodeGroup( 19770 cell->dependent_code()->DeoptimizeDependentCodeGroup(
19775 isolate, DependentCode::kPropertyCellChangedGroup); 19771 isolate, DependentCode::kPropertyCellChangedGroup);
19776 } 19772 }
19777 } 19773 }
19778 19774
19779 } // namespace internal 19775 } // namespace internal
19780 } // namespace v8 19776 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698