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

Side by Side Diff: runtime/vm/flow_graph_compiler_arm64.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_arm.cc ('k') | runtime/vm/flow_graph_compiler_ia32.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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 // R0: instance being type checked (preserved). 258 // R0: instance being type checked (preserved).
259 // Clobbers R2. 259 // Clobbers R2.
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 = R0; 270 const Register kInstanceReg = R0;
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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 __ b(is_not_equal_lbl); 342 __ b(is_not_equal_lbl);
343 } 343 }
344 344
345 345
346 // Testing against an instantiated type with no arguments, without 346 // Testing against an instantiated type with no arguments, without
347 // SubtypeTestCache. 347 // SubtypeTestCache.
348 // R0: instance being type checked (preserved). 348 // R0: instance being type checked (preserved).
349 // Clobbers R2, R3. 349 // Clobbers R2, R3.
350 // Returns true if there is a fallthrough. 350 // Returns true if there is a fallthrough.
351 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest( 351 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
352 intptr_t token_pos, 352 TokenPosition token_pos,
353 const AbstractType& type, 353 const AbstractType& type,
354 Label* is_instance_lbl, 354 Label* is_instance_lbl,
355 Label* is_not_instance_lbl) { 355 Label* is_not_instance_lbl) {
356 __ Comment("InstantiatedTypeNoArgumentsTest"); 356 __ Comment("InstantiatedTypeNoArgumentsTest");
357 ASSERT(type.IsInstantiated()); 357 ASSERT(type.IsInstantiated());
358 if (type.IsFunctionType()) { 358 if (type.IsFunctionType()) {
359 // Fallthrough. 359 // Fallthrough.
360 return true; 360 return true;
361 } 361 }
362 const Class& type_class = Class::Handle(zone(), type.type_class()); 362 const Class& type_class = Class::Handle(zone(), type.type_class());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 412
413 413
414 // Uses SubtypeTestCache to store instance class and result. 414 // Uses SubtypeTestCache to store instance class and result.
415 // R0: instance to test. 415 // R0: instance to test.
416 // Clobbers R1-R5. 416 // Clobbers R1-R5.
417 // Immediate class test already done. 417 // Immediate class test already done.
418 // TODO(srdjan): Implement a quicker subtype check, as type test 418 // TODO(srdjan): Implement a quicker subtype check, as type test
419 // arrays can grow too high, but they may be useful when optimizing 419 // arrays can grow too high, but they may be useful when optimizing
420 // code (type-feedback). 420 // code (type-feedback).
421 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup( 421 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
422 intptr_t token_pos, 422 TokenPosition token_pos,
423 const Class& type_class, 423 const Class& type_class,
424 Label* is_instance_lbl, 424 Label* is_instance_lbl,
425 Label* is_not_instance_lbl) { 425 Label* is_not_instance_lbl) {
426 __ Comment("Subtype1TestCacheLookup"); 426 __ Comment("Subtype1TestCacheLookup");
427 const Register kInstanceReg = R0; 427 const Register kInstanceReg = R0;
428 __ LoadClass(R1, kInstanceReg); 428 __ LoadClass(R1, kInstanceReg);
429 // R1: instance class. 429 // R1: instance class.
430 // Check immediate superclass equality. 430 // Check immediate superclass equality.
431 __ LoadFieldFromOffset(R2, R1, Class::super_type_offset()); 431 __ LoadFieldFromOffset(R2, R1, Class::super_type_offset());
432 __ LoadFieldFromOffset(R2, R2, Type::type_class_offset()); 432 __ LoadFieldFromOffset(R2, R2, Type::type_class_offset());
433 __ CompareObject(R2, type_class); 433 __ CompareObject(R2, type_class);
434 __ b(is_instance_lbl, EQ); 434 __ b(is_instance_lbl, EQ);
435 435
436 const Register kTypeArgumentsReg = kNoRegister; 436 const Register kTypeArgumentsReg = kNoRegister;
437 const Register kTempReg = kNoRegister; 437 const Register kTempReg = kNoRegister;
438 return GenerateCallSubtypeTestStub(kTestTypeOneArg, 438 return GenerateCallSubtypeTestStub(kTestTypeOneArg,
439 kInstanceReg, 439 kInstanceReg,
440 kTypeArgumentsReg, 440 kTypeArgumentsReg,
441 kTempReg, 441 kTempReg,
442 is_instance_lbl, 442 is_instance_lbl,
443 is_not_instance_lbl); 443 is_not_instance_lbl);
444 } 444 }
445 445
446 446
447 // Generates inlined check if 'type' is a type parameter or type itself 447 // Generates inlined check if 'type' is a type parameter or type itself
448 // R0: instance (preserved). 448 // R0: instance (preserved).
449 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest( 449 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
450 intptr_t token_pos, 450 TokenPosition token_pos,
451 const AbstractType& type, 451 const AbstractType& type,
452 Label* is_instance_lbl, 452 Label* is_instance_lbl,
453 Label* is_not_instance_lbl) { 453 Label* is_not_instance_lbl) {
454 __ Comment("UninstantiatedTypeTest"); 454 __ Comment("UninstantiatedTypeTest");
455 ASSERT(!type.IsInstantiated()); 455 ASSERT(!type.IsInstantiated());
456 // Skip check if destination is a dynamic type. 456 // Skip check if destination is a dynamic type.
457 if (type.IsTypeParameter()) { 457 if (type.IsTypeParameter()) {
458 const TypeParameter& type_param = TypeParameter::Cast(type); 458 const TypeParameter& type_param = TypeParameter::Cast(type);
459 // Load instantiator type arguments on stack. 459 // Load instantiator type arguments on stack.
460 __ ldr(R1, Address(SP)); // Get instantiator type arguments. 460 __ ldr(R1, Address(SP)); // Get instantiator type arguments.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 // Inputs: 523 // Inputs:
524 // - R0: instance being type checked (preserved). 524 // - R0: instance being type checked (preserved).
525 // - R1: optional instantiator type arguments (preserved). 525 // - R1: optional instantiator type arguments (preserved).
526 // Clobbers R2, R3. 526 // Clobbers R2, R3.
527 // Returns: 527 // Returns:
528 // - preserved instance in R0 and optional instantiator type arguments in R1. 528 // - preserved instance in R0 and optional instantiator type arguments in R1.
529 // Note that this inlined code must be followed by the runtime_call code, as it 529 // Note that this inlined code must be followed by the runtime_call code, as it
530 // may fall through to it. Otherwise, this inline code will jump to the label 530 // may fall through to it. Otherwise, this inline code will jump to the label
531 // is_instance or to the label is_not_instance. 531 // is_instance or to the label is_not_instance.
532 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof( 532 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
533 intptr_t token_pos, 533 TokenPosition token_pos,
534 const AbstractType& type, 534 const AbstractType& type,
535 Label* is_instance_lbl, 535 Label* is_instance_lbl,
536 Label* is_not_instance_lbl) { 536 Label* is_not_instance_lbl) {
537 __ Comment("InlineInstanceof"); 537 __ Comment("InlineInstanceof");
538 if (type.IsVoidType()) { 538 if (type.IsVoidType()) {
539 // A non-null value is returned from a void function, which will result in a 539 // A non-null value is returned from a void function, which will result in a
540 // type error. A null value is handled prior to executing this inline code. 540 // type error. A null value is handled prior to executing this inline code.
541 return SubtypeTestCache::null(); 541 return SubtypeTestCache::null();
542 } 542 }
543 if (type.IsInstantiated()) { 543 if (type.IsInstantiated()) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 // If instanceof type test cannot be performed successfully at compile time and 576 // If instanceof type test cannot be performed successfully at compile time and
577 // therefore eliminated, optimize it by adding inlined tests for: 577 // therefore eliminated, optimize it by adding inlined tests for:
578 // - NULL -> return false. 578 // - NULL -> return false.
579 // - Smi -> compile time subtype check (only if dst class is not parameterized). 579 // - Smi -> compile time subtype check (only if dst class is not parameterized).
580 // - Class equality (only if class is not parameterized). 580 // - Class equality (only if class is not parameterized).
581 // Inputs: 581 // Inputs:
582 // - R0: object. 582 // - R0: object.
583 // - R1: instantiator type arguments or raw_null. 583 // - R1: instantiator type arguments or raw_null.
584 // Returns: 584 // Returns:
585 // - true or false in R0. 585 // - true or false in R0.
586 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos, 586 void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
587 intptr_t deopt_id, 587 intptr_t deopt_id,
588 const AbstractType& type, 588 const AbstractType& type,
589 bool negate_result, 589 bool negate_result,
590 LocationSummary* locs) { 590 LocationSummary* locs) {
591 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); 591 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
592 592
593 // Preserve instantiator type arguments (R1). 593 // Preserve instantiator type arguments (R1).
594 __ Push(R1); 594 __ Push(R1);
595 595
596 Label is_instance, is_not_instance; 596 Label is_instance, is_not_instance;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 // - NULL -> return NULL. 656 // - NULL -> return NULL.
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 // - R0: instance being type checked. 660 // - R0: instance being type checked.
661 // - R1: instantiator type arguments or raw_null. 661 // - R1: instantiator type arguments or raw_null.
662 // Returns: 662 // Returns:
663 // - object in R0 for successful assignable check (or throws TypeError). 663 // - object in R0 for successful assignable check (or throws TypeError).
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(TokenPosition 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 ASSERT(!Token::IsClassifying(token_pos)); 671 ASSERT(!TokenPosition(token_pos).IsClassifying());
672 ASSERT(!dst_type.IsNull()); 672 ASSERT(!dst_type.IsNull());
673 ASSERT(dst_type.IsFinalized()); 673 ASSERT(dst_type.IsFinalized());
674 // Assignable check is skipped in FlowGraphBuilder, not here. 674 // Assignable check is skipped in FlowGraphBuilder, not here.
675 ASSERT(dst_type.IsMalformedOrMalbounded() || 675 ASSERT(dst_type.IsMalformedOrMalbounded() ||
676 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); 676 (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
677 // Preserve instantiator type arguments (R1). 677 // Preserve instantiator type arguments (R1).
678 __ Push(R1); 678 __ Push(R1);
679 // A null object is always assignable and is returned as result. 679 // A null object is always assignable and is returned as result.
680 Label is_assignable, runtime_call; 680 Label is_assignable, runtime_call;
681 __ CompareObject(R0, Object::null_object()); 681 __ CompareObject(R0, Object::null_object());
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 i < CallPattern::kDeoptCallLengthInInstructions; 1125 i < CallPattern::kDeoptCallLengthInInstructions;
1126 ++i) { 1126 ++i) {
1127 __ orr(R0, ZR, Operand(R0)); // nop 1127 __ orr(R0, ZR, Operand(R0)); // nop
1128 } 1128 }
1129 lazy_deopt_pc_offset_ = assembler()->CodeSize(); 1129 lazy_deopt_pc_offset_ = assembler()->CodeSize();
1130 __ BranchPatchable(*StubCode::DeoptimizeLazy_entry()); 1130 __ BranchPatchable(*StubCode::DeoptimizeLazy_entry());
1131 } 1131 }
1132 } 1132 }
1133 1133
1134 1134
1135 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 1135 void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
1136 const StubEntry& stub_entry, 1136 const StubEntry& stub_entry,
1137 RawPcDescriptors::Kind kind, 1137 RawPcDescriptors::Kind kind,
1138 LocationSummary* locs) { 1138 LocationSummary* locs) {
1139 __ BranchLinkPatchable(stub_entry); 1139 __ BranchLinkPatchable(stub_entry);
1140 AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos); 1140 AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
1141 RecordSafepoint(locs); 1141 RecordSafepoint(locs);
1142 } 1142 }
1143 1143
1144 1144
1145 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, 1145 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
1146 intptr_t token_pos, 1146 TokenPosition token_pos,
1147 const StubEntry& stub_entry, 1147 const StubEntry& stub_entry,
1148 RawPcDescriptors::Kind kind, 1148 RawPcDescriptors::Kind kind,
1149 LocationSummary* locs) { 1149 LocationSummary* locs) {
1150 __ BranchLinkPatchable(stub_entry); 1150 __ BranchLinkPatchable(stub_entry);
1151 AddCurrentDescriptor(kind, deopt_id, token_pos); 1151 AddCurrentDescriptor(kind, deopt_id, token_pos);
1152 RecordSafepoint(locs); 1152 RecordSafepoint(locs);
1153 // Marks either the continuation point in unoptimized code or the 1153 // Marks either the continuation point in unoptimized code or the
1154 // deoptimization point in optimized code, after call. 1154 // deoptimization point in optimized code, after call.
1155 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); 1155 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
1156 if (is_optimizing()) { 1156 if (is_optimizing()) {
1157 AddDeoptIndexAtCall(deopt_id_after, token_pos); 1157 AddDeoptIndexAtCall(deopt_id_after, token_pos);
1158 } else { 1158 } else {
1159 // Add deoptimization continuation point after the call and before the 1159 // Add deoptimization continuation point after the call and before the
1160 // arguments are removed. 1160 // arguments are removed.
1161 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); 1161 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
1162 } 1162 }
1163 } 1163 }
1164 1164
1165 1165
1166 void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos, 1166 void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
1167 intptr_t deopt_id, 1167 intptr_t deopt_id,
1168 const RuntimeEntry& entry, 1168 const RuntimeEntry& entry,
1169 intptr_t argument_count, 1169 intptr_t argument_count,
1170 LocationSummary* locs) { 1170 LocationSummary* locs) {
1171 __ CallRuntime(entry, argument_count); 1171 __ CallRuntime(entry, argument_count);
1172 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos); 1172 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos);
1173 RecordSafepoint(locs); 1173 RecordSafepoint(locs);
1174 if (deopt_id != Thread::kNoDeoptId) { 1174 if (deopt_id != Thread::kNoDeoptId) {
1175 // Marks either the continuation point in unoptimized code or the 1175 // Marks either the continuation point in unoptimized code or the
1176 // deoptimization point in optimized code, after call. 1176 // deoptimization point in optimized code, after call.
(...skipping 23 matching lines...) Expand all
1200 __ add(TMP, TMP, Operand(Smi::RawValue(1))); 1200 __ add(TMP, TMP, Operand(Smi::RawValue(1)));
1201 __ StoreFieldToOffset(TMP, R0, Array::element_offset(edge_id)); 1201 __ StoreFieldToOffset(TMP, R0, Array::element_offset(edge_id));
1202 } 1202 }
1203 1203
1204 1204
1205 void FlowGraphCompiler::EmitOptimizedInstanceCall( 1205 void FlowGraphCompiler::EmitOptimizedInstanceCall(
1206 const StubEntry& stub_entry, 1206 const StubEntry& stub_entry,
1207 const ICData& ic_data, 1207 const ICData& ic_data,
1208 intptr_t argument_count, 1208 intptr_t argument_count,
1209 intptr_t deopt_id, 1209 intptr_t deopt_id,
1210 intptr_t token_pos, 1210 TokenPosition token_pos,
1211 LocationSummary* locs) { 1211 LocationSummary* locs) {
1212 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0); 1212 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
1213 // Each ICData propagated from unoptimized to optimized code contains the 1213 // Each ICData propagated from unoptimized to optimized code contains the
1214 // function that corresponds to the Dart function of that IC call. Due 1214 // function that corresponds to the Dart function of that IC call. Due
1215 // to inlining in optimized code, that function may not correspond to the 1215 // to inlining in optimized code, that function may not correspond to the
1216 // top-level function (parsed_function().function()) which could be 1216 // top-level function (parsed_function().function()) which could be
1217 // reoptimized and which counter needs to be incremented. 1217 // reoptimized and which counter needs to be incremented.
1218 // Pass the function explicitly, it is used in IC stub. 1218 // Pass the function explicitly, it is used in IC stub.
1219 1219
1220 __ LoadObject(R6, parsed_function().function()); 1220 __ LoadObject(R6, parsed_function().function());
1221 __ LoadUniqueObject(R5, ic_data); 1221 __ LoadUniqueObject(R5, ic_data);
1222 GenerateDartCall(deopt_id, 1222 GenerateDartCall(deopt_id,
1223 token_pos, 1223 token_pos,
1224 stub_entry, 1224 stub_entry,
1225 RawPcDescriptors::kIcCall, 1225 RawPcDescriptors::kIcCall,
1226 locs); 1226 locs);
1227 __ Drop(argument_count); 1227 __ Drop(argument_count);
1228 } 1228 }
1229 1229
1230 1230
1231 void FlowGraphCompiler::EmitInstanceCall(const StubEntry& stub_entry, 1231 void FlowGraphCompiler::EmitInstanceCall(const StubEntry& stub_entry,
1232 const ICData& ic_data, 1232 const ICData& ic_data,
1233 intptr_t argument_count, 1233 intptr_t argument_count,
1234 intptr_t deopt_id, 1234 intptr_t deopt_id,
1235 intptr_t token_pos, 1235 TokenPosition token_pos,
1236 LocationSummary* locs) { 1236 LocationSummary* locs) {
1237 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0); 1237 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
1238 __ LoadUniqueObject(R5, ic_data); 1238 __ LoadUniqueObject(R5, ic_data);
1239 GenerateDartCall(deopt_id, 1239 GenerateDartCall(deopt_id,
1240 token_pos, 1240 token_pos,
1241 stub_entry, 1241 stub_entry,
1242 RawPcDescriptors::kIcCall, 1242 RawPcDescriptors::kIcCall,
1243 locs); 1243 locs);
1244 __ Drop(argument_count); 1244 __ Drop(argument_count);
1245 } 1245 }
1246 1246
1247 1247
1248 void FlowGraphCompiler::EmitMegamorphicInstanceCall( 1248 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
1249 const ICData& ic_data, 1249 const ICData& ic_data,
1250 intptr_t argument_count, 1250 intptr_t argument_count,
1251 intptr_t deopt_id, 1251 intptr_t deopt_id,
1252 intptr_t token_pos, 1252 TokenPosition token_pos,
1253 LocationSummary* locs, 1253 LocationSummary* locs,
1254 intptr_t try_index) { 1254 intptr_t try_index) {
1255 const String& name = String::Handle(zone(), ic_data.target_name()); 1255 const String& name = String::Handle(zone(), ic_data.target_name());
1256 const Array& arguments_descriptor = 1256 const Array& arguments_descriptor =
1257 Array::ZoneHandle(zone(), ic_data.arguments_descriptor()); 1257 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
1258 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1258 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1259 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(), 1259 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
1260 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor)); 1260 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
1261 1261
1262 __ Comment("MegamorphicCall"); 1262 __ Comment("MegamorphicCall");
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); 1294 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
1295 } 1295 }
1296 __ Drop(argument_count); 1296 __ Drop(argument_count);
1297 } 1297 }
1298 1298
1299 1299
1300 void FlowGraphCompiler::EmitSwitchableInstanceCall( 1300 void FlowGraphCompiler::EmitSwitchableInstanceCall(
1301 const ICData& ic_data, 1301 const ICData& ic_data,
1302 intptr_t argument_count, 1302 intptr_t argument_count,
1303 intptr_t deopt_id, 1303 intptr_t deopt_id,
1304 intptr_t token_pos, 1304 TokenPosition token_pos,
1305 LocationSummary* locs) { 1305 LocationSummary* locs) {
1306 __ Comment("SwitchableCall"); 1306 __ Comment("SwitchableCall");
1307 __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize); 1307 __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
1308 if (ic_data.NumArgsTested() == 1) { 1308 if (ic_data.NumArgsTested() == 1) {
1309 __ LoadUniqueObject(R5, ic_data); 1309 __ LoadUniqueObject(R5, ic_data);
1310 __ BranchLinkPatchable(*StubCode::ICLookup_entry()); 1310 __ BranchLinkPatchable(*StubCode::ICLookup_entry());
1311 } else { 1311 } else {
1312 const String& name = String::Handle(zone(), ic_data.target_name()); 1312 const String& name = String::Handle(zone(), ic_data.target_name());
1313 const Array& arguments_descriptor = 1313 const Array& arguments_descriptor =
1314 Array::ZoneHandle(zone(), ic_data.arguments_descriptor()); 1314 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
(...skipping 18 matching lines...) Expand all
1333 // arguments are removed. 1333 // arguments are removed.
1334 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); 1334 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
1335 } 1335 }
1336 __ Drop(argument_count); 1336 __ Drop(argument_count);
1337 } 1337 }
1338 1338
1339 1339
1340 void FlowGraphCompiler::EmitUnoptimizedStaticCall( 1340 void FlowGraphCompiler::EmitUnoptimizedStaticCall(
1341 intptr_t argument_count, 1341 intptr_t argument_count,
1342 intptr_t deopt_id, 1342 intptr_t deopt_id,
1343 intptr_t token_pos, 1343 TokenPosition token_pos,
1344 LocationSummary* locs, 1344 LocationSummary* locs,
1345 const ICData& ic_data) { 1345 const ICData& ic_data) {
1346 const StubEntry* stub_entry = 1346 const StubEntry* stub_entry =
1347 StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested()); 1347 StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
1348 __ LoadObject(R5, ic_data); 1348 __ LoadObject(R5, ic_data);
1349 GenerateDartCall(deopt_id, 1349 GenerateDartCall(deopt_id,
1350 token_pos, 1350 token_pos,
1351 *stub_entry, 1351 *stub_entry,
1352 RawPcDescriptors::kUnoptStaticCall, 1352 RawPcDescriptors::kUnoptStaticCall,
1353 locs); 1353 locs);
1354 __ Drop(argument_count); 1354 __ Drop(argument_count);
1355 } 1355 }
1356 1356
1357 1357
1358 void FlowGraphCompiler::EmitOptimizedStaticCall( 1358 void FlowGraphCompiler::EmitOptimizedStaticCall(
1359 const Function& function, 1359 const Function& function,
1360 const Array& arguments_descriptor, 1360 const Array& arguments_descriptor,
1361 intptr_t argument_count, 1361 intptr_t argument_count,
1362 intptr_t deopt_id, 1362 intptr_t deopt_id,
1363 intptr_t token_pos, 1363 TokenPosition token_pos,
1364 LocationSummary* locs) { 1364 LocationSummary* locs) {
1365 __ LoadObject(R4, arguments_descriptor); 1365 __ LoadObject(R4, arguments_descriptor);
1366 // Do not use the code from the function, but let the code be patched so that 1366 // Do not use the code from the function, but let the code be patched so that
1367 // we can record the outgoing edges to other code. 1367 // we can record the outgoing edges to other code.
1368 GenerateDartCall(deopt_id, 1368 GenerateDartCall(deopt_id,
1369 token_pos, 1369 token_pos,
1370 *StubCode::CallStaticFunction_entry(), 1370 *StubCode::CallStaticFunction_entry(),
1371 RawPcDescriptors::kOther, 1371 RawPcDescriptors::kOther,
1372 locs); 1372 locs);
1373 AddStaticCallTarget(function); 1373 AddStaticCallTarget(function);
1374 __ Drop(argument_count); 1374 __ Drop(argument_count);
1375 } 1375 }
1376 1376
1377 1377
1378 Condition FlowGraphCompiler::EmitEqualityRegConstCompare( 1378 Condition FlowGraphCompiler::EmitEqualityRegConstCompare(
1379 Register reg, 1379 Register reg,
1380 const Object& obj, 1380 const Object& obj,
1381 bool needs_number_check, 1381 bool needs_number_check,
1382 intptr_t token_pos) { 1382 TokenPosition token_pos) {
1383 if (needs_number_check) { 1383 if (needs_number_check) {
1384 ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()); 1384 ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint());
1385 __ Push(reg); 1385 __ Push(reg);
1386 __ PushObject(obj); 1386 __ PushObject(obj);
1387 if (is_optimizing()) { 1387 if (is_optimizing()) {
1388 __ BranchLinkPatchable( 1388 __ BranchLinkPatchable(
1389 *StubCode::OptimizedIdenticalWithNumberCheck_entry()); 1389 *StubCode::OptimizedIdenticalWithNumberCheck_entry());
1390 } else { 1390 } else {
1391 __ BranchLinkPatchable( 1391 __ BranchLinkPatchable(
1392 *StubCode::UnoptimizedIdenticalWithNumberCheck_entry()); 1392 *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
1393 } 1393 }
1394 if (token_pos >= 0) { 1394 if (token_pos.IsReal()) {
1395 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1395 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1396 Thread::kNoDeoptId, 1396 Thread::kNoDeoptId,
1397 token_pos); 1397 token_pos);
1398 } 1398 }
1399 // Stub returns result in flags (result of a cmp, we need Z computed). 1399 // Stub returns result in flags (result of a cmp, we need Z computed).
1400 __ Drop(1); // Discard constant. 1400 __ Drop(1); // Discard constant.
1401 __ Pop(reg); // Restore 'reg'. 1401 __ Pop(reg); // Restore 'reg'.
1402 } else { 1402 } else {
1403 __ CompareObject(reg, obj); 1403 __ CompareObject(reg, obj);
1404 } 1404 }
1405 return EQ; 1405 return EQ;
1406 } 1406 }
1407 1407
1408 1408
1409 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left, 1409 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(
1410 Register right, 1410 Register left,
1411 bool needs_number_check, 1411 Register right,
1412 intptr_t token_pos) { 1412 bool needs_number_check,
1413 TokenPosition token_pos) {
1413 if (needs_number_check) { 1414 if (needs_number_check) {
1414 __ Push(left); 1415 __ Push(left);
1415 __ Push(right); 1416 __ Push(right);
1416 if (is_optimizing()) { 1417 if (is_optimizing()) {
1417 __ BranchLinkPatchable( 1418 __ BranchLinkPatchable(
1418 *StubCode::OptimizedIdenticalWithNumberCheck_entry()); 1419 *StubCode::OptimizedIdenticalWithNumberCheck_entry());
1419 } else { 1420 } else {
1420 __ BranchLinkPatchable( 1421 __ BranchLinkPatchable(
1421 *StubCode::UnoptimizedIdenticalWithNumberCheck_entry()); 1422 *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
1422 } 1423 }
1423 if (token_pos >= 0) { 1424 if (token_pos.IsReal()) {
1424 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1425 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1425 Thread::kNoDeoptId, 1426 Thread::kNoDeoptId,
1426 token_pos); 1427 token_pos);
1427 } 1428 }
1428 // Stub returns result in flags (result of a cmp, we need Z computed). 1429 // Stub returns result in flags (result of a cmp, we need Z computed).
1429 __ Pop(right); 1430 __ Pop(right);
1430 __ Pop(left); 1431 __ Pop(left);
1431 } else { 1432 } else {
1432 __ CompareRegisters(left, right); 1433 __ CompareRegisters(left, right);
1433 } 1434 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1502 } 1503 }
1503 #endif 1504 #endif
1504 1505
1505 1506
1506 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, 1507 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
1507 intptr_t argument_count, 1508 intptr_t argument_count,
1508 const Array& argument_names, 1509 const Array& argument_names,
1509 Label* failed, 1510 Label* failed,
1510 Label* match_found, 1511 Label* match_found,
1511 intptr_t deopt_id, 1512 intptr_t deopt_id,
1512 intptr_t token_index, 1513 TokenPosition token_index,
1513 LocationSummary* locs) { 1514 LocationSummary* locs) {
1514 ASSERT(is_optimizing()); 1515 ASSERT(is_optimizing());
1515 1516
1516 __ Comment("EmitTestAndCall"); 1517 __ Comment("EmitTestAndCall");
1517 const Array& arguments_descriptor = 1518 const Array& arguments_descriptor =
1518 Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count, 1519 Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count,
1519 argument_names)); 1520 argument_names));
1520 1521
1521 // Load receiver into R0. 1522 // Load receiver into R0.
1522 __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize); 1523 __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
1873 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { 1874 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
1874 __ PopDouble(reg); 1875 __ PopDouble(reg);
1875 } 1876 }
1876 1877
1877 1878
1878 #undef __ 1879 #undef __
1879 1880
1880 } // namespace dart 1881 } // namespace dart
1881 1882
1882 #endif // defined TARGET_ARCH_ARM64 1883 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_arm.cc ('k') | runtime/vm/flow_graph_compiler_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698