OLD | NEW |
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 2103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2114 | 2114 |
2115 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) { | 2115 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) { |
2116 if (!HasFastProperties()) return this; | 2116 if (!HasFastProperties()) return this; |
2117 | 2117 |
2118 // Allocate new content | 2118 // Allocate new content |
2119 Object* obj = | 2119 Object* obj = |
2120 StringDictionary::Allocate(map()->NumberOfDescribedProperties() * 2 + 4); | 2120 StringDictionary::Allocate(map()->NumberOfDescribedProperties() * 2 + 4); |
2121 if (obj->IsFailure()) return obj; | 2121 if (obj->IsFailure()) return obj; |
2122 StringDictionary* dictionary = StringDictionary::cast(obj); | 2122 StringDictionary* dictionary = StringDictionary::cast(obj); |
2123 | 2123 |
2124 for (DescriptorReader r(map()->instance_descriptors()); | 2124 DescriptorArray* descs = map()->instance_descriptors(); |
2125 !r.eos(); | 2125 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
2126 r.advance()) { | 2126 PropertyDetails details = descs->GetDetails(i); |
2127 PropertyDetails details = r.GetDetails(); | |
2128 switch (details.type()) { | 2127 switch (details.type()) { |
2129 case CONSTANT_FUNCTION: { | 2128 case CONSTANT_FUNCTION: { |
2130 PropertyDetails d = | 2129 PropertyDetails d = |
2131 PropertyDetails(details.attributes(), NORMAL, details.index()); | 2130 PropertyDetails(details.attributes(), NORMAL, details.index()); |
2132 Object* value = r.GetConstantFunction(); | 2131 Object* value = descs->GetConstantFunction(i); |
2133 if (IsGlobalObject()) { | 2132 if (IsGlobalObject()) { |
2134 value = Heap::AllocateJSGlobalPropertyCell(value); | 2133 value = Heap::AllocateJSGlobalPropertyCell(value); |
2135 if (value->IsFailure()) return value; | 2134 if (value->IsFailure()) return value; |
2136 } | 2135 } |
2137 Object* result = dictionary->Add(r.GetKey(), value, d); | 2136 Object* result = dictionary->Add(descs->GetKey(i), value, d); |
2138 if (result->IsFailure()) return result; | 2137 if (result->IsFailure()) return result; |
2139 dictionary = StringDictionary::cast(result); | 2138 dictionary = StringDictionary::cast(result); |
2140 break; | 2139 break; |
2141 } | 2140 } |
2142 case FIELD: { | 2141 case FIELD: { |
2143 PropertyDetails d = | 2142 PropertyDetails d = |
2144 PropertyDetails(details.attributes(), NORMAL, details.index()); | 2143 PropertyDetails(details.attributes(), NORMAL, details.index()); |
2145 Object* value = FastPropertyAt(r.GetFieldIndex()); | 2144 Object* value = FastPropertyAt(descs->GetFieldIndex(i)); |
2146 if (IsGlobalObject()) { | 2145 if (IsGlobalObject()) { |
2147 value = Heap::AllocateJSGlobalPropertyCell(value); | 2146 value = Heap::AllocateJSGlobalPropertyCell(value); |
2148 if (value->IsFailure()) return value; | 2147 if (value->IsFailure()) return value; |
2149 } | 2148 } |
2150 Object* result = dictionary->Add(r.GetKey(), value, d); | 2149 Object* result = dictionary->Add(descs->GetKey(i), value, d); |
2151 if (result->IsFailure()) return result; | 2150 if (result->IsFailure()) return result; |
2152 dictionary = StringDictionary::cast(result); | 2151 dictionary = StringDictionary::cast(result); |
2153 break; | 2152 break; |
2154 } | 2153 } |
2155 case CALLBACKS: { | 2154 case CALLBACKS: { |
2156 PropertyDetails d = | 2155 PropertyDetails d = |
2157 PropertyDetails(details.attributes(), CALLBACKS, details.index()); | 2156 PropertyDetails(details.attributes(), CALLBACKS, details.index()); |
2158 Object* value = r.GetCallbacksObject(); | 2157 Object* value = descs->GetCallbacksObject(i); |
2159 if (IsGlobalObject()) { | 2158 if (IsGlobalObject()) { |
2160 value = Heap::AllocateJSGlobalPropertyCell(value); | 2159 value = Heap::AllocateJSGlobalPropertyCell(value); |
2161 if (value->IsFailure()) return value; | 2160 if (value->IsFailure()) return value; |
2162 } | 2161 } |
2163 Object* result = dictionary->Add(r.GetKey(), value, d); | 2162 Object* result = dictionary->Add(descs->GetKey(i), value, d); |
2164 if (result->IsFailure()) return result; | 2163 if (result->IsFailure()) return result; |
2165 dictionary = StringDictionary::cast(result); | 2164 dictionary = StringDictionary::cast(result); |
2166 break; | 2165 break; |
2167 } | 2166 } |
2168 case MAP_TRANSITION: | 2167 case MAP_TRANSITION: |
2169 case CONSTANT_TRANSITION: | 2168 case CONSTANT_TRANSITION: |
2170 case NULL_DESCRIPTOR: | 2169 case NULL_DESCRIPTOR: |
2171 case INTERCEPTOR: | 2170 case INTERCEPTOR: |
2172 break; | 2171 break; |
2173 default: | 2172 default: |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2567 return false; | 2566 return false; |
2568 } | 2567 } |
2569 } | 2568 } |
2570 } | 2569 } |
2571 return true; | 2570 return true; |
2572 } | 2571 } |
2573 | 2572 |
2574 | 2573 |
2575 int Map::NumberOfDescribedProperties() { | 2574 int Map::NumberOfDescribedProperties() { |
2576 int result = 0; | 2575 int result = 0; |
2577 for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) { | 2576 DescriptorArray* descs = instance_descriptors(); |
2578 if (r.IsProperty()) result++; | 2577 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| 2578 if (descs->IsProperty(i)) result++; |
2579 } | 2579 } |
2580 return result; | 2580 return result; |
2581 } | 2581 } |
2582 | 2582 |
2583 | 2583 |
2584 int Map::PropertyIndexFor(String* name) { | 2584 int Map::PropertyIndexFor(String* name) { |
2585 for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) { | 2585 DescriptorArray* descs = instance_descriptors(); |
2586 if (r.Equals(name) && !r.IsNullDescriptor()) return r.GetFieldIndex(); | 2586 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| 2587 if (name->Equals(descs->GetKey(i)) && !descs->IsNullDescriptor(i)) { |
| 2588 return descs->GetFieldIndex(i); |
| 2589 } |
2587 } | 2590 } |
2588 return -1; | 2591 return -1; |
2589 } | 2592 } |
2590 | 2593 |
2591 | 2594 |
2592 int Map::NextFreePropertyIndex() { | 2595 int Map::NextFreePropertyIndex() { |
2593 int index = -1; | 2596 int max_index = -1; |
2594 for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) { | 2597 DescriptorArray* descs = instance_descriptors(); |
2595 if (r.type() == FIELD) { | 2598 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
2596 if (r.GetFieldIndex() > index) index = r.GetFieldIndex(); | 2599 if (descs->GetType(i) == FIELD) { |
| 2600 int current_index = descs->GetFieldIndex(i); |
| 2601 if (current_index > max_index) max_index = current_index; |
2597 } | 2602 } |
2598 } | 2603 } |
2599 return index+1; | 2604 return max_index + 1; |
2600 } | 2605 } |
2601 | 2606 |
2602 | 2607 |
2603 AccessorDescriptor* Map::FindAccessor(String* name) { | 2608 AccessorDescriptor* Map::FindAccessor(String* name) { |
2604 for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) { | 2609 DescriptorArray* descs = instance_descriptors(); |
2605 if (r.Equals(name) && r.type() == CALLBACKS) return r.GetCallbacks(); | 2610 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| 2611 if (name->Equals(descs->GetKey(i)) && descs->GetType(i) == CALLBACKS) { |
| 2612 return descs->GetCallbacks(i); |
| 2613 } |
2606 } | 2614 } |
2607 return NULL; | 2615 return NULL; |
2608 } | 2616 } |
2609 | 2617 |
2610 | 2618 |
2611 void JSObject::LocalLookup(String* name, LookupResult* result) { | 2619 void JSObject::LocalLookup(String* name, LookupResult* result) { |
2612 ASSERT(name->IsString()); | 2620 ASSERT(name->IsString()); |
2613 | 2621 |
2614 if (IsJSGlobalProxy()) { | 2622 if (IsJSGlobalProxy()) { |
2615 Object* proto = GetPrototype(); | 2623 Object* proto = GetPrototype(); |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2843 } | 2851 } |
2844 } | 2852 } |
2845 } | 2853 } |
2846 } | 2854 } |
2847 return Heap::undefined_value(); | 2855 return Heap::undefined_value(); |
2848 } | 2856 } |
2849 | 2857 |
2850 | 2858 |
2851 Object* JSObject::SlowReverseLookup(Object* value) { | 2859 Object* JSObject::SlowReverseLookup(Object* value) { |
2852 if (HasFastProperties()) { | 2860 if (HasFastProperties()) { |
2853 for (DescriptorReader r(map()->instance_descriptors()); | 2861 DescriptorArray* descs = map()->instance_descriptors(); |
2854 !r.eos(); | 2862 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
2855 r.advance()) { | 2863 if (descs->GetType(i) == FIELD) { |
2856 if (r.type() == FIELD) { | 2864 if (FastPropertyAt(descs->GetFieldIndex(i)) == value) { |
2857 if (FastPropertyAt(r.GetFieldIndex()) == value) { | 2865 return descs->GetKey(i); |
2858 return r.GetKey(); | |
2859 } | 2866 } |
2860 } else if (r.type() == CONSTANT_FUNCTION) { | 2867 } else if (descs->GetType(i) == CONSTANT_FUNCTION) { |
2861 if (r.GetConstantFunction() == value) { | 2868 if (descs->GetConstantFunction(i) == value) { |
2862 return r.GetKey(); | 2869 return descs->GetKey(i); |
2863 } | 2870 } |
2864 } | 2871 } |
2865 } | 2872 } |
2866 return Heap::undefined_value(); | 2873 return Heap::undefined_value(); |
2867 } else { | 2874 } else { |
2868 return property_dictionary()->SlowReverseLookup(value); | 2875 return property_dictionary()->SlowReverseLookup(value); |
2869 } | 2876 } |
2870 } | 2877 } |
2871 | 2878 |
2872 | 2879 |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3166 ASSERT(remove_transitions == !descriptor->GetDetails().IsTransition()); | 3173 ASSERT(remove_transitions == !descriptor->GetDetails().IsTransition()); |
3167 ASSERT(descriptor->GetDetails().type() != NULL_DESCRIPTOR); | 3174 ASSERT(descriptor->GetDetails().type() != NULL_DESCRIPTOR); |
3168 | 3175 |
3169 // Ensure the key is a symbol. | 3176 // Ensure the key is a symbol. |
3170 Object* result = descriptor->KeyToSymbol(); | 3177 Object* result = descriptor->KeyToSymbol(); |
3171 if (result->IsFailure()) return result; | 3178 if (result->IsFailure()) return result; |
3172 | 3179 |
3173 int transitions = 0; | 3180 int transitions = 0; |
3174 int null_descriptors = 0; | 3181 int null_descriptors = 0; |
3175 if (remove_transitions) { | 3182 if (remove_transitions) { |
3176 for (DescriptorReader r(this); !r.eos(); r.advance()) { | 3183 for (int i = 0; i < number_of_descriptors(); i++) { |
3177 if (r.IsTransition()) transitions++; | 3184 if (IsTransition(i)) transitions++; |
3178 if (r.IsNullDescriptor()) null_descriptors++; | 3185 if (IsNullDescriptor(i)) null_descriptors++; |
3179 } | 3186 } |
3180 } else { | 3187 } else { |
3181 for (DescriptorReader r(this); !r.eos(); r.advance()) { | 3188 for (int i = 0; i < number_of_descriptors(); i++) { |
3182 if (r.IsNullDescriptor()) null_descriptors++; | 3189 if (IsNullDescriptor(i)) null_descriptors++; |
3183 } | 3190 } |
3184 } | 3191 } |
3185 int new_size = number_of_descriptors() - transitions - null_descriptors; | 3192 int new_size = number_of_descriptors() - transitions - null_descriptors; |
3186 | 3193 |
3187 // If key is in descriptor, we replace it in-place when filtering. | 3194 // If key is in descriptor, we replace it in-place when filtering. |
3188 // Count a null descriptor for key as inserted, not replaced. | 3195 // Count a null descriptor for key as inserted, not replaced. |
3189 int index = Search(descriptor->GetKey()); | 3196 int index = Search(descriptor->GetKey()); |
3190 const bool inserting = (index == kNotFound); | 3197 const bool inserting = (index == kNotFound); |
3191 const bool replacing = !inserting; | 3198 const bool replacing = !inserting; |
3192 bool keep_enumeration_index = false; | 3199 bool keep_enumeration_index = false; |
(...skipping 27 matching lines...) Expand all Loading... |
3220 PropertyDetails(GetDetails(index)).index()); | 3227 PropertyDetails(GetDetails(index)).index()); |
3221 } else { | 3228 } else { |
3222 descriptor->SetEnumerationIndex(enumeration_index); | 3229 descriptor->SetEnumerationIndex(enumeration_index); |
3223 ++enumeration_index; | 3230 ++enumeration_index; |
3224 } | 3231 } |
3225 } | 3232 } |
3226 new_descriptors->SetNextEnumerationIndex(enumeration_index); | 3233 new_descriptors->SetNextEnumerationIndex(enumeration_index); |
3227 | 3234 |
3228 // Copy the descriptors, filtering out transitions and null descriptors, | 3235 // Copy the descriptors, filtering out transitions and null descriptors, |
3229 // and inserting or replacing a descriptor. | 3236 // and inserting or replacing a descriptor. |
3230 DescriptorWriter w(new_descriptors); | |
3231 DescriptorReader r(this); | |
3232 uint32_t descriptor_hash = descriptor->GetKey()->Hash(); | 3237 uint32_t descriptor_hash = descriptor->GetKey()->Hash(); |
| 3238 int from_index = 0; |
| 3239 int to_index = 0; |
3233 | 3240 |
3234 for (; !r.eos(); r.advance()) { | 3241 for (; from_index < number_of_descriptors(); from_index++) { |
3235 if (r.GetKey()->Hash() > descriptor_hash || | 3242 String* key = GetKey(from_index); |
3236 r.GetKey() == descriptor->GetKey()) break; | 3243 if (key->Hash() > descriptor_hash || key == descriptor->GetKey()) { |
3237 if (r.IsNullDescriptor()) continue; | 3244 break; |
3238 if (remove_transitions && r.IsTransition()) continue; | 3245 } |
3239 w.WriteFrom(&r); | 3246 if (IsNullDescriptor(from_index)) continue; |
| 3247 if (remove_transitions && IsTransition(from_index)) continue; |
| 3248 new_descriptors->SetFrom(to_index++, this, from_index); |
3240 } | 3249 } |
3241 w.Write(descriptor); | 3250 |
3242 if (replacing) { | 3251 new_descriptors->Set(to_index++, descriptor); |
3243 ASSERT(r.GetKey() == descriptor->GetKey()); | 3252 if (replacing) from_index++; |
3244 r.advance(); | 3253 |
3245 } else { | 3254 for (; from_index < number_of_descriptors(); from_index++) { |
3246 ASSERT(r.eos() || | 3255 if (IsNullDescriptor(from_index)) continue; |
3247 r.GetKey()->Hash() > descriptor_hash || | 3256 if (remove_transitions && IsTransition(from_index)) continue; |
3248 r.IsNullDescriptor()); | 3257 new_descriptors->SetFrom(to_index++, this, from_index); |
3249 } | 3258 } |
3250 for (; !r.eos(); r.advance()) { | 3259 |
3251 if (r.IsNullDescriptor()) continue; | 3260 ASSERT(to_index == new_descriptors->number_of_descriptors()); |
3252 if (remove_transitions && r.IsTransition()) continue; | 3261 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); |
3253 w.WriteFrom(&r); | |
3254 } | |
3255 ASSERT(w.eos()); | |
3256 | 3262 |
3257 return new_descriptors; | 3263 return new_descriptors; |
3258 } | 3264 } |
3259 | 3265 |
3260 | 3266 |
3261 Object* DescriptorArray::RemoveTransitions() { | 3267 Object* DescriptorArray::RemoveTransitions() { |
3262 // Remove all transitions and null descriptors. Return a copy of the array | 3268 // Remove all transitions and null descriptors. Return a copy of the array |
3263 // with all transitions removed, or a Failure object if the new array could | 3269 // with all transitions removed, or a Failure object if the new array could |
3264 // not be allocated. | 3270 // not be allocated. |
3265 | 3271 |
3266 // Compute the size of the map transition entries to be removed. | 3272 // Compute the size of the map transition entries to be removed. |
3267 int num_removed = 0; | 3273 int num_removed = 0; |
3268 for (DescriptorReader r(this); !r.eos(); r.advance()) { | 3274 for (int i = 0; i < number_of_descriptors(); i++) { |
3269 if (!r.IsProperty()) num_removed++; | 3275 if (!IsProperty(i)) num_removed++; |
3270 } | 3276 } |
3271 | 3277 |
3272 // Allocate the new descriptor array. | 3278 // Allocate the new descriptor array. |
3273 Object* result = Allocate(number_of_descriptors() - num_removed); | 3279 Object* result = Allocate(number_of_descriptors() - num_removed); |
3274 if (result->IsFailure()) return result; | 3280 if (result->IsFailure()) return result; |
3275 DescriptorArray* new_descriptors = DescriptorArray::cast(result); | 3281 DescriptorArray* new_descriptors = DescriptorArray::cast(result); |
3276 | 3282 |
3277 // Copy the content. | 3283 // Copy the content. |
3278 DescriptorWriter w(new_descriptors); | 3284 int next_descriptor = 0; |
3279 for (DescriptorReader r(this); !r.eos(); r.advance()) { | 3285 for (int i = 0; i < number_of_descriptors(); i++) { |
3280 if (r.IsProperty()) w.WriteFrom(&r); | 3286 if (IsProperty(i)) new_descriptors->SetFrom(next_descriptor++, this, i); |
3281 } | 3287 } |
3282 ASSERT(w.eos()); | 3288 ASSERT(next_descriptor == new_descriptors->number_of_descriptors()); |
3283 | 3289 |
3284 return new_descriptors; | 3290 return new_descriptors; |
3285 } | 3291 } |
3286 | 3292 |
3287 | 3293 |
3288 void DescriptorArray::Sort() { | 3294 void DescriptorArray::Sort() { |
3289 // In-place heap sort. | 3295 // In-place heap sort. |
3290 int len = number_of_descriptors(); | 3296 int len = number_of_descriptors(); |
3291 | 3297 |
3292 // Bottom-up max-heap construction. | 3298 // Bottom-up max-heap construction. |
(...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4579 void String::PrintOn(FILE* file) { | 4585 void String::PrintOn(FILE* file) { |
4580 int length = this->length(); | 4586 int length = this->length(); |
4581 for (int i = 0; i < length; i++) { | 4587 for (int i = 0; i < length; i++) { |
4582 fprintf(file, "%c", Get(i)); | 4588 fprintf(file, "%c", Get(i)); |
4583 } | 4589 } |
4584 } | 4590 } |
4585 | 4591 |
4586 | 4592 |
4587 void Map::CreateBackPointers() { | 4593 void Map::CreateBackPointers() { |
4588 DescriptorArray* descriptors = instance_descriptors(); | 4594 DescriptorArray* descriptors = instance_descriptors(); |
4589 for (DescriptorReader r(descriptors); !r.eos(); r.advance()) { | 4595 for (int i = 0; i < descriptors->number_of_descriptors(); i++) { |
4590 if (r.type() == MAP_TRANSITION) { | 4596 if (descriptors->GetType(i) == MAP_TRANSITION) { |
4591 // Get target. | 4597 // Get target. |
4592 Map* target = Map::cast(r.GetValue()); | 4598 Map* target = Map::cast(descriptors->GetValue(i)); |
4593 #ifdef DEBUG | 4599 #ifdef DEBUG |
4594 // Verify target. | 4600 // Verify target. |
4595 Object* source_prototype = prototype(); | 4601 Object* source_prototype = prototype(); |
4596 Object* target_prototype = target->prototype(); | 4602 Object* target_prototype = target->prototype(); |
4597 ASSERT(source_prototype->IsJSObject() || | 4603 ASSERT(source_prototype->IsJSObject() || |
4598 source_prototype->IsMap() || | 4604 source_prototype->IsMap() || |
4599 source_prototype->IsNull()); | 4605 source_prototype->IsNull()); |
4600 ASSERT(target_prototype->IsJSObject() || | 4606 ASSERT(target_prototype->IsJSObject() || |
4601 target_prototype->IsNull()); | 4607 target_prototype->IsNull()); |
4602 ASSERT(source_prototype->IsMap() || | 4608 ASSERT(source_prototype->IsMap() || |
4603 source_prototype == target_prototype); | 4609 source_prototype == target_prototype); |
4604 #endif | 4610 #endif |
4605 // Point target back to source. set_prototype() will not let us set | 4611 // Point target back to source. set_prototype() will not let us set |
4606 // the prototype to a map, as we do here. | 4612 // the prototype to a map, as we do here. |
4607 *RawField(target, kPrototypeOffset) = this; | 4613 *RawField(target, kPrototypeOffset) = this; |
4608 } | 4614 } |
4609 } | 4615 } |
4610 } | 4616 } |
4611 | 4617 |
4612 | 4618 |
4613 void Map::ClearNonLiveTransitions(Object* real_prototype) { | 4619 void Map::ClearNonLiveTransitions(Object* real_prototype) { |
(...skipping 1397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6011 } | 6017 } |
6012 | 6018 |
6013 LookupResult result; | 6019 LookupResult result; |
6014 LocalLookupRealNamedProperty(key, &result); | 6020 LocalLookupRealNamedProperty(key, &result); |
6015 return result.IsValid() && (result.type() == CALLBACKS); | 6021 return result.IsValid() && (result.type() == CALLBACKS); |
6016 } | 6022 } |
6017 | 6023 |
6018 | 6024 |
6019 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { | 6025 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { |
6020 if (HasFastProperties()) { | 6026 if (HasFastProperties()) { |
| 6027 DescriptorArray* descs = map()->instance_descriptors(); |
6021 int result = 0; | 6028 int result = 0; |
6022 for (DescriptorReader r(map()->instance_descriptors()); | 6029 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
6023 !r.eos(); | 6030 PropertyDetails details = descs->GetDetails(i); |
6024 r.advance()) { | 6031 if (details.IsProperty() && (details.attributes() & filter) == 0) { |
6025 PropertyDetails details = r.GetDetails(); | |
6026 if (details.IsProperty() && | |
6027 (details.attributes() & filter) == 0) { | |
6028 result++; | 6032 result++; |
6029 } | 6033 } |
6030 } | 6034 } |
6031 return result; | 6035 return result; |
6032 } else { | 6036 } else { |
6033 return property_dictionary()->NumberOfElementsFilterAttributes(filter); | 6037 return property_dictionary()->NumberOfElementsFilterAttributes(filter); |
6034 } | 6038 } |
6035 } | 6039 } |
6036 | 6040 |
6037 | 6041 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6150 HeapSortPairs(this, numbers, len); | 6154 HeapSortPairs(this, numbers, len); |
6151 return; | 6155 return; |
6152 } | 6156 } |
6153 } | 6157 } |
6154 | 6158 |
6155 | 6159 |
6156 // Fill in the names of local properties into the supplied storage. The main | 6160 // Fill in the names of local properties into the supplied storage. The main |
6157 // purpose of this function is to provide reflection information for the object | 6161 // purpose of this function is to provide reflection information for the object |
6158 // mirrors. | 6162 // mirrors. |
6159 void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) { | 6163 void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) { |
6160 ASSERT(storage->length() >= | 6164 ASSERT(storage->length() >= (NumberOfLocalProperties(NONE) - index)); |
6161 NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE)) - | |
6162 index); | |
6163 if (HasFastProperties()) { | 6165 if (HasFastProperties()) { |
6164 for (DescriptorReader r(map()->instance_descriptors()); | 6166 DescriptorArray* descs = map()->instance_descriptors(); |
6165 !r.eos(); | 6167 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
6166 r.advance()) { | 6168 if (descs->IsProperty(i)) storage->set(index++, descs->GetKey(i)); |
6167 if (r.IsProperty()) { | |
6168 storage->set(index++, r.GetKey()); | |
6169 } | |
6170 } | 6169 } |
6171 ASSERT(storage->length() >= index); | 6170 ASSERT(storage->length() >= index); |
6172 } else { | 6171 } else { |
6173 property_dictionary()->CopyKeysTo(storage); | 6172 property_dictionary()->CopyKeysTo(storage); |
6174 } | 6173 } |
6175 } | 6174 } |
6176 | 6175 |
6177 | 6176 |
6178 int JSObject::NumberOfLocalElements(PropertyAttributes filter) { | 6177 int JSObject::NumberOfLocalElements(PropertyAttributes filter) { |
6179 return GetLocalElementKeys(NULL, filter); | 6178 return GetLocalElementKeys(NULL, filter); |
(...skipping 1223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7403 | 7402 |
7404 int inobject_props = obj->map()->inobject_properties(); | 7403 int inobject_props = obj->map()->inobject_properties(); |
7405 int number_of_allocated_fields = | 7404 int number_of_allocated_fields = |
7406 number_of_fields + unused_property_fields - inobject_props; | 7405 number_of_fields + unused_property_fields - inobject_props; |
7407 | 7406 |
7408 // Allocate the fixed array for the fields. | 7407 // Allocate the fixed array for the fields. |
7409 Object* fields = Heap::AllocateFixedArray(number_of_allocated_fields); | 7408 Object* fields = Heap::AllocateFixedArray(number_of_allocated_fields); |
7410 if (fields->IsFailure()) return fields; | 7409 if (fields->IsFailure()) return fields; |
7411 | 7410 |
7412 // Fill in the instance descriptor and the fields. | 7411 // Fill in the instance descriptor and the fields. |
7413 DescriptorWriter w(descriptors); | 7412 int next_descriptor = 0; |
7414 int current_offset = 0; | 7413 int current_offset = 0; |
7415 for (int i = 0; i < capacity; i++) { | 7414 for (int i = 0; i < capacity; i++) { |
7416 Object* k = KeyAt(i); | 7415 Object* k = KeyAt(i); |
7417 if (IsKey(k)) { | 7416 if (IsKey(k)) { |
7418 Object* value = ValueAt(i); | 7417 Object* value = ValueAt(i); |
7419 // Ensure the key is a symbol before writing into the instance descriptor. | 7418 // Ensure the key is a symbol before writing into the instance descriptor. |
7420 Object* key = Heap::LookupSymbol(String::cast(k)); | 7419 Object* key = Heap::LookupSymbol(String::cast(k)); |
7421 if (key->IsFailure()) return key; | 7420 if (key->IsFailure()) return key; |
7422 PropertyDetails details = DetailsAt(i); | 7421 PropertyDetails details = DetailsAt(i); |
7423 PropertyType type = details.type(); | 7422 PropertyType type = details.type(); |
7424 | 7423 |
7425 if (value->IsJSFunction()) { | 7424 if (value->IsJSFunction()) { |
7426 ConstantFunctionDescriptor d(String::cast(key), | 7425 ConstantFunctionDescriptor d(String::cast(key), |
7427 JSFunction::cast(value), | 7426 JSFunction::cast(value), |
7428 details.attributes(), | 7427 details.attributes(), |
7429 details.index()); | 7428 details.index()); |
7430 w.Write(&d); | 7429 descriptors->Set(next_descriptor++, &d); |
7431 } else if (type == NORMAL) { | 7430 } else if (type == NORMAL) { |
7432 if (current_offset < inobject_props) { | 7431 if (current_offset < inobject_props) { |
7433 obj->InObjectPropertyAtPut(current_offset, | 7432 obj->InObjectPropertyAtPut(current_offset, |
7434 value, | 7433 value, |
7435 UPDATE_WRITE_BARRIER); | 7434 UPDATE_WRITE_BARRIER); |
7436 } else { | 7435 } else { |
7437 int offset = current_offset - inobject_props; | 7436 int offset = current_offset - inobject_props; |
7438 FixedArray::cast(fields)->set(offset, value); | 7437 FixedArray::cast(fields)->set(offset, value); |
7439 } | 7438 } |
7440 FieldDescriptor d(String::cast(key), | 7439 FieldDescriptor d(String::cast(key), |
7441 current_offset++, | 7440 current_offset++, |
7442 details.attributes(), | 7441 details.attributes(), |
7443 details.index()); | 7442 details.index()); |
7444 w.Write(&d); | 7443 descriptors->Set(next_descriptor++, &d); |
7445 } else if (type == CALLBACKS) { | 7444 } else if (type == CALLBACKS) { |
7446 CallbacksDescriptor d(String::cast(key), | 7445 CallbacksDescriptor d(String::cast(key), |
7447 value, | 7446 value, |
7448 details.attributes(), | 7447 details.attributes(), |
7449 details.index()); | 7448 details.index()); |
7450 w.Write(&d); | 7449 descriptors->Set(next_descriptor++, &d); |
7451 } else { | 7450 } else { |
7452 UNREACHABLE(); | 7451 UNREACHABLE(); |
7453 } | 7452 } |
7454 } | 7453 } |
7455 } | 7454 } |
7456 ASSERT(current_offset == number_of_fields); | 7455 ASSERT(current_offset == number_of_fields); |
7457 | 7456 |
7458 descriptors->Sort(); | 7457 descriptors->Sort(); |
7459 // Allocate new map. | 7458 // Allocate new map. |
7460 Object* new_map = obj->map()->CopyDropDescriptors(); | 7459 Object* new_map = obj->map()->CopyDropDescriptors(); |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7717 if (break_point_objects()->IsUndefined()) return 0; | 7716 if (break_point_objects()->IsUndefined()) return 0; |
7718 // Single beak point. | 7717 // Single beak point. |
7719 if (!break_point_objects()->IsFixedArray()) return 1; | 7718 if (!break_point_objects()->IsFixedArray()) return 1; |
7720 // Multiple break points. | 7719 // Multiple break points. |
7721 return FixedArray::cast(break_point_objects())->length(); | 7720 return FixedArray::cast(break_point_objects())->length(); |
7722 } | 7721 } |
7723 #endif | 7722 #endif |
7724 | 7723 |
7725 | 7724 |
7726 } } // namespace v8::internal | 7725 } } // namespace v8::internal |
OLD | NEW |