OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 Register new_obj = x4; | 408 Register new_obj = x4; |
409 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); | 409 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); |
410 __ Allocate(obj_size, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS); | 410 __ Allocate(obj_size, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS); |
411 | 411 |
412 // Allocated the JSObject, now initialize the fields. Map is set to | 412 // Allocated the JSObject, now initialize the fields. Map is set to |
413 // initial map and properties and elements are set to empty fixed array. | 413 // initial map and properties and elements are set to empty fixed array. |
414 // NB. the object pointer is not tagged, so MemOperand is used. | 414 // NB. the object pointer is not tagged, so MemOperand is used. |
415 Register empty = x5; | 415 Register empty = x5; |
416 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); | 416 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); |
417 __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset)); | 417 __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset)); |
418 __ Str(empty, MemOperand(new_obj, JSObject::kPropertiesOffset)); | 418 STATIC_ASSERT(JSObject::kElementsOffset == |
419 __ Str(empty, MemOperand(new_obj, JSObject::kElementsOffset)); | 419 (JSObject::kPropertiesOffset + kPointerSize)); |
| 420 __ Stp(empty, empty, MemOperand(new_obj, JSObject::kPropertiesOffset)); |
420 | 421 |
421 Register first_prop = x5; | 422 Register first_prop = x5; |
422 __ Add(first_prop, new_obj, JSObject::kHeaderSize); | 423 __ Add(first_prop, new_obj, JSObject::kHeaderSize); |
423 | 424 |
424 // Fill all of the in-object properties with the appropriate filler. | 425 // Fill all of the in-object properties with the appropriate filler. |
425 Register obj_end = x6; | |
426 __ Add(obj_end, new_obj, Operand(obj_size, LSL, kPointerSizeLog2)); | |
427 Register undef = x7; | 426 Register undef = x7; |
428 __ LoadRoot(undef, Heap::kUndefinedValueRootIndex); | 427 __ LoadRoot(undef, Heap::kUndefinedValueRootIndex); |
429 | 428 |
430 // Obtain number of pre-allocated property fields and in-object | 429 // Obtain number of pre-allocated property fields and in-object |
431 // properties. | 430 // properties. |
432 Register prealloc_fields = x10; | 431 Register prealloc_fields = x10; |
433 Register inobject_props = x11; | 432 Register inobject_props = x11; |
434 Register inst_sizes = x11; | 433 Register inst_sizes = x11; |
435 __ Ldr(inst_sizes, FieldMemOperand(init_map, Map::kInstanceSizesOffset)); | 434 __ Ldr(inst_sizes, FieldMemOperand(init_map, Map::kInstanceSizesOffset)); |
436 __ Ubfx(prealloc_fields, inst_sizes, | 435 __ Ubfx(prealloc_fields, inst_sizes, |
437 Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, | 436 Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, |
438 kBitsPerByte); | 437 kBitsPerByte); |
439 __ Ubfx(inobject_props, inst_sizes, | 438 __ Ubfx(inobject_props, inst_sizes, |
440 Map::kInObjectPropertiesByte * kBitsPerByte, kBitsPerByte); | 439 Map::kInObjectPropertiesByte * kBitsPerByte, kBitsPerByte); |
441 | 440 |
| 441 // Calculate number of property fields in the object. |
| 442 Register prop_fields = x6; |
| 443 __ Sub(prop_fields, obj_size, JSObject::kHeaderSize / kPointerSize); |
| 444 |
442 if (count_constructions) { | 445 if (count_constructions) { |
| 446 // Fill the pre-allocated fields with undef. |
| 447 __ FillFields(first_prop, prealloc_fields, undef); |
| 448 |
443 // Register first_non_prealloc is the offset of the first field after | 449 // Register first_non_prealloc is the offset of the first field after |
444 // pre-allocated fields. | 450 // pre-allocated fields. |
445 Register first_non_prealloc = x12; | 451 Register first_non_prealloc = x12; |
446 __ Add(first_non_prealloc, first_prop, | 452 __ Add(first_non_prealloc, first_prop, |
447 Operand(prealloc_fields, LSL, kPointerSizeLog2)); | 453 Operand(prealloc_fields, LSL, kPointerSizeLog2)); |
448 | 454 |
| 455 first_prop = NoReg; |
| 456 |
449 if (FLAG_debug_code) { | 457 if (FLAG_debug_code) { |
| 458 Register obj_end = x5; |
| 459 __ Add(obj_end, new_obj, Operand(obj_size, LSL, kPointerSizeLog2)); |
450 __ Cmp(first_non_prealloc, obj_end); | 460 __ Cmp(first_non_prealloc, obj_end); |
451 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); | 461 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); |
452 } | 462 } |
453 __ InitializeFieldsWithFiller(first_prop, first_non_prealloc, undef); | 463 |
454 // To allow for truncation. | 464 // Fill the remaining fields with one pointer filler map. |
455 __ LoadRoot(x12, Heap::kOnePointerFillerMapRootIndex); | 465 Register one_pointer_filler = x5; |
456 __ InitializeFieldsWithFiller(first_prop, obj_end, x12); | 466 Register non_prealloc_fields = x6; |
| 467 __ LoadRoot(one_pointer_filler, Heap::kOnePointerFillerMapRootIndex); |
| 468 __ Sub(non_prealloc_fields, prop_fields, prealloc_fields); |
| 469 __ FillFields(first_non_prealloc, non_prealloc_fields, |
| 470 one_pointer_filler); |
| 471 prop_fields = NoReg; |
457 } else { | 472 } else { |
458 __ InitializeFieldsWithFiller(first_prop, obj_end, undef); | 473 // Fill all of the property fields with undef. |
| 474 __ FillFields(first_prop, prop_fields, undef); |
| 475 first_prop = NoReg; |
| 476 prop_fields = NoReg; |
459 } | 477 } |
460 | 478 |
461 // Add the object tag to make the JSObject real, so that we can continue | 479 // Add the object tag to make the JSObject real, so that we can continue |
462 // and jump into the continuation code at any time from now on. Any | 480 // and jump into the continuation code at any time from now on. Any |
463 // failures need to undo the allocation, so that the heap is in a | 481 // failures need to undo the allocation, so that the heap is in a |
464 // consistent state and verifiable. | 482 // consistent state and verifiable. |
465 __ Add(new_obj, new_obj, kHeapObjectTag); | 483 __ Add(new_obj, new_obj, kHeapObjectTag); |
466 | 484 |
467 // Check if a non-empty properties array is needed. Continue with | 485 // Check if a non-empty properties array is needed. Continue with |
468 // allocated object if not, or fall through to runtime call if it is. | 486 // allocated object if not, or fall through to runtime call if it is. |
469 Register element_count = x3; | 487 Register element_count = x3; |
470 __ Ldrb(x3, FieldMemOperand(init_map, Map::kUnusedPropertyFieldsOffset)); | 488 __ Ldrb(element_count, |
| 489 FieldMemOperand(init_map, Map::kUnusedPropertyFieldsOffset)); |
471 // The field instance sizes contains both pre-allocated property fields | 490 // The field instance sizes contains both pre-allocated property fields |
472 // and in-object properties. | 491 // and in-object properties. |
473 __ Add(x3, x3, prealloc_fields); | 492 __ Add(element_count, element_count, prealloc_fields); |
474 __ Subs(element_count, x3, inobject_props); | 493 __ Subs(element_count, element_count, inobject_props); |
475 | 494 |
476 // Done if no extra properties are to be allocated. | 495 // Done if no extra properties are to be allocated. |
477 __ B(eq, &allocated); | 496 __ B(eq, &allocated); |
478 __ Assert(pl, kPropertyAllocationCountFailed); | 497 __ Assert(pl, kPropertyAllocationCountFailed); |
479 | 498 |
480 // Scale the number of elements by pointer size and add the header for | 499 // Scale the number of elements by pointer size and add the header for |
481 // FixedArrays to the start of the next object calculation from above. | 500 // FixedArrays to the start of the next object calculation from above. |
482 Register new_array = x5; | 501 Register new_array = x5; |
483 Register array_size = x6; | 502 Register array_size = x6; |
484 __ Add(array_size, element_count, FixedArray::kHeaderSize / kPointerSize); | 503 __ Add(array_size, element_count, FixedArray::kHeaderSize / kPointerSize); |
485 __ Allocate(array_size, new_array, x11, x12, &undo_allocation, | 504 __ Allocate(array_size, new_array, x11, x12, &undo_allocation, |
486 static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | | 505 static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | |
487 SIZE_IN_WORDS)); | 506 SIZE_IN_WORDS)); |
488 | 507 |
489 Register array_map = x10; | 508 Register array_map = x10; |
490 __ LoadRoot(array_map, Heap::kFixedArrayMapRootIndex); | 509 __ LoadRoot(array_map, Heap::kFixedArrayMapRootIndex); |
491 __ Str(array_map, MemOperand(new_array, FixedArray::kMapOffset)); | 510 __ Str(array_map, MemOperand(new_array, FixedArray::kMapOffset)); |
492 __ SmiTag(x0, element_count); | 511 __ SmiTag(x0, element_count); |
493 __ Str(x0, MemOperand(new_array, FixedArray::kLengthOffset)); | 512 __ Str(x0, MemOperand(new_array, FixedArray::kLengthOffset)); |
494 | 513 |
495 // Initialize the fields to undefined. | 514 // Initialize the fields to undefined. |
496 Register elements = x10; | 515 Register elements = x10; |
497 Register elements_end = x11; | |
498 __ Add(elements, new_array, FixedArray::kHeaderSize); | 516 __ Add(elements, new_array, FixedArray::kHeaderSize); |
499 __ Add(elements_end, elements, | 517 __ FillFields(elements, element_count, undef); |
500 Operand(element_count, LSL, kPointerSizeLog2)); | |
501 __ InitializeFieldsWithFiller(elements, elements_end, undef); | |
502 | 518 |
503 // Store the initialized FixedArray into the properties field of the | 519 // Store the initialized FixedArray into the properties field of the |
504 // JSObject. | 520 // JSObject. |
505 __ Add(new_array, new_array, kHeapObjectTag); | 521 __ Add(new_array, new_array, kHeapObjectTag); |
506 __ Str(new_array, FieldMemOperand(new_obj, JSObject::kPropertiesOffset)); | 522 __ Str(new_array, FieldMemOperand(new_obj, JSObject::kPropertiesOffset)); |
507 | 523 |
508 // Continue with JSObject being successfully allocated. | 524 // Continue with JSObject being successfully allocated. |
509 __ B(&allocated); | 525 __ B(&allocated); |
510 | 526 |
511 // Undo the setting of the new top so that the heap is verifiable. For | 527 // Undo the setting of the new top so that the heap is verifiable. For |
(...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1484 __ Bind(&dont_adapt_arguments); | 1500 __ Bind(&dont_adapt_arguments); |
1485 __ Jump(code_entry); | 1501 __ Jump(code_entry); |
1486 } | 1502 } |
1487 | 1503 |
1488 | 1504 |
1489 #undef __ | 1505 #undef __ |
1490 | 1506 |
1491 } } // namespace v8::internal | 1507 } } // namespace v8::internal |
1492 | 1508 |
1493 #endif // V8_TARGET_ARCH_ARM | 1509 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |