OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 } | 266 } |
267 | 267 |
268 | 268 |
269 static Handle<Map> ComputeObjectLiteralMap( | 269 static Handle<Map> ComputeObjectLiteralMap( |
270 Handle<Context> context, | 270 Handle<Context> context, |
271 Handle<FixedArray> constant_properties, | 271 Handle<FixedArray> constant_properties, |
272 bool* is_result_from_cache) { | 272 bool* is_result_from_cache) { |
273 Isolate* isolate = context->GetIsolate(); | 273 Isolate* isolate = context->GetIsolate(); |
274 int properties_length = constant_properties->length(); | 274 int properties_length = constant_properties->length(); |
275 int number_of_properties = properties_length / 2; | 275 int number_of_properties = properties_length / 2; |
276 if (FLAG_canonicalize_object_literal_maps) { | 276 // Check that there are only symbols and array indices among keys. |
277 // Check that there are only symbols and array indices among keys. | 277 int number_of_symbol_keys = 0; |
278 int number_of_symbol_keys = 0; | 278 for (int p = 0; p != properties_length; p += 2) { |
279 for (int p = 0; p != properties_length; p += 2) { | 279 Object* key = constant_properties->get(p); |
280 Object* key = constant_properties->get(p); | 280 uint32_t element_index = 0; |
281 uint32_t element_index = 0; | 281 if (key->IsSymbol()) { |
282 if (key->IsSymbol()) { | 282 number_of_symbol_keys++; |
283 number_of_symbol_keys++; | 283 } else if (key->ToArrayIndex(&element_index)) { |
284 } else if (key->ToArrayIndex(&element_index)) { | 284 // An index key does not require space in the property backing store. |
285 // An index key does not require space in the property backing store. | 285 number_of_properties--; |
286 number_of_properties--; | 286 } else { |
287 } else { | 287 // Bail out as a non-symbol non-index key makes caching impossible. |
288 // Bail out as a non-symbol non-index key makes caching impossible. | 288 // ASSERT to make sure that the if condition after the loop is false. |
289 // ASSERT to make sure that the if condition after the loop is false. | 289 ASSERT(number_of_symbol_keys != number_of_properties); |
290 ASSERT(number_of_symbol_keys != number_of_properties); | 290 break; |
291 break; | 291 } |
| 292 } |
| 293 // If we only have symbols and array indices among keys then we can |
| 294 // use the map cache in the global context. |
| 295 const int kMaxKeys = 10; |
| 296 if ((number_of_symbol_keys == number_of_properties) && |
| 297 (number_of_symbol_keys < kMaxKeys)) { |
| 298 // Create the fixed array with the key. |
| 299 Handle<FixedArray> keys = |
| 300 isolate->factory()->NewFixedArray(number_of_symbol_keys); |
| 301 if (number_of_symbol_keys > 0) { |
| 302 int index = 0; |
| 303 for (int p = 0; p < properties_length; p += 2) { |
| 304 Object* key = constant_properties->get(p); |
| 305 if (key->IsSymbol()) { |
| 306 keys->set(index++, key); |
| 307 } |
292 } | 308 } |
| 309 ASSERT(index == number_of_symbol_keys); |
293 } | 310 } |
294 // If we only have symbols and array indices among keys then we can | 311 *is_result_from_cache = true; |
295 // use the map cache in the global context. | 312 return isolate->factory()->ObjectLiteralMapFromCache(context, keys); |
296 const int kMaxKeys = 10; | |
297 if ((number_of_symbol_keys == number_of_properties) && | |
298 (number_of_symbol_keys < kMaxKeys)) { | |
299 // Create the fixed array with the key. | |
300 Handle<FixedArray> keys = | |
301 isolate->factory()->NewFixedArray(number_of_symbol_keys); | |
302 if (number_of_symbol_keys > 0) { | |
303 int index = 0; | |
304 for (int p = 0; p < properties_length; p += 2) { | |
305 Object* key = constant_properties->get(p); | |
306 if (key->IsSymbol()) { | |
307 keys->set(index++, key); | |
308 } | |
309 } | |
310 ASSERT(index == number_of_symbol_keys); | |
311 } | |
312 *is_result_from_cache = true; | |
313 return isolate->factory()->ObjectLiteralMapFromCache(context, keys); | |
314 } | |
315 } | 313 } |
316 *is_result_from_cache = false; | 314 *is_result_from_cache = false; |
317 return isolate->factory()->CopyMap( | 315 return isolate->factory()->CopyMap( |
318 Handle<Map>(context->object_function()->initial_map()), | 316 Handle<Map>(context->object_function()->initial_map()), |
319 number_of_properties); | 317 number_of_properties); |
320 } | 318 } |
321 | 319 |
322 | 320 |
323 static Handle<Object> CreateLiteralBoilerplate( | 321 static Handle<Object> CreateLiteralBoilerplate( |
324 Isolate* isolate, | 322 Isolate* isolate, |
(...skipping 13331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13656 // Handle last resort GC and make sure to allow future allocations | 13654 // Handle last resort GC and make sure to allow future allocations |
13657 // to grow the heap without causing GCs (if possible). | 13655 // to grow the heap without causing GCs (if possible). |
13658 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13656 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13659 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13657 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13660 "Runtime::PerformGC"); | 13658 "Runtime::PerformGC"); |
13661 } | 13659 } |
13662 } | 13660 } |
13663 | 13661 |
13664 | 13662 |
13665 } } // namespace v8::internal | 13663 } } // namespace v8::internal |
OLD | NEW |