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

Side by Side Diff: src/objects.cc

Issue 75035: Change the enumeration order for unsigned integer keys to always be... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 5119 matching lines...) Expand 10 before | Expand all | Expand 10 after
5130 } else if (!interceptor->getter()->IsUndefined()) { 5130 } else if (!interceptor->getter()->IsUndefined()) {
5131 v8::IndexedPropertyGetter getter = 5131 v8::IndexedPropertyGetter getter =
5132 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); 5132 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter());
5133 LOG(ApiIndexedPropertyAccess("interceptor-indexed-has-get", this, index)); 5133 LOG(ApiIndexedPropertyAccess("interceptor-indexed-has-get", this, index));
5134 v8::Handle<v8::Value> result; 5134 v8::Handle<v8::Value> result;
5135 { 5135 {
5136 // Leaving JavaScript. 5136 // Leaving JavaScript.
5137 VMState state(EXTERNAL); 5137 VMState state(EXTERNAL);
5138 result = getter(index, info); 5138 result = getter(index, info);
5139 } 5139 }
5140 if (!result.IsEmpty()) return !result->IsUndefined(); 5140 if (!result.IsEmpty()) return true;
Mads Ager (chromium) 2009/04/16 11:14:56 I have no idea why we treated an undefined result
5141 } 5141 }
5142 return holder_handle->HasElementPostInterceptor(*receiver_handle, index); 5142 return holder_handle->HasElementPostInterceptor(*receiver_handle, index);
5143 } 5143 }
5144 5144
5145 5145
5146 bool JSObject::HasLocalElement(uint32_t index) { 5146 bool JSObject::HasLocalElement(uint32_t index) {
5147 // Check access rights if needed. 5147 // Check access rights if needed.
5148 if (IsAccessCheckNeeded() && 5148 if (IsAccessCheckNeeded() &&
5149 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 5149 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
5150 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 5150 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS);
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
5857 return property_dictionary()->NumberOfElementsFilterAttributes(filter); 5857 return property_dictionary()->NumberOfElementsFilterAttributes(filter);
5858 } 5858 }
5859 } 5859 }
5860 5860
5861 5861
5862 int JSObject::NumberOfEnumProperties() { 5862 int JSObject::NumberOfEnumProperties() {
5863 return NumberOfLocalProperties(static_cast<PropertyAttributes>(DONT_ENUM)); 5863 return NumberOfLocalProperties(static_cast<PropertyAttributes>(DONT_ENUM));
5864 } 5864 }
5865 5865
5866 5866
5867 void FixedArray::Swap(int i, int j) { 5867 void FixedArray::SwapPairs(FixedArray* numbers, int i, int j) {
5868 Object* temp = get(i); 5868 Object* temp = get(i);
5869 set(i, get(j)); 5869 set(i, get(j));
5870 set(j, temp); 5870 set(j, temp);
5871 if (this != numbers) {
5872 temp = numbers->get(i);
5873 numbers->set(i, numbers->get(j));
5874 numbers->set(j, temp);
5875 }
5871 } 5876 }
5872 5877
5873 5878
5874 static void InsertionSortPairs(FixedArray* content, FixedArray* smis) { 5879 static void InsertionSortPairs(FixedArray* content,
5875 int len = smis->length(); 5880 FixedArray* numbers,
5881 int len) {
5876 for (int i = 1; i < len; i++) { 5882 for (int i = 1; i < len; i++) {
5877 int j = i; 5883 int j = i;
5878 while (j > 0 && 5884 while (j > 0 &&
5879 Smi::cast(smis->get(j-1))->value() > 5885 (NumberToUint32(numbers->get(j-1)) >
Kasper Lund 2009/04/16 11:22:04 j-1 -> j - 1
5880 Smi::cast(smis->get(j))->value()) { 5886 NumberToUint32(numbers->get(j)))) {
5881 smis->Swap(j-1, j); 5887 content->SwapPairs(numbers, j-1, j);
5882 content->Swap(j-1, j);
5883 j--; 5888 j--;
5884 } 5889 }
5885 } 5890 }
5886 } 5891 }
5887 5892
5888 5893
5889 void HeapSortPairs(FixedArray* content, FixedArray* smis) { 5894 void HeapSortPairs(FixedArray* content, FixedArray* numbers, int len) {
5890 // In-place heap sort. 5895 // In-place heap sort.
5891 ASSERT(content->length() == smis->length()); 5896 ASSERT(content->length() == numbers->length());
5892 int len = smis->length();
5893 5897
5894 // Bottom-up max-heap construction. 5898 // Bottom-up max-heap construction.
5895 for (int i = 1; i < len; ++i) { 5899 for (int i = 1; i < len; ++i) {
5896 int child_index = i; 5900 int child_index = i;
5897 while (child_index > 0) { 5901 while (child_index > 0) {
5898 int parent_index = ((child_index + 1) >> 1) - 1; 5902 int parent_index = ((child_index + 1) >> 1) - 1;
5899 int parent_value = Smi::cast(smis->get(parent_index))->value(); 5903 uint32_t parent_value = NumberToUint32(numbers->get(parent_index));
5900 int child_value = Smi::cast(smis->get(child_index))->value(); 5904 uint32_t child_value = NumberToUint32(numbers->get(child_index));
5901 if (parent_value < child_value) { 5905 if (parent_value < child_value) {
5902 content->Swap(parent_index, child_index); 5906 content->SwapPairs(numbers, parent_index, child_index);
5903 smis->Swap(parent_index, child_index);
5904 } else { 5907 } else {
5905 break; 5908 break;
5906 } 5909 }
5907 child_index = parent_index; 5910 child_index = parent_index;
5908 } 5911 }
5909 } 5912 }
5910 5913
5911 // Extract elements and create sorted array. 5914 // Extract elements and create sorted array.
5912 for (int i = len - 1; i > 0; --i) { 5915 for (int i = len - 1; i > 0; --i) {
5913 // Put max element at the back of the array. 5916 // Put max element at the back of the array.
5914 content->Swap(0, i); 5917 content->SwapPairs(numbers, 0, i);
5915 smis->Swap(0, i);
5916 // Sift down the new top element. 5918 // Sift down the new top element.
5917 int parent_index = 0; 5919 int parent_index = 0;
5918 while (true) { 5920 while (true) {
5919 int child_index = ((parent_index + 1) << 1) - 1; 5921 int child_index = ((parent_index + 1) << 1) - 1;
5920 if (child_index >= i) break; 5922 if (child_index >= i) break;
5921 uint32_t child1_value = Smi::cast(smis->get(child_index))->value(); 5923 uint32_t child1_value = NumberToUint32(numbers->get(child_index));
5922 uint32_t child2_value = Smi::cast(smis->get(child_index + 1))->value(); 5924 uint32_t child2_value = NumberToUint32(numbers->get(child_index + 1));
5923 uint32_t parent_value = Smi::cast(smis->get(parent_index))->value(); 5925 uint32_t parent_value = NumberToUint32(numbers->get(parent_index));
5924 if (child_index + 1 >= i || child1_value > child2_value) { 5926 if (child_index + 1 >= i || child1_value > child2_value) {
5925 if (parent_value > child1_value) break; 5927 if (parent_value > child1_value) break;
5926 content->Swap(parent_index, child_index); 5928 content->SwapPairs(numbers, parent_index, child_index);
5927 smis->Swap(parent_index, child_index);
5928 parent_index = child_index; 5929 parent_index = child_index;
5929 } else { 5930 } else {
5930 if (parent_value > child2_value) break; 5931 if (parent_value > child2_value) break;
5931 content->Swap(parent_index, child_index + 1); 5932 content->SwapPairs(numbers, parent_index, child_index + 1);
5932 smis->Swap(parent_index, child_index + 1);
5933 parent_index = child_index + 1; 5933 parent_index = child_index + 1;
5934 } 5934 }
5935 } 5935 }
5936 } 5936 }
5937 } 5937 }
5938 5938
5939 5939
5940 // Sort this array and the smis as pairs wrt. the (distinct) smis. 5940 // Sort this array and the numbers as pairs wrt. the (distinct) numbers.
5941 void FixedArray::SortPairs(FixedArray* smis) { 5941 void FixedArray::SortPairs(FixedArray* numbers, uint32_t len) {
5942 ASSERT(this->length() == smis->length()); 5942 ASSERT(this->length() == numbers->length());
5943 int len = smis->length();
5944 // For small arrays, simply use insertion sort. 5943 // For small arrays, simply use insertion sort.
5945 if (len <= 10) { 5944 if (len <= 10) {
5946 InsertionSortPairs(this, smis); 5945 InsertionSortPairs(this, numbers, len);
5947 return; 5946 return;
5948 } 5947 }
5949 // Check the range of indices. 5948 // Check the range of indices.
5950 int min_index = Smi::cast(smis->get(0))->value(); 5949 uint32_t min_index = NumberToUint32(numbers->get(0));
5951 int max_index = min_index; 5950 uint32_t max_index = min_index;
5952 int i; 5951 uint32_t i;
5953 for (i = 1; i < len; i++) { 5952 for (i = 1; i < len; i++) {
5954 if (Smi::cast(smis->get(i))->value() < min_index) { 5953 if (NumberToUint32(numbers->get(i)) < min_index) {
5955 min_index = Smi::cast(smis->get(i))->value(); 5954 min_index = NumberToUint32(numbers->get(i));
5956 } else if (Smi::cast(smis->get(i))->value() > max_index) { 5955 } else if (NumberToUint32(numbers->get(i)) > max_index) {
5957 max_index = Smi::cast(smis->get(i))->value(); 5956 max_index = NumberToUint32(numbers->get(i));
5958 } 5957 }
5959 } 5958 }
5960 if (max_index - min_index + 1 == len) { 5959 if (max_index - min_index + 1 == len) {
5961 // Indices form a contiguous range, unless there are duplicates. 5960 // Indices form a contiguous range, unless there are duplicates.
5962 // Do an in-place linear time sort assuming distinct smis, but 5961 // Do an in-place linear time sort assuming distinct numbers, but
5963 // avoid hanging in case they are not. 5962 // avoid hanging in case they are not.
5964 for (i = 0; i < len; i++) { 5963 for (i = 0; i < len; i++) {
5965 int p; 5964 uint32_t p;
5966 int j = 0; 5965 uint32_t j = 0;
5967 // While the current element at i is not at its correct position p, 5966 // While the current element at i is not at its correct position p,
5968 // swap the elements at these two positions. 5967 // swap the elements at these two positions.
5969 while ((p = Smi::cast(smis->get(i))->value() - min_index) != i && 5968 while ((p = NumberToUint32(numbers->get(i)) - min_index) != i &&
5970 j++ < len) { 5969 j++ < len) {
5971 this->Swap(i, p); 5970 SwapPairs(numbers, i, p);
5972 smis->Swap(i, p);
5973 } 5971 }
5974 } 5972 }
5975 } else { 5973 } else {
5976 HeapSortPairs(this, smis); 5974 HeapSortPairs(this, numbers, len);
5977 return; 5975 return;
5978 } 5976 }
5979 } 5977 }
5980 5978
5981 5979
5982 // Fill in the names of local properties into the supplied storage. The main 5980 // Fill in the names of local properties into the supplied storage. The main
5983 // purpose of this function is to provide reflection information for the object 5981 // purpose of this function is to provide reflection information for the object
5984 // mirrors. 5982 // mirrors.
5985 void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) { 5983 void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) {
5986 ASSERT(storage->length() >= 5984 ASSERT(storage->length() >=
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after
6754 int pos = 0; 6752 int pos = 0;
6755 for (int i = 0; i < capacity; i++) { 6753 for (int i = 0; i < capacity; i++) {
6756 if (IsKey(KeyAt(i))) { 6754 if (IsKey(KeyAt(i))) {
6757 enumeration_order->set(pos++, 6755 enumeration_order->set(pos++,
6758 Smi::FromInt(DetailsAt(i).index()), 6756 Smi::FromInt(DetailsAt(i).index()),
6759 SKIP_WRITE_BARRIER); 6757 SKIP_WRITE_BARRIER);
6760 } 6758 }
6761 } 6759 }
6762 6760
6763 // Sort the arrays wrt. enumeration order. 6761 // Sort the arrays wrt. enumeration order.
6764 iteration_order->SortPairs(enumeration_order); 6762 iteration_order->SortPairs(enumeration_order, enumeration_order->length());
6765 6763
6766 // Overwrite the enumeration_order with the enumeration indices. 6764 // Overwrite the enumeration_order with the enumeration indices.
6767 for (int i = 0; i < length; i++) { 6765 for (int i = 0; i < length; i++) {
6768 int index = Smi::cast(iteration_order->get(i))->value(); 6766 int index = Smi::cast(iteration_order->get(i))->value();
6769 int enum_index = PropertyDetails::kInitialIndex + i; 6767 int enum_index = PropertyDetails::kInitialIndex + i;
6770 enumeration_order->set(index, 6768 enumeration_order->set(index,
6771 Smi::FromInt(enum_index), 6769 Smi::FromInt(enum_index),
6772 SKIP_WRITE_BARRIER); 6770 SKIP_WRITE_BARRIER);
6773 } 6771 }
6774 6772
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
7006 ASSERT(storage->length() >= NumberOfEnumElements()); 7004 ASSERT(storage->length() >= NumberOfEnumElements());
7007 int capacity = Capacity(); 7005 int capacity = Capacity();
7008 int index = 0; 7006 int index = 0;
7009 for (int i = 0; i < capacity; i++) { 7007 for (int i = 0; i < capacity; i++) {
7010 Object* k = KeyAt(i); 7008 Object* k = KeyAt(i);
7011 if (IsKey(k)) { 7009 if (IsKey(k)) {
7012 PropertyAttributes attr = DetailsAt(i).attributes(); 7010 PropertyAttributes attr = DetailsAt(i).attributes();
7013 if ((attr & filter) == 0) storage->set(index++, k); 7011 if ((attr & filter) == 0) storage->set(index++, k);
7014 } 7012 }
7015 } 7013 }
7014 storage->SortPairs(storage, index);
7016 ASSERT(storage->length() >= index); 7015 ASSERT(storage->length() >= index);
7017 } 7016 }
7018 7017
7019 7018
7020 void Dictionary::CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array) { 7019 void Dictionary::CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array) {
7021 ASSERT(storage->length() >= NumberOfEnumElements()); 7020 ASSERT(storage->length() >= NumberOfEnumElements());
7022 int capacity = Capacity(); 7021 int capacity = Capacity();
7023 int index = 0; 7022 int index = 0;
7024 for (int i = 0; i < capacity; i++) { 7023 for (int i = 0; i < capacity; i++) {
7025 Object* k = KeyAt(i); 7024 Object* k = KeyAt(i);
7026 if (IsKey(k)) { 7025 if (IsKey(k)) {
7027 PropertyDetails details = DetailsAt(i); 7026 PropertyDetails details = DetailsAt(i);
7028 if (!details.IsDontEnum()) { 7027 if (!details.IsDontEnum()) {
7029 storage->set(index, k); 7028 storage->set(index, k);
7030 sort_array->set(index, 7029 sort_array->set(index,
7031 Smi::FromInt(details.index()), 7030 Smi::FromInt(details.index()),
7032 SKIP_WRITE_BARRIER); 7031 SKIP_WRITE_BARRIER);
7033 index++; 7032 index++;
7034 } 7033 }
7035 } 7034 }
7036 } 7035 }
7037 storage->SortPairs(sort_array); 7036 storage->SortPairs(sort_array, sort_array->length());
7038 ASSERT(storage->length() >= index); 7037 ASSERT(storage->length() >= index);
7039 } 7038 }
7040 7039
7041 7040
7042 void Dictionary::CopyKeysTo(FixedArray* storage) { 7041 void Dictionary::CopyKeysTo(FixedArray* storage) {
7043 ASSERT(storage->length() >= NumberOfElementsFilterAttributes( 7042 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(
7044 static_cast<PropertyAttributes>(NONE))); 7043 static_cast<PropertyAttributes>(NONE)));
7045 int capacity = Capacity(); 7044 int capacity = Capacity();
7046 int index = 0; 7045 int index = 0;
7047 for (int i = 0; i < capacity; i++) { 7046 for (int i = 0; i < capacity; i++) {
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
7418 // No break point. 7417 // No break point.
7419 if (break_point_objects()->IsUndefined()) return 0; 7418 if (break_point_objects()->IsUndefined()) return 0;
7420 // Single beak point. 7419 // Single beak point.
7421 if (!break_point_objects()->IsFixedArray()) return 1; 7420 if (!break_point_objects()->IsFixedArray()) return 1;
7422 // Multiple break points. 7421 // Multiple break points.
7423 return FixedArray::cast(break_point_objects())->length(); 7422 return FixedArray::cast(break_point_objects())->length();
7424 } 7423 }
7425 7424
7426 7425
7427 } } // namespace v8::internal 7426 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698