| 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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
| 6 | 6 |
| 7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 3618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3629 } | 3629 } |
| 3630 | 3630 |
| 3631 Label fast_elements_case; | 3631 Label fast_elements_case; |
| 3632 __ CompareAndBranch(kind, FAST_ELEMENTS, eq, &fast_elements_case); | 3632 __ CompareAndBranch(kind, FAST_ELEMENTS, eq, &fast_elements_case); |
| 3633 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 3633 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
| 3634 | 3634 |
| 3635 __ Bind(&fast_elements_case); | 3635 __ Bind(&fast_elements_case); |
| 3636 GenerateCase(masm, FAST_ELEMENTS); | 3636 GenerateCase(masm, FAST_ELEMENTS); |
| 3637 } | 3637 } |
| 3638 | 3638 |
| 3639 | |
| 3640 void FastNewObjectStub::Generate(MacroAssembler* masm) { | |
| 3641 // ----------- S t a t e ------------- | |
| 3642 // -- x1 : target | |
| 3643 // -- x3 : new target | |
| 3644 // -- cp : context | |
| 3645 // -- lr : return address | |
| 3646 // ----------------------------------- | |
| 3647 __ AssertFunction(x1); | |
| 3648 __ AssertReceiver(x3); | |
| 3649 | |
| 3650 // Verify that the new target is a JSFunction. | |
| 3651 Label new_object; | |
| 3652 __ JumpIfNotObjectType(x3, x2, x2, JS_FUNCTION_TYPE, &new_object); | |
| 3653 | |
| 3654 // Load the initial map and verify that it's in fact a map. | |
| 3655 __ Ldr(x2, FieldMemOperand(x3, JSFunction::kPrototypeOrInitialMapOffset)); | |
| 3656 __ JumpIfSmi(x2, &new_object); | |
| 3657 __ JumpIfNotObjectType(x2, x0, x0, MAP_TYPE, &new_object); | |
| 3658 | |
| 3659 // Fall back to runtime if the target differs from the new target's | |
| 3660 // initial map constructor. | |
| 3661 __ Ldr(x0, FieldMemOperand(x2, Map::kConstructorOrBackPointerOffset)); | |
| 3662 __ CompareAndBranch(x0, x1, ne, &new_object); | |
| 3663 | |
| 3664 // Allocate the JSObject on the heap. | |
| 3665 Label allocate, done_allocate; | |
| 3666 __ Ldrb(x4, FieldMemOperand(x2, Map::kInstanceSizeOffset)); | |
| 3667 __ Allocate(x4, x0, x5, x6, &allocate, SIZE_IN_WORDS); | |
| 3668 __ Bind(&done_allocate); | |
| 3669 | |
| 3670 // Initialize the JSObject fields. | |
| 3671 STATIC_ASSERT(JSObject::kMapOffset == 0 * kPointerSize); | |
| 3672 __ Str(x2, FieldMemOperand(x0, JSObject::kMapOffset)); | |
| 3673 __ LoadRoot(x3, Heap::kEmptyFixedArrayRootIndex); | |
| 3674 STATIC_ASSERT(JSObject::kPropertiesOffset == 1 * kPointerSize); | |
| 3675 STATIC_ASSERT(JSObject::kElementsOffset == 2 * kPointerSize); | |
| 3676 __ Str(x3, FieldMemOperand(x0, JSObject::kPropertiesOffset)); | |
| 3677 __ Str(x3, FieldMemOperand(x0, JSObject::kElementsOffset)); | |
| 3678 STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize); | |
| 3679 __ Add(x1, x0, Operand(JSObject::kHeaderSize - kHeapObjectTag)); | |
| 3680 | |
| 3681 // ----------- S t a t e ------------- | |
| 3682 // -- x0 : result (tagged) | |
| 3683 // -- x1 : result fields (untagged) | |
| 3684 // -- x5 : result end (untagged) | |
| 3685 // -- x2 : initial map | |
| 3686 // -- cp : context | |
| 3687 // -- lr : return address | |
| 3688 // ----------------------------------- | |
| 3689 | |
| 3690 // Perform in-object slack tracking if requested. | |
| 3691 Label slack_tracking; | |
| 3692 STATIC_ASSERT(Map::kNoSlackTracking == 0); | |
| 3693 __ LoadRoot(x6, Heap::kUndefinedValueRootIndex); | |
| 3694 __ Ldr(w3, FieldMemOperand(x2, Map::kBitField3Offset)); | |
| 3695 __ TestAndBranchIfAnySet(w3, Map::ConstructionCounter::kMask, | |
| 3696 &slack_tracking); | |
| 3697 { | |
| 3698 // Initialize all in-object fields with undefined. | |
| 3699 __ InitializeFieldsWithFiller(x1, x5, x6); | |
| 3700 __ Ret(); | |
| 3701 } | |
| 3702 __ Bind(&slack_tracking); | |
| 3703 { | |
| 3704 // Decrease generous allocation count. | |
| 3705 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); | |
| 3706 __ Sub(w3, w3, 1 << Map::ConstructionCounter::kShift); | |
| 3707 __ Str(w3, FieldMemOperand(x2, Map::kBitField3Offset)); | |
| 3708 | |
| 3709 // Initialize the in-object fields with undefined. | |
| 3710 __ Ldrb(x4, FieldMemOperand(x2, Map::kUnusedPropertyFieldsOffset)); | |
| 3711 __ Sub(x4, x5, Operand(x4, LSL, kPointerSizeLog2)); | |
| 3712 __ InitializeFieldsWithFiller(x1, x4, x6); | |
| 3713 | |
| 3714 // Initialize the remaining (reserved) fields with one pointer filler map. | |
| 3715 __ LoadRoot(x6, Heap::kOnePointerFillerMapRootIndex); | |
| 3716 __ InitializeFieldsWithFiller(x1, x5, x6); | |
| 3717 | |
| 3718 // Check if we can finalize the instance size. | |
| 3719 Label finalize; | |
| 3720 STATIC_ASSERT(Map::kSlackTrackingCounterEnd == 1); | |
| 3721 __ TestAndBranchIfAllClear(w3, Map::ConstructionCounter::kMask, &finalize); | |
| 3722 __ Ret(); | |
| 3723 | |
| 3724 // Finalize the instance size. | |
| 3725 __ Bind(&finalize); | |
| 3726 { | |
| 3727 FrameScope scope(masm, StackFrame::INTERNAL); | |
| 3728 __ Push(x0, x2); | |
| 3729 __ CallRuntime(Runtime::kFinalizeInstanceSize); | |
| 3730 __ Pop(x0); | |
| 3731 } | |
| 3732 __ Ret(); | |
| 3733 } | |
| 3734 | |
| 3735 // Fall back to %AllocateInNewSpace. | |
| 3736 __ Bind(&allocate); | |
| 3737 { | |
| 3738 FrameScope scope(masm, StackFrame::INTERNAL); | |
| 3739 STATIC_ASSERT(kSmiTag == 0); | |
| 3740 STATIC_ASSERT(kSmiTagSize == 1); | |
| 3741 __ Mov(x4, | |
| 3742 Operand(x4, LSL, kPointerSizeLog2 + kSmiTagSize + kSmiShiftSize)); | |
| 3743 __ Push(x2, x4); | |
| 3744 __ CallRuntime(Runtime::kAllocateInNewSpace); | |
| 3745 __ Pop(x2); | |
| 3746 } | |
| 3747 __ Ldrb(x5, FieldMemOperand(x2, Map::kInstanceSizeOffset)); | |
| 3748 __ Add(x5, x0, Operand(x5, LSL, kPointerSizeLog2)); | |
| 3749 STATIC_ASSERT(kHeapObjectTag == 1); | |
| 3750 __ Sub(x5, x5, kHeapObjectTag); // Subtract the tag from end. | |
| 3751 __ B(&done_allocate); | |
| 3752 | |
| 3753 // Fall back to %NewObject. | |
| 3754 __ Bind(&new_object); | |
| 3755 __ Push(x1, x3); | |
| 3756 __ TailCallRuntime(Runtime::kNewObject); | |
| 3757 } | |
| 3758 | |
| 3759 | |
| 3760 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { | 3639 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |
| 3761 // ----------- S t a t e ------------- | 3640 // ----------- S t a t e ------------- |
| 3762 // -- x1 : function | 3641 // -- x1 : function |
| 3763 // -- cp : context | 3642 // -- cp : context |
| 3764 // -- fp : frame pointer | 3643 // -- fp : frame pointer |
| 3765 // -- lr : return address | 3644 // -- lr : return address |
| 3766 // ----------------------------------- | 3645 // ----------------------------------- |
| 3767 __ AssertFunction(x1); | 3646 __ AssertFunction(x1); |
| 3768 | 3647 |
| 3769 // Make x2 point to the JavaScript frame. | 3648 // Make x2 point to the JavaScript frame. |
| (...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4673 kStackUnwindSpace, NULL, spill_offset, | 4552 kStackUnwindSpace, NULL, spill_offset, |
| 4674 return_value_operand, NULL); | 4553 return_value_operand, NULL); |
| 4675 } | 4554 } |
| 4676 | 4555 |
| 4677 #undef __ | 4556 #undef __ |
| 4678 | 4557 |
| 4679 } // namespace internal | 4558 } // namespace internal |
| 4680 } // namespace v8 | 4559 } // namespace v8 |
| 4681 | 4560 |
| 4682 #endif // V8_TARGET_ARCH_ARM64 | 4561 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |