OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 2373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2384 } | 2384 } |
2385 } | 2385 } |
2386 } | 2386 } |
2387 return true; | 2387 return true; |
2388 } | 2388 } |
2389 | 2389 |
2390 | 2390 |
2391 int Map::NumberOfDescribedProperties() { | 2391 int Map::NumberOfDescribedProperties() { |
2392 int result = 0; | 2392 int result = 0; |
2393 for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) { | 2393 for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) { |
2394 if (!r.IsTransition()) result++; | 2394 if (r.IsProperty()) result++; |
2395 } | 2395 } |
2396 return result; | 2396 return result; |
2397 } | 2397 } |
2398 | 2398 |
2399 | 2399 |
2400 int Map::PropertyIndexFor(String* name) { | 2400 int Map::PropertyIndexFor(String* name) { |
2401 for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) { | 2401 for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) { |
2402 if (r.Equals(name)) return r.GetFieldIndex(); | 2402 if (r.Equals(name) && !r.IsNullDescriptor()) return r.GetFieldIndex(); |
2403 } | 2403 } |
2404 return -1; | 2404 return -1; |
2405 } | 2405 } |
2406 | 2406 |
2407 | 2407 |
2408 int Map::NextFreePropertyIndex() { | 2408 int Map::NextFreePropertyIndex() { |
2409 int index = -1; | 2409 int index = -1; |
2410 for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) { | 2410 for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) { |
2411 if (r.type() == FIELD) { | 2411 if (r.type() == FIELD) { |
2412 if (r.GetFieldIndex() > index) index = r.GetFieldIndex(); | 2412 if (r.GetFieldIndex() > index) index = r.GetFieldIndex(); |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2926 if (r.IsNullDescriptor()) null_descriptors++; | 2926 if (r.IsNullDescriptor()) null_descriptors++; |
2927 } | 2927 } |
2928 } else { | 2928 } else { |
2929 for (DescriptorReader r(this); !r.eos(); r.advance()) { | 2929 for (DescriptorReader r(this); !r.eos(); r.advance()) { |
2930 if (r.IsNullDescriptor()) null_descriptors++; | 2930 if (r.IsNullDescriptor()) null_descriptors++; |
2931 } | 2931 } |
2932 } | 2932 } |
2933 int new_size = number_of_descriptors() - transitions - null_descriptors; | 2933 int new_size = number_of_descriptors() - transitions - null_descriptors; |
2934 | 2934 |
2935 // If key is in descriptor, we replace it in-place when filtering. | 2935 // If key is in descriptor, we replace it in-place when filtering. |
| 2936 // Count a null descriptor for key as inserted, not replaced. |
2936 int index = Search(descriptor->GetKey()); | 2937 int index = Search(descriptor->GetKey()); |
2937 const bool inserting = (index == kNotFound); | 2938 const bool inserting = (index == kNotFound); |
2938 const bool replacing = !inserting; | 2939 const bool replacing = !inserting; |
2939 bool keep_enumeration_index = false; | 2940 bool keep_enumeration_index = false; |
2940 if (inserting) { | 2941 if (inserting) { |
2941 ++new_size; | 2942 ++new_size; |
2942 } | 2943 } |
2943 if (replacing) { | 2944 if (replacing) { |
2944 // We are replacing an existing descriptor. We keep the enumeration | 2945 // We are replacing an existing descriptor. We keep the enumeration |
2945 // index of a visible property. | 2946 // index of a visible property. |
2946 PropertyType t = PropertyDetails(GetDetails(index)).type(); | 2947 PropertyType t = PropertyDetails(GetDetails(index)).type(); |
2947 if (t == CONSTANT_FUNCTION || | 2948 if (t == CONSTANT_FUNCTION || |
2948 t == FIELD || | 2949 t == FIELD || |
2949 t == CALLBACKS || | 2950 t == CALLBACKS || |
2950 t == INTERCEPTOR) { | 2951 t == INTERCEPTOR) { |
2951 keep_enumeration_index = true; | 2952 keep_enumeration_index = true; |
2952 } else if (t == NULL_DESCRIPTOR || remove_transitions) { | 2953 } else if (remove_transitions) { |
2953 // Replaced descriptor has been counted as removed if it is null | 2954 // Replaced descriptor has been counted as removed if it is |
2954 // or a transition that will be replaced. Adjust count in this case. | 2955 // a transition that will be replaced. Adjust count in this case. |
2955 ++new_size; | 2956 ++new_size; |
2956 } | 2957 } |
2957 } | 2958 } |
2958 result = Allocate(new_size); | 2959 result = Allocate(new_size); |
2959 if (result->IsFailure()) return result; | 2960 if (result->IsFailure()) return result; |
2960 DescriptorArray* new_descriptors = DescriptorArray::cast(result); | 2961 DescriptorArray* new_descriptors = DescriptorArray::cast(result); |
2961 // Set the enumeration index in the descriptors and set the enumeration index | 2962 // Set the enumeration index in the descriptors and set the enumeration index |
2962 // in the result. | 2963 // in the result. |
2963 int enumeration_index = NextEnumerationIndex(); | 2964 int enumeration_index = NextEnumerationIndex(); |
2964 if (!descriptor->GetDetails().IsTransition()) { | 2965 if (!descriptor->GetDetails().IsTransition()) { |
(...skipping 18 matching lines...) Expand all Loading... |
2983 r.GetKey() == descriptor->GetKey()) break; | 2984 r.GetKey() == descriptor->GetKey()) break; |
2984 if (r.IsNullDescriptor()) continue; | 2985 if (r.IsNullDescriptor()) continue; |
2985 if (remove_transitions && r.IsTransition()) continue; | 2986 if (remove_transitions && r.IsTransition()) continue; |
2986 w.WriteFrom(&r); | 2987 w.WriteFrom(&r); |
2987 } | 2988 } |
2988 w.Write(descriptor); | 2989 w.Write(descriptor); |
2989 if (replacing) { | 2990 if (replacing) { |
2990 ASSERT(r.GetKey() == descriptor->GetKey()); | 2991 ASSERT(r.GetKey() == descriptor->GetKey()); |
2991 r.advance(); | 2992 r.advance(); |
2992 } else { | 2993 } else { |
2993 ASSERT(r.eos() || r.GetKey()->Hash() > descriptor_hash); | 2994 ASSERT(r.eos() || |
| 2995 r.GetKey()->Hash() > descriptor_hash || |
| 2996 r.IsNullDescriptor()); |
2994 } | 2997 } |
2995 for (; !r.eos(); r.advance()) { | 2998 for (; !r.eos(); r.advance()) { |
2996 if (r.IsNullDescriptor()) continue; | 2999 if (r.IsNullDescriptor()) continue; |
2997 if (remove_transitions && r.IsTransition()) continue; | 3000 if (remove_transitions && r.IsTransition()) continue; |
2998 w.WriteFrom(&r); | 3001 w.WriteFrom(&r); |
2999 } | 3002 } |
3000 ASSERT(w.eos()); | 3003 ASSERT(w.eos()); |
3001 | 3004 |
3002 return new_descriptors; | 3005 return new_descriptors; |
3003 } | 3006 } |
3004 | 3007 |
3005 | 3008 |
3006 Object* DescriptorArray::RemoveTransitions() { | 3009 Object* DescriptorArray::RemoveTransitions() { |
3007 // Remove all transitions. Return a copy of the array with all transitions | 3010 // Remove all transitions and null descriptors. Return a copy of the array |
3008 // removed, or a Failure object if the new array could not be allocated. | 3011 // with all transitions removed, or a Failure object if the new array could |
| 3012 // not be allocated. |
3009 | 3013 |
3010 // Compute the size of the map transition entries to be removed. | 3014 // Compute the size of the map transition entries to be removed. |
3011 int count_transitions = 0; | 3015 int num_removed = 0; |
3012 for (DescriptorReader r(this); !r.eos(); r.advance()) { | 3016 for (DescriptorReader r(this); !r.eos(); r.advance()) { |
3013 if (r.IsTransition()) count_transitions++; | 3017 if (!r.IsProperty()) num_removed++; |
3014 } | 3018 } |
3015 | 3019 |
3016 // Allocate the new descriptor array. | 3020 // Allocate the new descriptor array. |
3017 Object* result = Allocate(number_of_descriptors() - count_transitions); | 3021 Object* result = Allocate(number_of_descriptors() - num_removed); |
3018 if (result->IsFailure()) return result; | 3022 if (result->IsFailure()) return result; |
3019 DescriptorArray* new_descriptors = DescriptorArray::cast(result); | 3023 DescriptorArray* new_descriptors = DescriptorArray::cast(result); |
3020 | 3024 |
3021 // Copy the content. | 3025 // Copy the content. |
3022 DescriptorWriter w(new_descriptors); | 3026 DescriptorWriter w(new_descriptors); |
3023 for (DescriptorReader r(this); !r.eos(); r.advance()) { | 3027 for (DescriptorReader r(this); !r.eos(); r.advance()) { |
3024 if (!r.IsTransition()) w.WriteFrom(&r); | 3028 if (r.IsProperty()) w.WriteFrom(&r); |
3025 } | 3029 } |
3026 ASSERT(w.eos()); | 3030 ASSERT(w.eos()); |
3027 | 3031 |
3028 return new_descriptors; | 3032 return new_descriptors; |
3029 } | 3033 } |
3030 | 3034 |
3031 | 3035 |
3032 void DescriptorArray::Sort() { | 3036 void DescriptorArray::Sort() { |
3033 // In-place heap sort. | 3037 // In-place heap sort. |
3034 int len = number_of_descriptors(); | 3038 int len = number_of_descriptors(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3090 continue; | 3094 continue; |
3091 } | 3095 } |
3092 if (mid_hash < hash) { | 3096 if (mid_hash < hash) { |
3093 low = mid + 1; | 3097 low = mid + 1; |
3094 continue; | 3098 continue; |
3095 } | 3099 } |
3096 // Found an element with the same hash-code. | 3100 // Found an element with the same hash-code. |
3097 ASSERT(hash == mid_hash); | 3101 ASSERT(hash == mid_hash); |
3098 // There might be more, so we find the first one and | 3102 // There might be more, so we find the first one and |
3099 // check them all to see if we have a match. | 3103 // check them all to see if we have a match. |
3100 if (name == mid_name) return mid; | 3104 if (name == mid_name && !is_null_descriptor(mid)) return mid; |
3101 while ((mid > low) && (GetKey(mid - 1)->Hash() == hash)) mid--; | 3105 while ((mid > low) && (GetKey(mid - 1)->Hash() == hash)) mid--; |
3102 for (; (mid <= high) && (GetKey(mid)->Hash() == hash); mid++) { | 3106 for (; (mid <= high) && (GetKey(mid)->Hash() == hash); mid++) { |
3103 if (GetKey(mid)->Equals(name)) return mid; | 3107 if (GetKey(mid)->Equals(name) && !is_null_descriptor(mid)) return mid; |
3104 } | 3108 } |
3105 break; | 3109 break; |
3106 } | 3110 } |
3107 return kNotFound; | 3111 return kNotFound; |
3108 } | 3112 } |
3109 | 3113 |
3110 | 3114 |
3111 int DescriptorArray::LinearSearch(String* name, int len) { | 3115 int DescriptorArray::LinearSearch(String* name, int len) { |
3112 for (int number = 0; number < len; number++) { | 3116 for (int number = 0; number < len; number++) { |
3113 if (name->Equals(GetKey(number))) return number; | 3117 if (name->Equals(GetKey(number)) && !is_null_descriptor(number)) { |
| 3118 return number; |
| 3119 } |
3114 } | 3120 } |
3115 return kNotFound; | 3121 return kNotFound; |
3116 } | 3122 } |
3117 | 3123 |
3118 | 3124 |
3119 #ifdef DEBUG | 3125 #ifdef DEBUG |
3120 bool DescriptorArray::IsEqualTo(DescriptorArray* other) { | 3126 bool DescriptorArray::IsEqualTo(DescriptorArray* other) { |
3121 if (IsEmpty()) return other->IsEmpty(); | 3127 if (IsEmpty()) return other->IsEmpty(); |
3122 if (other->IsEmpty()) return false; | 3128 if (other->IsEmpty()) return false; |
3123 if (length() != other->length()) return false; | 3129 if (length() != other->length()) return false; |
(...skipping 2512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5636 } | 5642 } |
5637 | 5643 |
5638 | 5644 |
5639 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { | 5645 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { |
5640 if (HasFastProperties()) { | 5646 if (HasFastProperties()) { |
5641 int result = 0; | 5647 int result = 0; |
5642 for (DescriptorReader r(map()->instance_descriptors()); | 5648 for (DescriptorReader r(map()->instance_descriptors()); |
5643 !r.eos(); | 5649 !r.eos(); |
5644 r.advance()) { | 5650 r.advance()) { |
5645 PropertyDetails details = r.GetDetails(); | 5651 PropertyDetails details = r.GetDetails(); |
5646 if (!details.IsTransition() && (details.attributes() & filter) == 0) { | 5652 if (details.IsProperty() && |
| 5653 (details.attributes() & filter) == 0) { |
5647 result++; | 5654 result++; |
5648 } | 5655 } |
5649 } | 5656 } |
5650 return result; | 5657 return result; |
5651 } else { | 5658 } else { |
5652 return property_dictionary()->NumberOfElementsFilterAttributes(filter); | 5659 return property_dictionary()->NumberOfElementsFilterAttributes(filter); |
5653 } | 5660 } |
5654 } | 5661 } |
5655 | 5662 |
5656 | 5663 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5778 // purpose of this function is to provide reflection information for the object | 5785 // purpose of this function is to provide reflection information for the object |
5779 // mirrors. | 5786 // mirrors. |
5780 void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) { | 5787 void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) { |
5781 ASSERT(storage->length() >= | 5788 ASSERT(storage->length() >= |
5782 NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE)) - | 5789 NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE)) - |
5783 index); | 5790 index); |
5784 if (HasFastProperties()) { | 5791 if (HasFastProperties()) { |
5785 for (DescriptorReader r(map()->instance_descriptors()); | 5792 for (DescriptorReader r(map()->instance_descriptors()); |
5786 !r.eos(); | 5793 !r.eos(); |
5787 r.advance()) { | 5794 r.advance()) { |
5788 if (!r.IsTransition()) { | 5795 if (r.IsProperty()) { |
5789 storage->set(index++, r.GetKey()); | 5796 storage->set(index++, r.GetKey()); |
5790 } | 5797 } |
5791 } | 5798 } |
5792 ASSERT(storage->length() >= index); | 5799 ASSERT(storage->length() >= index); |
5793 } else { | 5800 } else { |
5794 property_dictionary()->CopyKeysTo(storage); | 5801 property_dictionary()->CopyKeysTo(storage); |
5795 } | 5802 } |
5796 } | 5803 } |
5797 | 5804 |
5798 | 5805 |
(...skipping 1462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7261 // No break point. | 7268 // No break point. |
7262 if (break_point_objects()->IsUndefined()) return 0; | 7269 if (break_point_objects()->IsUndefined()) return 0; |
7263 // Single beak point. | 7270 // Single beak point. |
7264 if (!break_point_objects()->IsFixedArray()) return 1; | 7271 if (!break_point_objects()->IsFixedArray()) return 1; |
7265 // Multiple break points. | 7272 // Multiple break points. |
7266 return FixedArray::cast(break_point_objects())->length(); | 7273 return FixedArray::cast(break_point_objects())->length(); |
7267 } | 7274 } |
7268 | 7275 |
7269 | 7276 |
7270 } } // namespace v8::internal | 7277 } } // namespace v8::internal |
OLD | NEW |