| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 4612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4623 | 4623 |
| 4624 // Allocate new content. | 4624 // Allocate new content. |
| 4625 int real_size = map->NumberOfOwnDescriptors(); | 4625 int real_size = map->NumberOfOwnDescriptors(); |
| 4626 int property_count = real_size; | 4626 int property_count = real_size; |
| 4627 if (expected_additional_properties > 0) { | 4627 if (expected_additional_properties > 0) { |
| 4628 property_count += expected_additional_properties; | 4628 property_count += expected_additional_properties; |
| 4629 } else { | 4629 } else { |
| 4630 property_count += 2; // Make space for two more properties. | 4630 property_count += 2; // Make space for two more properties. |
| 4631 } | 4631 } |
| 4632 Handle<NameDictionary> dictionary = | 4632 Handle<NameDictionary> dictionary = |
| 4633 isolate->factory()->NewNameDictionary(property_count); | 4633 NameDictionary::New(isolate, property_count); |
| 4634 | 4634 |
| 4635 Handle<DescriptorArray> descs(map->instance_descriptors()); | 4635 Handle<DescriptorArray> descs(map->instance_descriptors()); |
| 4636 for (int i = 0; i < real_size; i++) { | 4636 for (int i = 0; i < real_size; i++) { |
| 4637 PropertyDetails details = descs->GetDetails(i); | 4637 PropertyDetails details = descs->GetDetails(i); |
| 4638 switch (details.type()) { | 4638 switch (details.type()) { |
| 4639 case CONSTANT: { | 4639 case CONSTANT: { |
| 4640 Handle<Name> key(descs->GetKey(i)); | 4640 Handle<Name> key(descs->GetKey(i)); |
| 4641 Handle<Object> value(descs->GetConstant(i), isolate); | 4641 Handle<Object> value(descs->GetConstant(i), isolate); |
| 4642 PropertyDetails d = PropertyDetails( | 4642 PropertyDetails d = PropertyDetails( |
| 4643 details.attributes(), NORMAL, i + 1); | 4643 details.attributes(), NORMAL, i + 1); |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4846 ASSERT(object->IsJSObject()); | 4846 ASSERT(object->IsJSObject()); |
| 4847 | 4847 |
| 4848 // Check that it really works. | 4848 // Check that it really works. |
| 4849 ASSERT(object->HasFastProperties()); | 4849 ASSERT(object->HasFastProperties()); |
| 4850 } | 4850 } |
| 4851 | 4851 |
| 4852 | 4852 |
| 4853 void JSObject::ResetElements(Handle<JSObject> object) { | 4853 void JSObject::ResetElements(Handle<JSObject> object) { |
| 4854 if (object->map()->is_observed()) { | 4854 if (object->map()->is_observed()) { |
| 4855 // Maintain invariant that observed elements are always in dictionary mode. | 4855 // Maintain invariant that observed elements are always in dictionary mode. |
| 4856 Factory* factory = object->GetIsolate()->factory(); | 4856 Isolate* isolate = object->GetIsolate(); |
| 4857 Factory* factory = isolate->factory(); |
| 4857 Handle<SeededNumberDictionary> dictionary = | 4858 Handle<SeededNumberDictionary> dictionary = |
| 4858 factory->NewSeededNumberDictionary(0); | 4859 SeededNumberDictionary::New(isolate, 0); |
| 4859 if (object->map() == *factory->sloppy_arguments_elements_map()) { | 4860 if (object->map() == *factory->sloppy_arguments_elements_map()) { |
| 4860 FixedArray::cast(object->elements())->set(1, *dictionary); | 4861 FixedArray::cast(object->elements())->set(1, *dictionary); |
| 4861 } else { | 4862 } else { |
| 4862 object->set_elements(*dictionary); | 4863 object->set_elements(*dictionary); |
| 4863 } | 4864 } |
| 4864 return; | 4865 return; |
| 4865 } | 4866 } |
| 4866 | 4867 |
| 4867 ElementsKind elements_kind = GetInitialFastElementsKind(); | 4868 ElementsKind elements_kind = GetInitialFastElementsKind(); |
| 4868 if (!FLAG_smi_only_arrays) { | 4869 if (!FLAG_smi_only_arrays) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4903 } | 4904 } |
| 4904 return dictionary; | 4905 return dictionary; |
| 4905 } | 4906 } |
| 4906 | 4907 |
| 4907 | 4908 |
| 4908 Handle<SeededNumberDictionary> JSObject::NormalizeElements( | 4909 Handle<SeededNumberDictionary> JSObject::NormalizeElements( |
| 4909 Handle<JSObject> object) { | 4910 Handle<JSObject> object) { |
| 4910 ASSERT(!object->HasExternalArrayElements() && | 4911 ASSERT(!object->HasExternalArrayElements() && |
| 4911 !object->HasFixedTypedArrayElements()); | 4912 !object->HasFixedTypedArrayElements()); |
| 4912 Isolate* isolate = object->GetIsolate(); | 4913 Isolate* isolate = object->GetIsolate(); |
| 4913 Factory* factory = isolate->factory(); | |
| 4914 | 4914 |
| 4915 // Find the backing store. | 4915 // Find the backing store. |
| 4916 Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements())); | 4916 Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements())); |
| 4917 bool is_arguments = | 4917 bool is_arguments = |
| 4918 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); | 4918 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); |
| 4919 if (is_arguments) { | 4919 if (is_arguments) { |
| 4920 array = handle(FixedArrayBase::cast( | 4920 array = handle(FixedArrayBase::cast( |
| 4921 Handle<FixedArray>::cast(array)->get(1))); | 4921 Handle<FixedArray>::cast(array)->get(1))); |
| 4922 } | 4922 } |
| 4923 if (array->IsDictionary()) return Handle<SeededNumberDictionary>::cast(array); | 4923 if (array->IsDictionary()) return Handle<SeededNumberDictionary>::cast(array); |
| 4924 | 4924 |
| 4925 ASSERT(object->HasFastSmiOrObjectElements() || | 4925 ASSERT(object->HasFastSmiOrObjectElements() || |
| 4926 object->HasFastDoubleElements() || | 4926 object->HasFastDoubleElements() || |
| 4927 object->HasFastArgumentsElements()); | 4927 object->HasFastArgumentsElements()); |
| 4928 // Compute the effective length and allocate a new backing store. | 4928 // Compute the effective length and allocate a new backing store. |
| 4929 int length = object->IsJSArray() | 4929 int length = object->IsJSArray() |
| 4930 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() | 4930 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() |
| 4931 : array->length(); | 4931 : array->length(); |
| 4932 int old_capacity = 0; | 4932 int old_capacity = 0; |
| 4933 int used_elements = 0; | 4933 int used_elements = 0; |
| 4934 object->GetElementsCapacityAndUsage(&old_capacity, &used_elements); | 4934 object->GetElementsCapacityAndUsage(&old_capacity, &used_elements); |
| 4935 Handle<SeededNumberDictionary> dictionary = | 4935 Handle<SeededNumberDictionary> dictionary = |
| 4936 factory->NewSeededNumberDictionary(used_elements); | 4936 SeededNumberDictionary::New(isolate, used_elements); |
| 4937 | 4937 |
| 4938 dictionary = CopyFastElementsToDictionary(array, length, dictionary); | 4938 dictionary = CopyFastElementsToDictionary(array, length, dictionary); |
| 4939 | 4939 |
| 4940 // Switch to using the dictionary as the backing storage for elements. | 4940 // Switch to using the dictionary as the backing storage for elements. |
| 4941 if (is_arguments) { | 4941 if (is_arguments) { |
| 4942 FixedArray::cast(object->elements())->set(1, *dictionary); | 4942 FixedArray::cast(object->elements())->set(1, *dictionary); |
| 4943 } else { | 4943 } else { |
| 4944 // Set the new map first to satify the elements type assert in | 4944 // Set the new map first to satify the elements type assert in |
| 4945 // set_elements(). | 4945 // set_elements(). |
| 4946 Handle<Map> new_map = | 4946 Handle<Map> new_map = |
| (...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5739 | 5739 |
| 5740 Handle<SeededNumberDictionary> new_element_dictionary; | 5740 Handle<SeededNumberDictionary> new_element_dictionary; |
| 5741 if (!object->elements()->IsDictionary()) { | 5741 if (!object->elements()->IsDictionary()) { |
| 5742 int length = object->IsJSArray() | 5742 int length = object->IsJSArray() |
| 5743 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() | 5743 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() |
| 5744 : object->elements()->length(); | 5744 : object->elements()->length(); |
| 5745 if (length > 0) { | 5745 if (length > 0) { |
| 5746 int capacity = 0; | 5746 int capacity = 0; |
| 5747 int used = 0; | 5747 int used = 0; |
| 5748 object->GetElementsCapacityAndUsage(&capacity, &used); | 5748 object->GetElementsCapacityAndUsage(&capacity, &used); |
| 5749 new_element_dictionary = | 5749 new_element_dictionary = SeededNumberDictionary::New(isolate, used); |
| 5750 isolate->factory()->NewSeededNumberDictionary(used); | |
| 5751 | 5750 |
| 5752 // Move elements to a dictionary; avoid calling NormalizeElements to avoid | 5751 // Move elements to a dictionary; avoid calling NormalizeElements to avoid |
| 5753 // unnecessary transitions. | 5752 // unnecessary transitions. |
| 5754 new_element_dictionary = CopyFastElementsToDictionary( | 5753 new_element_dictionary = CopyFastElementsToDictionary( |
| 5755 handle(object->elements()), length, new_element_dictionary); | 5754 handle(object->elements()), length, new_element_dictionary); |
| 5756 } else { | 5755 } else { |
| 5757 // No existing elements, use a pre-allocated empty backing store | 5756 // No existing elements, use a pre-allocated empty backing store |
| 5758 new_element_dictionary = | 5757 new_element_dictionary = |
| 5759 isolate->factory()->empty_slow_element_dictionary(); | 5758 isolate->factory()->empty_slow_element_dictionary(); |
| 5760 } | 5759 } |
| (...skipping 9116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14877 template class Dictionary<NameDictionary, NameDictionaryShape, Name*>; | 14876 template class Dictionary<NameDictionary, NameDictionaryShape, Name*>; |
| 14878 | 14877 |
| 14879 template class Dictionary<SeededNumberDictionary, | 14878 template class Dictionary<SeededNumberDictionary, |
| 14880 SeededNumberDictionaryShape, | 14879 SeededNumberDictionaryShape, |
| 14881 uint32_t>; | 14880 uint32_t>; |
| 14882 | 14881 |
| 14883 template class Dictionary<UnseededNumberDictionary, | 14882 template class Dictionary<UnseededNumberDictionary, |
| 14884 UnseededNumberDictionaryShape, | 14883 UnseededNumberDictionaryShape, |
| 14885 uint32_t>; | 14884 uint32_t>; |
| 14886 | 14885 |
| 14887 template MaybeObject* | 14886 template Handle<SeededNumberDictionary> |
| 14888 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14887 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14889 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); | 14888 New(Isolate*, int at_least_space_for, PretenureFlag pretenure); |
| 14890 | 14889 |
| 14891 template MaybeObject* | 14890 template Handle<UnseededNumberDictionary> |
| 14892 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: | 14891 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14893 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); | 14892 New(Isolate*, int at_least_space_for, PretenureFlag pretenure); |
| 14894 | |
| 14895 template MaybeObject* Dictionary<NameDictionary, NameDictionaryShape, Name*>:: | |
| 14896 Allocate(Heap* heap, int n, PretenureFlag pretenure); | |
| 14897 | 14893 |
| 14898 template Handle<NameDictionary> | 14894 template Handle<NameDictionary> |
| 14899 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: | 14895 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14900 New(Isolate* isolate, int n, PretenureFlag pretenure); | 14896 New(Isolate*, int n, PretenureFlag pretenure); |
| 14901 | 14897 |
| 14902 template Handle<SeededNumberDictionary> | 14898 template Handle<SeededNumberDictionary> |
| 14903 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14899 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14904 AtPut(Handle<SeededNumberDictionary>, uint32_t, Handle<Object>); | 14900 AtPut(Handle<SeededNumberDictionary>, uint32_t, Handle<Object>); |
| 14905 | 14901 |
| 14906 template Handle<UnseededNumberDictionary> | 14902 template Handle<UnseededNumberDictionary> |
| 14907 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: | 14903 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14908 AtPut(Handle<UnseededNumberDictionary>, uint32_t, Handle<Object>); | 14904 AtPut(Handle<UnseededNumberDictionary>, uint32_t, Handle<Object>); |
| 14909 | 14905 |
| 14910 template Object* | 14906 template Object* |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15039 | 15035 |
| 15040 Handle<Object> JSObject::PrepareSlowElementsForSort( | 15036 Handle<Object> JSObject::PrepareSlowElementsForSort( |
| 15041 Handle<JSObject> object, uint32_t limit) { | 15037 Handle<JSObject> object, uint32_t limit) { |
| 15042 ASSERT(object->HasDictionaryElements()); | 15038 ASSERT(object->HasDictionaryElements()); |
| 15043 Isolate* isolate = object->GetIsolate(); | 15039 Isolate* isolate = object->GetIsolate(); |
| 15044 // Must stay in dictionary mode, either because of requires_slow_elements, | 15040 // Must stay in dictionary mode, either because of requires_slow_elements, |
| 15045 // or because we are not going to sort (and therefore compact) all of the | 15041 // or because we are not going to sort (and therefore compact) all of the |
| 15046 // elements. | 15042 // elements. |
| 15047 Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate); | 15043 Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate); |
| 15048 Handle<SeededNumberDictionary> new_dict = | 15044 Handle<SeededNumberDictionary> new_dict = |
| 15049 isolate->factory()->NewSeededNumberDictionary(dict->NumberOfElements()); | 15045 SeededNumberDictionary::New(isolate, dict->NumberOfElements()); |
| 15050 | 15046 |
| 15051 uint32_t pos = 0; | 15047 uint32_t pos = 0; |
| 15052 uint32_t undefs = 0; | 15048 uint32_t undefs = 0; |
| 15053 int capacity = dict->Capacity(); | 15049 int capacity = dict->Capacity(); |
| 15054 Handle<Smi> bailout(Smi::FromInt(-1), isolate); | 15050 Handle<Smi> bailout(Smi::FromInt(-1), isolate); |
| 15055 // Entry to the new dictionary does not cause it to grow, as we have | 15051 // Entry to the new dictionary does not cause it to grow, as we have |
| 15056 // allocated one that is large enough for all entries. | 15052 // allocated one that is large enough for all entries. |
| 15057 DisallowHeapAllocation no_gc; | 15053 DisallowHeapAllocation no_gc; |
| 15058 for (int i = 0; i < capacity; i++) { | 15054 for (int i = 0; i < capacity; i++) { |
| 15059 Object* k = dict->KeyAt(i); | 15055 Object* k = dict->KeyAt(i); |
| (...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15770 Handle<MapCache> new_cache = EnsureCapacity(map_cache, 1, &key); | 15766 Handle<MapCache> new_cache = EnsureCapacity(map_cache, 1, &key); |
| 15771 int entry = new_cache->FindInsertionEntry(key.Hash()); | 15767 int entry = new_cache->FindInsertionEntry(key.Hash()); |
| 15772 new_cache->set(EntryToIndex(entry), *array); | 15768 new_cache->set(EntryToIndex(entry), *array); |
| 15773 new_cache->set(EntryToIndex(entry) + 1, *value); | 15769 new_cache->set(EntryToIndex(entry) + 1, *value); |
| 15774 new_cache->ElementAdded(); | 15770 new_cache->ElementAdded(); |
| 15775 return new_cache; | 15771 return new_cache; |
| 15776 } | 15772 } |
| 15777 | 15773 |
| 15778 | 15774 |
| 15779 template<typename Derived, typename Shape, typename Key> | 15775 template<typename Derived, typename Shape, typename Key> |
| 15780 MaybeObject* Dictionary<Derived, Shape, Key>::Allocate( | |
| 15781 Heap* heap, | |
| 15782 int at_least_space_for, | |
| 15783 PretenureFlag pretenure) { | |
| 15784 Object* obj; | |
| 15785 { MaybeObject* maybe_obj = | |
| 15786 DerivedHashTable::Allocate( | |
| 15787 heap, | |
| 15788 at_least_space_for, | |
| 15789 USE_DEFAULT_MINIMUM_CAPACITY, | |
| 15790 pretenure); | |
| 15791 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 15792 } | |
| 15793 // Initialize the next enumeration index. | |
| 15794 Dictionary::cast(obj)-> | |
| 15795 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | |
| 15796 return obj; | |
| 15797 } | |
| 15798 | |
| 15799 | |
| 15800 template<typename Derived, typename Shape, typename Key> | |
| 15801 Handle<Derived> Dictionary<Derived, Shape, Key>::New( | 15776 Handle<Derived> Dictionary<Derived, Shape, Key>::New( |
| 15802 Isolate* isolate, | 15777 Isolate* isolate, |
| 15803 int at_least_space_for, | 15778 int at_least_space_for, |
| 15804 PretenureFlag pretenure) { | 15779 PretenureFlag pretenure) { |
| 15780 ASSERT(0 <= at_least_space_for); |
| 15805 Handle<Derived> dict = DerivedHashTable::New(isolate, | 15781 Handle<Derived> dict = DerivedHashTable::New(isolate, |
| 15806 at_least_space_for, | 15782 at_least_space_for, |
| 15807 USE_DEFAULT_MINIMUM_CAPACITY, | 15783 USE_DEFAULT_MINIMUM_CAPACITY, |
| 15808 pretenure); | 15784 pretenure); |
| 15809 | 15785 |
| 15810 // Initialize the next enumeration index. | 15786 // Initialize the next enumeration index. |
| 15811 dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 15787 dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
| 15812 return dict; | 15788 return dict; |
| 15813 } | 15789 } |
| 15814 | 15790 |
| (...skipping 1570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17385 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17361 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 17386 static const char* error_messages_[] = { | 17362 static const char* error_messages_[] = { |
| 17387 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17363 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 17388 }; | 17364 }; |
| 17389 #undef ERROR_MESSAGES_TEXTS | 17365 #undef ERROR_MESSAGES_TEXTS |
| 17390 return error_messages_[reason]; | 17366 return error_messages_[reason]; |
| 17391 } | 17367 } |
| 17392 | 17368 |
| 17393 | 17369 |
| 17394 } } // namespace v8::internal | 17370 } } // namespace v8::internal |
| OLD | NEW |