| 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 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |