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 4781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4792 if (!value->IsTheHole()) { | 4792 if (!value->IsTheHole()) { |
4793 PropertyDetails details = PropertyDetails::Empty(); | 4793 PropertyDetails details = PropertyDetails::Empty(); |
4794 dictionary = | 4794 dictionary = |
4795 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); | 4795 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); |
4796 } | 4796 } |
4797 } | 4797 } |
4798 return dictionary; | 4798 return dictionary; |
4799 } | 4799 } |
4800 | 4800 |
4801 | 4801 |
4802 void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) { | |
4803 if (dictionary->requires_slow_elements()) return; | |
4804 dictionary->set_requires_slow_elements(); | |
4805 // TODO(verwaest): Remove this hack. | |
4806 if (map()->is_prototype_map()) { | |
4807 GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); | |
4808 } | |
4809 } | |
4810 | |
4811 | |
4802 Handle<SeededNumberDictionary> JSObject::NormalizeElements( | 4812 Handle<SeededNumberDictionary> JSObject::NormalizeElements( |
4803 Handle<JSObject> object) { | 4813 Handle<JSObject> object) { |
4804 DCHECK(!object->HasExternalArrayElements() && | 4814 DCHECK(!object->HasExternalArrayElements() && |
4805 !object->HasFixedTypedArrayElements()); | 4815 !object->HasFixedTypedArrayElements()); |
4806 Isolate* isolate = object->GetIsolate(); | 4816 Isolate* isolate = object->GetIsolate(); |
4807 | 4817 |
4808 // Find the backing store. | 4818 // Find the backing store. |
4809 Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements())); | 4819 Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements())); |
4810 bool is_arguments = | 4820 bool is_arguments = |
4811 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); | 4821 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5433 THROW_NEW_ERROR( | 5443 THROW_NEW_ERROR( |
5434 isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), | 5444 isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), |
5435 Object); | 5445 Object); |
5436 } | 5446 } |
5437 | 5447 |
5438 // If there are fast elements we normalize. | 5448 // If there are fast elements we normalize. |
5439 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 5449 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
5440 DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements()); | 5450 DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements()); |
5441 | 5451 |
5442 // Make sure that we never go back to fast case. | 5452 // Make sure that we never go back to fast case. |
5443 dictionary->set_requires_slow_elements(); | 5453 object->RequireSlowElements(*dictionary); |
5444 | 5454 |
5445 // Do a map transition, other objects with this map may still | 5455 // Do a map transition, other objects with this map may still |
5446 // be extensible. | 5456 // be extensible. |
5447 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. | 5457 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. |
5448 Handle<Map> new_map = Map::Copy(handle(object->map()), "PreventExtensions"); | 5458 Handle<Map> new_map = Map::Copy(handle(object->map()), "PreventExtensions"); |
5449 | 5459 |
5450 new_map->set_is_extensible(false); | 5460 new_map->set_is_extensible(false); |
5451 JSObject::MigrateToMap(object, new_map); | 5461 JSObject::MigrateToMap(object, new_map); |
5452 DCHECK(!object->map()->is_extensible()); | 5462 DCHECK(!object->map()->is_extensible()); |
5453 | 5463 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5604 } | 5614 } |
5605 } | 5615 } |
5606 } | 5616 } |
5607 | 5617 |
5608 DCHECK(object->map()->has_dictionary_elements()); | 5618 DCHECK(object->map()->has_dictionary_elements()); |
5609 if (!new_element_dictionary.is_null()) { | 5619 if (!new_element_dictionary.is_null()) { |
5610 object->set_elements(*new_element_dictionary); | 5620 object->set_elements(*new_element_dictionary); |
5611 } | 5621 } |
5612 | 5622 |
5613 if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) { | 5623 if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) { |
5614 SeededNumberDictionary* dictionary = object->element_dictionary(); | 5624 Handle<SeededNumberDictionary> dictionary(object->element_dictionary()); |
Igor Sheludko
2015/07/15 11:39:32
We don't need a handle here.
| |
5615 // Make sure we never go back to the fast case | 5625 // Make sure we never go back to the fast case |
5616 dictionary->set_requires_slow_elements(); | 5626 object->RequireSlowElements(*dictionary); |
5617 if (attrs != NONE) { | 5627 if (attrs != NONE) { |
5618 ApplyAttributesToDictionary(dictionary, attrs); | 5628 ApplyAttributesToDictionary(*dictionary, attrs); |
5619 } | 5629 } |
5620 } | 5630 } |
5621 | 5631 |
5622 return object; | 5632 return object; |
5623 } | 5633 } |
5624 | 5634 |
5625 | 5635 |
5626 MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) { | 5636 MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) { |
5627 return PreventExtensionsWithTransition<FROZEN>(object); | 5637 return PreventExtensionsWithTransition<FROZEN>(object); |
5628 } | 5638 } |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6227 bool Map::DictionaryElementsInPrototypeChainOnly() { | 6237 bool Map::DictionaryElementsInPrototypeChainOnly() { |
6228 if (IsDictionaryElementsKind(elements_kind())) { | 6238 if (IsDictionaryElementsKind(elements_kind())) { |
6229 return false; | 6239 return false; |
6230 } | 6240 } |
6231 | 6241 |
6232 for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) { | 6242 for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) { |
6233 // Be conservative, don't walk into proxies. | 6243 // Be conservative, don't walk into proxies. |
6234 if (iter.GetCurrent()->IsJSProxy()) return true; | 6244 if (iter.GetCurrent()->IsJSProxy()) return true; |
6235 // String wrappers have non-configurable, non-writable elements. | 6245 // String wrappers have non-configurable, non-writable elements. |
6236 if (iter.GetCurrent()->IsStringWrapper()) return true; | 6246 if (iter.GetCurrent()->IsStringWrapper()) return true; |
6247 JSObject* current = JSObject::cast(iter.GetCurrent()); | |
6237 | 6248 |
6238 if (IsDictionaryElementsKind( | 6249 if (current->HasDictionaryElements() && |
6239 JSObject::cast(iter.GetCurrent())->map()->elements_kind())) { | 6250 current->element_dictionary()->requires_slow_elements()) { |
6240 return true; | 6251 return true; |
6241 } | 6252 } |
6253 | |
6254 if (current->HasSlowArgumentsElements()) { | |
6255 FixedArray* parameter_map = FixedArray::cast(current->elements()); | |
6256 Object* arguments = parameter_map->get(1); | |
6257 if (SeededNumberDictionary::cast(arguments)->requires_slow_elements()) { | |
6258 return true; | |
6259 } | |
6260 } | |
6242 } | 6261 } |
6243 | 6262 |
6244 return false; | 6263 return false; |
6245 } | 6264 } |
6246 | 6265 |
6247 | 6266 |
6248 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object, | 6267 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object, |
6249 Handle<Name> name, | 6268 Handle<Name> name, |
6250 Handle<Object> getter, | 6269 Handle<Object> getter, |
6251 Handle<Object> setter, | 6270 Handle<Object> setter, |
(...skipping 8411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14663 | 14682 |
14664 | 14683 |
14665 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { | 14684 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { |
14666 DisallowHeapAllocation no_allocation; | 14685 DisallowHeapAllocation no_allocation; |
14667 // If the dictionary requires slow elements an element has already | 14686 // If the dictionary requires slow elements an element has already |
14668 // been added at a high index. | 14687 // been added at a high index. |
14669 if (requires_slow_elements()) return; | 14688 if (requires_slow_elements()) return; |
14670 // Check if this index is high enough that we should require slow | 14689 // Check if this index is high enough that we should require slow |
14671 // elements. | 14690 // elements. |
14672 if (key > kRequiresSlowElementsLimit) { | 14691 if (key > kRequiresSlowElementsLimit) { |
14692 // TODO(verwaest): Remove this hack. | |
14693 GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); | |
14673 set_requires_slow_elements(); | 14694 set_requires_slow_elements(); |
14674 return; | 14695 return; |
14675 } | 14696 } |
14676 // Update max key value. | 14697 // Update max key value. |
14677 Object* max_index_object = get(kMaxNumberKeyIndex); | 14698 Object* max_index_object = get(kMaxNumberKeyIndex); |
14678 if (!max_index_object->IsSmi() || max_number_key() < key) { | 14699 if (!max_index_object->IsSmi() || max_number_key() < key) { |
14679 FixedArray::set(kMaxNumberKeyIndex, | 14700 FixedArray::set(kMaxNumberKeyIndex, |
14680 Smi::FromInt(key << kRequiresSlowElementsTagSize)); | 14701 Smi::FromInt(key << kRequiresSlowElementsTagSize)); |
14681 } | 14702 } |
14682 } | 14703 } |
(...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15930 Handle<Object> new_value) { | 15951 Handle<Object> new_value) { |
15931 if (cell->value() != *new_value) { | 15952 if (cell->value() != *new_value) { |
15932 cell->set_value(*new_value); | 15953 cell->set_value(*new_value); |
15933 Isolate* isolate = cell->GetIsolate(); | 15954 Isolate* isolate = cell->GetIsolate(); |
15934 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 15955 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
15935 isolate, DependentCode::kPropertyCellChangedGroup); | 15956 isolate, DependentCode::kPropertyCellChangedGroup); |
15936 } | 15957 } |
15937 } | 15958 } |
15938 } // namespace internal | 15959 } // namespace internal |
15939 } // namespace v8 | 15960 } // namespace v8 |
OLD | NEW |