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 2463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2474 // goto not_unique_name | 2474 // goto not_unique_name |
2475 // } | 2475 // } |
2476 Tst(type, kIsNotStringMask | kIsNotInternalizedMask); | 2476 Tst(type, kIsNotStringMask | kIsNotInternalizedMask); |
2477 Ccmp(type, SYMBOL_TYPE, ZFlag, ne); | 2477 Ccmp(type, SYMBOL_TYPE, ZFlag, ne); |
2478 B(ne, not_unique_name); | 2478 B(ne, not_unique_name); |
2479 } | 2479 } |
2480 | 2480 |
2481 | 2481 |
2482 void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 2482 void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
2483 const ParameterCount& actual, | 2483 const ParameterCount& actual, |
2484 Handle<Code> code_constant, | |
2485 Register code_reg, | |
2486 Label* done, | 2484 Label* done, |
2487 InvokeFlag flag, | 2485 InvokeFlag flag, |
2488 bool* definitely_mismatches, | 2486 bool* definitely_mismatches, |
2489 const CallWrapper& call_wrapper) { | 2487 const CallWrapper& call_wrapper) { |
2490 bool definitely_matches = false; | 2488 bool definitely_matches = false; |
2491 *definitely_mismatches = false; | 2489 *definitely_mismatches = false; |
2492 Label regular_invoke; | 2490 Label regular_invoke; |
2493 | 2491 |
2494 // Check whether the expected and actual arguments count match. If not, | 2492 // Check whether the expected and actual arguments count match. If not, |
2495 // setup registers according to contract with ArgumentsAdaptorTrampoline: | 2493 // setup registers according to contract with ArgumentsAdaptorTrampoline: |
2496 // x0: actual arguments count. | 2494 // x0: actual arguments count. |
2497 // x1: function (passed through to callee). | 2495 // x1: function (passed through to callee). |
2498 // x2: expected arguments count. | 2496 // x2: expected arguments count. |
2499 | 2497 |
2500 // The code below is made a lot easier because the calling code already sets | 2498 // The code below is made a lot easier because the calling code already sets |
2501 // up actual and expected registers according to the contract if values are | 2499 // up actual and expected registers according to the contract if values are |
2502 // passed in registers. | 2500 // passed in registers. |
2503 DCHECK(actual.is_immediate() || actual.reg().is(x0)); | 2501 DCHECK(actual.is_immediate() || actual.reg().is(x0)); |
2504 DCHECK(expected.is_immediate() || expected.reg().is(x2)); | 2502 DCHECK(expected.is_immediate() || expected.reg().is(x2)); |
2505 DCHECK((!code_constant.is_null() && code_reg.is(no_reg)) || code_reg.is(x3)); | |
2506 | 2503 |
2507 if (expected.is_immediate()) { | 2504 if (expected.is_immediate()) { |
2508 DCHECK(actual.is_immediate()); | 2505 DCHECK(actual.is_immediate()); |
2509 Mov(x0, actual.immediate()); | 2506 Mov(x0, actual.immediate()); |
2510 if (expected.immediate() == actual.immediate()) { | 2507 if (expected.immediate() == actual.immediate()) { |
2511 definitely_matches = true; | 2508 definitely_matches = true; |
2512 | 2509 |
2513 } else { | 2510 } else { |
2514 if (expected.immediate() == | 2511 if (expected.immediate() == |
2515 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { | 2512 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { |
(...skipping 14 matching lines...) Expand all Loading... |
2530 : Operand(actual.reg()); | 2527 : Operand(actual.reg()); |
2531 Mov(x0, actual_op); | 2528 Mov(x0, actual_op); |
2532 // If actual == expected perform a regular invocation. | 2529 // If actual == expected perform a regular invocation. |
2533 Cmp(expected.reg(), actual_op); | 2530 Cmp(expected.reg(), actual_op); |
2534 B(eq, ®ular_invoke); | 2531 B(eq, ®ular_invoke); |
2535 } | 2532 } |
2536 | 2533 |
2537 // If the argument counts may mismatch, generate a call to the argument | 2534 // If the argument counts may mismatch, generate a call to the argument |
2538 // adaptor. | 2535 // adaptor. |
2539 if (!definitely_matches) { | 2536 if (!definitely_matches) { |
2540 if (!code_constant.is_null()) { | |
2541 Mov(x3, Operand(code_constant)); | |
2542 Add(x3, x3, Code::kHeaderSize - kHeapObjectTag); | |
2543 } | |
2544 | |
2545 Handle<Code> adaptor = | 2537 Handle<Code> adaptor = |
2546 isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 2538 isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
2547 if (flag == CALL_FUNCTION) { | 2539 if (flag == CALL_FUNCTION) { |
2548 call_wrapper.BeforeCall(CallSize(adaptor)); | 2540 call_wrapper.BeforeCall(CallSize(adaptor)); |
2549 Call(adaptor); | 2541 Call(adaptor); |
2550 call_wrapper.AfterCall(); | 2542 call_wrapper.AfterCall(); |
2551 if (!*definitely_mismatches) { | 2543 if (!*definitely_mismatches) { |
2552 // If the arg counts don't match, no extra code is emitted by | 2544 // If the arg counts don't match, no extra code is emitted by |
2553 // MAsm::InvokeCode and we can just fall through. | 2545 // MAsm::InvokeCode and we can just fall through. |
2554 B(done); | 2546 B(done); |
(...skipping 10 matching lines...) Expand all Loading... |
2565 const ParameterCount& expected, | 2557 const ParameterCount& expected, |
2566 const ParameterCount& actual, | 2558 const ParameterCount& actual, |
2567 InvokeFlag flag, | 2559 InvokeFlag flag, |
2568 const CallWrapper& call_wrapper) { | 2560 const CallWrapper& call_wrapper) { |
2569 // You can't call a function without a valid frame. | 2561 // You can't call a function without a valid frame. |
2570 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 2562 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
2571 | 2563 |
2572 Label done; | 2564 Label done; |
2573 | 2565 |
2574 bool definitely_mismatches = false; | 2566 bool definitely_mismatches = false; |
2575 InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag, | 2567 InvokePrologue(expected, actual, &done, flag, &definitely_mismatches, |
2576 &definitely_mismatches, call_wrapper); | 2568 call_wrapper); |
2577 | 2569 |
2578 // If we are certain that actual != expected, then we know InvokePrologue will | 2570 // If we are certain that actual != expected, then we know InvokePrologue will |
2579 // have handled the call through the argument adaptor mechanism. | 2571 // have handled the call through the argument adaptor mechanism. |
2580 // The called function expects the call kind in x5. | 2572 // The called function expects the call kind in x5. |
2581 if (!definitely_mismatches) { | 2573 if (!definitely_mismatches) { |
2582 if (flag == CALL_FUNCTION) { | 2574 if (flag == CALL_FUNCTION) { |
2583 call_wrapper.BeforeCall(CallSize(code)); | 2575 call_wrapper.BeforeCall(CallSize(code)); |
2584 Call(code); | 2576 Call(code); |
2585 call_wrapper.AfterCall(); | 2577 call_wrapper.AfterCall(); |
2586 } else { | 2578 } else { |
(...skipping 2490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5077 } | 5069 } |
5078 | 5070 |
5079 | 5071 |
5080 #undef __ | 5072 #undef __ |
5081 | 5073 |
5082 | 5074 |
5083 } // namespace internal | 5075 } // namespace internal |
5084 } // namespace v8 | 5076 } // namespace v8 |
5085 | 5077 |
5086 #endif // V8_TARGET_ARCH_ARM64 | 5078 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |