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

Side by Side Diff: src/objects.cc

Issue 160382: Avoid dictionary expansion during bootstrapping (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 4 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/runtime.cc » ('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-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 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 } 1237 }
1238 1238
1239 1239
1240 Object* JSObject::AddFastProperty(String* name, 1240 Object* JSObject::AddFastProperty(String* name,
1241 Object* value, 1241 Object* value,
1242 PropertyAttributes attributes) { 1242 PropertyAttributes attributes) {
1243 // Normalize the object if the name is an actual string (not the 1243 // Normalize the object if the name is an actual string (not the
1244 // hidden symbols) and is not a real identifier. 1244 // hidden symbols) and is not a real identifier.
1245 StringInputBuffer buffer(name); 1245 StringInputBuffer buffer(name);
1246 if (!Scanner::IsIdentifier(&buffer) && name != Heap::hidden_symbol()) { 1246 if (!Scanner::IsIdentifier(&buffer) && name != Heap::hidden_symbol()) {
1247 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); 1247 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1248 if (obj->IsFailure()) return obj; 1248 if (obj->IsFailure()) return obj;
1249 return AddSlowProperty(name, value, attributes); 1249 return AddSlowProperty(name, value, attributes);
1250 } 1250 }
1251 1251
1252 DescriptorArray* old_descriptors = map()->instance_descriptors(); 1252 DescriptorArray* old_descriptors = map()->instance_descriptors();
1253 // Compute the new index for new field. 1253 // Compute the new index for new field.
1254 int index = map()->NextFreePropertyIndex(); 1254 int index = map()->NextFreePropertyIndex();
1255 1255
1256 // Allocate new instance descriptors with (name, index) added 1256 // Allocate new instance descriptors with (name, index) added
1257 FieldDescriptor new_field(name, index, attributes); 1257 FieldDescriptor new_field(name, index, attributes);
(...skipping 17 matching lines...) Expand all
1275 if (allow_map_transition) { 1275 if (allow_map_transition) {
1276 // Allocate new instance descriptors for the old map with map transition. 1276 // Allocate new instance descriptors for the old map with map transition.
1277 MapTransitionDescriptor d(name, Map::cast(new_map), attributes); 1277 MapTransitionDescriptor d(name, Map::cast(new_map), attributes);
1278 Object* r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS); 1278 Object* r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS);
1279 if (r->IsFailure()) return r; 1279 if (r->IsFailure()) return r;
1280 old_descriptors = DescriptorArray::cast(r); 1280 old_descriptors = DescriptorArray::cast(r);
1281 } 1281 }
1282 1282
1283 if (map()->unused_property_fields() == 0) { 1283 if (map()->unused_property_fields() == 0) {
1284 if (properties()->length() > kMaxFastProperties) { 1284 if (properties()->length() > kMaxFastProperties) {
1285 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); 1285 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1286 if (obj->IsFailure()) return obj; 1286 if (obj->IsFailure()) return obj;
1287 return AddSlowProperty(name, value, attributes); 1287 return AddSlowProperty(name, value, attributes);
1288 } 1288 }
1289 // Make room for the new value 1289 // Make room for the new value
1290 Object* values = 1290 Object* values =
1291 properties()->CopySize(properties()->length() + kFieldsAdded); 1291 properties()->CopySize(properties()->length() + kFieldsAdded);
1292 if (values->IsFailure()) return values; 1292 if (values->IsFailure()) return values;
1293 set_properties(FixedArray::cast(values)); 1293 set_properties(FixedArray::cast(values));
1294 new_map->set_unused_property_fields(kFieldsAdded - 1); 1294 new_map->set_unused_property_fields(kFieldsAdded - 1);
1295 } else { 1295 } else {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 if (value->IsJSFunction()) { 1396 if (value->IsJSFunction()) {
1397 return AddConstantFunctionProperty(name, 1397 return AddConstantFunctionProperty(name,
1398 JSFunction::cast(value), 1398 JSFunction::cast(value),
1399 attributes); 1399 attributes);
1400 } else { 1400 } else {
1401 return AddFastProperty(name, value, attributes); 1401 return AddFastProperty(name, value, attributes);
1402 } 1402 }
1403 } else { 1403 } else {
1404 // Normalize the object to prevent very large instance descriptors. 1404 // Normalize the object to prevent very large instance descriptors.
1405 // This eliminates unwanted N^2 allocation and lookup behavior. 1405 // This eliminates unwanted N^2 allocation and lookup behavior.
1406 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); 1406 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1407 if (obj->IsFailure()) return obj; 1407 if (obj->IsFailure()) return obj;
1408 } 1408 }
1409 } 1409 }
1410 return AddSlowProperty(name, value, attributes); 1410 return AddSlowProperty(name, value, attributes);
1411 } 1411 }
1412 1412
1413 1413
1414 Object* JSObject::SetPropertyPostInterceptor(String* name, 1414 Object* JSObject::SetPropertyPostInterceptor(String* name,
1415 Object* value, 1415 Object* value,
1416 PropertyAttributes attributes) { 1416 PropertyAttributes attributes) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); 1466 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
1467 return result; 1467 return result;
1468 } 1468 }
1469 1469
1470 1470
1471 Object* JSObject::ConvertDescriptorToField(String* name, 1471 Object* JSObject::ConvertDescriptorToField(String* name,
1472 Object* new_value, 1472 Object* new_value,
1473 PropertyAttributes attributes) { 1473 PropertyAttributes attributes) {
1474 if (map()->unused_property_fields() == 0 && 1474 if (map()->unused_property_fields() == 0 &&
1475 properties()->length() > kMaxFastProperties) { 1475 properties()->length() > kMaxFastProperties) {
1476 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); 1476 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1477 if (obj->IsFailure()) return obj; 1477 if (obj->IsFailure()) return obj;
1478 return ReplaceSlowProperty(name, new_value, attributes); 1478 return ReplaceSlowProperty(name, new_value, attributes);
1479 } 1479 }
1480 1480
1481 int index = map()->NextFreePropertyIndex(); 1481 int index = map()->NextFreePropertyIndex();
1482 FieldDescriptor new_field(name, index, attributes); 1482 FieldDescriptor new_field(name, index, attributes);
1483 // Make a new DescriptorArray replacing an entry with FieldDescriptor. 1483 // Make a new DescriptorArray replacing an entry with FieldDescriptor.
1484 Object* descriptors_unchecked = map()->instance_descriptors()-> 1484 Object* descriptors_unchecked = map()->instance_descriptors()->
1485 CopyInsert(&new_field, REMOVE_TRANSITIONS); 1485 CopyInsert(&new_field, REMOVE_TRANSITIONS);
1486 if (descriptors_unchecked->IsFailure()) return descriptors_unchecked; 1486 if (descriptors_unchecked->IsFailure()) return descriptors_unchecked;
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after
2117 if (HasLocalElement(index)) return NONE; 2117 if (HasLocalElement(index)) return NONE;
2118 return ABSENT; 2118 return ABSENT;
2119 } 2119 }
2120 // Named property. 2120 // Named property.
2121 LookupResult result; 2121 LookupResult result;
2122 LocalLookup(name, &result); 2122 LocalLookup(name, &result);
2123 return GetPropertyAttribute(this, &result, name, false); 2123 return GetPropertyAttribute(this, &result, name, false);
2124 } 2124 }
2125 2125
2126 2126
2127 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) { 2127 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
2128 int expected_additional_properties) {
2128 if (!HasFastProperties()) return this; 2129 if (!HasFastProperties()) return this;
2129 2130
2130 // The global object is always normalized. 2131 // The global object is always normalized.
2131 ASSERT(!IsGlobalObject()); 2132 ASSERT(!IsGlobalObject());
2132 2133
2133 // Allocate new content. 2134 // Allocate new content.
2135 int property_count = map()->NumberOfDescribedProperties();
2136 if (expected_additional_properties > 0) {
2137 property_count += expected_additional_properties;
2138 } else {
2139 property_count += 2; // Make space for two more properties.
2140 }
2134 Object* obj = 2141 Object* obj =
2135 StringDictionary::Allocate(map()->NumberOfDescribedProperties() * 2 + 4); 2142 StringDictionary::Allocate(property_count * 2);
2136 if (obj->IsFailure()) return obj; 2143 if (obj->IsFailure()) return obj;
2137 StringDictionary* dictionary = StringDictionary::cast(obj); 2144 StringDictionary* dictionary = StringDictionary::cast(obj);
2138 2145
2139 DescriptorArray* descs = map()->instance_descriptors(); 2146 DescriptorArray* descs = map()->instance_descriptors();
2140 for (int i = 0; i < descs->number_of_descriptors(); i++) { 2147 for (int i = 0; i < descs->number_of_descriptors(); i++) {
2141 PropertyDetails details = descs->GetDetails(i); 2148 PropertyDetails details = descs->GetDetails(i);
2142 switch (details.type()) { 2149 switch (details.type()) {
2143 case CONSTANT_FUNCTION: { 2150 case CONSTANT_FUNCTION: {
2144 PropertyDetails d = 2151 PropertyDetails d =
2145 PropertyDetails(details.attributes(), NORMAL, details.index()); 2152 PropertyDetails(details.attributes(), NORMAL, details.index());
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
2265 } 2272 }
2266 2273
2267 2274
2268 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) { 2275 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) {
2269 // Check local property, ignore interceptor. 2276 // Check local property, ignore interceptor.
2270 LookupResult result; 2277 LookupResult result;
2271 LocalLookupRealNamedProperty(name, &result); 2278 LocalLookupRealNamedProperty(name, &result);
2272 if (!result.IsValid()) return Heap::true_value(); 2279 if (!result.IsValid()) return Heap::true_value();
2273 2280
2274 // Normalize object if needed. 2281 // Normalize object if needed.
2275 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); 2282 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2276 if (obj->IsFailure()) return obj; 2283 if (obj->IsFailure()) return obj;
2277 2284
2278 return DeleteNormalizedProperty(name, mode); 2285 return DeleteNormalizedProperty(name, mode);
2279 } 2286 }
2280 2287
2281 2288
2282 Object* JSObject::DeletePropertyWithInterceptor(String* name) { 2289 Object* JSObject::DeletePropertyWithInterceptor(String* name) {
2283 HandleScope scope; 2290 HandleScope scope;
2284 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); 2291 Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
2285 Handle<String> name_handle(name); 2292 Handle<String> name_handle(name);
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
2462 return DeletePropertyPostInterceptor(name, mode); 2469 return DeletePropertyPostInterceptor(name, mode);
2463 } 2470 }
2464 return DeletePropertyWithInterceptor(name); 2471 return DeletePropertyWithInterceptor(name);
2465 } 2472 }
2466 if (!result.IsLoaded()) { 2473 if (!result.IsLoaded()) {
2467 return JSObject::cast(this)->DeleteLazyProperty(&result, 2474 return JSObject::cast(this)->DeleteLazyProperty(&result,
2468 name, 2475 name,
2469 mode); 2476 mode);
2470 } 2477 }
2471 // Normalize object if needed. 2478 // Normalize object if needed.
2472 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); 2479 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2473 if (obj->IsFailure()) return obj; 2480 if (obj->IsFailure()) return obj;
2474 // Make sure the properties are normalized before removing the entry. 2481 // Make sure the properties are normalized before removing the entry.
2475 return DeleteNormalizedProperty(name, mode); 2482 return DeleteNormalizedProperty(name, mode);
2476 } 2483 }
2477 } 2484 }
2478 2485
2479 2486
2480 // Check whether this object references another object. 2487 // Check whether this object references another object.
2481 bool JSObject::ReferencesObject(Object* obj) { 2488 bool JSObject::ReferencesObject(Object* obj) {
2482 AssertNoAllocation no_alloc; 2489 AssertNoAllocation no_alloc;
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
2795 element_dictionary()->Set(index, structure, details); 2802 element_dictionary()->Set(index, structure, details);
2796 if (dict->IsFailure()) return dict; 2803 if (dict->IsFailure()) return dict;
2797 2804
2798 // If name is an index we need to stay in slow case. 2805 // If name is an index we need to stay in slow case.
2799 NumberDictionary* elements = NumberDictionary::cast(dict); 2806 NumberDictionary* elements = NumberDictionary::cast(dict);
2800 elements->set_requires_slow_elements(); 2807 elements->set_requires_slow_elements();
2801 // Set the potential new dictionary on the object. 2808 // Set the potential new dictionary on the object.
2802 set_elements(NumberDictionary::cast(dict)); 2809 set_elements(NumberDictionary::cast(dict));
2803 } else { 2810 } else {
2804 // Normalize object to make this operation simple. 2811 // Normalize object to make this operation simple.
2805 Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); 2812 Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2806 if (ok->IsFailure()) return ok; 2813 if (ok->IsFailure()) return ok;
2807 2814
2808 // For the global object allocate a new map to invalidate the global inline 2815 // For the global object allocate a new map to invalidate the global inline
2809 // caches which have a global property cell reference directly in the code. 2816 // caches which have a global property cell reference directly in the code.
2810 if (IsGlobalObject()) { 2817 if (IsGlobalObject()) {
2811 Object* new_map = map()->CopyDropDescriptors(); 2818 Object* new_map = map()->CopyDropDescriptors();
2812 if (new_map->IsFailure()) return new_map; 2819 if (new_map->IsFailure()) return new_map;
2813 set_map(Map::cast(new_map)); 2820 set_map(Map::cast(new_map));
2814 } 2821 }
2815 2822
(...skipping 5099 matching lines...) Expand 10 before | Expand all | Expand 10 after
7915 if (break_point_objects()->IsUndefined()) return 0; 7922 if (break_point_objects()->IsUndefined()) return 0;
7916 // Single beak point. 7923 // Single beak point.
7917 if (!break_point_objects()->IsFixedArray()) return 1; 7924 if (!break_point_objects()->IsFixedArray()) return 1;
7918 // Multiple break points. 7925 // Multiple break points.
7919 return FixedArray::cast(break_point_objects())->length(); 7926 return FixedArray::cast(break_point_objects())->length();
7920 } 7927 }
7921 #endif 7928 #endif
7922 7929
7923 7930
7924 } } // namespace v8::internal 7931 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698