OLD | NEW |
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 5674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5685 if (object->map()->has_dictionary_elements()) { | 5685 if (object->map()->has_dictionary_elements()) { |
5686 Handle<SeededNumberDictionary> new_elements = | 5686 Handle<SeededNumberDictionary> new_elements = |
5687 SeededNumberDictionary::New(isolate, 0); | 5687 SeededNumberDictionary::New(isolate, 0); |
5688 object->set_elements(*new_elements); | 5688 object->set_elements(*new_elements); |
5689 } else { | 5689 } else { |
5690 object->set_elements(object->map()->GetInitialElements()); | 5690 object->set_elements(object->map()->GetInitialElements()); |
5691 } | 5691 } |
5692 } | 5692 } |
5693 | 5693 |
5694 | 5694 |
5695 static Handle<SeededNumberDictionary> CopyFastElementsToDictionary( | |
5696 Handle<FixedArrayBase> array, int length, | |
5697 Handle<SeededNumberDictionary> dictionary, bool used_as_prototype) { | |
5698 Isolate* isolate = array->GetIsolate(); | |
5699 Factory* factory = isolate->factory(); | |
5700 bool has_double_elements = array->IsFixedDoubleArray(); | |
5701 for (int i = 0; i < length; i++) { | |
5702 Handle<Object> value; | |
5703 if (has_double_elements) { | |
5704 Handle<FixedDoubleArray> double_array = | |
5705 Handle<FixedDoubleArray>::cast(array); | |
5706 if (double_array->is_the_hole(i)) { | |
5707 value = factory->the_hole_value(); | |
5708 } else { | |
5709 value = factory->NewHeapNumber(double_array->get_scalar(i)); | |
5710 } | |
5711 } else { | |
5712 value = handle(Handle<FixedArray>::cast(array)->get(i), isolate); | |
5713 } | |
5714 if (!value->IsTheHole()) { | |
5715 PropertyDetails details = PropertyDetails::Empty(); | |
5716 dictionary = SeededNumberDictionary::AddNumberEntry( | |
5717 dictionary, i, value, details, used_as_prototype); | |
5718 } | |
5719 } | |
5720 return dictionary; | |
5721 } | |
5722 | |
5723 | |
5724 void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) { | 5695 void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) { |
5725 if (dictionary->requires_slow_elements()) return; | 5696 if (dictionary->requires_slow_elements()) return; |
5726 dictionary->set_requires_slow_elements(); | 5697 dictionary->set_requires_slow_elements(); |
5727 // TODO(verwaest): Remove this hack. | 5698 // TODO(verwaest): Remove this hack. |
5728 if (map()->is_prototype_map()) { | 5699 if (map()->is_prototype_map()) { |
5729 TypeFeedbackVector::ClearAllKeyedStoreICs(GetIsolate()); | 5700 TypeFeedbackVector::ClearAllKeyedStoreICs(GetIsolate()); |
5730 } | 5701 } |
5731 } | 5702 } |
5732 | 5703 |
5733 | 5704 |
5734 Handle<SeededNumberDictionary> JSObject::GetNormalizedElementDictionary( | |
5735 Handle<JSObject> object, Handle<FixedArrayBase> elements) { | |
5736 DCHECK(!object->HasDictionaryElements()); | |
5737 DCHECK(!object->HasSlowArgumentsElements()); | |
5738 Isolate* isolate = object->GetIsolate(); | |
5739 // Ensure that notifications fire if the array or object prototypes are | |
5740 // normalizing. | |
5741 isolate->UpdateArrayProtectorOnNormalizeElements(object); | |
5742 int length = object->IsJSArray() | |
5743 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() | |
5744 : elements->length(); | |
5745 int used = object->GetFastElementsUsage(); | |
5746 Handle<SeededNumberDictionary> dictionary = | |
5747 SeededNumberDictionary::New(isolate, used); | |
5748 return CopyFastElementsToDictionary(elements, length, dictionary, | |
5749 object->map()->is_prototype_map()); | |
5750 } | |
5751 | |
5752 | |
5753 Handle<SeededNumberDictionary> JSObject::NormalizeElements( | 5705 Handle<SeededNumberDictionary> JSObject::NormalizeElements( |
5754 Handle<JSObject> object) { | 5706 Handle<JSObject> object) { |
5755 DCHECK(!object->HasFixedTypedArrayElements()); | 5707 DCHECK(!object->HasFixedTypedArrayElements()); |
5756 Isolate* isolate = object->GetIsolate(); | 5708 Isolate* isolate = object->GetIsolate(); |
| 5709 bool is_arguments = object->HasSloppyArgumentsElements(); |
| 5710 { |
| 5711 DisallowHeapAllocation no_gc; |
| 5712 FixedArrayBase* elements = object->elements(); |
5757 | 5713 |
5758 // Find the backing store. | 5714 if (is_arguments) { |
5759 Handle<FixedArrayBase> elements(object->elements(), isolate); | 5715 FixedArray* parameter_map = FixedArray::cast(elements); |
5760 bool is_arguments = object->HasSloppyArgumentsElements(); | 5716 elements = FixedArrayBase::cast(parameter_map->get(1)); |
5761 if (is_arguments) { | 5717 } |
5762 FixedArray* parameter_map = FixedArray::cast(*elements); | |
5763 elements = handle(FixedArrayBase::cast(parameter_map->get(1)), isolate); | |
5764 } | |
5765 | 5718 |
5766 if (elements->IsDictionary()) { | 5719 if (elements->IsDictionary()) { |
5767 return Handle<SeededNumberDictionary>::cast(elements); | 5720 return handle(SeededNumberDictionary::cast(elements), isolate); |
| 5721 } |
5768 } | 5722 } |
5769 | 5723 |
5770 DCHECK(object->HasFastSmiOrObjectElements() || | 5724 DCHECK(object->HasFastSmiOrObjectElements() || |
5771 object->HasFastDoubleElements() || | 5725 object->HasFastDoubleElements() || |
5772 object->HasFastArgumentsElements() || | 5726 object->HasFastArgumentsElements() || |
5773 object->HasFastStringWrapperElements()); | 5727 object->HasFastStringWrapperElements()); |
5774 | 5728 |
5775 Handle<SeededNumberDictionary> dictionary = | 5729 Handle<SeededNumberDictionary> dictionary = |
5776 GetNormalizedElementDictionary(object, elements); | 5730 object->GetElementsAccessor()->Normalize(object); |
5777 | 5731 |
5778 // Switch to using the dictionary as the backing storage for elements. | 5732 // Switch to using the dictionary as the backing storage for elements. |
5779 ElementsKind target_kind = is_arguments | 5733 ElementsKind target_kind = is_arguments |
5780 ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS | 5734 ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS |
5781 : object->HasFastStringWrapperElements() | 5735 : object->HasFastStringWrapperElements() |
5782 ? SLOW_STRING_WRAPPER_ELEMENTS | 5736 ? SLOW_STRING_WRAPPER_ELEMENTS |
5783 : DICTIONARY_ELEMENTS; | 5737 : DICTIONARY_ELEMENTS; |
5784 Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind); | 5738 Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind); |
5785 // Set the new map first to satify the elements type assert in set_elements(). | 5739 // Set the new map first to satify the elements type assert in set_elements(). |
5786 JSObject::MigrateToMap(object, new_map); | 5740 JSObject::MigrateToMap(object, new_map); |
(...skipping 1966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7753 Handle<SeededNumberDictionary> new_element_dictionary; | 7707 Handle<SeededNumberDictionary> new_element_dictionary; |
7754 if (!object->HasFixedTypedArrayElements() && | 7708 if (!object->HasFixedTypedArrayElements() && |
7755 !object->HasDictionaryElements() && | 7709 !object->HasDictionaryElements() && |
7756 !object->HasSlowStringWrapperElements()) { | 7710 !object->HasSlowStringWrapperElements()) { |
7757 int length = | 7711 int length = |
7758 object->IsJSArray() | 7712 object->IsJSArray() |
7759 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() | 7713 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() |
7760 : object->elements()->length(); | 7714 : object->elements()->length(); |
7761 new_element_dictionary = | 7715 new_element_dictionary = |
7762 length == 0 ? isolate->factory()->empty_slow_element_dictionary() | 7716 length == 0 ? isolate->factory()->empty_slow_element_dictionary() |
7763 : GetNormalizedElementDictionary( | 7717 : object->GetElementsAccessor()->Normalize(object); |
7764 object, handle(object->elements())); | |
7765 } | 7718 } |
7766 | 7719 |
7767 Handle<Symbol> transition_marker; | 7720 Handle<Symbol> transition_marker; |
7768 if (attrs == NONE) { | 7721 if (attrs == NONE) { |
7769 transition_marker = isolate->factory()->nonextensible_symbol(); | 7722 transition_marker = isolate->factory()->nonextensible_symbol(); |
7770 } else if (attrs == SEALED) { | 7723 } else if (attrs == SEALED) { |
7771 transition_marker = isolate->factory()->sealed_symbol(); | 7724 transition_marker = isolate->factory()->sealed_symbol(); |
7772 } else { | 7725 } else { |
7773 DCHECK(attrs == FROZEN); | 7726 DCHECK(attrs == FROZEN); |
7774 transition_marker = isolate->factory()->frozen_symbol(); | 7727 transition_marker = isolate->factory()->frozen_symbol(); |
(...skipping 11997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19772 if (cell->value() != *new_value) { | 19725 if (cell->value() != *new_value) { |
19773 cell->set_value(*new_value); | 19726 cell->set_value(*new_value); |
19774 Isolate* isolate = cell->GetIsolate(); | 19727 Isolate* isolate = cell->GetIsolate(); |
19775 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19728 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
19776 isolate, DependentCode::kPropertyCellChangedGroup); | 19729 isolate, DependentCode::kPropertyCellChangedGroup); |
19777 } | 19730 } |
19778 } | 19731 } |
19779 | 19732 |
19780 } // namespace internal | 19733 } // namespace internal |
19781 } // namespace v8 | 19734 } // namespace v8 |
OLD | NEW |