OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |