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

Side by Side Diff: src/objects.cc

Issue 1275363002: [IC] Make SeededNumberDictionary::UpdateMaxNumberKey prototype aware (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 4 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/runtime/runtime-array.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 // 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 <iomanip> 5 #include <iomanip>
6 #include <sstream> 6 #include <sstream>
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
(...skipping 4891 matching lines...) Expand 10 before | Expand all | Expand 10 after
4902 Handle<SeededNumberDictionary> new_elements = 4902 Handle<SeededNumberDictionary> new_elements =
4903 SeededNumberDictionary::New(isolate, 0); 4903 SeededNumberDictionary::New(isolate, 0);
4904 object->set_elements(*new_elements); 4904 object->set_elements(*new_elements);
4905 } else { 4905 } else {
4906 object->set_elements(object->map()->GetInitialElements()); 4906 object->set_elements(object->map()->GetInitialElements());
4907 } 4907 }
4908 } 4908 }
4909 4909
4910 4910
4911 static Handle<SeededNumberDictionary> CopyFastElementsToDictionary( 4911 static Handle<SeededNumberDictionary> CopyFastElementsToDictionary(
4912 Handle<FixedArrayBase> array, 4912 Handle<FixedArrayBase> array, int length,
4913 int length, 4913 Handle<SeededNumberDictionary> dictionary, bool used_as_prototype) {
4914 Handle<SeededNumberDictionary> dictionary) {
4915 Isolate* isolate = array->GetIsolate(); 4914 Isolate* isolate = array->GetIsolate();
4916 Factory* factory = isolate->factory(); 4915 Factory* factory = isolate->factory();
4917 bool has_double_elements = array->IsFixedDoubleArray(); 4916 bool has_double_elements = array->IsFixedDoubleArray();
4918 for (int i = 0; i < length; i++) { 4917 for (int i = 0; i < length; i++) {
4919 Handle<Object> value; 4918 Handle<Object> value;
4920 if (has_double_elements) { 4919 if (has_double_elements) {
4921 Handle<FixedDoubleArray> double_array = 4920 Handle<FixedDoubleArray> double_array =
4922 Handle<FixedDoubleArray>::cast(array); 4921 Handle<FixedDoubleArray>::cast(array);
4923 if (double_array->is_the_hole(i)) { 4922 if (double_array->is_the_hole(i)) {
4924 value = factory->the_hole_value(); 4923 value = factory->the_hole_value();
4925 } else { 4924 } else {
4926 value = factory->NewHeapNumber(double_array->get_scalar(i)); 4925 value = factory->NewHeapNumber(double_array->get_scalar(i));
4927 } 4926 }
4928 } else { 4927 } else {
4929 value = handle(Handle<FixedArray>::cast(array)->get(i), isolate); 4928 value = handle(Handle<FixedArray>::cast(array)->get(i), isolate);
4930 } 4929 }
4931 if (!value->IsTheHole()) { 4930 if (!value->IsTheHole()) {
4932 PropertyDetails details = PropertyDetails::Empty(); 4931 PropertyDetails details = PropertyDetails::Empty();
4933 dictionary = 4932 dictionary = SeededNumberDictionary::AddNumberEntry(
4934 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); 4933 dictionary, i, value, details, used_as_prototype);
4935 } 4934 }
4936 } 4935 }
4937 return dictionary; 4936 return dictionary;
4938 } 4937 }
4939 4938
4940 4939
4941 void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) { 4940 void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) {
4942 if (dictionary->requires_slow_elements()) return; 4941 if (dictionary->requires_slow_elements()) return;
4943 dictionary->set_requires_slow_elements(); 4942 dictionary->set_requires_slow_elements();
4944 // TODO(verwaest): Remove this hack. 4943 // TODO(verwaest): Remove this hack.
(...skipping 10 matching lines...) Expand all
4955 Isolate* isolate = object->GetIsolate(); 4954 Isolate* isolate = object->GetIsolate();
4956 // Ensure that notifications fire if the array or object prototypes are 4955 // Ensure that notifications fire if the array or object prototypes are
4957 // normalizing. 4956 // normalizing.
4958 isolate->UpdateArrayProtectorOnNormalizeElements(object); 4957 isolate->UpdateArrayProtectorOnNormalizeElements(object);
4959 int length = object->IsJSArray() 4958 int length = object->IsJSArray()
4960 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() 4959 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value()
4961 : elements->length(); 4960 : elements->length();
4962 int used = object->GetFastElementsUsage(); 4961 int used = object->GetFastElementsUsage();
4963 Handle<SeededNumberDictionary> dictionary = 4962 Handle<SeededNumberDictionary> dictionary =
4964 SeededNumberDictionary::New(isolate, used); 4963 SeededNumberDictionary::New(isolate, used);
4965 return CopyFastElementsToDictionary(elements, length, dictionary); 4964 return CopyFastElementsToDictionary(elements, length, dictionary,
4965 object->map()->is_prototype_map());
4966 } 4966 }
4967 4967
4968 4968
4969 Handle<SeededNumberDictionary> JSObject::NormalizeElements( 4969 Handle<SeededNumberDictionary> JSObject::NormalizeElements(
4970 Handle<JSObject> object) { 4970 Handle<JSObject> object) {
4971 DCHECK(!object->HasFixedTypedArrayElements()); 4971 DCHECK(!object->HasFixedTypedArrayElements());
4972 Isolate* isolate = object->GetIsolate(); 4972 Isolate* isolate = object->GetIsolate();
4973 4973
4974 // Find the backing store. 4974 // Find the backing store.
4975 Handle<FixedArrayBase> elements(object->elements(), isolate); 4975 Handle<FixedArrayBase> elements(object->elements(), isolate);
(...skipping 8884 matching lines...) Expand 10 before | Expand all | Expand 10 after
13860 uint32_t key = NumberToUint32(k); 13860 uint32_t key = NumberToUint32(k);
13861 if (key < limit) { 13861 if (key < limit) {
13862 if (value->IsUndefined()) { 13862 if (value->IsUndefined()) {
13863 undefs++; 13863 undefs++;
13864 } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { 13864 } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
13865 // Adding an entry with the key beyond smi-range requires 13865 // Adding an entry with the key beyond smi-range requires
13866 // allocation. Bailout. 13866 // allocation. Bailout.
13867 return bailout; 13867 return bailout;
13868 } else { 13868 } else {
13869 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( 13869 Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
13870 new_dict, pos, value, details); 13870 new_dict, pos, value, details, object->map()->is_prototype_map());
13871 DCHECK(result.is_identical_to(new_dict)); 13871 DCHECK(result.is_identical_to(new_dict));
13872 USE(result); 13872 USE(result);
13873 pos++; 13873 pos++;
13874 } 13874 }
13875 } else if (key > static_cast<uint32_t>(Smi::kMaxValue)) { 13875 } else if (key > static_cast<uint32_t>(Smi::kMaxValue)) {
13876 // Adding an entry with the key beyond smi-range requires 13876 // Adding an entry with the key beyond smi-range requires
13877 // allocation. Bailout. 13877 // allocation. Bailout.
13878 return bailout; 13878 return bailout;
13879 } else { 13879 } else {
13880 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( 13880 Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
13881 new_dict, key, value, details); 13881 new_dict, key, value, details, object->map()->is_prototype_map());
13882 DCHECK(result.is_identical_to(new_dict)); 13882 DCHECK(result.is_identical_to(new_dict));
13883 USE(result); 13883 USE(result);
13884 } 13884 }
13885 } 13885 }
13886 13886
13887 uint32_t result = pos; 13887 uint32_t result = pos;
13888 PropertyDetails no_details = PropertyDetails::Empty(); 13888 PropertyDetails no_details = PropertyDetails::Empty();
13889 while (undefs > 0) { 13889 while (undefs > 0) {
13890 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { 13890 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
13891 // Adding an entry with the key beyond smi-range requires 13891 // Adding an entry with the key beyond smi-range requires
13892 // allocation. Bailout. 13892 // allocation. Bailout.
13893 return bailout; 13893 return bailout;
13894 } 13894 }
13895 HandleScope scope(isolate); 13895 HandleScope scope(isolate);
13896 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( 13896 Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
13897 new_dict, pos, isolate->factory()->undefined_value(), no_details); 13897 new_dict, pos, isolate->factory()->undefined_value(), no_details,
13898 object->map()->is_prototype_map());
13898 DCHECK(result.is_identical_to(new_dict)); 13899 DCHECK(result.is_identical_to(new_dict));
13899 USE(result); 13900 USE(result);
13900 pos++; 13901 pos++;
13901 undefs--; 13902 undefs--;
13902 } 13903 }
13903 13904
13904 object->set_elements(*new_dict); 13905 object->set_elements(*new_dict);
13905 13906
13906 AllowHeapAllocation allocate_return_value; 13907 AllowHeapAllocation allocate_return_value;
13907 return isolate->factory()->NewNumberFromUint(result); 13908 return isolate->factory()->NewNumberFromUint(result);
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after
14626 details = details.set_index(index); 14627 details = details.set_index(index);
14627 dictionary->SetNextEnumerationIndex(index + 1); 14628 dictionary->SetNextEnumerationIndex(index + 1);
14628 } 14629 }
14629 dictionary->SetEntry(entry, k, value, details); 14630 dictionary->SetEntry(entry, k, value, details);
14630 DCHECK((dictionary->KeyAt(entry)->IsNumber() || 14631 DCHECK((dictionary->KeyAt(entry)->IsNumber() ||
14631 dictionary->KeyAt(entry)->IsName())); 14632 dictionary->KeyAt(entry)->IsName()));
14632 dictionary->ElementAdded(); 14633 dictionary->ElementAdded();
14633 } 14634 }
14634 14635
14635 14636
14636 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { 14637 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key,
14638 bool used_as_prototype) {
14637 DisallowHeapAllocation no_allocation; 14639 DisallowHeapAllocation no_allocation;
14638 // If the dictionary requires slow elements an element has already 14640 // If the dictionary requires slow elements an element has already
14639 // been added at a high index. 14641 // been added at a high index.
14640 if (requires_slow_elements()) return; 14642 if (requires_slow_elements()) return;
14641 // Check if this index is high enough that we should require slow 14643 // Check if this index is high enough that we should require slow
14642 // elements. 14644 // elements.
14643 if (key > kRequiresSlowElementsLimit) { 14645 if (key > kRequiresSlowElementsLimit) {
14644 // TODO(verwaest): Remove this hack. 14646 if (used_as_prototype) {
14645 GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); 14647 // TODO(verwaest): Remove this hack.
Yang 2015/08/07 21:28:50 Indeed!
14648 GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC);
14649 }
14646 set_requires_slow_elements(); 14650 set_requires_slow_elements();
14647 return; 14651 return;
14648 } 14652 }
14649 // Update max key value. 14653 // Update max key value.
14650 Object* max_index_object = get(kMaxNumberKeyIndex); 14654 Object* max_index_object = get(kMaxNumberKeyIndex);
14651 if (!max_index_object->IsSmi() || max_number_key() < key) { 14655 if (!max_index_object->IsSmi() || max_number_key() < key) {
14652 FixedArray::set(kMaxNumberKeyIndex, 14656 FixedArray::set(kMaxNumberKeyIndex,
14653 Smi::FromInt(key << kRequiresSlowElementsTagSize)); 14657 Smi::FromInt(key << kRequiresSlowElementsTagSize));
14654 } 14658 }
14655 } 14659 }
14656 14660
14657 14661
14658 Handle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry( 14662 Handle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry(
14659 Handle<SeededNumberDictionary> dictionary, 14663 Handle<SeededNumberDictionary> dictionary, uint32_t key,
14660 uint32_t key, 14664 Handle<Object> value, PropertyDetails details, bool used_as_prototype) {
14661 Handle<Object> value, 14665 dictionary->UpdateMaxNumberKey(key, used_as_prototype);
14662 PropertyDetails details) {
14663 dictionary->UpdateMaxNumberKey(key);
14664 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound); 14666 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
14665 return Add(dictionary, key, value, details); 14667 return Add(dictionary, key, value, details);
14666 } 14668 }
14667 14669
14668 14670
14669 Handle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry( 14671 Handle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry(
14670 Handle<UnseededNumberDictionary> dictionary, 14672 Handle<UnseededNumberDictionary> dictionary,
14671 uint32_t key, 14673 uint32_t key,
14672 Handle<Object> value) { 14674 Handle<Object> value) {
14673 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound); 14675 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
14674 return Add(dictionary, key, value, PropertyDetails::Empty()); 14676 return Add(dictionary, key, value, PropertyDetails::Empty());
14675 } 14677 }
14676 14678
14677 14679
14678 Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut( 14680 Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut(
14679 Handle<SeededNumberDictionary> dictionary, 14681 Handle<SeededNumberDictionary> dictionary, uint32_t key,
14680 uint32_t key, 14682 Handle<Object> value, bool used_as_prototype) {
14681 Handle<Object> value) { 14683 dictionary->UpdateMaxNumberKey(key, used_as_prototype);
14682 dictionary->UpdateMaxNumberKey(key);
14683 return AtPut(dictionary, key, value); 14684 return AtPut(dictionary, key, value);
14684 } 14685 }
14685 14686
14686 14687
14687 Handle<UnseededNumberDictionary> UnseededNumberDictionary::AtNumberPut( 14688 Handle<UnseededNumberDictionary> UnseededNumberDictionary::AtNumberPut(
14688 Handle<UnseededNumberDictionary> dictionary, 14689 Handle<UnseededNumberDictionary> dictionary,
14689 uint32_t key, 14690 uint32_t key,
14690 Handle<Object> value) { 14691 Handle<Object> value) {
14691 return AtPut(dictionary, key, value); 14692 return AtPut(dictionary, key, value);
14692 } 14693 }
14693 14694
14694 14695
14695 Handle<SeededNumberDictionary> SeededNumberDictionary::Set( 14696 Handle<SeededNumberDictionary> SeededNumberDictionary::Set(
14696 Handle<SeededNumberDictionary> dictionary, 14697 Handle<SeededNumberDictionary> dictionary, uint32_t key,
14697 uint32_t key, 14698 Handle<Object> value, PropertyDetails details, bool used_as_prototype) {
14698 Handle<Object> value,
14699 PropertyDetails details) {
14700 int entry = dictionary->FindEntry(key); 14699 int entry = dictionary->FindEntry(key);
14701 if (entry == kNotFound) { 14700 if (entry == kNotFound) {
14702 return AddNumberEntry(dictionary, key, value, details); 14701 return AddNumberEntry(dictionary, key, value, details, used_as_prototype);
14703 } 14702 }
14704 // Preserve enumeration index. 14703 // Preserve enumeration index.
14705 details = details.set_index(dictionary->DetailsAt(entry).dictionary_index()); 14704 details = details.set_index(dictionary->DetailsAt(entry).dictionary_index());
14706 Handle<Object> object_key = 14705 Handle<Object> object_key =
14707 SeededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key); 14706 SeededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key);
14708 dictionary->SetEntry(entry, object_key, value, details); 14707 dictionary->SetEntry(entry, object_key, value, details);
14709 return dictionary; 14708 return dictionary;
14710 } 14709 }
14711 14710
14712 14711
(...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after
15869 if (cell->value() != *new_value) { 15868 if (cell->value() != *new_value) {
15870 cell->set_value(*new_value); 15869 cell->set_value(*new_value);
15871 Isolate* isolate = cell->GetIsolate(); 15870 Isolate* isolate = cell->GetIsolate();
15872 cell->dependent_code()->DeoptimizeDependentCodeGroup( 15871 cell->dependent_code()->DeoptimizeDependentCodeGroup(
15873 isolate, DependentCode::kPropertyCellChangedGroup); 15872 isolate, DependentCode::kPropertyCellChangedGroup);
15874 } 15873 }
15875 } 15874 }
15876 15875
15877 } // namespace internal 15876 } // namespace internal
15878 } // namespace v8 15877 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-array.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698