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/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 __ Bind(&allocated); | 494 __ Bind(&allocated); |
495 | 495 |
496 // Reload the number of arguments from the stack. | 496 // Reload the number of arguments from the stack. |
497 // Set it up in x0 for the function call below. | 497 // Set it up in x0 for the function call below. |
498 // jssp[0]: number of arguments (smi-tagged) | 498 // jssp[0]: number of arguments (smi-tagged) |
499 __ Peek(argc, 0); // Load number of arguments. | 499 __ Peek(argc, 0); // Load number of arguments. |
500 } | 500 } |
501 | 501 |
502 __ SmiUntag(argc); | 502 __ SmiUntag(argc); |
503 | 503 |
504 // Push new.target onto the construct frame. This is stored just below the | |
505 // receiver on the stack. | |
506 if (create_implicit_receiver) { | 504 if (create_implicit_receiver) { |
507 // Push the allocated receiver to the stack. We need two copies | 505 // Push the allocated receiver to the stack. We need two copies |
508 // because we may have to return the original one and the calling | 506 // because we may have to return the original one and the calling |
509 // conventions dictate that the called function pops the receiver. | 507 // conventions dictate that the called function pops the receiver. |
510 __ Push(new_target, x4, x4); | 508 __ Push(x4, x4); |
511 } else { | 509 } else { |
512 __ push(new_target); | |
513 __ PushRoot(Heap::kTheHoleValueRootIndex); | 510 __ PushRoot(Heap::kTheHoleValueRootIndex); |
514 } | 511 } |
515 | 512 |
516 // Set up pointer to last argument. | 513 // Set up pointer to last argument. |
517 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset); | 514 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset); |
518 | 515 |
519 // Copy arguments and receiver to the expression stack. | 516 // Copy arguments and receiver to the expression stack. |
520 // Copy 2 values every loop to use ldp/stp. | 517 // Copy 2 values every loop to use ldp/stp. |
521 // x0: number of arguments | 518 // x0: number of arguments |
522 // x1: constructor function | 519 // x1: constructor function |
523 // x2: address of last argument (caller sp) | 520 // x2: address of last argument (caller sp) |
524 // x3: new target | 521 // x3: new target |
525 // jssp[0]: receiver | 522 // jssp[0]: receiver |
526 // jssp[1]: receiver | 523 // jssp[1]: receiver |
527 // jssp[2]: new.target | 524 // jssp[2]: number of arguments (smi-tagged) |
528 // jssp[3]: number of arguments (smi-tagged) | |
529 // Compute the start address of the copy in x3. | 525 // Compute the start address of the copy in x3. |
530 __ Add(x4, x2, Operand(argc, LSL, kPointerSizeLog2)); | 526 __ Add(x4, x2, Operand(argc, LSL, kPointerSizeLog2)); |
531 Label loop, entry, done_copying_arguments; | 527 Label loop, entry, done_copying_arguments; |
532 __ B(&entry); | 528 __ B(&entry); |
533 __ Bind(&loop); | 529 __ Bind(&loop); |
534 __ Ldp(x10, x11, MemOperand(x4, -2 * kPointerSize, PreIndex)); | 530 __ Ldp(x10, x11, MemOperand(x4, -2 * kPointerSize, PreIndex)); |
535 __ Push(x11, x10); | 531 __ Push(x11, x10); |
536 __ Bind(&entry); | 532 __ Bind(&entry); |
537 __ Cmp(x4, x2); | 533 __ Cmp(x4, x2); |
538 __ B(gt, &loop); | 534 __ B(gt, &loop); |
(...skipping 19 matching lines...) Expand all Loading... |
558 } | 554 } |
559 | 555 |
560 // Store offset of return address for deoptimizer. | 556 // Store offset of return address for deoptimizer. |
561 if (create_implicit_receiver && !is_api_function) { | 557 if (create_implicit_receiver && !is_api_function) { |
562 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); | 558 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); |
563 } | 559 } |
564 | 560 |
565 // Restore the context from the frame. | 561 // Restore the context from the frame. |
566 // x0: result | 562 // x0: result |
567 // jssp[0]: receiver | 563 // jssp[0]: receiver |
568 // jssp[1]: new.target | 564 // jssp[1]: number of arguments (smi-tagged) |
569 // jssp[2]: number of arguments (smi-tagged) | |
570 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 565 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
571 | 566 |
572 if (create_implicit_receiver) { | 567 if (create_implicit_receiver) { |
573 // If the result is an object (in the ECMA sense), we should get rid | 568 // If the result is an object (in the ECMA sense), we should get rid |
574 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 | 569 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 |
575 // on page 74. | 570 // on page 74. |
576 Label use_receiver, exit; | 571 Label use_receiver, exit; |
577 | 572 |
578 // If the result is a smi, it is *not* an object in the ECMA sense. | 573 // If the result is a smi, it is *not* an object in the ECMA sense. |
579 // x0: result | 574 // x0: result |
580 // jssp[0]: receiver (newly allocated object) | 575 // jssp[0]: receiver (newly allocated object) |
581 // jssp[1]: number of arguments (smi-tagged) | 576 // jssp[1]: number of arguments (smi-tagged) |
582 __ JumpIfSmi(x0, &use_receiver); | 577 __ JumpIfSmi(x0, &use_receiver); |
583 | 578 |
584 // If the type of the result (stored in its map) is less than | 579 // If the type of the result (stored in its map) is less than |
585 // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense. | 580 // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense. |
586 __ JumpIfObjectType(x0, x1, x3, FIRST_JS_RECEIVER_TYPE, &exit, ge); | 581 __ JumpIfObjectType(x0, x1, x3, FIRST_JS_RECEIVER_TYPE, &exit, ge); |
587 | 582 |
588 // Throw away the result of the constructor invocation and use the | 583 // Throw away the result of the constructor invocation and use the |
589 // on-stack receiver as the result. | 584 // on-stack receiver as the result. |
590 __ Bind(&use_receiver); | 585 __ Bind(&use_receiver); |
591 __ Peek(x0, 0); | 586 __ Peek(x0, 0); |
592 | 587 |
593 // Remove the receiver from the stack, remove caller arguments, and | 588 // Remove the receiver from the stack, remove caller arguments, and |
594 // return. | 589 // return. |
595 __ Bind(&exit); | 590 __ Bind(&exit); |
596 // x0: result | 591 // x0: result |
597 // jssp[0]: receiver (newly allocated object) | 592 // jssp[0]: receiver (newly allocated object) |
598 // jssp[1]: new target | 593 // jssp[1]: number of arguments (smi-tagged) |
599 // jssp[2]: number of arguments (smi-tagged) | 594 __ Peek(x1, 1 * kXRegSize); |
600 __ Peek(x1, 2 * kXRegSize); | |
601 } else { | 595 } else { |
602 __ Peek(x1, kXRegSize); | 596 __ Peek(x1, 0); |
603 } | 597 } |
604 | 598 |
605 // Leave construct frame. | 599 // Leave construct frame. |
606 } | 600 } |
607 | 601 |
608 __ DropBySMI(x1); | 602 __ DropBySMI(x1); |
609 __ Drop(1); | 603 __ Drop(1); |
610 if (create_implicit_receiver) { | 604 if (create_implicit_receiver) { |
611 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); | 605 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); |
612 } | 606 } |
(...skipping 1414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2027 } | 2021 } |
2028 } | 2022 } |
2029 | 2023 |
2030 | 2024 |
2031 #undef __ | 2025 #undef __ |
2032 | 2026 |
2033 } // namespace internal | 2027 } // namespace internal |
2034 } // namespace v8 | 2028 } // namespace v8 |
2035 | 2029 |
2036 #endif // V8_TARGET_ARCH_ARM | 2030 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |