| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/assembler_macros.h" | 9 #include "vm/assembler_macros.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 __ popq(RAX); | 547 __ popq(RAX); |
| 548 __ popq(RAX); | 548 __ popq(RAX); |
| 549 __ popq(RAX); // Get result into RAX. | 549 __ popq(RAX); // Get result into RAX. |
| 550 | 550 |
| 551 // Remove the stub frame as we are about to return. | 551 // Remove the stub frame as we are about to return. |
| 552 __ LeaveFrame(); | 552 __ LeaveFrame(); |
| 553 __ ret(); | 553 __ ret(); |
| 554 } | 554 } |
| 555 | 555 |
| 556 | 556 |
| 557 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
| 558 intptr_t deopt_reason, |
| 559 intptr_t* saved_registers_address); |
| 560 |
| 561 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); |
| 562 |
| 563 // This stub translates optimized frame into unoptimized frame. The optimized |
| 564 // frame can contain values in registers and on stack, the unoptimized |
| 565 // frame contains all values on stack. |
| 566 // Deoptimization occurs in following steps: |
| 567 // - Push all registers that can contain values. |
| 568 // - Call C routine to copy the stack and saved registers into temporary buffer. |
| 569 // - Adjust caller's frame to correct unoptimized frame size. |
| 570 // - Fill the unoptimized frame. |
| 571 // Stack: |
| 572 // +------------------+ |
| 573 // | 0 as PC marker | <- TOS |
| 574 // +------------------+ |
| 575 // | Saved FP | |
| 576 // +------------------+ |
| 577 // | return-address | (deoptimization point) |
| 578 // +------------------+ |
| 579 // | optimized frame | |
| 580 // | ... | |
| 581 // |
| 582 // RAX: Deoptimization reason id. |
| 557 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { | 583 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { |
| 558 AssemblerMacros::EnterStubFrame(assembler); | 584 __ EnterFrame(0); |
| 559 // RAX: deoptimization reason id. | 585 // Push registers in their enumeration order. |
| 560 // Stack at this point: | 586 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { |
| 561 // TOS + 0: PC marker => RawInstruction object. | 587 __ pushq(static_cast<Register>(i)); |
| 562 // TOS + 1: Saved EBP of function frame that will be deoptimized. <== EBP | 588 } |
| 563 // TOS + 2: Deoptimization point (return address), will be patched. | 589 __ movq(RCX, RSP); // Saved saved registers block. |
| 564 // TOS + 3: top-of-stack at deoptimization point (all arguments on stack). | 590 __ ReserveAlignedFrameSpace(0); |
| 565 __ pushq(RAX); | 591 __ SmiUntag(RAX); |
| 566 __ CallRuntime(kDeoptimizeRuntimeEntry); | 592 __ movq(RDI, RAX); // Set up argument 1 deopt_reason. |
| 567 __ popq(RAX); | 593 __ movq(RSI, RCX); // Set up argument 2 saved_registers_address. |
| 594 |
| 595 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry); |
| 596 // Result (RAX) is stack-size (FP - SP) in bytes, incl. the return address. |
| 597 __ LeaveFrame(); |
| 598 __ popq(RCX); // Discard return address. |
| 599 __ movq(RSP, RBP); |
| 600 __ subq(RSP, RAX); |
| 601 |
| 602 __ EnterFrame(0); |
| 603 __ movq(RCX, RSP); // Get last FP address. |
| 604 __ ReserveAlignedFrameSpace(0); |
| 605 __ movq(RDI, RCX); // Set up argument 1 last_fp. |
| 606 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); |
| 568 __ LeaveFrame(); | 607 __ LeaveFrame(); |
| 569 __ ret(); | 608 __ ret(); |
| 570 } | 609 } |
| 571 | 610 |
| 572 | 611 |
| 573 // Called for inline allocation of arrays. | 612 // Called for inline allocation of arrays. |
| 574 // Input parameters: | 613 // Input parameters: |
| 575 // R10 : Array length as Smi. | 614 // R10 : Array length as Smi. |
| 576 // RBX : array element type (either NULL or an instantiated type). | 615 // RBX : array element type (either NULL or an instantiated type). |
| 577 // NOTE: R10 cannot be clobbered here as the caller relies on it being saved. | 616 // NOTE: R10 cannot be clobbered here as the caller relies on it being saved. |
| (...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1894 void StubCode::GenerateJumpToErrorHandlerStub(Assembler* assembler) { | 1933 void StubCode::GenerateJumpToErrorHandlerStub(Assembler* assembler) { |
| 1895 __ movq(RAX, RCX); // error object. | 1934 __ movq(RAX, RCX); // error object. |
| 1896 __ movq(RBP, RDX); // target frame_pointer. | 1935 __ movq(RBP, RDX); // target frame_pointer. |
| 1897 __ movq(RSP, RSI); // target stack_pointer. | 1936 __ movq(RSP, RSI); // target stack_pointer. |
| 1898 __ jmp(RDI); // Jump to the exception handler code. | 1937 __ jmp(RDI); // Jump to the exception handler code. |
| 1899 } | 1938 } |
| 1900 | 1939 |
| 1901 } // namespace dart | 1940 } // namespace dart |
| 1902 | 1941 |
| 1903 #endif // defined TARGET_ARCH_X64 | 1942 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |