| 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 |