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 |