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/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 2967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2978 ASM_LOCATION("CallFunctionStub::Generate"); | 2978 ASM_LOCATION("CallFunctionStub::Generate"); |
2979 CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod()); | 2979 CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod()); |
2980 } | 2980 } |
2981 | 2981 |
2982 | 2982 |
2983 void CallConstructStub::Generate(MacroAssembler* masm) { | 2983 void CallConstructStub::Generate(MacroAssembler* masm) { |
2984 ASM_LOCATION("CallConstructStub::Generate"); | 2984 ASM_LOCATION("CallConstructStub::Generate"); |
2985 // x0 : number of arguments | 2985 // x0 : number of arguments |
2986 // x1 : the function to call | 2986 // x1 : the function to call |
2987 // x2 : feedback vector | 2987 // x2 : feedback vector |
2988 // x3 : slot in feedback vector (smi) (if r2 is not the megamorphic symbol) | 2988 // x3 : slot in feedback vector (Smi, for RecordCallTarget) |
| 2989 // x4 : original constructor (for IsSuperConstructorCall) |
2989 Register function = x1; | 2990 Register function = x1; |
2990 Label slow, non_function_call; | 2991 Label slow, non_function_call; |
2991 | 2992 |
2992 // Check that the function is not a smi. | 2993 // Check that the function is not a smi. |
2993 __ JumpIfSmi(function, &non_function_call); | 2994 __ JumpIfSmi(function, &non_function_call); |
2994 // Check that the function is a JSFunction. | 2995 // Check that the function is a JSFunction. |
2995 Register object_type = x10; | 2996 Register object_type = x10; |
2996 __ JumpIfNotObjectType(function, object_type, object_type, JS_FUNCTION_TYPE, | 2997 __ JumpIfNotObjectType(function, object_type, object_type, JS_FUNCTION_TYPE, |
2997 &slow); | 2998 &slow); |
2998 | 2999 |
2999 if (RecordCallTarget()) { | 3000 if (RecordCallTarget()) { |
| 3001 if (IsSuperConstructorCall()) { |
| 3002 __ Push(x4); |
| 3003 } |
| 3004 // TODO(mstarzinger): Consider tweaking target recording to avoid push/pop. |
3000 GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5, x11); | 3005 GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5, x11); |
| 3006 if (IsSuperConstructorCall()) { |
| 3007 __ Pop(x4); |
| 3008 } |
3001 | 3009 |
3002 __ Add(x5, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2)); | 3010 __ Add(x5, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2)); |
3003 if (FLAG_pretenuring_call_new) { | 3011 if (FLAG_pretenuring_call_new) { |
3004 // Put the AllocationSite from the feedback vector into x2. | 3012 // Put the AllocationSite from the feedback vector into x2. |
3005 // By adding kPointerSize we encode that we know the AllocationSite | 3013 // By adding kPointerSize we encode that we know the AllocationSite |
3006 // entry is at the feedback vector slot given by x3 + 1. | 3014 // entry is at the feedback vector slot given by x3 + 1. |
3007 __ Ldr(x2, FieldMemOperand(x5, FixedArray::kHeaderSize + kPointerSize)); | 3015 __ Ldr(x2, FieldMemOperand(x5, FixedArray::kHeaderSize + kPointerSize)); |
3008 } else { | 3016 } else { |
3009 Label feedback_register_initialized; | 3017 Label feedback_register_initialized; |
3010 // Put the AllocationSite from the feedback vector into x2, or undefined. | 3018 // Put the AllocationSite from the feedback vector into x2, or undefined. |
3011 __ Ldr(x2, FieldMemOperand(x5, FixedArray::kHeaderSize)); | 3019 __ Ldr(x2, FieldMemOperand(x5, FixedArray::kHeaderSize)); |
3012 __ Ldr(x5, FieldMemOperand(x2, AllocationSite::kMapOffset)); | 3020 __ Ldr(x5, FieldMemOperand(x2, AllocationSite::kMapOffset)); |
3013 __ JumpIfRoot(x5, Heap::kAllocationSiteMapRootIndex, | 3021 __ JumpIfRoot(x5, Heap::kAllocationSiteMapRootIndex, |
3014 &feedback_register_initialized); | 3022 &feedback_register_initialized); |
3015 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); | 3023 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); |
3016 __ bind(&feedback_register_initialized); | 3024 __ bind(&feedback_register_initialized); |
3017 } | 3025 } |
3018 | 3026 |
3019 __ AssertUndefinedOrAllocationSite(x2, x5); | 3027 __ AssertUndefinedOrAllocationSite(x2, x5); |
3020 } | 3028 } |
3021 | 3029 |
3022 if (IsSuperConstructorCall()) { | 3030 if (IsSuperConstructorCall()) { |
3023 __ Mov(x4, Operand(1 * kPointerSize)); | 3031 __ Mov(x3, x4); |
3024 __ Add(x4, x4, Operand(x0, LSL, kPointerSizeLog2)); | |
3025 __ Peek(x3, x4); | |
3026 } else { | 3032 } else { |
3027 __ Mov(x3, function); | 3033 __ Mov(x3, function); |
3028 } | 3034 } |
3029 | 3035 |
3030 // Jump to the function-specific construct stub. | 3036 // Jump to the function-specific construct stub. |
3031 Register jump_reg = x4; | 3037 Register jump_reg = x4; |
3032 Register shared_func_info = jump_reg; | 3038 Register shared_func_info = jump_reg; |
3033 Register cons_stub = jump_reg; | 3039 Register cons_stub = jump_reg; |
3034 Register cons_stub_code = jump_reg; | 3040 Register cons_stub_code = jump_reg; |
3035 __ Ldr(shared_func_info, | 3041 __ Ldr(shared_func_info, |
(...skipping 2791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5827 MemOperand(fp, 6 * kPointerSize), NULL); | 5833 MemOperand(fp, 6 * kPointerSize), NULL); |
5828 } | 5834 } |
5829 | 5835 |
5830 | 5836 |
5831 #undef __ | 5837 #undef __ |
5832 | 5838 |
5833 } // namespace internal | 5839 } // namespace internal |
5834 } // namespace v8 | 5840 } // namespace v8 |
5835 | 5841 |
5836 #endif // V8_TARGET_ARCH_ARM64 | 5842 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |