| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/debug.h" | 10 #include "src/debug.h" |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 __ Cmp(constructor, original_constructor); | 372 __ Cmp(constructor, original_constructor); |
| 373 __ B(eq, &normal_new); | 373 __ B(eq, &normal_new); |
| 374 Generate_Runtime_NewObject(masm, create_memento, original_constructor, | 374 Generate_Runtime_NewObject(masm, create_memento, original_constructor, |
| 375 &count_incremented, &allocated); | 375 &count_incremented, &allocated); |
| 376 | 376 |
| 377 __ Bind(&normal_new); | 377 __ Bind(&normal_new); |
| 378 | 378 |
| 379 // Try to allocate the object without transitioning into C code. If any of | 379 // Try to allocate the object without transitioning into C code. If any of |
| 380 // the preconditions is not met, the code bails out to the runtime call. | 380 // the preconditions is not met, the code bails out to the runtime call. |
| 381 if (FLAG_inline_new) { | 381 if (FLAG_inline_new) { |
| 382 Label undo_allocation; | |
| 383 ExternalReference debug_step_in_fp = | 382 ExternalReference debug_step_in_fp = |
| 384 ExternalReference::debug_step_in_fp_address(isolate); | 383 ExternalReference::debug_step_in_fp_address(isolate); |
| 385 __ Mov(x2, Operand(debug_step_in_fp)); | 384 __ Mov(x2, Operand(debug_step_in_fp)); |
| 386 __ Ldr(x2, MemOperand(x2)); | 385 __ Ldr(x2, MemOperand(x2)); |
| 387 __ Cbnz(x2, &rt_call); | 386 __ Cbnz(x2, &rt_call); |
| 388 // Load the initial map and verify that it is in fact a map. | 387 // Load the initial map and verify that it is in fact a map. |
| 389 Register init_map = x2; | 388 Register init_map = x2; |
| 390 __ Ldr(init_map, | 389 __ Ldr(init_map, |
| 391 FieldMemOperand(constructor, | 390 FieldMemOperand(constructor, |
| 392 JSFunction::kPrototypeOrInitialMapOffset)); | 391 JSFunction::kPrototypeOrInitialMapOffset)); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 | 447 |
| 449 Register first_prop = x5; | 448 Register first_prop = x5; |
| 450 __ Add(first_prop, new_obj, JSObject::kHeaderSize); | 449 __ Add(first_prop, new_obj, JSObject::kHeaderSize); |
| 451 | 450 |
| 452 // Fill all of the in-object properties with the appropriate filler. | 451 // Fill all of the in-object properties with the appropriate filler. |
| 453 Register filler = x7; | 452 Register filler = x7; |
| 454 __ LoadRoot(filler, Heap::kUndefinedValueRootIndex); | 453 __ LoadRoot(filler, Heap::kUndefinedValueRootIndex); |
| 455 | 454 |
| 456 // Obtain number of pre-allocated property fields and in-object | 455 // Obtain number of pre-allocated property fields and in-object |
| 457 // properties. | 456 // properties. |
| 457 Register unused_props = x10; |
| 458 Register inobject_props = x11; |
| 459 Register inst_sizes_or_attrs = x11; |
| 458 Register prealloc_fields = x10; | 460 Register prealloc_fields = x10; |
| 459 Register inobject_props = x11; | 461 __ Ldr(inst_sizes_or_attrs, |
| 460 Register inst_sizes = x11; | 462 FieldMemOperand(init_map, Map::kInstanceAttributesOffset)); |
| 461 __ Ldr(inst_sizes, FieldMemOperand(init_map, Map::kInstanceSizesOffset)); | 463 __ Ubfx(unused_props, inst_sizes_or_attrs, |
| 462 __ Ubfx(prealloc_fields, inst_sizes, | 464 Map::kUnusedPropertyFieldsByte * kBitsPerByte, kBitsPerByte); |
| 463 Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, | 465 __ Ldr(inst_sizes_or_attrs, |
| 464 kBitsPerByte); | 466 FieldMemOperand(init_map, Map::kInstanceSizesOffset)); |
| 465 __ Ubfx(inobject_props, inst_sizes, | 467 __ Ubfx(inobject_props, inst_sizes_or_attrs, |
| 466 Map::kInObjectPropertiesByte * kBitsPerByte, kBitsPerByte); | 468 Map::kInObjectPropertiesByte * kBitsPerByte, kBitsPerByte); |
| 469 __ Sub(prealloc_fields, inobject_props, unused_props); |
| 467 | 470 |
| 468 // Calculate number of property fields in the object. | 471 // Calculate number of property fields in the object. |
| 469 Register prop_fields = x6; | 472 Register prop_fields = x6; |
| 470 __ Sub(prop_fields, obj_size, JSObject::kHeaderSize / kPointerSize); | 473 __ Sub(prop_fields, obj_size, JSObject::kHeaderSize / kPointerSize); |
| 471 | 474 |
| 472 if (!is_api_function) { | 475 if (!is_api_function) { |
| 473 Label no_inobject_slack_tracking; | 476 Label no_inobject_slack_tracking; |
| 474 | 477 |
| 475 // Check if slack tracking is enabled. | 478 // Check if slack tracking is enabled. |
| 476 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); | 479 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex)); | 514 __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex)); |
| 512 first_prop = NoReg; | 515 first_prop = NoReg; |
| 513 } else { | 516 } else { |
| 514 // Fill all of the property fields with undef. | 517 // Fill all of the property fields with undef. |
| 515 __ FillFields(first_prop, prop_fields, filler); | 518 __ FillFields(first_prop, prop_fields, filler); |
| 516 first_prop = NoReg; | 519 first_prop = NoReg; |
| 517 prop_fields = NoReg; | 520 prop_fields = NoReg; |
| 518 } | 521 } |
| 519 | 522 |
| 520 // Add the object tag to make the JSObject real, so that we can continue | 523 // Add the object tag to make the JSObject real, so that we can continue |
| 521 // and jump into the continuation code at any time from now on. Any | 524 // and jump into the continuation code at any time from now on. |
| 522 // failures need to undo the allocation, so that the heap is in a | |
| 523 // consistent state and verifiable. | |
| 524 __ Add(new_obj, new_obj, kHeapObjectTag); | 525 __ Add(new_obj, new_obj, kHeapObjectTag); |
| 525 | 526 |
| 526 // Check if a non-empty properties array is needed. Continue with | |
| 527 // allocated object if not; allocate and initialize a FixedArray if yes. | |
| 528 Register element_count = x3; | |
| 529 __ Ldrb(element_count, | |
| 530 FieldMemOperand(init_map, Map::kUnusedPropertyFieldsOffset)); | |
| 531 // The field instance sizes contains both pre-allocated property fields | |
| 532 // and in-object properties. | |
| 533 __ Add(element_count, element_count, prealloc_fields); | |
| 534 __ Subs(element_count, element_count, inobject_props); | |
| 535 | |
| 536 // Done if no extra properties are to be allocated. | |
| 537 __ B(eq, &allocated); | |
| 538 __ Assert(pl, kPropertyAllocationCountFailed); | |
| 539 | |
| 540 // Scale the number of elements by pointer size and add the header for | |
| 541 // FixedArrays to the start of the next object calculation from above. | |
| 542 Register new_array = x5; | |
| 543 Register array_size = x6; | |
| 544 __ Add(array_size, element_count, FixedArray::kHeaderSize / kPointerSize); | |
| 545 __ Allocate(array_size, new_array, x11, x12, &undo_allocation, | |
| 546 static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | | |
| 547 SIZE_IN_WORDS)); | |
| 548 | |
| 549 Register array_map = x10; | |
| 550 __ LoadRoot(array_map, Heap::kFixedArrayMapRootIndex); | |
| 551 __ Str(array_map, MemOperand(new_array, FixedArray::kMapOffset)); | |
| 552 __ SmiTag(x0, element_count); | |
| 553 __ Str(x0, MemOperand(new_array, FixedArray::kLengthOffset)); | |
| 554 | |
| 555 // Initialize the fields to undefined. | |
| 556 Register elements = x10; | |
| 557 __ Add(elements, new_array, FixedArray::kHeaderSize); | |
| 558 __ FillFields(elements, element_count, filler); | |
| 559 | |
| 560 // Store the initialized FixedArray into the properties field of the | |
| 561 // JSObject. | |
| 562 __ Add(new_array, new_array, kHeapObjectTag); | |
| 563 __ Str(new_array, FieldMemOperand(new_obj, JSObject::kPropertiesOffset)); | |
| 564 | |
| 565 // Continue with JSObject being successfully allocated. | 527 // Continue with JSObject being successfully allocated. |
| 566 __ B(&allocated); | 528 __ B(&allocated); |
| 567 | |
| 568 // Undo the setting of the new top so that the heap is verifiable. For | |
| 569 // example, the map's unused properties potentially do not match the | |
| 570 // allocated objects unused properties. | |
| 571 __ Bind(&undo_allocation); | |
| 572 __ UndoAllocationInNewSpace(new_obj, x14); | |
| 573 } | 529 } |
| 574 | 530 |
| 575 // Allocate the new receiver object using the runtime call. | 531 // Allocate the new receiver object using the runtime call. |
| 576 __ Bind(&rt_call); | 532 __ Bind(&rt_call); |
| 577 Generate_Runtime_NewObject(masm, create_memento, constructor, | 533 Generate_Runtime_NewObject(masm, create_memento, constructor, |
| 578 &count_incremented, &allocated); | 534 &count_incremented, &allocated); |
| 579 | 535 |
| 580 // Receiver for constructor call allocated. | 536 // Receiver for constructor call allocated. |
| 581 // x4: JSObject | 537 // x4: JSObject |
| 582 __ Bind(&allocated); | 538 __ Bind(&allocated); |
| (...skipping 1256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1839 } | 1795 } |
| 1840 } | 1796 } |
| 1841 | 1797 |
| 1842 | 1798 |
| 1843 #undef __ | 1799 #undef __ |
| 1844 | 1800 |
| 1845 } // namespace internal | 1801 } // namespace internal |
| 1846 } // namespace v8 | 1802 } // namespace v8 |
| 1847 | 1803 |
| 1848 #endif // V8_TARGET_ARCH_ARM | 1804 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |