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/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 2533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2544 } | 2544 } |
2545 } else { | 2545 } else { |
2546 Jump(adaptor, RelocInfo::CODE_TARGET); | 2546 Jump(adaptor, RelocInfo::CODE_TARGET); |
2547 } | 2547 } |
2548 } | 2548 } |
2549 Bind(®ular_invoke); | 2549 Bind(®ular_invoke); |
2550 } | 2550 } |
2551 | 2551 |
2552 | 2552 |
2553 void MacroAssembler::InvokeCode(Register code, | 2553 void MacroAssembler::InvokeCode(Register code, |
| 2554 Register new_target, |
2554 const ParameterCount& expected, | 2555 const ParameterCount& expected, |
2555 const ParameterCount& actual, | 2556 const ParameterCount& actual, |
2556 InvokeFlag flag, | 2557 InvokeFlag flag, |
2557 const CallWrapper& call_wrapper) { | 2558 const CallWrapper& call_wrapper) { |
2558 // You can't call a function without a valid frame. | 2559 // You can't call a function without a valid frame. |
2559 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 2560 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
2560 | 2561 |
| 2562 // Ensure new target is passed in the correct register. Otherwise clear the |
| 2563 // appropriate register in case new target is not given. |
| 2564 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(x3)); |
| 2565 if (!new_target.is_valid()) { |
| 2566 LoadRoot(x3, Heap::kUndefinedValueRootIndex); |
| 2567 } |
| 2568 |
2561 Label done; | 2569 Label done; |
2562 | |
2563 bool definitely_mismatches = false; | 2570 bool definitely_mismatches = false; |
2564 InvokePrologue(expected, actual, &done, flag, &definitely_mismatches, | 2571 InvokePrologue(expected, actual, &done, flag, &definitely_mismatches, |
2565 call_wrapper); | 2572 call_wrapper); |
2566 | 2573 |
2567 // If we are certain that actual != expected, then we know InvokePrologue will | 2574 // If we are certain that actual != expected, then we know InvokePrologue will |
2568 // have handled the call through the argument adaptor mechanism. | 2575 // have handled the call through the argument adaptor mechanism. |
2569 // The called function expects the call kind in x5. | 2576 // The called function expects the call kind in x5. |
2570 if (!definitely_mismatches) { | 2577 if (!definitely_mismatches) { |
2571 if (flag == CALL_FUNCTION) { | 2578 if (flag == CALL_FUNCTION) { |
2572 call_wrapper.BeforeCall(CallSize(code)); | 2579 call_wrapper.BeforeCall(CallSize(code)); |
2573 Call(code); | 2580 Call(code); |
2574 call_wrapper.AfterCall(); | 2581 call_wrapper.AfterCall(); |
2575 } else { | 2582 } else { |
2576 DCHECK(flag == JUMP_FUNCTION); | 2583 DCHECK(flag == JUMP_FUNCTION); |
2577 Jump(code); | 2584 Jump(code); |
2578 } | 2585 } |
2579 } | 2586 } |
2580 | 2587 |
2581 // Continue here if InvokePrologue does handle the invocation due to | 2588 // Continue here if InvokePrologue does handle the invocation due to |
2582 // mismatched parameter counts. | 2589 // mismatched parameter counts. |
2583 Bind(&done); | 2590 Bind(&done); |
2584 } | 2591 } |
2585 | 2592 |
2586 | 2593 |
2587 void MacroAssembler::InvokeFunction(Register function, | 2594 void MacroAssembler::InvokeFunction(Register function, |
| 2595 Register new_target, |
2588 const ParameterCount& actual, | 2596 const ParameterCount& actual, |
2589 InvokeFlag flag, | 2597 InvokeFlag flag, |
2590 const CallWrapper& call_wrapper) { | 2598 const CallWrapper& call_wrapper) { |
2591 // You can't call a function without a valid frame. | 2599 // You can't call a function without a valid frame. |
2592 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 2600 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
2593 | 2601 |
2594 // Contract with called JS functions requires that function is passed in x1. | 2602 // Contract with called JS functions requires that function is passed in x1. |
2595 // (See FullCodeGenerator::Generate().) | 2603 // (See FullCodeGenerator::Generate().) |
2596 DCHECK(function.is(x1)); | 2604 DCHECK(function.is(x1)); |
2597 | 2605 |
2598 Register expected_reg = x2; | 2606 Register expected_reg = x2; |
2599 Register code_reg = x3; | 2607 Register code_reg = x4; |
2600 | 2608 |
2601 Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); | 2609 Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); |
2602 // The number of arguments is stored as an int32_t, and -1 is a marker | 2610 // The number of arguments is stored as an int32_t, and -1 is a marker |
2603 // (SharedFunctionInfo::kDontAdaptArgumentsSentinel), so we need sign | 2611 // (SharedFunctionInfo::kDontAdaptArgumentsSentinel), so we need sign |
2604 // extension to correctly handle it. | 2612 // extension to correctly handle it. |
2605 Ldr(expected_reg, FieldMemOperand(function, | 2613 Ldr(expected_reg, FieldMemOperand(function, |
2606 JSFunction::kSharedFunctionInfoOffset)); | 2614 JSFunction::kSharedFunctionInfoOffset)); |
2607 Ldrsw(expected_reg, | 2615 Ldrsw(expected_reg, |
2608 FieldMemOperand(expected_reg, | 2616 FieldMemOperand(expected_reg, |
2609 SharedFunctionInfo::kFormalParameterCountOffset)); | 2617 SharedFunctionInfo::kFormalParameterCountOffset)); |
2610 Ldr(code_reg, | 2618 Ldr(code_reg, |
2611 FieldMemOperand(function, JSFunction::kCodeEntryOffset)); | 2619 FieldMemOperand(function, JSFunction::kCodeEntryOffset)); |
2612 | 2620 |
2613 ParameterCount expected(expected_reg); | 2621 ParameterCount expected(expected_reg); |
2614 InvokeCode(code_reg, expected, actual, flag, call_wrapper); | 2622 InvokeCode(code_reg, new_target, expected, actual, flag, call_wrapper); |
2615 } | 2623 } |
2616 | 2624 |
2617 | 2625 |
2618 void MacroAssembler::InvokeFunction(Register function, | 2626 void MacroAssembler::InvokeFunction(Register function, |
2619 const ParameterCount& expected, | 2627 const ParameterCount& expected, |
2620 const ParameterCount& actual, | 2628 const ParameterCount& actual, |
2621 InvokeFlag flag, | 2629 InvokeFlag flag, |
2622 const CallWrapper& call_wrapper) { | 2630 const CallWrapper& call_wrapper) { |
2623 // You can't call a function without a valid frame. | 2631 // You can't call a function without a valid frame. |
2624 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 2632 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
2625 | 2633 |
2626 // Contract with called JS functions requires that function is passed in x1. | 2634 // Contract with called JS functions requires that function is passed in x1. |
2627 // (See FullCodeGenerator::Generate().) | 2635 // (See FullCodeGenerator::Generate().) |
2628 DCHECK(function.Is(x1)); | 2636 DCHECK(function.Is(x1)); |
2629 | 2637 |
2630 Register code_reg = x3; | 2638 Register code_reg = x4; |
2631 | 2639 |
2632 // Set up the context. | 2640 // Set up the context. |
2633 Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); | 2641 Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); |
2634 | 2642 |
2635 // We call indirectly through the code field in the function to | 2643 // We call indirectly through the code field in the function to |
2636 // allow recompilation to take effect without changing any of the | 2644 // allow recompilation to take effect without changing any of the |
2637 // call sites. | 2645 // call sites. |
2638 Ldr(code_reg, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); | 2646 Ldr(code_reg, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); |
2639 InvokeCode(code_reg, expected, actual, flag, call_wrapper); | 2647 InvokeCode(code_reg, no_reg, expected, actual, flag, call_wrapper); |
2640 } | 2648 } |
2641 | 2649 |
2642 | 2650 |
2643 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, | 2651 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, |
2644 const ParameterCount& expected, | 2652 const ParameterCount& expected, |
2645 const ParameterCount& actual, | 2653 const ParameterCount& actual, |
2646 InvokeFlag flag, | 2654 InvokeFlag flag, |
2647 const CallWrapper& call_wrapper) { | 2655 const CallWrapper& call_wrapper) { |
2648 // Contract with called JS functions requires that function is passed in x1. | 2656 // Contract with called JS functions requires that function is passed in x1. |
2649 // (See FullCodeGenerator::Generate().) | 2657 // (See FullCodeGenerator::Generate().) |
(...skipping 2413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5063 } | 5071 } |
5064 | 5072 |
5065 | 5073 |
5066 #undef __ | 5074 #undef __ |
5067 | 5075 |
5068 | 5076 |
5069 } // namespace internal | 5077 } // namespace internal |
5070 } // namespace v8 | 5078 } // namespace v8 |
5071 | 5079 |
5072 #endif // V8_TARGET_ARCH_ARM64 | 5080 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |