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

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

Powered by Google App Engine
This is Rietveld 408576698