Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: src/objects.cc

Issue 1228113003: Fix non-standard element handling (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix and expand tests Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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,
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
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
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
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->HasSloppyArgumentsElements()) {
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
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);
Igor Sheludko 2015/07/15 10:53:18 JSObject::RequireSlowElements()?
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
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
OLDNEW
« src/lookup.cc ('K') | « src/objects.h ('k') | test/mjsunit/element-read-only.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698