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

Side by Side Diff: src/objects.cc

Issue 2127583002: [runtime] Better encapsulation of dictionary objects handling in lookup iterator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fixes Created 4 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
« no previous file with comments | « src/objects.h ('k') | src/objects-printer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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 "src/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after
1599 Handle<Name> name, 1599 Handle<Name> name,
1600 Handle<Object> value, 1600 Handle<Object> value,
1601 PropertyDetails details) { 1601 PropertyDetails details) {
1602 DCHECK(!object->HasFastProperties()); 1602 DCHECK(!object->HasFastProperties());
1603 if (!name->IsUniqueName()) { 1603 if (!name->IsUniqueName()) {
1604 name = object->GetIsolate()->factory()->InternalizeString( 1604 name = object->GetIsolate()->factory()->InternalizeString(
1605 Handle<String>::cast(name)); 1605 Handle<String>::cast(name));
1606 } 1606 }
1607 1607
1608 if (object->IsJSGlobalObject()) { 1608 if (object->IsJSGlobalObject()) {
1609 Handle<GlobalDictionary> property_dictionary(object->global_dictionary()); 1609 Handle<GlobalDictionary> dictionary(object->global_dictionary());
1610 1610
1611 int entry = property_dictionary->FindEntry(name); 1611 int entry = dictionary->FindEntry(name);
1612 if (entry == GlobalDictionary::kNotFound) { 1612 if (entry == GlobalDictionary::kNotFound) {
1613 Isolate* isolate = object->GetIsolate(); 1613 Isolate* isolate = object->GetIsolate();
1614 auto cell = isolate->factory()->NewPropertyCell(); 1614 auto cell = isolate->factory()->NewPropertyCell();
1615 cell->set_value(*value); 1615 cell->set_value(*value);
1616 auto cell_type = value->IsUndefined(isolate) 1616 auto cell_type = value->IsUndefined(isolate)
1617 ? PropertyCellType::kUndefined 1617 ? PropertyCellType::kUndefined
1618 : PropertyCellType::kConstant; 1618 : PropertyCellType::kConstant;
1619 details = details.set_cell_type(cell_type); 1619 details = details.set_cell_type(cell_type);
1620 value = cell; 1620 value = cell;
1621 property_dictionary = 1621 dictionary = GlobalDictionary::Add(dictionary, name, value, details);
1622 GlobalDictionary::Add(property_dictionary, name, value, details); 1622 object->set_properties(*dictionary);
1623 object->set_properties(*property_dictionary);
1624 } else { 1623 } else {
1625 PropertyCell::UpdateCell(property_dictionary, entry, value, details); 1624 Handle<PropertyCell> cell =
1625 PropertyCell::PrepareForValue(dictionary, entry, value, details);
1626 cell->set_value(*value);
1626 } 1627 }
1627 } else { 1628 } else {
1628 Handle<NameDictionary> property_dictionary(object->property_dictionary()); 1629 Handle<NameDictionary> dictionary(object->property_dictionary());
1629 1630
1630 int entry = property_dictionary->FindEntry(name); 1631 int entry = dictionary->FindEntry(name);
1631 if (entry == NameDictionary::kNotFound) { 1632 if (entry == NameDictionary::kNotFound) {
1632 property_dictionary = 1633 dictionary = NameDictionary::Add(dictionary, name, value, details);
1633 NameDictionary::Add(property_dictionary, name, value, details); 1634 object->set_properties(*dictionary);
1634 object->set_properties(*property_dictionary);
1635 } else { 1635 } else {
1636 PropertyDetails original_details = property_dictionary->DetailsAt(entry); 1636 PropertyDetails original_details = dictionary->DetailsAt(entry);
1637 int enumeration_index = original_details.dictionary_index(); 1637 int enumeration_index = original_details.dictionary_index();
1638 DCHECK(enumeration_index > 0); 1638 DCHECK(enumeration_index > 0);
1639 details = details.set_index(enumeration_index); 1639 details = details.set_index(enumeration_index);
1640 property_dictionary->SetEntry(entry, name, value, details); 1640 dictionary->SetEntry(entry, name, value, details);
1641 } 1641 }
1642 } 1642 }
1643 } 1643 }
1644 1644
1645 // static 1645 // static
1646 Maybe<bool> JSReceiver::HasInPrototypeChain(Isolate* isolate, 1646 Maybe<bool> JSReceiver::HasInPrototypeChain(Isolate* isolate,
1647 Handle<JSReceiver> object, 1647 Handle<JSReceiver> object,
1648 Handle<Object> proto) { 1648 Handle<Object> proto) {
1649 PrototypeIterator iter(isolate, object, kStartAtReceiver); 1649 PrototypeIterator iter(isolate, object, kStartAtReceiver);
1650 while (true) { 1650 while (true) {
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after
2841 // Ensure the descriptor array does not get too big. 2841 // Ensure the descriptor array does not get too big.
2842 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { 2842 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) {
2843 return MaybeHandle<Map>(); 2843 return MaybeHandle<Map>();
2844 } 2844 }
2845 2845
2846 // Allocate new instance descriptors with (name, constant) added. 2846 // Allocate new instance descriptors with (name, constant) added.
2847 DataConstantDescriptor new_constant_desc(name, constant, attributes); 2847 DataConstantDescriptor new_constant_desc(name, constant, attributes);
2848 return Map::CopyAddDescriptor(map, &new_constant_desc, flag); 2848 return Map::CopyAddDescriptor(map, &new_constant_desc, flag);
2849 } 2849 }
2850 2850
2851
2852 void JSObject::AddSlowProperty(Handle<JSObject> object,
2853 Handle<Name> name,
2854 Handle<Object> value,
2855 PropertyAttributes attributes) {
2856 DCHECK(!object->HasFastProperties());
2857 Isolate* isolate = object->GetIsolate();
2858 if (object->IsJSGlobalObject()) {
2859 Handle<GlobalDictionary> dict(object->global_dictionary());
2860 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
2861 int entry = dict->FindEntry(name);
2862 // If there's a cell there, just invalidate and set the property.
2863 if (entry != GlobalDictionary::kNotFound) {
2864 PropertyCell::UpdateCell(dict, entry, value, details);
2865 // TODO(ishell): move this to UpdateCell.
2866 // Need to adjust the details.
2867 int index = dict->NextEnumerationIndex();
2868 dict->SetNextEnumerationIndex(index + 1);
2869 PropertyCell* cell = PropertyCell::cast(dict->ValueAt(entry));
2870 details = cell->property_details().set_index(index);
2871 cell->set_property_details(details);
2872
2873 } else {
2874 auto cell = isolate->factory()->NewPropertyCell();
2875 cell->set_value(*value);
2876 auto cell_type = value->IsUndefined(isolate)
2877 ? PropertyCellType::kUndefined
2878 : PropertyCellType::kConstant;
2879 details = details.set_cell_type(cell_type);
2880 value = cell;
2881
2882 Handle<GlobalDictionary> result =
2883 GlobalDictionary::Add(dict, name, value, details);
2884 if (*dict != *result) object->set_properties(*result);
2885 }
2886 } else {
2887 Handle<NameDictionary> dict(object->property_dictionary());
2888 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
2889 Handle<NameDictionary> result =
2890 NameDictionary::Add(dict, name, value, details);
2891 if (*dict != *result) object->set_properties(*result);
2892 }
2893 }
2894
2895
2896 const char* Representation::Mnemonic() const { 2851 const char* Representation::Mnemonic() const {
2897 switch (kind_) { 2852 switch (kind_) {
2898 case kNone: return "v"; 2853 case kNone: return "v";
2899 case kTagged: return "t"; 2854 case kTagged: return "t";
2900 case kSmi: return "s"; 2855 case kSmi: return "s";
2901 case kDouble: return "d"; 2856 case kDouble: return "d";
2902 case kInteger32: return "i"; 2857 case kInteger32: return "i";
2903 case kHeapObject: return "h"; 2858 case kHeapObject: return "h";
2904 case kExternal: return "x"; 2859 case kExternal: return "x";
2905 default: 2860 default:
(...skipping 1830 matching lines...) Expand 10 before | Expand all | Expand 10 after
4736 return result; 4691 return result;
4737 } else { 4692 } else {
4738 it->UpdateProtector(); 4693 it->UpdateProtector();
4739 // Migrate to the most up-to-date map that will be able to store |value| 4694 // Migrate to the most up-to-date map that will be able to store |value|
4740 // under it->name() with |attributes|. 4695 // under it->name() with |attributes|.
4741 it->PrepareTransitionToDataProperty(receiver, value, attributes, 4696 it->PrepareTransitionToDataProperty(receiver, value, attributes,
4742 store_mode); 4697 store_mode);
4743 DCHECK_EQ(LookupIterator::TRANSITION, it->state()); 4698 DCHECK_EQ(LookupIterator::TRANSITION, it->state());
4744 it->ApplyTransitionToDataProperty(receiver); 4699 it->ApplyTransitionToDataProperty(receiver);
4745 4700
4746 // TODO(verwaest): Encapsulate dictionary handling better. 4701 // Write the property value.
4747 if (receiver->map()->is_dictionary_map()) { 4702 it->WriteDataValue(value);
4748 // TODO(dcarney): just populate TransitionPropertyCell here?
4749 JSObject::AddSlowProperty(receiver, it->name(), value, attributes);
4750 } else {
4751 // Write the property value.
4752 it->WriteDataValue(value);
4753 }
4754 4703
4755 #if VERIFY_HEAP 4704 #if VERIFY_HEAP
4756 if (FLAG_verify_heap) { 4705 if (FLAG_verify_heap) {
4757 receiver->JSObjectVerify(); 4706 receiver->JSObjectVerify();
4758 } 4707 }
4759 #endif 4708 #endif
4760 } 4709 }
4761 4710
4762 return Just(true); 4711 return Just(true);
4763 } 4712 }
(...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after
6080 Isolate* isolate = object->GetIsolate(); 6029 Isolate* isolate = object->GetIsolate();
6081 6030
6082 if (object->IsJSGlobalObject()) { 6031 if (object->IsJSGlobalObject()) {
6083 // If we have a global object, invalidate the cell and swap in a new one. 6032 // If we have a global object, invalidate the cell and swap in a new one.
6084 Handle<GlobalDictionary> dictionary( 6033 Handle<GlobalDictionary> dictionary(
6085 JSObject::cast(*object)->global_dictionary()); 6034 JSObject::cast(*object)->global_dictionary());
6086 DCHECK_NE(GlobalDictionary::kNotFound, entry); 6035 DCHECK_NE(GlobalDictionary::kNotFound, entry);
6087 6036
6088 auto cell = PropertyCell::InvalidateEntry(dictionary, entry); 6037 auto cell = PropertyCell::InvalidateEntry(dictionary, entry);
6089 cell->set_value(isolate->heap()->the_hole_value()); 6038 cell->set_value(isolate->heap()->the_hole_value());
6090 // TODO(ishell): InvalidateForDelete
6091 cell->set_property_details( 6039 cell->set_property_details(
6092 cell->property_details().set_cell_type(PropertyCellType::kInvalidated)); 6040 PropertyDetails::Empty(PropertyCellType::kUninitialized));
6093 } else { 6041 } else {
6094 Handle<NameDictionary> dictionary(object->property_dictionary()); 6042 Handle<NameDictionary> dictionary(object->property_dictionary());
6095 DCHECK_NE(NameDictionary::kNotFound, entry); 6043 DCHECK_NE(NameDictionary::kNotFound, entry);
6096 6044
6097 NameDictionary::DeleteProperty(dictionary, entry); 6045 NameDictionary::DeleteProperty(dictionary, entry);
6098 Handle<NameDictionary> new_properties = 6046 Handle<NameDictionary> new_properties =
6099 NameDictionary::Shrink(dictionary, name); 6047 NameDictionary::Shrink(dictionary, name);
6100 object->set_properties(*new_properties); 6048 object->set_properties(*new_properties);
6101 } 6049 }
6102 } 6050 }
(...skipping 10357 matching lines...) Expand 10 before | Expand all | Expand 10 after
16460 16408
16461 template Handle<SeededNumberDictionary> 16409 template Handle<SeededNumberDictionary>
16462 HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: 16410 HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
16463 Shrink(Handle<SeededNumberDictionary>, uint32_t); 16411 Shrink(Handle<SeededNumberDictionary>, uint32_t);
16464 16412
16465 template Handle<UnseededNumberDictionary> 16413 template Handle<UnseededNumberDictionary>
16466 HashTable<UnseededNumberDictionary, UnseededNumberDictionaryShape, 16414 HashTable<UnseededNumberDictionary, UnseededNumberDictionaryShape,
16467 uint32_t>::Shrink(Handle<UnseededNumberDictionary>, uint32_t); 16415 uint32_t>::Shrink(Handle<UnseededNumberDictionary>, uint32_t);
16468 16416
16469 template Handle<NameDictionary> 16417 template Handle<NameDictionary>
16470 Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::Add( 16418 Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::Add(
16471 Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails); 16419 Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails,
16420 int*);
16472 16421
16473 template Handle<GlobalDictionary> 16422 template Handle<GlobalDictionary>
16474 Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name> >::Add( 16423 Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::Add(
16475 Handle<GlobalDictionary>, Handle<Name>, Handle<Object>, 16424 Handle<GlobalDictionary>, Handle<Name>, Handle<Object>, PropertyDetails,
16476 PropertyDetails); 16425 int*);
16477 16426
16478 template Handle<FixedArray> Dictionary< 16427 template Handle<FixedArray> Dictionary<
16479 NameDictionary, NameDictionaryShape, 16428 NameDictionary, NameDictionaryShape,
16480 Handle<Name> >::BuildIterationIndicesArray(Handle<NameDictionary>); 16429 Handle<Name> >::BuildIterationIndicesArray(Handle<NameDictionary>);
16481 16430
16482 template Handle<FixedArray> Dictionary< 16431 template Handle<FixedArray> Dictionary<
16483 NameDictionary, NameDictionaryShape, 16432 NameDictionary, NameDictionaryShape,
16484 Handle<Name> >::GenerateNewEnumerationIndices(Handle<NameDictionary>); 16433 Handle<Name> >::GenerateNewEnumerationIndices(Handle<NameDictionary>);
16485 16434
16486 template Handle<SeededNumberDictionary> 16435 template Handle<SeededNumberDictionary>
16487 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: 16436 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::Add(
16488 Add(Handle<SeededNumberDictionary>, 16437 Handle<SeededNumberDictionary>, uint32_t, Handle<Object>, PropertyDetails,
16489 uint32_t, 16438 int*);
16490 Handle<Object>,
16491 PropertyDetails);
16492 16439
16493 template Handle<UnseededNumberDictionary> 16440 template Handle<UnseededNumberDictionary>
16494 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: 16441 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape,
16495 Add(Handle<UnseededNumberDictionary>, 16442 uint32_t>::Add(Handle<UnseededNumberDictionary>, uint32_t,
16496 uint32_t, 16443 Handle<Object>, PropertyDetails, int*);
16497 Handle<Object>,
16498 PropertyDetails);
16499 16444
16500 template Handle<SeededNumberDictionary> 16445 template Handle<SeededNumberDictionary>
16501 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: 16446 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
16502 EnsureCapacity(Handle<SeededNumberDictionary>, int, uint32_t); 16447 EnsureCapacity(Handle<SeededNumberDictionary>, int, uint32_t);
16503 16448
16504 template Handle<UnseededNumberDictionary> 16449 template Handle<UnseededNumberDictionary>
16505 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: 16450 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
16506 EnsureCapacity(Handle<UnseededNumberDictionary>, int, uint32_t); 16451 EnsureCapacity(Handle<UnseededNumberDictionary>, int, uint32_t);
16507 16452
16508 template void Dictionary<NameDictionary, NameDictionaryShape, 16453 template void Dictionary<NameDictionary, NameDictionaryShape,
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
16811 16756
16812 void JSGlobalObject::InvalidatePropertyCell(Handle<JSGlobalObject> global, 16757 void JSGlobalObject::InvalidatePropertyCell(Handle<JSGlobalObject> global,
16813 Handle<Name> name) { 16758 Handle<Name> name) {
16814 DCHECK(!global->HasFastProperties()); 16759 DCHECK(!global->HasFastProperties());
16815 auto dictionary = handle(global->global_dictionary()); 16760 auto dictionary = handle(global->global_dictionary());
16816 int entry = dictionary->FindEntry(name); 16761 int entry = dictionary->FindEntry(name);
16817 if (entry == GlobalDictionary::kNotFound) return; 16762 if (entry == GlobalDictionary::kNotFound) return;
16818 PropertyCell::InvalidateEntry(dictionary, entry); 16763 PropertyCell::InvalidateEntry(dictionary, entry);
16819 } 16764 }
16820 16765
16821 16766 Handle<PropertyCell> JSGlobalObject::EnsureEmptyPropertyCell(
16822 // TODO(ishell): rename to EnsureEmptyPropertyCell or something. 16767 Handle<JSGlobalObject> global, Handle<Name> name,
16823 Handle<PropertyCell> JSGlobalObject::EnsurePropertyCell( 16768 PropertyCellType cell_type, int* entry_out) {
16824 Handle<JSGlobalObject> global, Handle<Name> name) {
16825 Isolate* isolate = global->GetIsolate(); 16769 Isolate* isolate = global->GetIsolate();
16826 DCHECK(!global->HasFastProperties()); 16770 DCHECK(!global->HasFastProperties());
16827 auto dictionary = handle(global->global_dictionary(), isolate); 16771 Handle<GlobalDictionary> dictionary(global->global_dictionary(), isolate);
16828 int entry = dictionary->FindEntry(name); 16772 int entry = dictionary->FindEntry(name);
16829 Handle<PropertyCell> cell; 16773 Handle<PropertyCell> cell;
16830 if (entry != GlobalDictionary::kNotFound) { 16774 if (entry != GlobalDictionary::kNotFound) {
16775 if (entry_out) *entry_out = entry;
16831 // This call should be idempotent. 16776 // This call should be idempotent.
16832 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); 16777 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
16833 cell = handle(PropertyCell::cast(dictionary->ValueAt(entry))); 16778 cell = handle(PropertyCell::cast(dictionary->ValueAt(entry)));
16834 DCHECK(cell->property_details().cell_type() == 16779 PropertyCellType original_cell_type = cell->property_details().cell_type();
16835 PropertyCellType::kUninitialized || 16780 DCHECK(original_cell_type == PropertyCellType::kInvalidated ||
16836 cell->property_details().cell_type() == 16781 original_cell_type == PropertyCellType::kUninitialized);
16837 PropertyCellType::kInvalidated);
16838 DCHECK(cell->value()->IsTheHole(isolate)); 16782 DCHECK(cell->value()->IsTheHole(isolate));
16783 if (original_cell_type == PropertyCellType::kInvalidated) {
16784 cell = PropertyCell::InvalidateEntry(dictionary, entry);
16785 }
16786 PropertyDetails details(NONE, DATA, 0, cell_type);
16787 cell->set_property_details(details);
16839 return cell; 16788 return cell;
16840 } 16789 }
16841 cell = isolate->factory()->NewPropertyCell(); 16790 cell = isolate->factory()->NewPropertyCell();
16842 PropertyDetails details(NONE, DATA, 0, PropertyCellType::kUninitialized); 16791 PropertyDetails details(NONE, DATA, 0, cell_type);
16843 dictionary = GlobalDictionary::Add(dictionary, name, cell, details); 16792 dictionary =
16793 GlobalDictionary::Add(dictionary, name, cell, details, entry_out);
16794 // {*entry_out} is initialized inside GlobalDictionary::Add().
16844 global->set_properties(*dictionary); 16795 global->set_properties(*dictionary);
16845 return cell; 16796 return cell;
16846 } 16797 }
16847 16798
16848 16799
16849 // This class is used for looking up two character strings in the string table. 16800 // This class is used for looking up two character strings in the string table.
16850 // If we don't have a hit we don't want to waste much time so we unroll the 16801 // If we don't have a hit we don't want to waste much time so we unroll the
16851 // string hash calculation loop here for speed. Doesn't work if the two 16802 // string hash calculation loop here for speed. Doesn't work if the two
16852 // characters form a decimal integer, since such strings have a different hash 16803 // characters form a decimal integer, since such strings have a different hash
16853 // algorithm. 16804 // algorithm.
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
17332 dictionary = EnsureCapacity(dictionary, 1, key); 17283 dictionary = EnsureCapacity(dictionary, 1, key);
17333 #ifdef DEBUG 17284 #ifdef DEBUG
17334 USE(Shape::AsHandle(dictionary->GetIsolate(), key)); 17285 USE(Shape::AsHandle(dictionary->GetIsolate(), key));
17335 #endif 17286 #endif
17336 PropertyDetails details = PropertyDetails::Empty(); 17287 PropertyDetails details = PropertyDetails::Empty();
17337 17288
17338 AddEntry(dictionary, key, value, details, dictionary->Hash(key)); 17289 AddEntry(dictionary, key, value, details, dictionary->Hash(key));
17339 return dictionary; 17290 return dictionary;
17340 } 17291 }
17341 17292
17342 17293 template <typename Derived, typename Shape, typename Key>
17343 template<typename Derived, typename Shape, typename Key> 17294 Handle<Derived> Dictionary<Derived, Shape, Key>::Add(Handle<Derived> dictionary,
17344 Handle<Derived> Dictionary<Derived, Shape, Key>::Add( 17295 Key key,
17345 Handle<Derived> dictionary, 17296 Handle<Object> value,
17346 Key key, 17297 PropertyDetails details,
17347 Handle<Object> value, 17298 int* entry_out) {
17348 PropertyDetails details) {
17349 // Valdate key is absent. 17299 // Valdate key is absent.
17350 SLOW_DCHECK((dictionary->FindEntry(key) == Dictionary::kNotFound)); 17300 SLOW_DCHECK((dictionary->FindEntry(key) == Dictionary::kNotFound));
17351 // Check whether the dictionary should be extended. 17301 // Check whether the dictionary should be extended.
17352 dictionary = EnsureCapacity(dictionary, 1, key); 17302 dictionary = EnsureCapacity(dictionary, 1, key);
17353 17303
17354 AddEntry(dictionary, key, value, details, dictionary->Hash(key)); 17304 int entry = AddEntry(dictionary, key, value, details, dictionary->Hash(key));
17305 if (entry_out) *entry_out = entry;
17355 return dictionary; 17306 return dictionary;
17356 } 17307 }
17357 17308
17358 17309 // Add a key, value pair to the dictionary. Returns entry value.
17359 // Add a key, value pair to the dictionary. 17310 template <typename Derived, typename Shape, typename Key>
17360 template<typename Derived, typename Shape, typename Key> 17311 int Dictionary<Derived, Shape, Key>::AddEntry(Handle<Derived> dictionary,
17361 void Dictionary<Derived, Shape, Key>::AddEntry( 17312 Key key, Handle<Object> value,
17362 Handle<Derived> dictionary, 17313 PropertyDetails details,
17363 Key key, 17314 uint32_t hash) {
17364 Handle<Object> value,
17365 PropertyDetails details,
17366 uint32_t hash) {
17367 // Compute the key object. 17315 // Compute the key object.
17368 Handle<Object> k = Shape::AsHandle(dictionary->GetIsolate(), key); 17316 Handle<Object> k = Shape::AsHandle(dictionary->GetIsolate(), key);
17369 17317
17370 uint32_t entry = dictionary->FindInsertionEntry(hash); 17318 uint32_t entry = dictionary->FindInsertionEntry(hash);
17371 // Insert element at empty or deleted entry 17319 // Insert element at empty or deleted entry
17372 if (details.dictionary_index() == 0 && Shape::kIsEnumerable) { 17320 if (details.dictionary_index() == 0 && Shape::kIsEnumerable) {
17373 // Assign an enumeration index to the property and update 17321 // Assign an enumeration index to the property and update
17374 // SetNextEnumerationIndex. 17322 // SetNextEnumerationIndex.
17375 int index = dictionary->NextEnumerationIndex(); 17323 int index = dictionary->NextEnumerationIndex();
17376 details = details.set_index(index); 17324 details = details.set_index(index);
17377 dictionary->SetNextEnumerationIndex(index + 1); 17325 dictionary->SetNextEnumerationIndex(index + 1);
17378 } 17326 }
17379 dictionary->SetEntry(entry, k, value, details); 17327 dictionary->SetEntry(entry, k, value, details);
17380 DCHECK((dictionary->KeyAt(entry)->IsNumber() || 17328 DCHECK((dictionary->KeyAt(entry)->IsNumber() ||
17381 dictionary->KeyAt(entry)->IsName())); 17329 dictionary->KeyAt(entry)->IsName()));
17382 dictionary->ElementAdded(); 17330 dictionary->ElementAdded();
17331 return entry;
17383 } 17332 }
17384 17333
17385 bool SeededNumberDictionary::HasComplexElements() { 17334 bool SeededNumberDictionary::HasComplexElements() {
17386 if (!requires_slow_elements()) return false; 17335 if (!requires_slow_elements()) return false;
17387 Isolate* isolate = this->GetIsolate(); 17336 Isolate* isolate = this->GetIsolate();
17388 int capacity = this->Capacity(); 17337 int capacity = this->Capacity();
17389 for (int i = 0; i < capacity; i++) { 17338 for (int i = 0; i < capacity; i++) {
17390 Object* k = this->KeyAt(i); 17339 Object* k = this->KeyAt(i);
17391 if (!this->IsKey(isolate, k)) continue; 17340 if (!this->IsKey(isolate, k)) continue;
17392 DCHECK(!IsDeleted(i)); 17341 DCHECK(!IsDeleted(i));
(...skipping 1370 matching lines...) Expand 10 before | Expand all | Expand 10 after
18763 return MaterializeArrayBuffer(self); 18712 return MaterializeArrayBuffer(self);
18764 } 18713 }
18765 18714
18766 18715
18767 Handle<PropertyCell> PropertyCell::InvalidateEntry( 18716 Handle<PropertyCell> PropertyCell::InvalidateEntry(
18768 Handle<GlobalDictionary> dictionary, int entry) { 18717 Handle<GlobalDictionary> dictionary, int entry) {
18769 Isolate* isolate = dictionary->GetIsolate(); 18718 Isolate* isolate = dictionary->GetIsolate();
18770 // Swap with a copy. 18719 // Swap with a copy.
18771 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); 18720 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
18772 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); 18721 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
18773 auto new_cell = isolate->factory()->NewPropertyCell(); 18722 Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell();
18774 new_cell->set_value(cell->value()); 18723 new_cell->set_value(cell->value());
18775 dictionary->ValueAtPut(entry, *new_cell); 18724 dictionary->ValueAtPut(entry, *new_cell);
18776 bool is_the_hole = cell->value()->IsTheHole(isolate); 18725 bool is_the_hole = cell->value()->IsTheHole(isolate);
18777 // Cell is officially mutable henceforth. 18726 // Cell is officially mutable henceforth.
18778 PropertyDetails details = cell->property_details(); 18727 PropertyDetails details = cell->property_details();
18779 details = details.set_cell_type(is_the_hole ? PropertyCellType::kInvalidated 18728 details = details.set_cell_type(is_the_hole ? PropertyCellType::kUninitialized
18780 : PropertyCellType::kMutable); 18729 : PropertyCellType::kMutable);
18781 new_cell->set_property_details(details); 18730 new_cell->set_property_details(details);
18782 // Old cell is ready for invalidation. 18731 // Old cell is ready for invalidation.
18783 if (is_the_hole) { 18732 if (is_the_hole) {
18784 cell->set_value(isolate->heap()->undefined_value()); 18733 cell->set_value(isolate->heap()->undefined_value());
18785 } else { 18734 } else {
18786 cell->set_value(isolate->heap()->the_hole_value()); 18735 cell->set_value(isolate->heap()->the_hole_value());
18787 } 18736 }
18788 details = details.set_cell_type(PropertyCellType::kInvalidated); 18737 details = details.set_cell_type(PropertyCellType::kInvalidated);
18789 cell->set_property_details(details); 18738 cell->set_property_details(details);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
18843 return PropertyCellType::kConstantType; 18792 return PropertyCellType::kConstantType;
18844 } 18793 }
18845 // Fall through. 18794 // Fall through.
18846 case PropertyCellType::kMutable: 18795 case PropertyCellType::kMutable:
18847 return PropertyCellType::kMutable; 18796 return PropertyCellType::kMutable;
18848 } 18797 }
18849 UNREACHABLE(); 18798 UNREACHABLE();
18850 return PropertyCellType::kMutable; 18799 return PropertyCellType::kMutable;
18851 } 18800 }
18852 18801
18853 18802 Handle<PropertyCell> PropertyCell::PrepareForValue(
18854 void PropertyCell::UpdateCell(Handle<GlobalDictionary> dictionary, int entry, 18803 Handle<GlobalDictionary> dictionary, int entry, Handle<Object> value,
18855 Handle<Object> value, PropertyDetails details) { 18804 PropertyDetails details) {
18856 Isolate* isolate = dictionary->GetIsolate(); 18805 Isolate* isolate = dictionary->GetIsolate();
18857 DCHECK(!value->IsTheHole(isolate)); 18806 DCHECK(!value->IsTheHole(isolate));
18858 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); 18807 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
18859 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); 18808 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
18860 const PropertyDetails original_details = cell->property_details(); 18809 const PropertyDetails original_details = cell->property_details();
18861 // Data accesses could be cached in ics or optimized code. 18810 // Data accesses could be cached in ics or optimized code.
18862 bool invalidate = 18811 bool invalidate =
18863 original_details.kind() == kData && details.kind() == kAccessor; 18812 original_details.kind() == kData && details.kind() == kAccessor;
18864 int index = original_details.dictionary_index(); 18813 int index = original_details.dictionary_index();
18865 PropertyCellType old_type = original_details.cell_type(); 18814 PropertyCellType old_type = original_details.cell_type();
18866 // Preserve the enumeration index unless the property was deleted or never 18815 // Preserve the enumeration index unless the property was deleted or never
18867 // initialized. 18816 // initialized.
18868 if (cell->value()->IsTheHole(isolate)) { 18817 if (cell->value()->IsTheHole(isolate)) {
18869 index = dictionary->NextEnumerationIndex(); 18818 index = dictionary->NextEnumerationIndex();
18870 dictionary->SetNextEnumerationIndex(index + 1); 18819 dictionary->SetNextEnumerationIndex(index + 1);
18871 // Negative lookup cells must be invalidated.
18872 invalidate = true;
18873 } 18820 }
18874 DCHECK(index > 0); 18821 DCHECK(index > 0);
18875 details = details.set_index(index); 18822 details = details.set_index(index);
18876 18823
18877 PropertyCellType new_type = UpdatedType(cell, value, original_details); 18824 PropertyCellType new_type = UpdatedType(cell, value, original_details);
18878 if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry); 18825 if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry);
18879 18826
18880 // Install new property details and cell value. 18827 // Install new property details.
18881 details = details.set_cell_type(new_type); 18828 details = details.set_cell_type(new_type);
18882 cell->set_property_details(details); 18829 cell->set_property_details(details);
18883 cell->set_value(*value);
18884 18830
18885 // Deopt when transitioning from a constant type. 18831 // Deopt when transitioning from a constant type.
18886 if (!invalidate && (old_type != new_type || 18832 if (!invalidate && (old_type != new_type ||
18887 original_details.IsReadOnly() != details.IsReadOnly())) { 18833 original_details.IsReadOnly() != details.IsReadOnly())) {
18888 cell->dependent_code()->DeoptimizeDependentCodeGroup( 18834 cell->dependent_code()->DeoptimizeDependentCodeGroup(
18889 isolate, DependentCode::kPropertyCellChangedGroup); 18835 isolate, DependentCode::kPropertyCellChangedGroup);
18890 } 18836 }
18837 return cell;
18891 } 18838 }
18892 18839
18893 18840
18894 // static 18841 // static
18895 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, 18842 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell,
18896 Handle<Object> new_value) { 18843 Handle<Object> new_value) {
18897 if (cell->value() != *new_value) { 18844 if (cell->value() != *new_value) {
18898 cell->set_value(*new_value); 18845 cell->set_value(*new_value);
18899 Isolate* isolate = cell->GetIsolate(); 18846 Isolate* isolate = cell->GetIsolate();
18900 cell->dependent_code()->DeoptimizeDependentCodeGroup( 18847 cell->dependent_code()->DeoptimizeDependentCodeGroup(
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
18937 18884
18938 Object* data_obj = 18885 Object* data_obj =
18939 constructor->shared()->get_api_func_data()->access_check_info(); 18886 constructor->shared()->get_api_func_data()->access_check_info();
18940 if (data_obj->IsUndefined(isolate)) return nullptr; 18887 if (data_obj->IsUndefined(isolate)) return nullptr;
18941 18888
18942 return AccessCheckInfo::cast(data_obj); 18889 return AccessCheckInfo::cast(data_obj);
18943 } 18890 }
18944 18891
18945 } // namespace internal 18892 } // namespace internal
18946 } // namespace v8 18893 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698