| 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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| 11 #include "vm/dart_entry.h" | 11 #include "vm/dart_entry.h" |
| 12 #include "vm/flow_graph_compiler.h" | 12 #include "vm/flow_graph_compiler.h" |
| 13 #include "vm/locations.h" | 13 #include "vm/locations.h" |
| 14 #include "vm/object_store.h" | 14 #include "vm/object_store.h" |
| 15 #include "vm/parser.h" | 15 #include "vm/parser.h" |
| 16 #include "vm/simulator.h" | 16 #include "vm/simulator.h" |
| 17 #include "vm/stack_frame.h" | 17 #include "vm/stack_frame.h" |
| 18 #include "vm/stub_code.h" | 18 #include "vm/stub_code.h" |
| 19 #include "vm/symbols.h" | 19 #include "vm/symbols.h" |
| 20 | 20 |
| 21 #define __ compiler->assembler()-> | 21 #define __ compiler->assembler()-> |
| 22 | 22 |
| 23 namespace dart { | 23 namespace dart { |
| 24 | 24 |
| 25 DECLARE_FLAG(int, optimization_counter_threshold); | 25 DECLARE_FLAG(int, optimization_counter_threshold); |
| 26 DECLARE_FLAG(bool, propagate_ic_data); | 26 DECLARE_FLAG(bool, propagate_ic_data); |
| 27 DECLARE_FLAG(bool, use_osr); |
| 27 | 28 |
| 28 // Generic summary for call instructions that have all arguments pushed | 29 // Generic summary for call instructions that have all arguments pushed |
| 29 // on the stack and return the result in a fixed register R0. | 30 // on the stack and return the result in a fixed register R0. |
| 30 LocationSummary* Instruction::MakeCallSummary() { | 31 LocationSummary* Instruction::MakeCallSummary() { |
| 31 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); | 32 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); |
| 32 result->set_out(Location::RegisterLocation(R0)); | 33 result->set_out(Location::RegisterLocation(R0)); |
| 33 return result; | 34 return result; |
| 34 } | 35 } |
| 35 | 36 |
| 36 | 37 |
| (...skipping 2007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2044 __ StoreToOffset(kStoreWord, kStackTraceObjectReg, | 2045 __ StoreToOffset(kStoreWord, kStackTraceObjectReg, |
| 2045 FP, stacktrace_var().index() * kWordSize); | 2046 FP, stacktrace_var().index() * kWordSize); |
| 2046 | 2047 |
| 2047 // Restore the pool pointer. | 2048 // Restore the pool pointer. |
| 2048 __ LoadPoolPointer(); | 2049 __ LoadPoolPointer(); |
| 2049 } | 2050 } |
| 2050 | 2051 |
| 2051 | 2052 |
| 2052 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { | 2053 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { |
| 2053 const intptr_t kNumInputs = 0; | 2054 const intptr_t kNumInputs = 0; |
| 2054 const intptr_t kNumTemps = 0; | 2055 const intptr_t kNumTemps = 1; |
| 2055 LocationSummary* summary = | 2056 LocationSummary* summary = |
| 2056 new LocationSummary(kNumInputs, | 2057 new LocationSummary(kNumInputs, |
| 2057 kNumTemps, | 2058 kNumTemps, |
| 2058 LocationSummary::kCallOnSlowPath); | 2059 LocationSummary::kCallOnSlowPath); |
| 2060 summary->set_temp(0, Location::RequiresRegister()); |
| 2059 return summary; | 2061 return summary; |
| 2060 } | 2062 } |
| 2061 | 2063 |
| 2062 | 2064 |
| 2063 class CheckStackOverflowSlowPath : public SlowPathCode { | 2065 class CheckStackOverflowSlowPath : public SlowPathCode { |
| 2064 public: | 2066 public: |
| 2065 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) | 2067 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) |
| 2066 : instruction_(instruction) { } | 2068 : instruction_(instruction) { } |
| 2067 | 2069 |
| 2068 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2070 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2069 __ Comment("CheckStackOverflowSlowPath"); | 2071 __ Comment("CheckStackOverflowSlowPath"); |
| 2070 __ Bind(entry_label()); | 2072 __ Bind(entry_label()); |
| 2071 compiler->SaveLiveRegisters(instruction_->locs()); | 2073 compiler->SaveLiveRegisters(instruction_->locs()); |
| 2072 // pending_deoptimization_env_ is needed to generate a runtime call that | 2074 // pending_deoptimization_env_ is needed to generate a runtime call that |
| 2073 // may throw an exception. | 2075 // may throw an exception. |
| 2074 ASSERT(compiler->pending_deoptimization_env_ == NULL); | 2076 ASSERT(compiler->pending_deoptimization_env_ == NULL); |
| 2075 compiler->pending_deoptimization_env_ = instruction_->env(); | 2077 compiler->pending_deoptimization_env_ = instruction_->env(); |
| 2076 compiler->GenerateCallRuntime(instruction_->token_pos(), | 2078 compiler->GenerateCallRuntime(instruction_->token_pos(), |
| 2077 instruction_->deopt_id(), | 2079 instruction_->deopt_id(), |
| 2078 kStackOverflowRuntimeEntry, | 2080 kStackOverflowRuntimeEntry, |
| 2079 instruction_->locs()); | 2081 instruction_->locs()); |
| 2082 |
| 2083 if (FLAG_use_osr && !compiler->is_optimizing() && instruction_->in_loop()) { |
| 2084 // In unoptimized code, record loop stack checks as possible OSR entries. |
| 2085 compiler->AddCurrentDescriptor(PcDescriptors::kOsrEntry, |
| 2086 instruction_->deopt_id(), |
| 2087 0); // No token position. |
| 2088 } |
| 2080 compiler->pending_deoptimization_env_ = NULL; | 2089 compiler->pending_deoptimization_env_ = NULL; |
| 2081 compiler->RestoreLiveRegisters(instruction_->locs()); | 2090 compiler->RestoreLiveRegisters(instruction_->locs()); |
| 2082 __ b(exit_label()); | 2091 __ b(exit_label()); |
| 2083 } | 2092 } |
| 2084 | 2093 |
| 2085 private: | 2094 private: |
| 2086 CheckStackOverflowInstr* instruction_; | 2095 CheckStackOverflowInstr* instruction_; |
| 2087 }; | 2096 }; |
| 2088 | 2097 |
| 2089 | 2098 |
| 2090 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2099 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2091 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); | 2100 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); |
| 2092 compiler->AddSlowPathCode(slow_path); | 2101 compiler->AddSlowPathCode(slow_path); |
| 2093 | 2102 |
| 2094 __ LoadImmediate(IP, Isolate::Current()->stack_limit_address()); | 2103 __ LoadImmediate(IP, Isolate::Current()->stack_limit_address()); |
| 2095 __ ldr(IP, Address(IP)); | 2104 __ ldr(IP, Address(IP)); |
| 2096 __ cmp(SP, ShifterOperand(IP)); | 2105 __ cmp(SP, ShifterOperand(IP)); |
| 2097 __ b(slow_path->entry_label(), LS); | 2106 __ b(slow_path->entry_label(), LS); |
| 2107 if (compiler->CanOSRFunction() && in_loop()) { |
| 2108 Register temp = locs()->temp(0).reg(); |
| 2109 // In unoptimized code check the usage counter to trigger OSR at loop |
| 2110 // stack checks. Use progressively higher thresholds for more deeply |
| 2111 // nested loops to attempt to hit outer loops with OSR when possible. |
| 2112 __ LoadObject(temp, compiler->parsed_function().function()); |
| 2113 intptr_t threshold = |
| 2114 FLAG_optimization_counter_threshold * (loop_depth() + 1); |
| 2115 __ ldr(temp, FieldAddress(temp, Function::usage_counter_offset())); |
| 2116 __ CompareImmediate(temp, threshold); |
| 2117 __ b(slow_path->entry_label(), GE); |
| 2118 } |
| 2098 __ Bind(slow_path->exit_label()); | 2119 __ Bind(slow_path->exit_label()); |
| 2099 } | 2120 } |
| 2100 | 2121 |
| 2101 | 2122 |
| 2102 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, | 2123 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
| 2103 BinarySmiOpInstr* shift_left) { | 2124 BinarySmiOpInstr* shift_left) { |
| 2104 const bool is_truncating = shift_left->is_truncating(); | 2125 const bool is_truncating = shift_left->is_truncating(); |
| 2105 const LocationSummary& locs = *shift_left->locs(); | 2126 const LocationSummary& locs = *shift_left->locs(); |
| 2106 Register left = locs.in(0).reg(); | 2127 Register left = locs.in(0).reg(); |
| 2107 Register result = locs.out().reg(); | 2128 Register result = locs.out().reg(); |
| (...skipping 1519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3627 compiler->GenerateCall(token_pos(), | 3648 compiler->GenerateCall(token_pos(), |
| 3628 &label, | 3649 &label, |
| 3629 PcDescriptors::kOther, | 3650 PcDescriptors::kOther, |
| 3630 locs()); | 3651 locs()); |
| 3631 __ Drop(2); // Discard type arguments and receiver. | 3652 __ Drop(2); // Discard type arguments and receiver. |
| 3632 } | 3653 } |
| 3633 | 3654 |
| 3634 } // namespace dart | 3655 } // namespace dart |
| 3635 | 3656 |
| 3636 #endif // defined TARGET_ARCH_ARM | 3657 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |