| 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 // +------------------+ |
| 354 // | ... | <- SP of optimized frame | 356 // | ... | <- SP of optimized frame |
| 355 // | 357 // |
| 356 // Parts of the code cannot GC, part of the code can GC. | 358 // Parts of the code cannot GC, part of the code can GC. |
| 357 static void GenerateDeoptimizationSequence(Assembler* assembler, | 359 static void GenerateDeoptimizationSequence(Assembler* assembler, |
| 358 DeoptStubKind kind) { | 360 DeoptStubKind kind) { |
| 359 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. | 361 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. |
| 360 __ EnterDartFrame(0); | 362 __ EnterDartFrame(0); |
| 361 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry | 363 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry |
| 362 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. | 364 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. |
| 363 const intptr_t saved_result_slot_from_fp = | 365 const intptr_t saved_result_slot_from_fp = |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 __ popl(EAX); // Restore result. | 455 __ popl(EAX); // Restore result. |
| 454 } else if (kind == kLazyDeoptFromThrow) { | 456 } else if (kind == kLazyDeoptFromThrow) { |
| 455 __ popl(EDX); // Restore exception. | 457 __ popl(EDX); // Restore exception. |
| 456 __ popl(EAX); // Restore stacktrace. | 458 __ popl(EAX); // Restore stacktrace. |
| 457 } | 459 } |
| 458 __ LeaveFrame(); | 460 __ LeaveFrame(); |
| 459 | 461 |
| 460 __ popl(ECX); // Pop return address. | 462 __ popl(ECX); // Pop return address. |
| 461 __ addl(ESP, EBX); // Remove materialization arguments. | 463 __ addl(ESP, EBX); // Remove materialization arguments. |
| 462 __ pushl(ECX); // Push return address. | 464 __ pushl(ECX); // Push return address. |
| 463 // The caller is responsible for emitting the return instruction. | 465 __ ret(); |
| 464 } | 466 } |
| 465 | 467 |
| 466 | 468 |
| 467 // EAX: result, must be preserved | 469 // EAX: result, must be preserved |
| 468 void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) { | 470 void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) { |
| 469 // Return address for "call" to deopt stub. | 471 // Return address for "call" to deopt stub. |
| 470 __ pushl(Immediate(kZapReturnAddress)); | 472 __ pushl(Immediate(0xe1e1e1e1)); |
| 471 GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn); | 473 GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn); |
| 472 __ ret(); | |
| 473 } | 474 } |
| 474 | 475 |
| 475 | 476 |
| 476 // EAX: exception, must be preserved | 477 // EAX: exception, must be preserved |
| 477 // EDX: stacktrace, must be preserved | 478 // EDX: stacktrace, must be preserved |
| 478 void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) { | 479 void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) { |
| 479 // Return address for "call" to deopt stub. | 480 // Return address for "call" to deopt stub. |
| 480 __ pushl(Immediate(kZapReturnAddress)); | 481 __ pushl(Immediate(0xe1e1e1e1)); |
| 481 GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow); | 482 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(); | |
| 489 } | 488 } |
| 490 | 489 |
| 491 | 490 |
| 492 static void GenerateDispatcherCode(Assembler* assembler, | 491 static void GenerateDispatcherCode(Assembler* assembler, |
| 493 Label* call_target_function) { | 492 Label* call_target_function) { |
| 494 __ Comment("NoSuchMethodDispatch"); | 493 __ Comment("NoSuchMethodDispatch"); |
| 495 // When lazily generated invocation dispatchers are disabled, the | 494 // When lazily generated invocation dispatchers are disabled, the |
| 496 // miss-handler may return null. | 495 // miss-handler may return null. |
| 497 const Immediate& raw_null = | 496 const Immediate& raw_null = |
| 498 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 497 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| (...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1829 | 1828 |
| 1830 // Load the stacktrace from the current thread. | 1829 // Load the stacktrace from the current thread. |
| 1831 Address stacktrace_addr(THR, Thread::active_stacktrace_offset()); | 1830 Address stacktrace_addr(THR, Thread::active_stacktrace_offset()); |
| 1832 __ movl(kStackTraceObjectReg, stacktrace_addr); | 1831 __ movl(kStackTraceObjectReg, stacktrace_addr); |
| 1833 __ movl(stacktrace_addr, Immediate(0)); | 1832 __ movl(stacktrace_addr, Immediate(0)); |
| 1834 | 1833 |
| 1835 __ jmp(EBX); // Jump to continuation point. | 1834 __ jmp(EBX); // Jump to continuation point. |
| 1836 } | 1835 } |
| 1837 | 1836 |
| 1838 | 1837 |
| 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 | |
| 1855 // Calls to the runtime to optimize the given function. | 1838 // Calls to the runtime to optimize the given function. |
| 1856 // EBX: function to be reoptimized. | 1839 // EBX: function to be reoptimized. |
| 1857 // EDX: argument descriptor (preserved). | 1840 // EDX: argument descriptor (preserved). |
| 1858 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 1841 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
| 1859 __ EnterStubFrame(); | 1842 __ EnterStubFrame(); |
| 1860 __ pushl(EDX); | 1843 __ pushl(EDX); |
| 1861 __ pushl(Immediate(0)); // Setup space on stack for return value. | 1844 __ pushl(Immediate(0)); // Setup space on stack for return value. |
| 1862 __ pushl(EBX); | 1845 __ pushl(EBX); |
| 1863 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); | 1846 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
| 1864 __ popl(EAX); // Discard argument. | 1847 __ popl(EAX); // Discard argument. |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2087 } | 2070 } |
| 2088 | 2071 |
| 2089 | 2072 |
| 2090 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2073 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
| 2091 __ int3(); | 2074 __ int3(); |
| 2092 } | 2075 } |
| 2093 | 2076 |
| 2094 } // namespace dart | 2077 } // namespace dart |
| 2095 | 2078 |
| 2096 #endif // defined TARGET_ARCH_IA32 | 2079 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |