| 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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 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 V0. | 30 // on the stack and return the result in a fixed register V0. |
| 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(V0)); | 33 result->set_out(Location::RegisterLocation(V0)); |
| 33 return result; | 34 return result; |
| 34 } | 35 } |
| 35 | 36 |
| 36 | 37 |
| (...skipping 2117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2154 compiler->assembler()->CodeSize(); | 2155 compiler->assembler()->CodeSize(); |
| 2155 | 2156 |
| 2156 __ Bind(&next); | 2157 __ Bind(&next); |
| 2157 __ mov(RA, TMP); // Restore return address. | 2158 __ mov(RA, TMP); // Restore return address. |
| 2158 __ lw(PP, Address(CMPRES, -object_pool_pc_dist)); | 2159 __ lw(PP, Address(CMPRES, -object_pool_pc_dist)); |
| 2159 } | 2160 } |
| 2160 | 2161 |
| 2161 | 2162 |
| 2162 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { | 2163 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { |
| 2163 const intptr_t kNumInputs = 0; | 2164 const intptr_t kNumInputs = 0; |
| 2164 const intptr_t kNumTemps = 0; | 2165 const intptr_t kNumTemps = 1; |
| 2165 LocationSummary* summary = | 2166 LocationSummary* summary = |
| 2166 new LocationSummary(kNumInputs, | 2167 new LocationSummary(kNumInputs, |
| 2167 kNumTemps, | 2168 kNumTemps, |
| 2168 LocationSummary::kCallOnSlowPath); | 2169 LocationSummary::kCallOnSlowPath); |
| 2170 summary->set_temp(0, Location::RequiresRegister()); |
| 2169 return summary; | 2171 return summary; |
| 2170 } | 2172 } |
| 2171 | 2173 |
| 2172 | 2174 |
| 2173 class CheckStackOverflowSlowPath : public SlowPathCode { | 2175 class CheckStackOverflowSlowPath : public SlowPathCode { |
| 2174 public: | 2176 public: |
| 2175 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) | 2177 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) |
| 2176 : instruction_(instruction) { } | 2178 : instruction_(instruction) { } |
| 2177 | 2179 |
| 2178 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2180 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2179 __ TraceSimMsg("CheckStackOverflowSlowPath"); | 2181 __ TraceSimMsg("CheckStackOverflowSlowPath"); |
| 2180 __ Comment("CheckStackOverflowSlowPath"); | 2182 __ Comment("CheckStackOverflowSlowPath"); |
| 2181 __ Bind(entry_label()); | 2183 __ Bind(entry_label()); |
| 2182 compiler->SaveLiveRegisters(instruction_->locs()); | 2184 compiler->SaveLiveRegisters(instruction_->locs()); |
| 2183 // pending_deoptimization_env_ is needed to generate a runtime call that | 2185 // pending_deoptimization_env_ is needed to generate a runtime call that |
| 2184 // may throw an exception. | 2186 // may throw an exception. |
| 2185 ASSERT(compiler->pending_deoptimization_env_ == NULL); | 2187 ASSERT(compiler->pending_deoptimization_env_ == NULL); |
| 2186 compiler->pending_deoptimization_env_ = instruction_->env(); | 2188 compiler->pending_deoptimization_env_ = instruction_->env(); |
| 2187 compiler->GenerateCallRuntime(instruction_->token_pos(), | 2189 compiler->GenerateCallRuntime(instruction_->token_pos(), |
| 2188 instruction_->deopt_id(), | 2190 instruction_->deopt_id(), |
| 2189 kStackOverflowRuntimeEntry, | 2191 kStackOverflowRuntimeEntry, |
| 2190 instruction_->locs()); | 2192 instruction_->locs()); |
| 2193 |
| 2194 if (FLAG_use_osr && !compiler->is_optimizing() && instruction_->in_loop()) { |
| 2195 // In unoptimized code, record loop stack checks as possible OSR entries. |
| 2196 compiler->AddCurrentDescriptor(PcDescriptors::kOsrEntry, |
| 2197 instruction_->deopt_id(), |
| 2198 0); // No token position. |
| 2199 } |
| 2191 compiler->pending_deoptimization_env_ = NULL; | 2200 compiler->pending_deoptimization_env_ = NULL; |
| 2192 compiler->RestoreLiveRegisters(instruction_->locs()); | 2201 compiler->RestoreLiveRegisters(instruction_->locs()); |
| 2193 __ b(exit_label()); | 2202 __ b(exit_label()); |
| 2194 } | 2203 } |
| 2195 | 2204 |
| 2196 private: | 2205 private: |
| 2197 CheckStackOverflowInstr* instruction_; | 2206 CheckStackOverflowInstr* instruction_; |
| 2198 }; | 2207 }; |
| 2199 | 2208 |
| 2200 | 2209 |
| 2201 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2210 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2202 __ TraceSimMsg("CheckStackOverflowInstr"); | 2211 __ TraceSimMsg("CheckStackOverflowInstr"); |
| 2203 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); | 2212 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); |
| 2204 compiler->AddSlowPathCode(slow_path); | 2213 compiler->AddSlowPathCode(slow_path); |
| 2205 | 2214 |
| 2206 __ LoadImmediate(TMP1, Isolate::Current()->stack_limit_address()); | 2215 __ LoadImmediate(TMP1, Isolate::Current()->stack_limit_address()); |
| 2207 | 2216 |
| 2208 __ lw(TMP1, Address(TMP1)); | 2217 __ lw(TMP1, Address(TMP1)); |
| 2209 __ BranchUnsignedLessEqual(SP, TMP1, slow_path->entry_label()); | 2218 __ BranchUnsignedLessEqual(SP, TMP1, slow_path->entry_label()); |
| 2210 | 2219 if (compiler->CanOSRFunction() && in_loop()) { |
| 2220 Register temp = locs()->temp(0).reg(); |
| 2221 // In unoptimized code check the usage counter to trigger OSR at loop |
| 2222 // stack checks. Use progressively higher thresholds for more deeply |
| 2223 // nested loops to attempt to hit outer loops with OSR when possible. |
| 2224 __ LoadObject(temp, compiler->parsed_function().function()); |
| 2225 intptr_t threshold = |
| 2226 FLAG_optimization_counter_threshold * (loop_depth() + 1); |
| 2227 __ lw(temp, FieldAddress(temp, Function::usage_counter_offset())); |
| 2228 __ BranchSignedGreaterEqual(temp, threshold, slow_path->entry_label()); |
| 2229 } |
| 2211 __ Bind(slow_path->exit_label()); | 2230 __ Bind(slow_path->exit_label()); |
| 2212 } | 2231 } |
| 2213 | 2232 |
| 2214 | 2233 |
| 2215 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, | 2234 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
| 2216 BinarySmiOpInstr* shift_left) { | 2235 BinarySmiOpInstr* shift_left) { |
| 2217 const bool is_truncating = shift_left->is_truncating(); | 2236 const bool is_truncating = shift_left->is_truncating(); |
| 2218 const LocationSummary& locs = *shift_left->locs(); | 2237 const LocationSummary& locs = *shift_left->locs(); |
| 2219 Register left = locs.in(0).reg(); | 2238 Register left = locs.in(0).reg(); |
| 2220 Register result = locs.out().reg(); | 2239 Register result = locs.out().reg(); |
| (...skipping 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3772 compiler->GenerateCall(token_pos(), | 3791 compiler->GenerateCall(token_pos(), |
| 3773 &label, | 3792 &label, |
| 3774 PcDescriptors::kOther, | 3793 PcDescriptors::kOther, |
| 3775 locs()); | 3794 locs()); |
| 3776 __ Drop(2); // Discard type arguments and receiver. | 3795 __ Drop(2); // Discard type arguments and receiver. |
| 3777 } | 3796 } |
| 3778 | 3797 |
| 3779 } // namespace dart | 3798 } // namespace dart |
| 3780 | 3799 |
| 3781 #endif // defined TARGET_ARCH_MIPS | 3800 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |