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