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 |