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

Side by Side Diff: src/objects.cc

Issue 40218: Fix garbage collection of unused maps. Null descriptors, created... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 9 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
« no previous file with comments | « src/objects.h ('k') | src/property.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/property.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698