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" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 2518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2529 return summary; | 2529 return summary; |
2530 } | 2530 } |
2531 | 2531 |
2532 | 2532 |
2533 class CheckStackOverflowSlowPath : public SlowPathCode { | 2533 class CheckStackOverflowSlowPath : public SlowPathCode { |
2534 public: | 2534 public: |
2535 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) | 2535 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) |
2536 : instruction_(instruction) { } | 2536 : instruction_(instruction) { } |
2537 | 2537 |
2538 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2538 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2539 if (FLAG_use_osr) { |
| 2540 uword flags_address = Isolate::Current()->stack_overflow_flags_address(); |
| 2541 __ Comment("CheckStackOverflowSlowPathOsr"); |
| 2542 __ Bind(osr_entry_label()); |
| 2543 __ movl(Address::Absolute(flags_address), |
| 2544 Immediate(Isolate::kOsrRequest)); |
| 2545 } |
2539 __ Comment("CheckStackOverflowSlowPath"); | 2546 __ Comment("CheckStackOverflowSlowPath"); |
2540 __ Bind(entry_label()); | 2547 __ Bind(entry_label()); |
2541 compiler->SaveLiveRegisters(instruction_->locs()); | 2548 compiler->SaveLiveRegisters(instruction_->locs()); |
2542 // pending_deoptimization_env_ is needed to generate a runtime call that | 2549 // pending_deoptimization_env_ is needed to generate a runtime call that |
2543 // may throw an exception. | 2550 // may throw an exception. |
2544 ASSERT(compiler->pending_deoptimization_env_ == NULL); | 2551 ASSERT(compiler->pending_deoptimization_env_ == NULL); |
2545 Environment* env = compiler->SlowPathEnvironmentFor(instruction_); | 2552 Environment* env = compiler->SlowPathEnvironmentFor(instruction_); |
2546 compiler->pending_deoptimization_env_ = env; | 2553 compiler->pending_deoptimization_env_ = env; |
2547 compiler->GenerateRuntimeCall(instruction_->token_pos(), | 2554 compiler->GenerateRuntimeCall(instruction_->token_pos(), |
2548 instruction_->deopt_id(), | 2555 instruction_->deopt_id(), |
2549 kStackOverflowRuntimeEntry, | 2556 kStackOverflowRuntimeEntry, |
2550 0, | 2557 0, |
2551 instruction_->locs()); | 2558 instruction_->locs()); |
2552 | 2559 |
2553 if (FLAG_use_osr && !compiler->is_optimizing() && instruction_->in_loop()) { | 2560 if (FLAG_use_osr && !compiler->is_optimizing() && instruction_->in_loop()) { |
2554 // In unoptimized code, record loop stack checks as possible OSR entries. | 2561 // In unoptimized code, record loop stack checks as possible OSR entries. |
2555 compiler->AddCurrentDescriptor(PcDescriptors::kOsrEntry, | 2562 compiler->AddCurrentDescriptor(PcDescriptors::kOsrEntry, |
2556 instruction_->deopt_id(), | 2563 instruction_->deopt_id(), |
2557 0); // No token position. | 2564 0); // No token position. |
2558 } | 2565 } |
2559 compiler->pending_deoptimization_env_ = NULL; | 2566 compiler->pending_deoptimization_env_ = NULL; |
2560 compiler->RestoreLiveRegisters(instruction_->locs()); | 2567 compiler->RestoreLiveRegisters(instruction_->locs()); |
2561 __ jmp(exit_label()); | 2568 __ jmp(exit_label()); |
2562 } | 2569 } |
2563 | 2570 |
| 2571 Label* osr_entry_label() { |
| 2572 ASSERT(FLAG_use_osr); |
| 2573 return &osr_entry_label_; |
| 2574 } |
| 2575 |
2564 private: | 2576 private: |
2565 CheckStackOverflowInstr* instruction_; | 2577 CheckStackOverflowInstr* instruction_; |
| 2578 Label osr_entry_label_; |
2566 }; | 2579 }; |
2567 | 2580 |
2568 | 2581 |
2569 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2582 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2570 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); | 2583 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); |
2571 compiler->AddSlowPathCode(slow_path); | 2584 compiler->AddSlowPathCode(slow_path); |
2572 | 2585 |
2573 if (compiler->ShouldDeoptimizeFunction()) { | |
2574 __ jmp(slow_path->entry_label()); | |
2575 } | |
2576 __ cmpl(ESP, | 2586 __ cmpl(ESP, |
2577 Address::Absolute(Isolate::Current()->stack_limit_address())); | 2587 Address::Absolute(Isolate::Current()->stack_limit_address())); |
2578 __ j(BELOW_EQUAL, slow_path->entry_label()); | 2588 __ j(BELOW_EQUAL, slow_path->entry_label()); |
2579 if (compiler->CanOSRFunction() && in_loop()) { | 2589 if (compiler->CanOSRFunction() && in_loop()) { |
2580 // In unoptimized code check the usage counter to trigger OSR at loop | 2590 // In unoptimized code check the usage counter to trigger OSR at loop |
2581 // stack checks. Use progressively higher thresholds for more deeply | 2591 // stack checks. Use progressively higher thresholds for more deeply |
2582 // nested loops to attempt to hit outer loops with OSR when possible. | 2592 // nested loops to attempt to hit outer loops with OSR when possible. |
2583 __ LoadObject(EDI, compiler->parsed_function().function()); | 2593 __ LoadObject(EDI, compiler->parsed_function().function()); |
2584 intptr_t threshold = | 2594 intptr_t threshold = |
2585 FLAG_optimization_counter_threshold * (loop_depth() + 1); | 2595 FLAG_optimization_counter_threshold * (loop_depth() + 1); |
2586 __ cmpl(FieldAddress(EDI, Function::usage_counter_offset()), | 2596 __ cmpl(FieldAddress(EDI, Function::usage_counter_offset()), |
2587 Immediate(threshold)); | 2597 Immediate(threshold)); |
2588 __ j(GREATER_EQUAL, slow_path->entry_label()); | 2598 __ j(GREATER_EQUAL, slow_path->osr_entry_label()); |
| 2599 } |
| 2600 if (compiler->ForceSlowPathForStackOverflow()) { |
| 2601 // TODO(turnidge): Implement stack overflow count in assembly to |
| 2602 // make --stacktrace-every and --deoptimize-every faster. |
| 2603 __ jmp(slow_path->entry_label()); |
2589 } | 2604 } |
2590 __ Bind(slow_path->exit_label()); | 2605 __ Bind(slow_path->exit_label()); |
2591 } | 2606 } |
2592 | 2607 |
2593 | 2608 |
2594 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, | 2609 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
2595 BinarySmiOpInstr* shift_left) { | 2610 BinarySmiOpInstr* shift_left) { |
2596 const bool is_truncating = shift_left->is_truncating(); | 2611 const bool is_truncating = shift_left->is_truncating(); |
2597 const LocationSummary& locs = *shift_left->locs(); | 2612 const LocationSummary& locs = *shift_left->locs(); |
2598 Register left = locs.in(0).reg(); | 2613 Register left = locs.in(0).reg(); |
(...skipping 3243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5842 PcDescriptors::kOther, | 5857 PcDescriptors::kOther, |
5843 locs()); | 5858 locs()); |
5844 __ Drop(ArgumentCount()); // Discard arguments. | 5859 __ Drop(ArgumentCount()); // Discard arguments. |
5845 } | 5860 } |
5846 | 5861 |
5847 } // namespace dart | 5862 } // namespace dart |
5848 | 5863 |
5849 #undef __ | 5864 #undef __ |
5850 | 5865 |
5851 #endif // defined TARGET_ARCH_IA32 | 5866 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |