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 |