| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 // - Materialize objects that require allocation (e.g. Double instances). | 344 // - Materialize objects that require allocation (e.g. Double instances). |
| 345 // GC can occur only after frame is fully rewritten. | 345 // GC can occur only after frame is fully rewritten. |
| 346 // Stack after EnterDartFrame(0) below: | 346 // Stack after EnterDartFrame(0) below: |
| 347 // +------------------+ | 347 // +------------------+ |
| 348 // | PC marker | <- TOS | 348 // | PC marker | <- TOS |
| 349 // +------------------+ | 349 // +------------------+ |
| 350 // | Saved FP | <- FP of stub | 350 // | Saved FP | <- FP of stub |
| 351 // +------------------+ | 351 // +------------------+ |
| 352 // | return-address | (deoptimization point) | 352 // | return-address | (deoptimization point) |
| 353 // +------------------+ | 353 // +------------------+ |
| 354 // | Saved CODE_REG | | |
| 355 // +------------------+ | |
| 356 // | ... | <- SP of optimized frame | 354 // | ... | <- SP of optimized frame |
| 357 // | 355 // |
| 358 // Parts of the code cannot GC, part of the code can GC. | 356 // Parts of the code cannot GC, part of the code can GC. |
| 359 static void GenerateDeoptimizationSequence(Assembler* assembler, | 357 static void GenerateDeoptimizationSequence(Assembler* assembler, |
| 360 DeoptStubKind kind) { | 358 DeoptStubKind kind) { |
| 361 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. | 359 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. |
| 362 __ EnterDartFrame(0); | 360 __ EnterDartFrame(0); |
| 363 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry | 361 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry |
| 364 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. | 362 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. |
| 365 const intptr_t saved_result_slot_from_fp = | 363 const intptr_t saved_result_slot_from_fp = |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 __ popl(EAX); // Restore result. | 453 __ popl(EAX); // Restore result. |
| 456 } else if (kind == kLazyDeoptFromThrow) { | 454 } else if (kind == kLazyDeoptFromThrow) { |
| 457 __ popl(EDX); // Restore exception. | 455 __ popl(EDX); // Restore exception. |
| 458 __ popl(EAX); // Restore stacktrace. | 456 __ popl(EAX); // Restore stacktrace. |
| 459 } | 457 } |
| 460 __ LeaveFrame(); | 458 __ LeaveFrame(); |
| 461 | 459 |
| 462 __ popl(ECX); // Pop return address. | 460 __ popl(ECX); // Pop return address. |
| 463 __ addl(ESP, EBX); // Remove materialization arguments. | 461 __ addl(ESP, EBX); // Remove materialization arguments. |
| 464 __ pushl(ECX); // Push return address. | 462 __ pushl(ECX); // Push return address. |
| 465 __ ret(); | 463 // The caller is responsible for emitting the return instruction. |
| 466 } | 464 } |
| 467 | 465 |
| 468 | 466 |
| 469 // EAX: result, must be preserved | 467 // EAX: result, must be preserved |
| 470 void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) { | 468 void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) { |
| 471 // Return address for "call" to deopt stub. | 469 // Return address for "call" to deopt stub. |
| 472 __ pushl(Immediate(0xe1e1e1e1)); | 470 __ pushl(Immediate(kZapReturnAddress)); |
| 473 GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn); | 471 GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn); |
| 472 __ ret(); |
| 474 } | 473 } |
| 475 | 474 |
| 476 | 475 |
| 477 // EAX: exception, must be preserved | 476 // EAX: exception, must be preserved |
| 478 // EDX: stacktrace, must be preserved | 477 // EDX: stacktrace, must be preserved |
| 479 void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) { | 478 void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) { |
| 480 // Return address for "call" to deopt stub. | 479 // Return address for "call" to deopt stub. |
| 481 __ pushl(Immediate(0xe1e1e1e1)); | 480 __ pushl(Immediate(kZapReturnAddress)); |
| 482 GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow); | 481 GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow); |
| 482 __ ret(); |
| 483 } | 483 } |
| 484 | 484 |
| 485 | 485 |
| 486 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { | 486 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { |
| 487 GenerateDeoptimizationSequence(assembler, kEagerDeopt); | 487 GenerateDeoptimizationSequence(assembler, kEagerDeopt); |
| 488 __ ret(); |
| 488 } | 489 } |
| 489 | 490 |
| 490 | 491 |
| 491 static void GenerateDispatcherCode(Assembler* assembler, | 492 static void GenerateDispatcherCode(Assembler* assembler, |
| 492 Label* call_target_function) { | 493 Label* call_target_function) { |
| 493 __ Comment("NoSuchMethodDispatch"); | 494 __ Comment("NoSuchMethodDispatch"); |
| 494 // When lazily generated invocation dispatchers are disabled, the | 495 // When lazily generated invocation dispatchers are disabled, the |
| 495 // miss-handler may return null. | 496 // miss-handler may return null. |
| 496 const Immediate& raw_null = | 497 const Immediate& raw_null = |
| 497 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 498 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| (...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1828 | 1829 |
| 1829 // Load the stacktrace from the current thread. | 1830 // Load the stacktrace from the current thread. |
| 1830 Address stacktrace_addr(THR, Thread::active_stacktrace_offset()); | 1831 Address stacktrace_addr(THR, Thread::active_stacktrace_offset()); |
| 1831 __ movl(kStackTraceObjectReg, stacktrace_addr); | 1832 __ movl(kStackTraceObjectReg, stacktrace_addr); |
| 1832 __ movl(stacktrace_addr, Immediate(0)); | 1833 __ movl(stacktrace_addr, Immediate(0)); |
| 1833 | 1834 |
| 1834 __ jmp(EBX); // Jump to continuation point. | 1835 __ jmp(EBX); // Jump to continuation point. |
| 1835 } | 1836 } |
| 1836 | 1837 |
| 1837 | 1838 |
| 1839 // Deoptimize a frame on the call stack before rewinding. |
| 1840 // The arguments are stored in the Thread object. |
| 1841 // No result. |
| 1842 void StubCode::GenerateDeoptForRewindStub(Assembler* assembler) { |
| 1843 // Push the deopt pc. |
| 1844 __ pushl(Address(THR, Thread::resume_pc_offset())); |
| 1845 GenerateDeoptimizationSequence(assembler, kEagerDeopt); |
| 1846 |
| 1847 // After we have deoptimized, jump to the correct frame. |
| 1848 __ EnterStubFrame(); |
| 1849 __ CallRuntime(kRewindPostDeoptRuntimeEntry, 0); |
| 1850 __ LeaveFrame(); |
| 1851 __ int3(); |
| 1852 } |
| 1853 |
| 1854 |
| 1838 // Calls to the runtime to optimize the given function. | 1855 // Calls to the runtime to optimize the given function. |
| 1839 // EBX: function to be reoptimized. | 1856 // EBX: function to be reoptimized. |
| 1840 // EDX: argument descriptor (preserved). | 1857 // EDX: argument descriptor (preserved). |
| 1841 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 1858 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
| 1842 __ EnterStubFrame(); | 1859 __ EnterStubFrame(); |
| 1843 __ pushl(EDX); | 1860 __ pushl(EDX); |
| 1844 __ pushl(Immediate(0)); // Setup space on stack for return value. | 1861 __ pushl(Immediate(0)); // Setup space on stack for return value. |
| 1845 __ pushl(EBX); | 1862 __ pushl(EBX); |
| 1846 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); | 1863 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
| 1847 __ popl(EAX); // Discard argument. | 1864 __ popl(EAX); // Discard argument. |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2070 } | 2087 } |
| 2071 | 2088 |
| 2072 | 2089 |
| 2073 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2090 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
| 2074 __ int3(); | 2091 __ int3(); |
| 2075 } | 2092 } |
| 2076 | 2093 |
| 2077 } // namespace dart | 2094 } // namespace dart |
| 2078 | 2095 |
| 2079 #endif // defined TARGET_ARCH_IA32 | 2096 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |