| 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/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "vm/ast_printer.h" | 10 #include "vm/ast_printer.h" |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 Register type_arguments_reg, | 220 Register type_arguments_reg, |
| 221 Register temp_reg, | 221 Register temp_reg, |
| 222 Label* is_instance_lbl, | 222 Label* is_instance_lbl, |
| 223 Label* is_not_instance_lbl) { | 223 Label* is_not_instance_lbl) { |
| 224 __ Comment("CallSubtypeTestStub"); | 224 __ Comment("CallSubtypeTestStub"); |
| 225 ASSERT(instance_reg == A0); | 225 ASSERT(instance_reg == A0); |
| 226 ASSERT(temp_reg == kNoRegister); // Unused on MIPS. | 226 ASSERT(temp_reg == kNoRegister); // Unused on MIPS. |
| 227 const SubtypeTestCache& type_test_cache = | 227 const SubtypeTestCache& type_test_cache = |
| 228 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); | 228 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); |
| 229 StubCode* stub_code = isolate()->stub_code(); | 229 StubCode* stub_code = isolate()->stub_code(); |
| 230 __ LoadObject(A2, type_test_cache); | 230 __ LoadUniqueObject(A2, type_test_cache); |
| 231 if (test_kind == kTestTypeOneArg) { | 231 if (test_kind == kTestTypeOneArg) { |
| 232 ASSERT(type_arguments_reg == kNoRegister); | 232 ASSERT(type_arguments_reg == kNoRegister); |
| 233 __ LoadImmediate(A1, reinterpret_cast<int32_t>(Object::null())); | 233 __ LoadImmediate(A1, reinterpret_cast<int32_t>(Object::null())); |
| 234 __ BranchLink(&stub_code->Subtype1TestCacheLabel()); | 234 __ BranchLink(&stub_code->Subtype1TestCacheLabel()); |
| 235 } else if (test_kind == kTestTypeTwoArgs) { | 235 } else if (test_kind == kTestTypeTwoArgs) { |
| 236 ASSERT(type_arguments_reg == kNoRegister); | 236 ASSERT(type_arguments_reg == kNoRegister); |
| 237 __ LoadImmediate(A1, reinterpret_cast<int32_t>(Object::null())); | 237 __ LoadImmediate(A1, reinterpret_cast<int32_t>(Object::null())); |
| 238 __ BranchLink(&stub_code->Subtype2TestCacheLabel()); | 238 __ BranchLink(&stub_code->Subtype2TestCacheLabel()); |
| 239 } else if (test_kind == kTestTypeThreeArgs) { | 239 } else if (test_kind == kTestTypeThreeArgs) { |
| 240 ASSERT(type_arguments_reg == A1); | 240 ASSERT(type_arguments_reg == A1); |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 __ lw(A2, Address(SP, 1 * kWordSize)); | 609 __ lw(A2, Address(SP, 1 * kWordSize)); |
| 610 | 610 |
| 611 __ addiu(SP, SP, Immediate(-6 * kWordSize)); | 611 __ addiu(SP, SP, Immediate(-6 * kWordSize)); |
| 612 __ LoadObject(TMP, Object::null_object()); | 612 __ LoadObject(TMP, Object::null_object()); |
| 613 __ sw(TMP, Address(SP, 5 * kWordSize)); // Make room for the result. | 613 __ sw(TMP, Address(SP, 5 * kWordSize)); // Make room for the result. |
| 614 __ sw(A0, Address(SP, 4 * kWordSize)); // Push the instance. | 614 __ sw(A0, Address(SP, 4 * kWordSize)); // Push the instance. |
| 615 __ LoadObject(TMP, type); | 615 __ LoadObject(TMP, type); |
| 616 __ sw(TMP, Address(SP, 3 * kWordSize)); // Push the type. | 616 __ sw(TMP, Address(SP, 3 * kWordSize)); // Push the type. |
| 617 __ sw(A2, Address(SP, 2 * kWordSize)); // Push instantiator. | 617 __ sw(A2, Address(SP, 2 * kWordSize)); // Push instantiator. |
| 618 __ sw(A1, Address(SP, 1 * kWordSize)); // Push type arguments. | 618 __ sw(A1, Address(SP, 1 * kWordSize)); // Push type arguments. |
| 619 __ LoadObject(A0, test_cache); | 619 __ LoadUniqueObject(A0, test_cache); |
| 620 __ sw(A0, Address(SP, 0 * kWordSize)); | 620 __ sw(A0, Address(SP, 0 * kWordSize)); |
| 621 GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs); | 621 GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs); |
| 622 // Pop the parameters supplied to the runtime entry. The result of the | 622 // Pop the parameters supplied to the runtime entry. The result of the |
| 623 // instanceof runtime call will be left as the result of the operation. | 623 // instanceof runtime call will be left as the result of the operation. |
| 624 __ lw(T0, Address(SP, 5 * kWordSize)); | 624 __ lw(T0, Address(SP, 5 * kWordSize)); |
| 625 __ addiu(SP, SP, Immediate(6 * kWordSize)); | 625 __ addiu(SP, SP, Immediate(6 * kWordSize)); |
| 626 if (negate_result) { | 626 if (negate_result) { |
| 627 __ LoadObject(V0, Bool::True()); | 627 __ LoadObject(V0, Bool::True()); |
| 628 __ bne(T0, V0, &done); | 628 __ bne(T0, V0, &done); |
| 629 __ LoadObject(V0, Bool::False()); | 629 __ LoadObject(V0, Bool::False()); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 __ addiu(SP, SP, Immediate(-7 * kWordSize)); | 719 __ addiu(SP, SP, Immediate(-7 * kWordSize)); |
| 720 __ LoadObject(TMP, Object::null_object()); | 720 __ LoadObject(TMP, Object::null_object()); |
| 721 __ sw(TMP, Address(SP, 6 * kWordSize)); // Make room for the result. | 721 __ sw(TMP, Address(SP, 6 * kWordSize)); // Make room for the result. |
| 722 __ sw(A0, Address(SP, 5 * kWordSize)); // Push the source object. | 722 __ sw(A0, Address(SP, 5 * kWordSize)); // Push the source object. |
| 723 __ LoadObject(TMP, dst_type); | 723 __ LoadObject(TMP, dst_type); |
| 724 __ sw(TMP, Address(SP, 4 * kWordSize)); // Push the type of the destination. | 724 __ sw(TMP, Address(SP, 4 * kWordSize)); // Push the type of the destination. |
| 725 __ sw(A2, Address(SP, 3 * kWordSize)); // Push instantiator. | 725 __ sw(A2, Address(SP, 3 * kWordSize)); // Push instantiator. |
| 726 __ sw(A1, Address(SP, 2 * kWordSize)); // Push type arguments. | 726 __ sw(A1, Address(SP, 2 * kWordSize)); // Push type arguments. |
| 727 __ LoadObject(TMP, dst_name); | 727 __ LoadObject(TMP, dst_name); |
| 728 __ sw(TMP, Address(SP, 1 * kWordSize)); // Push the name of the destination. | 728 __ sw(TMP, Address(SP, 1 * kWordSize)); // Push the name of the destination. |
| 729 __ LoadObject(T0, test_cache); | 729 __ LoadUniqueObject(T0, test_cache); |
| 730 __ sw(T0, Address(SP, 0 * kWordSize)); | 730 __ sw(T0, Address(SP, 0 * kWordSize)); |
| 731 | 731 |
| 732 GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs); | 732 GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs); |
| 733 // Pop the parameters supplied to the runtime entry. The result of the | 733 // Pop the parameters supplied to the runtime entry. The result of the |
| 734 // type check runtime call is the checked value. | 734 // type check runtime call is the checked value. |
| 735 __ lw(A0, Address(SP, 6 * kWordSize)); | 735 __ lw(A0, Address(SP, 6 * kWordSize)); |
| 736 __ addiu(SP, SP, Immediate(7 * kWordSize)); | 736 __ addiu(SP, SP, Immediate(7 * kWordSize)); |
| 737 | 737 |
| 738 __ Bind(&is_assignable); | 738 __ Bind(&is_assignable); |
| 739 // Restore instantiator and its type arguments. | 739 // Restore instantiator and its type arguments. |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1220 | 1220 |
| 1221 void FlowGraphCompiler::EmitEdgeCounter() { | 1221 void FlowGraphCompiler::EmitEdgeCounter() { |
| 1222 // We do not check for overflow when incrementing the edge counter. The | 1222 // We do not check for overflow when incrementing the edge counter. The |
| 1223 // function should normally be optimized long before the counter can | 1223 // function should normally be optimized long before the counter can |
| 1224 // overflow; and though we do not reset the counters when we optimize or | 1224 // overflow; and though we do not reset the counters when we optimize or |
| 1225 // deoptimize, there is a bound on the number of | 1225 // deoptimize, there is a bound on the number of |
| 1226 // optimization/deoptimization cycles we will attempt. | 1226 // optimization/deoptimization cycles we will attempt. |
| 1227 const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld)); | 1227 const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld)); |
| 1228 counter.SetAt(0, Smi::Handle(Smi::New(0))); | 1228 counter.SetAt(0, Smi::Handle(Smi::New(0))); |
| 1229 __ Comment("Edge counter"); | 1229 __ Comment("Edge counter"); |
| 1230 __ LoadObject(T0, counter); | 1230 __ LoadUniqueObject(T0, counter); |
| 1231 __ lw(T1, FieldAddress(T0, Array::element_offset(0))); | 1231 __ lw(T1, FieldAddress(T0, Array::element_offset(0))); |
| 1232 __ AddImmediate(T1, T1, Smi::RawValue(1)); | 1232 __ AddImmediate(T1, T1, Smi::RawValue(1)); |
| 1233 __ sw(T1, FieldAddress(T0, Array::element_offset(0))); | 1233 __ sw(T1, FieldAddress(T0, Array::element_offset(0))); |
| 1234 } | 1234 } |
| 1235 | 1235 |
| 1236 | 1236 |
| 1237 void FlowGraphCompiler::EmitOptimizedInstanceCall( | 1237 void FlowGraphCompiler::EmitOptimizedInstanceCall( |
| 1238 ExternalLabel* target_label, | 1238 ExternalLabel* target_label, |
| 1239 const ICData& ic_data, | 1239 const ICData& ic_data, |
| 1240 intptr_t argument_count, | 1240 intptr_t argument_count, |
| 1241 intptr_t deopt_id, | 1241 intptr_t deopt_id, |
| 1242 intptr_t token_pos, | 1242 intptr_t token_pos, |
| 1243 LocationSummary* locs) { | 1243 LocationSummary* locs) { |
| 1244 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); | 1244 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); |
| 1245 // Each ICData propagated from unoptimized to optimized code contains the | 1245 // Each ICData propagated from unoptimized to optimized code contains the |
| 1246 // function that corresponds to the Dart function of that IC call. Due | 1246 // function that corresponds to the Dart function of that IC call. Due |
| 1247 // to inlining in optimized code, that function may not correspond to the | 1247 // to inlining in optimized code, that function may not correspond to the |
| 1248 // top-level function (parsed_function().function()) which could be | 1248 // top-level function (parsed_function().function()) which could be |
| 1249 // reoptimized and which counter needs to be incremented. | 1249 // reoptimized and which counter needs to be incremented. |
| 1250 // Pass the function explicitly, it is used in IC stub. | 1250 // Pass the function explicitly, it is used in IC stub. |
| 1251 __ Comment("OptimizedInstanceCall"); | 1251 __ Comment("OptimizedInstanceCall"); |
| 1252 __ LoadObject(T0, parsed_function().function()); | 1252 __ LoadObject(T0, parsed_function().function()); |
| 1253 __ LoadObject(S5, ic_data); | 1253 __ LoadUniqueObject(S5, ic_data); |
| 1254 GenerateDartCall(deopt_id, | 1254 GenerateDartCall(deopt_id, |
| 1255 token_pos, | 1255 token_pos, |
| 1256 target_label, | 1256 target_label, |
| 1257 RawPcDescriptors::kIcCall, | 1257 RawPcDescriptors::kIcCall, |
| 1258 locs); | 1258 locs); |
| 1259 __ Drop(argument_count); | 1259 __ Drop(argument_count); |
| 1260 } | 1260 } |
| 1261 | 1261 |
| 1262 | 1262 |
| 1263 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, | 1263 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, |
| 1264 const ICData& ic_data, | 1264 const ICData& ic_data, |
| 1265 intptr_t argument_count, | 1265 intptr_t argument_count, |
| 1266 intptr_t deopt_id, | 1266 intptr_t deopt_id, |
| 1267 intptr_t token_pos, | 1267 intptr_t token_pos, |
| 1268 LocationSummary* locs) { | 1268 LocationSummary* locs) { |
| 1269 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); | 1269 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); |
| 1270 __ Comment("InstanceCall"); | 1270 __ Comment("InstanceCall"); |
| 1271 __ LoadObject(S5, ic_data); | 1271 __ LoadUniqueObject(S5, ic_data); |
| 1272 GenerateDartCall(deopt_id, | 1272 GenerateDartCall(deopt_id, |
| 1273 token_pos, | 1273 token_pos, |
| 1274 target_label, | 1274 target_label, |
| 1275 RawPcDescriptors::kIcCall, | 1275 RawPcDescriptors::kIcCall, |
| 1276 locs); | 1276 locs); |
| 1277 __ Comment("InstanceCall return"); | 1277 __ Comment("InstanceCall return"); |
| 1278 __ Drop(argument_count); | 1278 __ Drop(argument_count); |
| 1279 } | 1279 } |
| 1280 | 1280 |
| 1281 | 1281 |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1868 __ AddImmediate(SP, kDoubleSize); | 1868 __ AddImmediate(SP, kDoubleSize); |
| 1869 } | 1869 } |
| 1870 | 1870 |
| 1871 | 1871 |
| 1872 #undef __ | 1872 #undef __ |
| 1873 | 1873 |
| 1874 | 1874 |
| 1875 } // namespace dart | 1875 } // namespace dart |
| 1876 | 1876 |
| 1877 #endif // defined TARGET_ARCH_MIPS | 1877 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |