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

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

Powered by Google App Engine
This is Rietveld 408576698