Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: runtime/vm/flow_graph_compiler_mips.cc

Issue 1644793002: Replace intptr_t with TokenDescriptor (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 } 251 }
252 252
253 253
254 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if 254 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if
255 // type test is conclusive, otherwise fallthrough if a type test could not 255 // type test is conclusive, otherwise fallthrough if a type test could not
256 // be completed. 256 // be completed.
257 // A0: instance being type checked (preserved). 257 // A0: instance being type checked (preserved).
258 // Clobbers T0. 258 // Clobbers T0.
259 RawSubtypeTestCache* 259 RawSubtypeTestCache*
260 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest( 260 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
261 intptr_t token_pos, 261 TokenDescriptor token_pos,
262 const AbstractType& type, 262 const AbstractType& type,
263 Label* is_instance_lbl, 263 Label* is_instance_lbl,
264 Label* is_not_instance_lbl) { 264 Label* is_not_instance_lbl) {
265 __ Comment("InstantiatedTypeWithArgumentsTest"); 265 __ Comment("InstantiatedTypeWithArgumentsTest");
266 ASSERT(type.IsInstantiated()); 266 ASSERT(type.IsInstantiated());
267 const Class& type_class = Class::ZoneHandle(zone(), type.type_class()); 267 const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
268 ASSERT(type.IsFunctionType() || (type_class.NumTypeArguments() > 0)); 268 ASSERT(type.IsFunctionType() || (type_class.NumTypeArguments() > 0));
269 const Register kInstanceReg = A0; 269 const Register kInstanceReg = A0;
270 Error& bound_error = Error::Handle(zone()); 270 Error& bound_error = Error::Handle(zone());
271 const Type& int_type = Type::Handle(zone(), Type::IntType()); 271 const Type& int_type = Type::Handle(zone(), Type::IntType());
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 __ b(is_not_equal_lbl); 340 __ b(is_not_equal_lbl);
341 } 341 }
342 342
343 343
344 // Testing against an instantiated type with no arguments, without 344 // Testing against an instantiated type with no arguments, without
345 // SubtypeTestCache. 345 // SubtypeTestCache.
346 // A0: instance being type checked (preserved). 346 // A0: instance being type checked (preserved).
347 // Clobbers: T0, T1, T2 347 // Clobbers: T0, T1, T2
348 // Returns true if there is a fallthrough. 348 // Returns true if there is a fallthrough.
349 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest( 349 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
350 intptr_t token_pos, 350 TokenDescriptor token_pos,
351 const AbstractType& type, 351 const AbstractType& type,
352 Label* is_instance_lbl, 352 Label* is_instance_lbl,
353 Label* is_not_instance_lbl) { 353 Label* is_not_instance_lbl) {
354 __ Comment("InstantiatedTypeNoArgumentsTest"); 354 __ Comment("InstantiatedTypeNoArgumentsTest");
355 ASSERT(type.IsInstantiated()); 355 ASSERT(type.IsInstantiated());
356 if (type.IsFunctionType()) { 356 if (type.IsFunctionType()) {
357 // Fallthrough. 357 // Fallthrough.
358 return true; 358 return true;
359 } 359 }
360 const Class& type_class = Class::Handle(zone(), type.type_class()); 360 const Class& type_class = Class::Handle(zone(), type.type_class());
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 408
409 409
410 // Uses SubtypeTestCache to store instance class and result. 410 // Uses SubtypeTestCache to store instance class and result.
411 // A0: instance to test. 411 // A0: instance to test.
412 // Clobbers A1, A2, T0-T3. 412 // Clobbers A1, A2, T0-T3.
413 // Immediate class test already done. 413 // Immediate class test already done.
414 // TODO(srdjan): Implement a quicker subtype check, as type test 414 // TODO(srdjan): Implement a quicker subtype check, as type test
415 // arrays can grow too high, but they may be useful when optimizing 415 // arrays can grow too high, but they may be useful when optimizing
416 // code (type-feedback). 416 // code (type-feedback).
417 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup( 417 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
418 intptr_t token_pos, 418 TokenDescriptor token_pos,
419 const Class& type_class, 419 const Class& type_class,
420 Label* is_instance_lbl, 420 Label* is_instance_lbl,
421 Label* is_not_instance_lbl) { 421 Label* is_not_instance_lbl) {
422 __ Comment("Subtype1TestCacheLookup"); 422 __ Comment("Subtype1TestCacheLookup");
423 const Register kInstanceReg = A0; 423 const Register kInstanceReg = A0;
424 __ LoadClass(T0, kInstanceReg); 424 __ LoadClass(T0, kInstanceReg);
425 // T0: instance class. 425 // T0: instance class.
426 // Check immediate superclass equality. 426 // Check immediate superclass equality.
427 __ lw(T0, FieldAddress(T0, Class::super_type_offset())); 427 __ lw(T0, FieldAddress(T0, Class::super_type_offset()));
428 __ lw(T0, FieldAddress(T0, Type::type_class_offset())); 428 __ lw(T0, FieldAddress(T0, Type::type_class_offset()));
429 __ BranchEqual(T0, type_class, is_instance_lbl); 429 __ BranchEqual(T0, type_class, is_instance_lbl);
430 430
431 const Register kTypeArgumentsReg = kNoRegister; 431 const Register kTypeArgumentsReg = kNoRegister;
432 const Register kTempReg = kNoRegister; 432 const Register kTempReg = kNoRegister;
433 return GenerateCallSubtypeTestStub(kTestTypeOneArg, 433 return GenerateCallSubtypeTestStub(kTestTypeOneArg,
434 kInstanceReg, 434 kInstanceReg,
435 kTypeArgumentsReg, 435 kTypeArgumentsReg,
436 kTempReg, 436 kTempReg,
437 is_instance_lbl, 437 is_instance_lbl,
438 is_not_instance_lbl); 438 is_not_instance_lbl);
439 } 439 }
440 440
441 441
442 // Generates inlined check if 'type' is a type parameter or type itself 442 // Generates inlined check if 'type' is a type parameter or type itself
443 // A0: instance (preserved). 443 // A0: instance (preserved).
444 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest( 444 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
445 intptr_t token_pos, 445 TokenDescriptor token_pos,
446 const AbstractType& type, 446 const AbstractType& type,
447 Label* is_instance_lbl, 447 Label* is_instance_lbl,
448 Label* is_not_instance_lbl) { 448 Label* is_not_instance_lbl) {
449 __ Comment("UninstantiatedTypeTest"); 449 __ Comment("UninstantiatedTypeTest");
450 ASSERT(!type.IsInstantiated()); 450 ASSERT(!type.IsInstantiated());
451 // Skip check if destination is a dynamic type. 451 // Skip check if destination is a dynamic type.
452 if (type.IsTypeParameter()) { 452 if (type.IsTypeParameter()) {
453 const TypeParameter& type_param = TypeParameter::Cast(type); 453 const TypeParameter& type_param = TypeParameter::Cast(type);
454 // Load instantiator type arguments on stack. 454 // Load instantiator type arguments on stack.
455 __ lw(A1, Address(SP, 0)); // Get instantiator type arguments. 455 __ lw(A1, Address(SP, 0)); // Get instantiator type arguments.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 // Inputs: 518 // Inputs:
519 // - A0: instance being type checked (preserved). 519 // - A0: instance being type checked (preserved).
520 // - A1: optional instantiator type arguments (preserved). 520 // - A1: optional instantiator type arguments (preserved).
521 // Returns: 521 // Returns:
522 // - preserved instance in A0 and optional instantiator type arguments in A1. 522 // - preserved instance in A0 and optional instantiator type arguments in A1.
523 // Clobbers: T0, T1, T2 523 // Clobbers: T0, T1, T2
524 // Note that this inlined code must be followed by the runtime_call code, as it 524 // Note that this inlined code must be followed by the runtime_call code, as it
525 // may fall through to it. Otherwise, this inline code will jump to the label 525 // may fall through to it. Otherwise, this inline code will jump to the label
526 // is_instance or to the label is_not_instance. 526 // is_instance or to the label is_not_instance.
527 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof( 527 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
528 intptr_t token_pos, 528 TokenDescriptor token_pos,
529 const AbstractType& type, 529 const AbstractType& type,
530 Label* is_instance_lbl, 530 Label* is_instance_lbl,
531 Label* is_not_instance_lbl) { 531 Label* is_not_instance_lbl) {
532 __ Comment("InlineInstanceof"); 532 __ Comment("InlineInstanceof");
533 if (type.IsVoidType()) { 533 if (type.IsVoidType()) {
534 // A non-null value is returned from a void function, which will result in a 534 // A non-null value is returned from a void function, which will result in a
535 // type error. A null value is handled prior to executing this inline code. 535 // type error. A null value is handled prior to executing this inline code.
536 return SubtypeTestCache::null(); 536 return SubtypeTestCache::null();
537 } 537 }
538 if (type.IsInstantiated()) { 538 if (type.IsInstantiated()) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 // If instanceof type test cannot be performed successfully at compile time and 571 // If instanceof type test cannot be performed successfully at compile time and
572 // therefore eliminated, optimize it by adding inlined tests for: 572 // therefore eliminated, optimize it by adding inlined tests for:
573 // - NULL -> return false. 573 // - NULL -> return false.
574 // - Smi -> compile time subtype check (only if dst class is not parameterized). 574 // - Smi -> compile time subtype check (only if dst class is not parameterized).
575 // - Class equality (only if class is not parameterized). 575 // - Class equality (only if class is not parameterized).
576 // Inputs: 576 // Inputs:
577 // - A0: object. 577 // - A0: object.
578 // - A1: instantiator type arguments or raw_null. 578 // - A1: instantiator type arguments or raw_null.
579 // Returns: 579 // Returns:
580 // - true or false in V0. 580 // - true or false in V0.
581 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos, 581 void FlowGraphCompiler::GenerateInstanceOf(TokenDescriptor token_pos,
582 intptr_t deopt_id, 582 intptr_t deopt_id,
583 const AbstractType& type, 583 const AbstractType& type,
584 bool negate_result, 584 bool negate_result,
585 LocationSummary* locs) { 585 LocationSummary* locs) {
586 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); 586 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
587 587
588 // Preserve instantiator type arguments (A1). 588 // Preserve instantiator type arguments (A1).
589 __ addiu(SP, SP, Immediate(-1 * kWordSize)); 589 __ addiu(SP, SP, Immediate(-1 * kWordSize));
590 __ sw(A1, Address(SP, 0 * kWordSize)); 590 __ sw(A1, Address(SP, 0 * kWordSize));
591 591
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 // - Smi -> compile time subtype check (only if dst class is not parameterized). 656 // - Smi -> compile time subtype check (only if dst class is not parameterized).
657 // - Class equality (only if class is not parameterized). 657 // - Class equality (only if class is not parameterized).
658 // Inputs: 658 // Inputs:
659 // - A0: instance being type checked. 659 // - A0: instance being type checked.
660 // - A1: instantiator type arguments or raw_null. 660 // - A1: instantiator type arguments or raw_null.
661 // Returns: 661 // Returns:
662 // - object in A0 for successful assignable check (or throws TypeError). 662 // - object in A0 for successful assignable check (or throws TypeError).
663 // Clobbers: T0, T1, T2 663 // Clobbers: T0, T1, T2
664 // Performance notes: positive checks must be quick, negative checks can be slow 664 // Performance notes: positive checks must be quick, negative checks can be slow
665 // as they throw an exception. 665 // as they throw an exception.
666 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos, 666 void FlowGraphCompiler::GenerateAssertAssignable(TokenDescriptor token_pos,
667 intptr_t deopt_id, 667 intptr_t deopt_id,
668 const AbstractType& dst_type, 668 const AbstractType& dst_type,
669 const String& dst_name, 669 const String& dst_name,
670 LocationSummary* locs) { 670 LocationSummary* locs) {
671 __ Comment("AssertAssignable"); 671 __ Comment("AssertAssignable");
672 ASSERT(!Token::IsClassifying(token_pos)); 672 ASSERT(!TokenDescriptor(token_pos).IsClassifying());
673 ASSERT(!dst_type.IsNull()); 673 ASSERT(!dst_type.IsNull());
674 ASSERT(dst_type.IsFinalized()); 674 ASSERT(dst_type.IsFinalized());
675 // Assignable check is skipped in FlowGraphBuilder, not here. 675 // Assignable check is skipped in FlowGraphBuilder, not here.
676 ASSERT(dst_type.IsMalformedOrMalbounded() || 676 ASSERT(dst_type.IsMalformedOrMalbounded() ||
677 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); 677 (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
678 // Preserve instantiator type arguments. 678 // Preserve instantiator type arguments.
679 __ addiu(SP, SP, Immediate(-1 * kWordSize)); 679 __ addiu(SP, SP, Immediate(-1 * kWordSize));
680 __ sw(A1, Address(SP, 0 * kWordSize)); 680 __ sw(A1, Address(SP, 0 * kWordSize));
681 681
682 // A null object is always assignable and is returned as result. 682 // A null object is always assignable and is returned as result.
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 i < CallPattern::kDeoptCallLengthInInstructions; 1144 i < CallPattern::kDeoptCallLengthInInstructions;
1145 ++i) { 1145 ++i) {
1146 __ nop(); 1146 __ nop();
1147 } 1147 }
1148 lazy_deopt_pc_offset_ = assembler()->CodeSize(); 1148 lazy_deopt_pc_offset_ = assembler()->CodeSize();
1149 __ Branch(*StubCode::DeoptimizeLazy_entry()); 1149 __ Branch(*StubCode::DeoptimizeLazy_entry());
1150 } 1150 }
1151 } 1151 }
1152 1152
1153 1153
1154 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 1154 void FlowGraphCompiler::GenerateCall(TokenDescriptor token_pos,
1155 const StubEntry& stub_entry, 1155 const StubEntry& stub_entry,
1156 RawPcDescriptors::Kind kind, 1156 RawPcDescriptors::Kind kind,
1157 LocationSummary* locs) { 1157 LocationSummary* locs) {
1158 __ BranchLinkPatchable(stub_entry); 1158 __ BranchLinkPatchable(stub_entry);
1159 AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos); 1159 AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
1160 RecordSafepoint(locs); 1160 RecordSafepoint(locs);
1161 } 1161 }
1162 1162
1163 1163
1164 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, 1164 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
1165 intptr_t token_pos, 1165 TokenDescriptor token_pos,
1166 const StubEntry& stub_entry, 1166 const StubEntry& stub_entry,
1167 RawPcDescriptors::Kind kind, 1167 RawPcDescriptors::Kind kind,
1168 LocationSummary* locs) { 1168 LocationSummary* locs) {
1169 __ BranchLinkPatchable(stub_entry); 1169 __ BranchLinkPatchable(stub_entry);
1170 AddCurrentDescriptor(kind, deopt_id, token_pos); 1170 AddCurrentDescriptor(kind, deopt_id, token_pos);
1171 RecordSafepoint(locs); 1171 RecordSafepoint(locs);
1172 // Marks either the continuation point in unoptimized code or the 1172 // Marks either the continuation point in unoptimized code or the
1173 // deoptimization point in optimized code, after call. 1173 // deoptimization point in optimized code, after call.
1174 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); 1174 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
1175 if (is_optimizing()) { 1175 if (is_optimizing()) {
1176 AddDeoptIndexAtCall(deopt_id_after, token_pos); 1176 AddDeoptIndexAtCall(deopt_id_after, token_pos);
1177 } else { 1177 } else {
1178 // Add deoptimization continuation point after the call and before the 1178 // Add deoptimization continuation point after the call and before the
1179 // arguments are removed. 1179 // arguments are removed.
1180 AddCurrentDescriptor(RawPcDescriptors::kDeopt, 1180 AddCurrentDescriptor(RawPcDescriptors::kDeopt,
1181 deopt_id_after, 1181 deopt_id_after,
1182 token_pos); 1182 token_pos);
1183 } 1183 }
1184 } 1184 }
1185 1185
1186 1186
1187 void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos, 1187 void FlowGraphCompiler::GenerateRuntimeCall(TokenDescriptor token_pos,
1188 intptr_t deopt_id, 1188 intptr_t deopt_id,
1189 const RuntimeEntry& entry, 1189 const RuntimeEntry& entry,
1190 intptr_t argument_count, 1190 intptr_t argument_count,
1191 LocationSummary* locs) { 1191 LocationSummary* locs) {
1192 __ CallRuntime(entry, argument_count); 1192 __ CallRuntime(entry, argument_count);
1193 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos); 1193 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos);
1194 RecordSafepoint(locs); 1194 RecordSafepoint(locs);
1195 if (deopt_id != Thread::kNoDeoptId) { 1195 if (deopt_id != Thread::kNoDeoptId) {
1196 // Marks either the continuation point in unoptimized code or the 1196 // Marks either the continuation point in unoptimized code or the
1197 // deoptimization point in optimized code, after call. 1197 // deoptimization point in optimized code, after call.
(...skipping 24 matching lines...) Expand all
1222 __ AddImmediate(T1, T1, Smi::RawValue(1)); 1222 __ AddImmediate(T1, T1, Smi::RawValue(1));
1223 __ StoreFieldToOffset(T1, T0, Array::element_offset(edge_id)); 1223 __ StoreFieldToOffset(T1, T0, Array::element_offset(edge_id));
1224 } 1224 }
1225 1225
1226 1226
1227 void FlowGraphCompiler::EmitOptimizedInstanceCall( 1227 void FlowGraphCompiler::EmitOptimizedInstanceCall(
1228 const StubEntry& stub_entry, 1228 const StubEntry& stub_entry,
1229 const ICData& ic_data, 1229 const ICData& ic_data,
1230 intptr_t argument_count, 1230 intptr_t argument_count,
1231 intptr_t deopt_id, 1231 intptr_t deopt_id,
1232 intptr_t token_pos, 1232 TokenDescriptor token_pos,
1233 LocationSummary* locs) { 1233 LocationSummary* locs) {
1234 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0); 1234 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
1235 // Each ICData propagated from unoptimized to optimized code contains the 1235 // Each ICData propagated from unoptimized to optimized code contains the
1236 // function that corresponds to the Dart function of that IC call. Due 1236 // function that corresponds to the Dart function of that IC call. Due
1237 // to inlining in optimized code, that function may not correspond to the 1237 // to inlining in optimized code, that function may not correspond to the
1238 // top-level function (parsed_function().function()) which could be 1238 // top-level function (parsed_function().function()) which could be
1239 // reoptimized and which counter needs to be incremented. 1239 // reoptimized and which counter needs to be incremented.
1240 // Pass the function explicitly, it is used in IC stub. 1240 // Pass the function explicitly, it is used in IC stub.
1241 __ Comment("OptimizedInstanceCall"); 1241 __ Comment("OptimizedInstanceCall");
1242 __ LoadObject(T0, parsed_function().function()); 1242 __ LoadObject(T0, parsed_function().function());
1243 __ LoadUniqueObject(S5, ic_data); 1243 __ LoadUniqueObject(S5, ic_data);
1244 GenerateDartCall(deopt_id, 1244 GenerateDartCall(deopt_id,
1245 token_pos, 1245 token_pos,
1246 stub_entry, 1246 stub_entry,
1247 RawPcDescriptors::kIcCall, 1247 RawPcDescriptors::kIcCall,
1248 locs); 1248 locs);
1249 __ Drop(argument_count); 1249 __ Drop(argument_count);
1250 } 1250 }
1251 1251
1252 1252
1253 void FlowGraphCompiler::EmitInstanceCall(const StubEntry& stub_entry, 1253 void FlowGraphCompiler::EmitInstanceCall(const StubEntry& stub_entry,
1254 const ICData& ic_data, 1254 const ICData& ic_data,
1255 intptr_t argument_count, 1255 intptr_t argument_count,
1256 intptr_t deopt_id, 1256 intptr_t deopt_id,
1257 intptr_t token_pos, 1257 TokenDescriptor token_pos,
1258 LocationSummary* locs) { 1258 LocationSummary* locs) {
1259 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0); 1259 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
1260 __ Comment("InstanceCall"); 1260 __ Comment("InstanceCall");
1261 __ LoadUniqueObject(S5, ic_data); 1261 __ LoadUniqueObject(S5, ic_data);
1262 GenerateDartCall(deopt_id, 1262 GenerateDartCall(deopt_id,
1263 token_pos, 1263 token_pos,
1264 stub_entry, 1264 stub_entry,
1265 RawPcDescriptors::kIcCall, 1265 RawPcDescriptors::kIcCall,
1266 locs); 1266 locs);
1267 __ Comment("InstanceCall return"); 1267 __ Comment("InstanceCall return");
1268 __ Drop(argument_count); 1268 __ Drop(argument_count);
1269 } 1269 }
1270 1270
1271 1271
1272 void FlowGraphCompiler::EmitMegamorphicInstanceCall( 1272 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
1273 const ICData& ic_data, 1273 const ICData& ic_data,
1274 intptr_t argument_count, 1274 intptr_t argument_count,
1275 intptr_t deopt_id, 1275 intptr_t deopt_id,
1276 intptr_t token_pos, 1276 TokenDescriptor token_pos,
1277 LocationSummary* locs, 1277 LocationSummary* locs,
1278 intptr_t try_index) { 1278 intptr_t try_index) {
1279 const String& name = String::Handle(zone(), ic_data.target_name()); 1279 const String& name = String::Handle(zone(), ic_data.target_name());
1280 const Array& arguments_descriptor = 1280 const Array& arguments_descriptor =
1281 Array::ZoneHandle(zone(), ic_data.arguments_descriptor()); 1281 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
1282 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1282 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1283 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(), 1283 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
1284 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor)); 1284 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
1285 1285
1286 __ Comment("MegamorphicCall"); 1286 __ Comment("MegamorphicCall");
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); 1318 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
1319 } 1319 }
1320 __ Drop(argument_count); 1320 __ Drop(argument_count);
1321 } 1321 }
1322 1322
1323 1323
1324 void FlowGraphCompiler::EmitSwitchableInstanceCall( 1324 void FlowGraphCompiler::EmitSwitchableInstanceCall(
1325 const ICData& ic_data, 1325 const ICData& ic_data,
1326 intptr_t argument_count, 1326 intptr_t argument_count,
1327 intptr_t deopt_id, 1327 intptr_t deopt_id,
1328 intptr_t token_pos, 1328 TokenDescriptor token_pos,
1329 LocationSummary* locs) { 1329 LocationSummary* locs) {
1330 __ Comment("SwitchableCall"); 1330 __ Comment("SwitchableCall");
1331 __ lw(T0, Address(SP, (argument_count - 1) * kWordSize)); 1331 __ lw(T0, Address(SP, (argument_count - 1) * kWordSize));
1332 if (ic_data.NumArgsTested() == 1) { 1332 if (ic_data.NumArgsTested() == 1) {
1333 __ LoadUniqueObject(S5, ic_data); 1333 __ LoadUniqueObject(S5, ic_data);
1334 __ BranchLinkPatchable(*StubCode::ICLookup_entry()); 1334 __ BranchLinkPatchable(*StubCode::ICLookup_entry());
1335 } else { 1335 } else {
1336 const String& name = String::Handle(zone(), ic_data.target_name()); 1336 const String& name = String::Handle(zone(), ic_data.target_name());
1337 const Array& arguments_descriptor = 1337 const Array& arguments_descriptor =
1338 Array::ZoneHandle(zone(), ic_data.arguments_descriptor()); 1338 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
(...skipping 18 matching lines...) Expand all
1357 // arguments are removed. 1357 // arguments are removed.
1358 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); 1358 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
1359 } 1359 }
1360 __ Drop(argument_count); 1360 __ Drop(argument_count);
1361 } 1361 }
1362 1362
1363 1363
1364 void FlowGraphCompiler::EmitUnoptimizedStaticCall( 1364 void FlowGraphCompiler::EmitUnoptimizedStaticCall(
1365 intptr_t argument_count, 1365 intptr_t argument_count,
1366 intptr_t deopt_id, 1366 intptr_t deopt_id,
1367 intptr_t token_pos, 1367 TokenDescriptor token_pos,
1368 LocationSummary* locs, 1368 LocationSummary* locs,
1369 const ICData& ic_data) { 1369 const ICData& ic_data) {
1370 const StubEntry* stub_entry = 1370 const StubEntry* stub_entry =
1371 StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested()); 1371 StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
1372 __ LoadObject(S5, ic_data); 1372 __ LoadObject(S5, ic_data);
1373 GenerateDartCall(deopt_id, 1373 GenerateDartCall(deopt_id,
1374 token_pos, 1374 token_pos,
1375 *stub_entry, 1375 *stub_entry,
1376 RawPcDescriptors::kUnoptStaticCall, 1376 RawPcDescriptors::kUnoptStaticCall,
1377 locs); 1377 locs);
1378 __ Drop(argument_count); 1378 __ Drop(argument_count);
1379 } 1379 }
1380 1380
1381 1381
1382 void FlowGraphCompiler::EmitOptimizedStaticCall( 1382 void FlowGraphCompiler::EmitOptimizedStaticCall(
1383 const Function& function, 1383 const Function& function,
1384 const Array& arguments_descriptor, 1384 const Array& arguments_descriptor,
1385 intptr_t argument_count, 1385 intptr_t argument_count,
1386 intptr_t deopt_id, 1386 intptr_t deopt_id,
1387 intptr_t token_pos, 1387 TokenDescriptor token_pos,
1388 LocationSummary* locs) { 1388 LocationSummary* locs) {
1389 __ Comment("StaticCall"); 1389 __ Comment("StaticCall");
1390 __ LoadObject(S4, arguments_descriptor); 1390 __ LoadObject(S4, arguments_descriptor);
1391 // Do not use the code from the function, but let the code be patched so that 1391 // Do not use the code from the function, but let the code be patched so that
1392 // we can record the outgoing edges to other code. 1392 // we can record the outgoing edges to other code.
1393 GenerateDartCall(deopt_id, 1393 GenerateDartCall(deopt_id,
1394 token_pos, 1394 token_pos,
1395 *StubCode::CallStaticFunction_entry(), 1395 *StubCode::CallStaticFunction_entry(),
1396 RawPcDescriptors::kOther, 1396 RawPcDescriptors::kOther,
1397 locs); 1397 locs);
1398 AddStaticCallTarget(function); 1398 AddStaticCallTarget(function);
1399 __ Drop(argument_count); 1399 __ Drop(argument_count);
1400 } 1400 }
1401 1401
1402 1402
1403 Condition FlowGraphCompiler::EmitEqualityRegConstCompare( 1403 Condition FlowGraphCompiler::EmitEqualityRegConstCompare(
1404 Register reg, 1404 Register reg,
1405 const Object& obj, 1405 const Object& obj,
1406 bool needs_number_check, 1406 bool needs_number_check,
1407 intptr_t token_pos) { 1407 TokenDescriptor token_pos) {
1408 __ Comment("EqualityRegConstCompare"); 1408 __ Comment("EqualityRegConstCompare");
1409 ASSERT(!needs_number_check || 1409 ASSERT(!needs_number_check ||
1410 (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint())); 1410 (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()));
1411 if (needs_number_check) { 1411 if (needs_number_check) {
1412 ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()); 1412 ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint());
1413 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 1413 __ addiu(SP, SP, Immediate(-2 * kWordSize));
1414 __ sw(reg, Address(SP, 1 * kWordSize)); 1414 __ sw(reg, Address(SP, 1 * kWordSize));
1415 __ LoadObject(TMP, obj); 1415 __ LoadObject(TMP, obj);
1416 __ sw(TMP, Address(SP, 0 * kWordSize)); 1416 __ sw(TMP, Address(SP, 0 * kWordSize));
1417 if (is_optimizing()) { 1417 if (is_optimizing()) {
1418 __ BranchLinkPatchable( 1418 __ BranchLinkPatchable(
1419 *StubCode::OptimizedIdenticalWithNumberCheck_entry()); 1419 *StubCode::OptimizedIdenticalWithNumberCheck_entry());
1420 } else { 1420 } else {
1421 __ BranchLinkPatchable( 1421 __ BranchLinkPatchable(
1422 *StubCode::UnoptimizedIdenticalWithNumberCheck_entry()); 1422 *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
1423 } 1423 }
1424 if (token_pos >= 0) { 1424 if (token_pos.IsReal()) {
1425 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1425 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1426 Thread::kNoDeoptId, 1426 Thread::kNoDeoptId,
1427 token_pos); 1427 token_pos);
1428 } 1428 }
1429 __ Comment("EqualityRegConstCompare return"); 1429 __ Comment("EqualityRegConstCompare return");
1430 // Stub returns result in CMPRES1 (if it is 0, then reg and obj are equal). 1430 // Stub returns result in CMPRES1 (if it is 0, then reg and obj are equal).
1431 __ lw(reg, Address(SP, 1 * kWordSize)); // Restore 'reg'. 1431 __ lw(reg, Address(SP, 1 * kWordSize)); // Restore 'reg'.
1432 __ addiu(SP, SP, Immediate(2 * kWordSize)); // Discard constant. 1432 __ addiu(SP, SP, Immediate(2 * kWordSize)); // Discard constant.
1433 return Condition(CMPRES1, ZR, EQ); 1433 return Condition(CMPRES1, ZR, EQ);
1434 } else { 1434 } else {
1435 int16_t imm = 0; 1435 int16_t imm = 0;
1436 const Register obj_reg = __ LoadConditionOperand(CMPRES1, obj, &imm); 1436 const Register obj_reg = __ LoadConditionOperand(CMPRES1, obj, &imm);
1437 return Condition(reg, obj_reg, EQ, imm); 1437 return Condition(reg, obj_reg, EQ, imm);
1438 } 1438 }
1439 } 1439 }
1440 1440
1441 1441
1442 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left, 1442 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(
1443 Register right, 1443 Register left,
1444 bool needs_number_check, 1444 Register right,
1445 intptr_t token_pos) { 1445 bool needs_number_check,
1446 TokenDescriptor token_pos) {
1446 __ Comment("EqualityRegRegCompare"); 1447 __ Comment("EqualityRegRegCompare");
1447 if (needs_number_check) { 1448 if (needs_number_check) {
1448 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 1449 __ addiu(SP, SP, Immediate(-2 * kWordSize));
1449 __ sw(left, Address(SP, 1 * kWordSize)); 1450 __ sw(left, Address(SP, 1 * kWordSize));
1450 __ sw(right, Address(SP, 0 * kWordSize)); 1451 __ sw(right, Address(SP, 0 * kWordSize));
1451 if (is_optimizing()) { 1452 if (is_optimizing()) {
1452 __ BranchLinkPatchable( 1453 __ BranchLinkPatchable(
1453 *StubCode::OptimizedIdenticalWithNumberCheck_entry()); 1454 *StubCode::OptimizedIdenticalWithNumberCheck_entry());
1454 } else { 1455 } else {
1455 __ BranchLinkPatchable( 1456 __ BranchLinkPatchable(
1456 *StubCode::UnoptimizedIdenticalWithNumberCheck_entry()); 1457 *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
1457 } 1458 }
1458 if (token_pos >= 0) { 1459 if (token_pos.IsReal()) {
1459 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1460 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1460 Thread::kNoDeoptId, 1461 Thread::kNoDeoptId,
1461 token_pos); 1462 token_pos);
1462 } 1463 }
1463 __ Comment("EqualityRegRegCompare return"); 1464 __ Comment("EqualityRegRegCompare return");
1464 // Stub returns result in CMPRES1 (if it is 0, then left and right are 1465 // Stub returns result in CMPRES1 (if it is 0, then left and right are
1465 // equal). 1466 // equal).
1466 __ lw(right, Address(SP, 0 * kWordSize)); 1467 __ lw(right, Address(SP, 0 * kWordSize));
1467 __ lw(left, Address(SP, 1 * kWordSize)); 1468 __ lw(left, Address(SP, 1 * kWordSize));
1468 __ addiu(SP, SP, Immediate(2 * kWordSize)); 1469 __ addiu(SP, SP, Immediate(2 * kWordSize));
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1568 } 1569 }
1569 #endif 1570 #endif
1570 1571
1571 1572
1572 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, 1573 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
1573 intptr_t argument_count, 1574 intptr_t argument_count,
1574 const Array& argument_names, 1575 const Array& argument_names,
1575 Label* failed, 1576 Label* failed,
1576 Label* match_found, 1577 Label* match_found,
1577 intptr_t deopt_id, 1578 intptr_t deopt_id,
1578 intptr_t token_index, 1579 TokenDescriptor token_index,
1579 LocationSummary* locs) { 1580 LocationSummary* locs) {
1580 ASSERT(is_optimizing()); 1581 ASSERT(is_optimizing());
1581 __ Comment("EmitTestAndCall"); 1582 __ Comment("EmitTestAndCall");
1582 const Array& arguments_descriptor = 1583 const Array& arguments_descriptor =
1583 Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count, 1584 Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count,
1584 argument_names)); 1585 argument_names));
1585 1586
1586 // Load receiver into T0. 1587 // Load receiver into T0.
1587 __ LoadFromOffset(T0, SP, (argument_count - 1) * kWordSize); 1588 __ LoadFromOffset(T0, SP, (argument_count - 1) * kWordSize);
1588 __ LoadObject(S4, arguments_descriptor); 1589 __ LoadObject(S4, arguments_descriptor);
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
1898 __ AddImmediate(SP, kDoubleSize); 1899 __ AddImmediate(SP, kDoubleSize);
1899 } 1900 }
1900 1901
1901 1902
1902 #undef __ 1903 #undef __
1903 1904
1904 1905
1905 } // namespace dart 1906 } // namespace dart
1906 1907
1907 #endif // defined TARGET_ARCH_MIPS 1908 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698