| 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 |