| OLD | NEW |
| 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 4884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4895 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); | 4895 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); |
| 4896 if (is_arguments) { | 4896 if (is_arguments) { |
| 4897 array = handle(FixedArrayBase::cast( | 4897 array = handle(FixedArrayBase::cast( |
| 4898 Handle<FixedArray>::cast(array)->get(1))); | 4898 Handle<FixedArray>::cast(array)->get(1))); |
| 4899 } | 4899 } |
| 4900 if (array->IsDictionary()) return Handle<SeededNumberDictionary>::cast(array); | 4900 if (array->IsDictionary()) return Handle<SeededNumberDictionary>::cast(array); |
| 4901 | 4901 |
| 4902 DCHECK(object->HasFastSmiOrObjectElements() || | 4902 DCHECK(object->HasFastSmiOrObjectElements() || |
| 4903 object->HasFastDoubleElements() || | 4903 object->HasFastDoubleElements() || |
| 4904 object->HasFastArgumentsElements()); | 4904 object->HasFastArgumentsElements()); |
| 4905 | |
| 4906 // Ensure that notifications fire if the array or object prototypes are | |
| 4907 // normalizing. | |
| 4908 isolate->UpdateArrayProtectorOnNormalizeElements(object); | |
| 4909 | |
| 4910 // Compute the effective length and allocate a new backing store. | 4905 // Compute the effective length and allocate a new backing store. |
| 4911 int length = object->IsJSArray() | 4906 int length = object->IsJSArray() |
| 4912 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() | 4907 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() |
| 4913 : array->length(); | 4908 : array->length(); |
| 4914 int old_capacity = 0; | 4909 int old_capacity = 0; |
| 4915 int used_elements = 0; | 4910 int used_elements = 0; |
| 4916 object->GetElementsCapacityAndUsage(&old_capacity, &used_elements); | 4911 object->GetElementsCapacityAndUsage(&old_capacity, &used_elements); |
| 4917 Handle<SeededNumberDictionary> dictionary = | 4912 Handle<SeededNumberDictionary> dictionary = |
| 4918 SeededNumberDictionary::New(isolate, used_elements); | 4913 SeededNumberDictionary::New(isolate, used_elements); |
| 4919 | 4914 |
| (...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5754 object->HasFixedTypedArrayElements()) { | 5749 object->HasFixedTypedArrayElements()) { |
| 5755 THROW_NEW_ERROR(isolate, | 5750 THROW_NEW_ERROR(isolate, |
| 5756 NewTypeError("cant_prevent_ext_external_array_elements", | 5751 NewTypeError("cant_prevent_ext_external_array_elements", |
| 5757 HandleVector(&object, 1)), | 5752 HandleVector(&object, 1)), |
| 5758 Object); | 5753 Object); |
| 5759 } | 5754 } |
| 5760 | 5755 |
| 5761 Handle<SeededNumberDictionary> new_element_dictionary; | 5756 Handle<SeededNumberDictionary> new_element_dictionary; |
| 5762 if (!object->elements()->IsDictionary()) { | 5757 if (!object->elements()->IsDictionary()) { |
| 5763 new_element_dictionary = GetNormalizedElementDictionary(object); | 5758 new_element_dictionary = GetNormalizedElementDictionary(object); |
| 5764 isolate->UpdateArrayProtectorOnNormalizeElements(object); | |
| 5765 } | 5759 } |
| 5766 | 5760 |
| 5767 Handle<Symbol> transition_marker; | 5761 Handle<Symbol> transition_marker; |
| 5768 if (attrs == NONE) { | 5762 if (attrs == NONE) { |
| 5769 transition_marker = isolate->factory()->nonextensible_symbol(); | 5763 transition_marker = isolate->factory()->nonextensible_symbol(); |
| 5770 } else if (attrs == SEALED) { | 5764 } else if (attrs == SEALED) { |
| 5771 transition_marker = isolate->factory()->sealed_symbol(); | 5765 transition_marker = isolate->factory()->sealed_symbol(); |
| 5772 } else { | 5766 } else { |
| 5773 DCHECK(attrs == FROZEN); | 5767 DCHECK(attrs == FROZEN); |
| 5774 transition_marker = isolate->factory()->frozen_symbol(); | 5768 transition_marker = isolate->factory()->frozen_symbol(); |
| (...skipping 6639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12414 | 12408 |
| 12415 | 12409 |
| 12416 const char* DependentCode::DependencyGroupName(DependencyGroup group) { | 12410 const char* DependentCode::DependencyGroupName(DependencyGroup group) { |
| 12417 switch (group) { | 12411 switch (group) { |
| 12418 case kWeakCodeGroup: | 12412 case kWeakCodeGroup: |
| 12419 return "weak-code"; | 12413 return "weak-code"; |
| 12420 case kTransitionGroup: | 12414 case kTransitionGroup: |
| 12421 return "transition"; | 12415 return "transition"; |
| 12422 case kPrototypeCheckGroup: | 12416 case kPrototypeCheckGroup: |
| 12423 return "prototype-check"; | 12417 return "prototype-check"; |
| 12418 case kElementsCantBeAddedGroup: |
| 12419 return "elements-cant-be-added"; |
| 12424 case kPropertyCellChangedGroup: | 12420 case kPropertyCellChangedGroup: |
| 12425 return "property-cell-changed"; | 12421 return "property-cell-changed"; |
| 12426 case kFieldTypeGroup: | 12422 case kFieldTypeGroup: |
| 12427 return "field-type"; | 12423 return "field-type"; |
| 12428 case kInitialMapChangedGroup: | 12424 case kInitialMapChangedGroup: |
| 12429 return "initial-map-changed"; | 12425 return "initial-map-changed"; |
| 12430 case kAllocationSiteTenuringChangedGroup: | 12426 case kAllocationSiteTenuringChangedGroup: |
| 12431 return "allocation-site-tenuring-changed"; | 12427 return "allocation-site-tenuring-changed"; |
| 12432 case kAllocationSiteTransitionChangedGroup: | 12428 case kAllocationSiteTransitionChangedGroup: |
| 12433 return "allocation-site-transition-changed"; | 12429 return "allocation-site-transition-changed"; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12512 } | 12508 } |
| 12513 } | 12509 } |
| 12514 } | 12510 } |
| 12515 | 12511 |
| 12516 // Set the new prototype of the object. | 12512 // Set the new prototype of the object. |
| 12517 Handle<Map> map(real_receiver->map()); | 12513 Handle<Map> map(real_receiver->map()); |
| 12518 | 12514 |
| 12519 // Nothing to do if prototype is already set. | 12515 // Nothing to do if prototype is already set. |
| 12520 if (map->prototype() == *value) return value; | 12516 if (map->prototype() == *value) return value; |
| 12521 | 12517 |
| 12522 isolate->UpdateArrayProtectorOnSetPrototype(real_receiver); | |
| 12523 | |
| 12524 PrototypeOptimizationMode mode = | 12518 PrototypeOptimizationMode mode = |
| 12525 from_javascript ? REGULAR_PROTOTYPE : FAST_PROTOTYPE; | 12519 from_javascript ? REGULAR_PROTOTYPE : FAST_PROTOTYPE; |
| 12526 Handle<Map> new_map = Map::TransitionToPrototype(map, value, mode); | 12520 Handle<Map> new_map = Map::TransitionToPrototype(map, value, mode); |
| 12527 DCHECK(new_map->prototype() == *value); | 12521 DCHECK(new_map->prototype() == *value); |
| 12528 JSObject::MigrateToMap(real_receiver, new_map); | 12522 JSObject::MigrateToMap(real_receiver, new_map); |
| 12529 | 12523 |
| 12530 if (from_javascript && !dictionary_elements_in_chain && | 12524 if (from_javascript && !dictionary_elements_in_chain && |
| 12531 new_map->DictionaryElementsInPrototypeChainOnly()) { | 12525 new_map->DictionaryElementsInPrototypeChainOnly()) { |
| 12532 // If the prototype chain didn't previously have element callbacks, then | 12526 // If the prototype chain didn't previously have element callbacks, then |
| 12533 // KeyedStoreICs need to be cleared to ensure any that involve this | 12527 // KeyedStoreICs need to be cleared to ensure any that involve this |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12734 LanguageMode language_mode, | 12728 LanguageMode language_mode, |
| 12735 bool check_prototype) { | 12729 bool check_prototype) { |
| 12736 DCHECK(object->HasFastSmiOrObjectElements() || | 12730 DCHECK(object->HasFastSmiOrObjectElements() || |
| 12737 object->HasFastArgumentsElements()); | 12731 object->HasFastArgumentsElements()); |
| 12738 | 12732 |
| 12739 Isolate* isolate = object->GetIsolate(); | 12733 Isolate* isolate = object->GetIsolate(); |
| 12740 | 12734 |
| 12741 // Array optimizations rely on the prototype lookups of Array objects always | 12735 // Array optimizations rely on the prototype lookups of Array objects always |
| 12742 // returning undefined. If there is a store to the initial prototype object, | 12736 // returning undefined. If there is a store to the initial prototype object, |
| 12743 // make sure all of these optimizations are invalidated. | 12737 // make sure all of these optimizations are invalidated. |
| 12744 isolate->UpdateArrayProtectorOnSetElement(object); | 12738 if (isolate->is_initial_object_prototype(*object) || |
| 12739 isolate->is_initial_array_prototype(*object)) { |
| 12740 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate, |
| 12741 DependentCode::kElementsCantBeAddedGroup); |
| 12742 } |
| 12745 | 12743 |
| 12746 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); | 12744 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); |
| 12747 if (backing_store->map() == | 12745 if (backing_store->map() == |
| 12748 isolate->heap()->sloppy_arguments_elements_map()) { | 12746 isolate->heap()->sloppy_arguments_elements_map()) { |
| 12749 backing_store = handle(FixedArray::cast(backing_store->get(1))); | 12747 backing_store = handle(FixedArray::cast(backing_store->get(1))); |
| 12750 } else { | 12748 } else { |
| 12751 backing_store = EnsureWritableFastElements(object); | 12749 backing_store = EnsureWritableFastElements(object); |
| 12752 } | 12750 } |
| 12753 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); | 12751 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); |
| 12754 | 12752 |
| (...skipping 4337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17092 // Deopt when transitioning from a constant type. | 17090 // Deopt when transitioning from a constant type. |
| 17093 if (!invalidate && old_type == PropertyCellType::kConstant && | 17091 if (!invalidate && old_type == PropertyCellType::kConstant && |
| 17094 new_type != PropertyCellType::kConstant) { | 17092 new_type != PropertyCellType::kConstant) { |
| 17095 auto isolate = dictionary->GetIsolate(); | 17093 auto isolate = dictionary->GetIsolate(); |
| 17096 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17094 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17097 isolate, DependentCode::kPropertyCellChangedGroup); | 17095 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17098 } | 17096 } |
| 17099 return value; | 17097 return value; |
| 17100 } | 17098 } |
| 17101 | 17099 |
| 17102 | |
| 17103 // static | |
| 17104 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, | |
| 17105 Handle<Object> new_value) { | |
| 17106 if (cell->value() != *new_value) { | |
| 17107 cell->set_value(*new_value); | |
| 17108 Isolate* isolate = cell->GetIsolate(); | |
| 17109 cell->dependent_code()->DeoptimizeDependentCodeGroup( | |
| 17110 isolate, DependentCode::kPropertyCellChangedGroup); | |
| 17111 } | |
| 17112 } | |
| 17113 } } // namespace v8::internal | 17100 } } // namespace v8::internal |
| OLD | NEW |