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

Side by Side Diff: runtime/vm/flow_graph_compiler_arm.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.cc ('k') | runtime/vm/flow_graph_compiler_arm64.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_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/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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 } 260 }
261 261
262 262
263 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if 263 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if
264 // type test is conclusive, otherwise fallthrough if a type test could not 264 // type test is conclusive, otherwise fallthrough if a type test could not
265 // be completed. 265 // be completed.
266 // R0: instance being type checked (preserved). 266 // R0: instance being type checked (preserved).
267 // Clobbers R2. 267 // Clobbers R2.
268 RawSubtypeTestCache* 268 RawSubtypeTestCache*
269 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest( 269 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
270 intptr_t token_pos, 270 TokenPosition token_pos,
271 const AbstractType& type, 271 const AbstractType& type,
272 Label* is_instance_lbl, 272 Label* is_instance_lbl,
273 Label* is_not_instance_lbl) { 273 Label* is_not_instance_lbl) {
274 __ Comment("InstantiatedTypeWithArgumentsTest"); 274 __ Comment("InstantiatedTypeWithArgumentsTest");
275 ASSERT(type.IsInstantiated()); 275 ASSERT(type.IsInstantiated());
276 const Class& type_class = Class::ZoneHandle(zone(), type.type_class()); 276 const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
277 ASSERT(type.IsFunctionType() || (type_class.NumTypeArguments() > 0)); 277 ASSERT(type.IsFunctionType() || (type_class.NumTypeArguments() > 0));
278 const Register kInstanceReg = R0; 278 const Register kInstanceReg = R0;
279 Error& bound_error = Error::Handle(zone()); 279 Error& bound_error = Error::Handle(zone());
280 const Type& int_type = Type::Handle(zone(), Type::IntType()); 280 const Type& int_type = Type::Handle(zone(), Type::IntType());
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 __ b(is_not_equal_lbl); 350 __ b(is_not_equal_lbl);
351 } 351 }
352 352
353 353
354 // Testing against an instantiated type with no arguments, without 354 // Testing against an instantiated type with no arguments, without
355 // SubtypeTestCache. 355 // SubtypeTestCache.
356 // R0: instance being type checked (preserved). 356 // R0: instance being type checked (preserved).
357 // Clobbers R2, R3. 357 // Clobbers R2, R3.
358 // Returns true if there is a fallthrough. 358 // Returns true if there is a fallthrough.
359 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest( 359 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
360 intptr_t token_pos, 360 TokenPosition token_pos,
361 const AbstractType& type, 361 const AbstractType& type,
362 Label* is_instance_lbl, 362 Label* is_instance_lbl,
363 Label* is_not_instance_lbl) { 363 Label* is_not_instance_lbl) {
364 __ Comment("InstantiatedTypeNoArgumentsTest"); 364 __ Comment("InstantiatedTypeNoArgumentsTest");
365 ASSERT(type.IsInstantiated()); 365 ASSERT(type.IsInstantiated());
366 if (type.IsFunctionType()) { 366 if (type.IsFunctionType()) {
367 // Fallthrough. 367 // Fallthrough.
368 return true; 368 return true;
369 } 369 }
370 const Class& type_class = Class::Handle(zone(), type.type_class()); 370 const Class& type_class = Class::Handle(zone(), type.type_class());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 420
421 421
422 // Uses SubtypeTestCache to store instance class and result. 422 // Uses SubtypeTestCache to store instance class and result.
423 // R0: instance to test. 423 // R0: instance to test.
424 // Clobbers R1-R4,R9. 424 // Clobbers R1-R4,R9.
425 // Immediate class test already done. 425 // Immediate class test already done.
426 // TODO(srdjan): Implement a quicker subtype check, as type test 426 // TODO(srdjan): Implement a quicker subtype check, as type test
427 // arrays can grow too high, but they may be useful when optimizing 427 // arrays can grow too high, but they may be useful when optimizing
428 // code (type-feedback). 428 // code (type-feedback).
429 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup( 429 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
430 intptr_t token_pos, 430 TokenPosition token_pos,
431 const Class& type_class, 431 const Class& type_class,
432 Label* is_instance_lbl, 432 Label* is_instance_lbl,
433 Label* is_not_instance_lbl) { 433 Label* is_not_instance_lbl) {
434 __ Comment("Subtype1TestCacheLookup"); 434 __ Comment("Subtype1TestCacheLookup");
435 const Register kInstanceReg = R0; 435 const Register kInstanceReg = R0;
436 __ LoadClass(R1, kInstanceReg, R2); 436 __ LoadClass(R1, kInstanceReg, R2);
437 // R1: instance class. 437 // R1: instance class.
438 // Check immediate superclass equality. 438 // Check immediate superclass equality.
439 __ ldr(R2, FieldAddress(R1, Class::super_type_offset())); 439 __ ldr(R2, FieldAddress(R1, Class::super_type_offset()));
440 __ ldr(R2, FieldAddress(R2, Type::type_class_offset())); 440 __ ldr(R2, FieldAddress(R2, Type::type_class_offset()));
441 __ CompareObject(R2, type_class); 441 __ CompareObject(R2, type_class);
442 __ b(is_instance_lbl, EQ); 442 __ b(is_instance_lbl, EQ);
443 443
444 const Register kTypeArgumentsReg = kNoRegister; 444 const Register kTypeArgumentsReg = kNoRegister;
445 const Register kTempReg = kNoRegister; 445 const Register kTempReg = kNoRegister;
446 return GenerateCallSubtypeTestStub(kTestTypeOneArg, 446 return GenerateCallSubtypeTestStub(kTestTypeOneArg,
447 kInstanceReg, 447 kInstanceReg,
448 kTypeArgumentsReg, 448 kTypeArgumentsReg,
449 kTempReg, 449 kTempReg,
450 is_instance_lbl, 450 is_instance_lbl,
451 is_not_instance_lbl); 451 is_not_instance_lbl);
452 } 452 }
453 453
454 454
455 // Generates inlined check if 'type' is a type parameter or type itself 455 // Generates inlined check if 'type' is a type parameter or type itself
456 // R0: instance (preserved). 456 // R0: instance (preserved).
457 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest( 457 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
458 intptr_t token_pos, 458 TokenPosition token_pos,
459 const AbstractType& type, 459 const AbstractType& type,
460 Label* is_instance_lbl, 460 Label* is_instance_lbl,
461 Label* is_not_instance_lbl) { 461 Label* is_not_instance_lbl) {
462 __ Comment("UninstantiatedTypeTest"); 462 __ Comment("UninstantiatedTypeTest");
463 ASSERT(!type.IsInstantiated()); 463 ASSERT(!type.IsInstantiated());
464 // Skip check if destination is a dynamic type. 464 // Skip check if destination is a dynamic type.
465 if (type.IsTypeParameter()) { 465 if (type.IsTypeParameter()) {
466 const TypeParameter& type_param = TypeParameter::Cast(type); 466 const TypeParameter& type_param = TypeParameter::Cast(type);
467 // Load instantiator type arguments on stack. 467 // Load instantiator type arguments on stack.
468 __ ldr(R1, Address(SP, 0)); // Get instantiator type arguments. 468 __ ldr(R1, Address(SP, 0)); // Get instantiator type arguments.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 // Inputs: 531 // Inputs:
532 // - R0: instance being type checked (preserved). 532 // - R0: instance being type checked (preserved).
533 // - R1: optional instantiator type arguments (preserved). 533 // - R1: optional instantiator type arguments (preserved).
534 // Clobbers R2, R3. 534 // Clobbers R2, R3.
535 // Returns: 535 // Returns:
536 // - preserved instance in R0 and optional instantiator type arguments in R1. 536 // - preserved instance in R0 and optional instantiator type arguments in R1.
537 // Note that this inlined code must be followed by the runtime_call code, as it 537 // Note that this inlined code must be followed by the runtime_call code, as it
538 // may fall through to it. Otherwise, this inline code will jump to the label 538 // may fall through to it. Otherwise, this inline code will jump to the label
539 // is_instance or to the label is_not_instance. 539 // is_instance or to the label is_not_instance.
540 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof( 540 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
541 intptr_t token_pos, 541 TokenPosition token_pos,
542 const AbstractType& type, 542 const AbstractType& type,
543 Label* is_instance_lbl, 543 Label* is_instance_lbl,
544 Label* is_not_instance_lbl) { 544 Label* is_not_instance_lbl) {
545 __ Comment("InlineInstanceof"); 545 __ Comment("InlineInstanceof");
546 if (type.IsVoidType()) { 546 if (type.IsVoidType()) {
547 // A non-null value is returned from a void function, which will result in a 547 // A non-null value is returned from a void function, which will result in a
548 // type error. A null value is handled prior to executing this inline code. 548 // type error. A null value is handled prior to executing this inline code.
549 return SubtypeTestCache::null(); 549 return SubtypeTestCache::null();
550 } 550 }
551 if (type.IsInstantiated()) { 551 if (type.IsInstantiated()) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 // If instanceof type test cannot be performed successfully at compile time and 584 // If instanceof type test cannot be performed successfully at compile time and
585 // therefore eliminated, optimize it by adding inlined tests for: 585 // therefore eliminated, optimize it by adding inlined tests for:
586 // - NULL -> return false. 586 // - NULL -> return false.
587 // - Smi -> compile time subtype check (only if dst class is not parameterized). 587 // - Smi -> compile time subtype check (only if dst class is not parameterized).
588 // - Class equality (only if class is not parameterized). 588 // - Class equality (only if class is not parameterized).
589 // Inputs: 589 // Inputs:
590 // - R0: object. 590 // - R0: object.
591 // - R1: instantiator type arguments or raw_null. 591 // - R1: instantiator type arguments or raw_null.
592 // Returns: 592 // Returns:
593 // - true or false in R0. 593 // - true or false in R0.
594 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos, 594 void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
595 intptr_t deopt_id, 595 intptr_t deopt_id,
596 const AbstractType& type, 596 const AbstractType& type,
597 bool negate_result, 597 bool negate_result,
598 LocationSummary* locs) { 598 LocationSummary* locs) {
599 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); 599 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
600 600
601 // Preserve instantiator type arguments (R1). 601 // Preserve instantiator type arguments (R1).
602 __ Push(R1); 602 __ Push(R1);
603 603
604 Label is_instance, is_not_instance; 604 Label is_instance, is_not_instance;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 // - NULL -> return NULL. 664 // - NULL -> return NULL.
665 // - Smi -> compile time subtype check (only if dst class is not parameterized). 665 // - Smi -> compile time subtype check (only if dst class is not parameterized).
666 // - Class equality (only if class is not parameterized). 666 // - Class equality (only if class is not parameterized).
667 // Inputs: 667 // Inputs:
668 // - R0: instance being type checked. 668 // - R0: instance being type checked.
669 // - R1: instantiator type arguments or raw_null. 669 // - R1: instantiator type arguments or raw_null.
670 // Returns: 670 // Returns:
671 // - object in R0 for successful assignable check (or throws TypeError). 671 // - object in R0 for successful assignable check (or throws TypeError).
672 // Performance notes: positive checks must be quick, negative checks can be slow 672 // Performance notes: positive checks must be quick, negative checks can be slow
673 // as they throw an exception. 673 // as they throw an exception.
674 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos, 674 void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
675 intptr_t deopt_id, 675 intptr_t deopt_id,
676 const AbstractType& dst_type, 676 const AbstractType& dst_type,
677 const String& dst_name, 677 const String& dst_name,
678 LocationSummary* locs) { 678 LocationSummary* locs) {
679 ASSERT(!Token::IsClassifying(token_pos)); 679 ASSERT(!token_pos.IsClassifying());
680 ASSERT(!dst_type.IsNull()); 680 ASSERT(!dst_type.IsNull());
681 ASSERT(dst_type.IsFinalized()); 681 ASSERT(dst_type.IsFinalized());
682 // Assignable check is skipped in FlowGraphBuilder, not here. 682 // Assignable check is skipped in FlowGraphBuilder, not here.
683 ASSERT(dst_type.IsMalformedOrMalbounded() || 683 ASSERT(dst_type.IsMalformedOrMalbounded() ||
684 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); 684 (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
685 // Preserve instantiator type arguments (R1). 685 // Preserve instantiator type arguments (R1).
686 __ Push(R1); 686 __ Push(R1);
687 // A null object is always assignable and is returned as result. 687 // A null object is always assignable and is returned as result.
688 Label is_assignable, runtime_call; 688 Label is_assignable, runtime_call;
689 __ CompareObject(R0, Object::null_object()); 689 __ CompareObject(R0, Object::null_object());
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 i < CallPattern::DeoptCallPatternLengthInInstructions(); 1132 i < CallPattern::DeoptCallPatternLengthInInstructions();
1133 ++i) { 1133 ++i) {
1134 __ nop(); 1134 __ nop();
1135 } 1135 }
1136 lazy_deopt_pc_offset_ = assembler()->CodeSize(); 1136 lazy_deopt_pc_offset_ = assembler()->CodeSize();
1137 __ Branch(*StubCode::DeoptimizeLazy_entry()); 1137 __ Branch(*StubCode::DeoptimizeLazy_entry());
1138 } 1138 }
1139 } 1139 }
1140 1140
1141 1141
1142 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 1142 void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
1143 const StubEntry& stub_entry, 1143 const StubEntry& stub_entry,
1144 RawPcDescriptors::Kind kind, 1144 RawPcDescriptors::Kind kind,
1145 LocationSummary* locs) { 1145 LocationSummary* locs) {
1146 __ BranchLinkPatchable(stub_entry); 1146 __ BranchLinkPatchable(stub_entry);
1147 AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos); 1147 AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
1148 RecordSafepoint(locs); 1148 RecordSafepoint(locs);
1149 } 1149 }
1150 1150
1151 1151
1152 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, 1152 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
1153 intptr_t token_pos, 1153 TokenPosition token_pos,
1154 const StubEntry& stub_entry, 1154 const StubEntry& stub_entry,
1155 RawPcDescriptors::Kind kind, 1155 RawPcDescriptors::Kind kind,
1156 LocationSummary* locs) { 1156 LocationSummary* locs) {
1157 __ BranchLinkPatchable(stub_entry); 1157 __ BranchLinkPatchable(stub_entry);
1158 AddCurrentDescriptor(kind, deopt_id, token_pos); 1158 AddCurrentDescriptor(kind, deopt_id, token_pos);
1159 RecordSafepoint(locs); 1159 RecordSafepoint(locs);
1160 // Marks either the continuation point in unoptimized code or the 1160 // Marks either the continuation point in unoptimized code or the
1161 // deoptimization point in optimized code, after call. 1161 // deoptimization point in optimized code, after call.
1162 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); 1162 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
1163 if (is_optimizing()) { 1163 if (is_optimizing()) {
1164 AddDeoptIndexAtCall(deopt_id_after, token_pos); 1164 AddDeoptIndexAtCall(deopt_id_after, token_pos);
1165 } else { 1165 } else {
1166 // Add deoptimization continuation point after the call and before the 1166 // Add deoptimization continuation point after the call and before the
1167 // arguments are removed. 1167 // arguments are removed.
1168 AddCurrentDescriptor(RawPcDescriptors::kDeopt, 1168 AddCurrentDescriptor(RawPcDescriptors::kDeopt,
1169 deopt_id_after, token_pos); 1169 deopt_id_after, token_pos);
1170 } 1170 }
1171 } 1171 }
1172 1172
1173 1173
1174 void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos, 1174 void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
1175 intptr_t deopt_id, 1175 intptr_t deopt_id,
1176 const RuntimeEntry& entry, 1176 const RuntimeEntry& entry,
1177 intptr_t argument_count, 1177 intptr_t argument_count,
1178 LocationSummary* locs) { 1178 LocationSummary* locs) {
1179 __ CallRuntime(entry, argument_count); 1179 __ CallRuntime(entry, argument_count);
1180 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos); 1180 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos);
1181 RecordSafepoint(locs); 1181 RecordSafepoint(locs);
1182 if (deopt_id != Thread::kNoDeoptId) { 1182 if (deopt_id != Thread::kNoDeoptId) {
1183 // Marks either the continuation point in unoptimized code or the 1183 // Marks either the continuation point in unoptimized code or the
1184 // deoptimization point in optimized code, after call. 1184 // deoptimization point in optimized code, after call.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 assembler_->set_use_far_branches(old_use_far_branches); 1218 assembler_->set_use_far_branches(old_use_far_branches);
1219 #endif // DEBUG 1219 #endif // DEBUG
1220 } 1220 }
1221 1221
1222 1222
1223 void FlowGraphCompiler::EmitOptimizedInstanceCall( 1223 void FlowGraphCompiler::EmitOptimizedInstanceCall(
1224 const StubEntry& stub_entry, 1224 const StubEntry& stub_entry,
1225 const ICData& ic_data, 1225 const ICData& ic_data,
1226 intptr_t argument_count, 1226 intptr_t argument_count,
1227 intptr_t deopt_id, 1227 intptr_t deopt_id,
1228 intptr_t token_pos, 1228 TokenPosition token_pos,
1229 LocationSummary* locs) { 1229 LocationSummary* locs) {
1230 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0); 1230 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
1231 // Each ICData propagated from unoptimized to optimized code contains the 1231 // Each ICData propagated from unoptimized to optimized code contains the
1232 // function that corresponds to the Dart function of that IC call. Due 1232 // function that corresponds to the Dart function of that IC call. Due
1233 // to inlining in optimized code, that function may not correspond to the 1233 // to inlining in optimized code, that function may not correspond to the
1234 // top-level function (parsed_function().function()) which could be 1234 // top-level function (parsed_function().function()) which could be
1235 // reoptimized and which counter needs to be incremented. 1235 // reoptimized and which counter needs to be incremented.
1236 // Pass the function explicitly, it is used in IC stub. 1236 // Pass the function explicitly, it is used in IC stub.
1237 1237
1238 __ LoadObject(R8, parsed_function().function()); 1238 __ LoadObject(R8, parsed_function().function());
1239 __ LoadUniqueObject(R9, ic_data); 1239 __ LoadUniqueObject(R9, ic_data);
1240 GenerateDartCall(deopt_id, 1240 GenerateDartCall(deopt_id,
1241 token_pos, 1241 token_pos,
1242 stub_entry, 1242 stub_entry,
1243 RawPcDescriptors::kIcCall, 1243 RawPcDescriptors::kIcCall,
1244 locs); 1244 locs);
1245 __ Drop(argument_count); 1245 __ Drop(argument_count);
1246 } 1246 }
1247 1247
1248 1248
1249 void FlowGraphCompiler::EmitInstanceCall(const StubEntry& stub_entry, 1249 void FlowGraphCompiler::EmitInstanceCall(const StubEntry& stub_entry,
1250 const ICData& ic_data, 1250 const ICData& ic_data,
1251 intptr_t argument_count, 1251 intptr_t argument_count,
1252 intptr_t deopt_id, 1252 intptr_t deopt_id,
1253 intptr_t token_pos, 1253 TokenPosition token_pos,
1254 LocationSummary* locs) { 1254 LocationSummary* locs) {
1255 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0); 1255 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
1256 __ LoadUniqueObject(R9, ic_data); 1256 __ LoadUniqueObject(R9, ic_data);
1257 GenerateDartCall(deopt_id, 1257 GenerateDartCall(deopt_id,
1258 token_pos, 1258 token_pos,
1259 stub_entry, 1259 stub_entry,
1260 RawPcDescriptors::kIcCall, 1260 RawPcDescriptors::kIcCall,
1261 locs); 1261 locs);
1262 __ Drop(argument_count); 1262 __ Drop(argument_count);
1263 } 1263 }
1264 1264
1265 1265
1266 void FlowGraphCompiler::EmitMegamorphicInstanceCall( 1266 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
1267 const ICData& ic_data, 1267 const ICData& ic_data,
1268 intptr_t argument_count, 1268 intptr_t argument_count,
1269 intptr_t deopt_id, 1269 intptr_t deopt_id,
1270 intptr_t token_pos, 1270 TokenPosition token_pos,
1271 LocationSummary* locs, 1271 LocationSummary* locs,
1272 intptr_t try_index) { 1272 intptr_t try_index) {
1273 const String& name = String::Handle(zone(), ic_data.target_name()); 1273 const String& name = String::Handle(zone(), ic_data.target_name());
1274 const Array& arguments_descriptor = 1274 const Array& arguments_descriptor =
1275 Array::ZoneHandle(zone(), ic_data.arguments_descriptor()); 1275 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
1276 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1276 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1277 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(), 1277 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
1278 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor)); 1278 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
1279 1279
1280 __ Comment("MegamorphicCall"); 1280 __ Comment("MegamorphicCall");
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1313 deopt_id_after, token_pos); 1313 deopt_id_after, token_pos);
1314 } 1314 }
1315 __ Drop(argument_count); 1315 __ Drop(argument_count);
1316 } 1316 }
1317 1317
1318 1318
1319 void FlowGraphCompiler::EmitSwitchableInstanceCall( 1319 void FlowGraphCompiler::EmitSwitchableInstanceCall(
1320 const ICData& ic_data, 1320 const ICData& ic_data,
1321 intptr_t argument_count, 1321 intptr_t argument_count,
1322 intptr_t deopt_id, 1322 intptr_t deopt_id,
1323 intptr_t token_pos, 1323 TokenPosition token_pos,
1324 LocationSummary* locs) { 1324 LocationSummary* locs) {
1325 __ Comment("SwitchableCall"); 1325 __ Comment("SwitchableCall");
1326 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize); 1326 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
1327 if (ic_data.NumArgsTested() == 1) { 1327 if (ic_data.NumArgsTested() == 1) {
1328 __ LoadUniqueObject(R9, ic_data); 1328 __ LoadUniqueObject(R9, ic_data);
1329 __ BranchLinkPatchable(*StubCode::ICLookup_entry()); 1329 __ BranchLinkPatchable(*StubCode::ICLookup_entry());
1330 } else { 1330 } else {
1331 const String& name = String::Handle(zone(), ic_data.target_name()); 1331 const String& name = String::Handle(zone(), ic_data.target_name());
1332 const Array& arguments_descriptor = 1332 const Array& arguments_descriptor =
1333 Array::ZoneHandle(zone(), ic_data.arguments_descriptor()); 1333 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
(...skipping 18 matching lines...) Expand all
1352 AddCurrentDescriptor(RawPcDescriptors::kDeopt, 1352 AddCurrentDescriptor(RawPcDescriptors::kDeopt,
1353 deopt_id_after, token_pos); 1353 deopt_id_after, token_pos);
1354 } 1354 }
1355 __ Drop(argument_count); 1355 __ Drop(argument_count);
1356 } 1356 }
1357 1357
1358 1358
1359 void FlowGraphCompiler::EmitUnoptimizedStaticCall( 1359 void FlowGraphCompiler::EmitUnoptimizedStaticCall(
1360 intptr_t argument_count, 1360 intptr_t argument_count,
1361 intptr_t deopt_id, 1361 intptr_t deopt_id,
1362 intptr_t token_pos, 1362 TokenPosition token_pos,
1363 LocationSummary* locs, 1363 LocationSummary* locs,
1364 const ICData& ic_data) { 1364 const ICData& ic_data) {
1365 const StubEntry* stub_entry = 1365 const StubEntry* stub_entry =
1366 StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested()); 1366 StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
1367 __ LoadObject(R9, ic_data); 1367 __ LoadObject(R9, ic_data);
1368 GenerateDartCall(deopt_id, 1368 GenerateDartCall(deopt_id,
1369 token_pos, 1369 token_pos,
1370 *stub_entry, 1370 *stub_entry,
1371 RawPcDescriptors::kUnoptStaticCall, 1371 RawPcDescriptors::kUnoptStaticCall,
1372 locs); 1372 locs);
1373 __ Drop(argument_count); 1373 __ Drop(argument_count);
1374 } 1374 }
1375 1375
1376 1376
1377 void FlowGraphCompiler::EmitOptimizedStaticCall( 1377 void FlowGraphCompiler::EmitOptimizedStaticCall(
1378 const Function& function, 1378 const Function& function,
1379 const Array& arguments_descriptor, 1379 const Array& arguments_descriptor,
1380 intptr_t argument_count, 1380 intptr_t argument_count,
1381 intptr_t deopt_id, 1381 intptr_t deopt_id,
1382 intptr_t token_pos, 1382 TokenPosition token_pos,
1383 LocationSummary* locs) { 1383 LocationSummary* locs) {
1384 __ LoadObject(R4, arguments_descriptor); 1384 __ LoadObject(R4, arguments_descriptor);
1385 // Do not use the code from the function, but let the code be patched so that 1385 // Do not use the code from the function, but let the code be patched so that
1386 // we can record the outgoing edges to other code. 1386 // we can record the outgoing edges to other code.
1387 GenerateDartCall(deopt_id, 1387 GenerateDartCall(deopt_id,
1388 token_pos, 1388 token_pos,
1389 *StubCode::CallStaticFunction_entry(), 1389 *StubCode::CallStaticFunction_entry(),
1390 RawPcDescriptors::kOther, 1390 RawPcDescriptors::kOther,
1391 locs); 1391 locs);
1392 AddStaticCallTarget(function); 1392 AddStaticCallTarget(function);
1393 __ Drop(argument_count); 1393 __ Drop(argument_count);
1394 } 1394 }
1395 1395
1396 1396
1397 Condition FlowGraphCompiler::EmitEqualityRegConstCompare( 1397 Condition FlowGraphCompiler::EmitEqualityRegConstCompare(
1398 Register reg, 1398 Register reg,
1399 const Object& obj, 1399 const Object& obj,
1400 bool needs_number_check, 1400 bool needs_number_check,
1401 intptr_t token_pos) { 1401 TokenPosition token_pos) {
1402 if (needs_number_check) { 1402 if (needs_number_check) {
1403 ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()); 1403 ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint());
1404 __ Push(reg); 1404 __ Push(reg);
1405 __ PushObject(obj); 1405 __ PushObject(obj);
1406 if (is_optimizing()) { 1406 if (is_optimizing()) {
1407 __ BranchLinkPatchable( 1407 __ BranchLinkPatchable(
1408 *StubCode::OptimizedIdenticalWithNumberCheck_entry()); 1408 *StubCode::OptimizedIdenticalWithNumberCheck_entry());
1409 } else { 1409 } else {
1410 __ BranchLinkPatchable( 1410 __ BranchLinkPatchable(
1411 *StubCode::UnoptimizedIdenticalWithNumberCheck_entry()); 1411 *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
1412 } 1412 }
1413 if (token_pos >= 0) { 1413 if (token_pos.IsReal()) {
1414 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1414 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1415 Thread::kNoDeoptId, 1415 Thread::kNoDeoptId,
1416 token_pos); 1416 token_pos);
1417 } 1417 }
1418 // Stub returns result in flags (result of a cmp, we need Z computed). 1418 // Stub returns result in flags (result of a cmp, we need Z computed).
1419 __ Drop(1); // Discard constant. 1419 __ Drop(1); // Discard constant.
1420 __ Pop(reg); // Restore 'reg'. 1420 __ Pop(reg); // Restore 'reg'.
1421 } else { 1421 } else {
1422 __ CompareObject(reg, obj); 1422 __ CompareObject(reg, obj);
1423 } 1423 }
1424 return EQ; 1424 return EQ;
1425 } 1425 }
1426 1426
1427 1427
1428 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left, 1428 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(
1429 Register right, 1429 Register left,
1430 bool needs_number_check, 1430 Register right,
1431 intptr_t token_pos) { 1431 bool needs_number_check,
1432 TokenPosition token_pos) {
1432 if (needs_number_check) { 1433 if (needs_number_check) {
1433 __ Push(left); 1434 __ Push(left);
1434 __ Push(right); 1435 __ Push(right);
1435 if (is_optimizing()) { 1436 if (is_optimizing()) {
1436 __ BranchLinkPatchable( 1437 __ BranchLinkPatchable(
1437 *StubCode::OptimizedIdenticalWithNumberCheck_entry()); 1438 *StubCode::OptimizedIdenticalWithNumberCheck_entry());
1438 } else { 1439 } else {
1439 __ BranchLinkPatchable( 1440 __ BranchLinkPatchable(
1440 *StubCode::UnoptimizedIdenticalWithNumberCheck_entry()); 1441 *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
1441 } 1442 }
1442 if (token_pos >= 0) { 1443 if (token_pos.IsReal()) {
1443 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1444 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1444 Thread::kNoDeoptId, 1445 Thread::kNoDeoptId,
1445 token_pos); 1446 token_pos);
1446 } 1447 }
1447 // Stub returns result in flags (result of a cmp, we need Z computed). 1448 // Stub returns result in flags (result of a cmp, we need Z computed).
1448 __ Pop(right); 1449 __ Pop(right);
1449 __ Pop(left); 1450 __ Pop(left);
1450 } else { 1451 } else {
1451 __ cmp(left, Operand(right)); 1452 __ cmp(left, Operand(right));
1452 } 1453 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 } 1547 }
1547 #endif 1548 #endif
1548 1549
1549 1550
1550 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, 1551 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
1551 intptr_t argument_count, 1552 intptr_t argument_count,
1552 const Array& argument_names, 1553 const Array& argument_names,
1553 Label* failed, 1554 Label* failed,
1554 Label* match_found, 1555 Label* match_found,
1555 intptr_t deopt_id, 1556 intptr_t deopt_id,
1556 intptr_t token_index, 1557 TokenPosition token_index,
1557 LocationSummary* locs) { 1558 LocationSummary* locs) {
1558 ASSERT(is_optimizing()); 1559 ASSERT(is_optimizing());
1559 __ Comment("EmitTestAndCall"); 1560 __ Comment("EmitTestAndCall");
1560 const Array& arguments_descriptor = 1561 const Array& arguments_descriptor =
1561 Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count, 1562 Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count,
1562 argument_names)); 1563 argument_names));
1563 1564
1564 // Load receiver into R0. 1565 // Load receiver into R0.
1565 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize); 1566 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
1566 __ LoadObject(R4, arguments_descriptor); 1567 __ LoadObject(R4, arguments_descriptor);
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1935 DRegister dreg = EvenDRegisterOf(reg); 1936 DRegister dreg = EvenDRegisterOf(reg);
1936 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); 1937 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex));
1937 } 1938 }
1938 1939
1939 1940
1940 #undef __ 1941 #undef __
1941 1942
1942 } // namespace dart 1943 } // namespace dart
1943 1944
1944 #endif // defined TARGET_ARCH_ARM 1945 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler.cc ('k') | runtime/vm/flow_graph_compiler_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698