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