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 |