| 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 |