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 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 static Object* Runtime_CloneShallowLiteralBoilerplate(Arguments args) { | 205 static Object* Runtime_CloneShallowLiteralBoilerplate(Arguments args) { |
206 CONVERT_CHECKED(JSObject, boilerplate, args[0]); | 206 CONVERT_CHECKED(JSObject, boilerplate, args[0]); |
207 return Heap::CopyJSObject(boilerplate); | 207 return Heap::CopyJSObject(boilerplate); |
208 } | 208 } |
209 | 209 |
210 | 210 |
211 static Handle<Map> ComputeObjectLiteralMap( | 211 static Handle<Map> ComputeObjectLiteralMap( |
212 Handle<Context> context, | 212 Handle<Context> context, |
213 Handle<FixedArray> constant_properties, | 213 Handle<FixedArray> constant_properties, |
214 bool* is_result_from_cache) { | 214 bool* is_result_from_cache) { |
215 int number_of_properties = constant_properties->length() / 2; | 215 int properties_length = constant_properties->length(); |
| 216 int number_of_properties = properties_length / 2; |
216 if (FLAG_canonicalize_object_literal_maps) { | 217 if (FLAG_canonicalize_object_literal_maps) { |
217 // First find prefix of consecutive symbol keys. | 218 // Check that there are only symbols and array indices among keys. |
218 int number_of_symbol_keys = 0; | 219 int number_of_symbol_keys = 0; |
219 while ((number_of_symbol_keys < number_of_properties) && | 220 for (int p = 0; p != properties_length; p += 2) { |
220 (constant_properties->get(number_of_symbol_keys*2)->IsSymbol())) { | 221 Object* key = constant_properties->get(p); |
221 number_of_symbol_keys++; | 222 uint32_t element_index = 0; |
| 223 if (key->IsSymbol()) { |
| 224 number_of_symbol_keys++; |
| 225 } else if (key->ToArrayIndex(&element_index)) { |
| 226 // An index key does not require space in the property backing store. |
| 227 number_of_properties--; |
| 228 } else { |
| 229 // Bail out as a non-symbol non-index key makes caching impossible. |
| 230 // ASSERT to make sure that the if condition after the loop is false. |
| 231 ASSERT(number_of_symbol_keys != number_of_properties); |
| 232 break; |
| 233 } |
222 } | 234 } |
223 // Based on the number of prefix symbols key we decide whether | 235 // If we only have symbols and array indices among keys then we can |
224 // to use the map cache in the global context. | 236 // use the map cache in the global context. |
225 const int kMaxKeys = 10; | 237 const int kMaxKeys = 10; |
226 if ((number_of_symbol_keys == number_of_properties) && | 238 if ((number_of_symbol_keys == number_of_properties) && |
227 (number_of_symbol_keys < kMaxKeys)) { | 239 (number_of_symbol_keys < kMaxKeys)) { |
228 // Create the fixed array with the key. | 240 // Create the fixed array with the key. |
229 Handle<FixedArray> keys = Factory::NewFixedArray(number_of_symbol_keys); | 241 Handle<FixedArray> keys = Factory::NewFixedArray(number_of_symbol_keys); |
230 for (int i = 0; i < number_of_symbol_keys; i++) { | 242 if (number_of_symbol_keys > 0) { |
231 keys->set(i, constant_properties->get(i*2)); | 243 int index = 0; |
| 244 for (int p = 0; p < properties_length; p += 2) { |
| 245 Object* key = constant_properties->get(p); |
| 246 if (key->IsSymbol()) { |
| 247 keys->set(index++, key); |
| 248 } |
| 249 } |
| 250 ASSERT(index == number_of_symbol_keys); |
232 } | 251 } |
233 *is_result_from_cache = true; | 252 *is_result_from_cache = true; |
234 return Factory::ObjectLiteralMapFromCache(context, keys); | 253 return Factory::ObjectLiteralMapFromCache(context, keys); |
235 } | 254 } |
236 } | 255 } |
237 *is_result_from_cache = false; | 256 *is_result_from_cache = false; |
238 return Factory::CopyMap( | 257 return Factory::CopyMap( |
239 Handle<Map>(context->object_function()->initial_map()), | 258 Handle<Map>(context->object_function()->initial_map()), |
240 number_of_properties); | 259 number_of_properties); |
241 } | 260 } |
(...skipping 10302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10544 } else { | 10563 } else { |
10545 // Handle last resort GC and make sure to allow future allocations | 10564 // Handle last resort GC and make sure to allow future allocations |
10546 // to grow the heap without causing GCs (if possible). | 10565 // to grow the heap without causing GCs (if possible). |
10547 Counters::gc_last_resort_from_js.Increment(); | 10566 Counters::gc_last_resort_from_js.Increment(); |
10548 Heap::CollectAllGarbage(false); | 10567 Heap::CollectAllGarbage(false); |
10549 } | 10568 } |
10550 } | 10569 } |
10551 | 10570 |
10552 | 10571 |
10553 } } // namespace v8::internal | 10572 } } // namespace v8::internal |
OLD | NEW |