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