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

Side by Side Diff: runtime/vm/flow_graph_compiler_ia32.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_arm64.cc ('k') | runtime/vm/flow_graph_compiler_mips.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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 } 264 }
265 265
266 266
267 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if 267 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if
268 // type test is conclusive, otherwise fallthrough if a type test could not 268 // type test is conclusive, otherwise fallthrough if a type test could not
269 // be completed. 269 // be completed.
270 // EAX: instance (must survive). 270 // EAX: instance (must survive).
271 // Clobbers ECX, EDI. 271 // Clobbers ECX, EDI.
272 RawSubtypeTestCache* 272 RawSubtypeTestCache*
273 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest( 273 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
274 intptr_t token_pos, 274 TokenPosition token_pos,
275 const AbstractType& type, 275 const AbstractType& type,
276 Label* is_instance_lbl, 276 Label* is_instance_lbl,
277 Label* is_not_instance_lbl) { 277 Label* is_not_instance_lbl) {
278 __ Comment("InstantiatedTypeWithArgumentsTest"); 278 __ Comment("InstantiatedTypeWithArgumentsTest");
279 ASSERT(type.IsInstantiated()); 279 ASSERT(type.IsInstantiated());
280 const Class& type_class = Class::ZoneHandle(zone(), type.type_class()); 280 const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
281 ASSERT(type.IsFunctionType() || (type_class.NumTypeArguments() > 0)); 281 ASSERT(type.IsFunctionType() || (type_class.NumTypeArguments() > 0));
282 const Register kInstanceReg = EAX; 282 const Register kInstanceReg = EAX;
283 Error& bound_error = Error::Handle(zone()); 283 Error& bound_error = Error::Handle(zone());
284 const Type& int_type = Type::Handle(zone(), Type::IntType()); 284 const Type& int_type = Type::Handle(zone(), Type::IntType());
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 __ jmp(is_not_equal_lbl); 353 __ jmp(is_not_equal_lbl);
354 } 354 }
355 355
356 356
357 // Testing against an instantiated type with no arguments, without 357 // Testing against an instantiated type with no arguments, without
358 // SubtypeTestCache. 358 // SubtypeTestCache.
359 // EAX: instance to test against (preserved). 359 // EAX: instance to test against (preserved).
360 // Clobbers ECX, EDI. 360 // Clobbers ECX, EDI.
361 // Returns true if there is a fallthrough. 361 // Returns true if there is a fallthrough.
362 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest( 362 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
363 intptr_t token_pos, 363 TokenPosition token_pos,
364 const AbstractType& type, 364 const AbstractType& type,
365 Label* is_instance_lbl, 365 Label* is_instance_lbl,
366 Label* is_not_instance_lbl) { 366 Label* is_not_instance_lbl) {
367 __ Comment("InstantiatedTypeNoArgumentsTest"); 367 __ Comment("InstantiatedTypeNoArgumentsTest");
368 ASSERT(type.IsInstantiated()); 368 ASSERT(type.IsInstantiated());
369 if (type.IsFunctionType()) { 369 if (type.IsFunctionType()) {
370 // Fallthrough. 370 // Fallthrough.
371 return true; 371 return true;
372 } 372 }
373 const Class& type_class = Class::Handle(zone(), type.type_class()); 373 const Class& type_class = Class::Handle(zone(), type.type_class());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 423
424 424
425 // Uses SubtypeTestCache to store instance class and result. 425 // Uses SubtypeTestCache to store instance class and result.
426 // EAX: instance to test. 426 // EAX: instance to test.
427 // Clobbers EDI, ECX. 427 // Clobbers EDI, ECX.
428 // Immediate class test already done. 428 // Immediate class test already done.
429 // TODO(srdjan): Implement a quicker subtype check, as type test 429 // TODO(srdjan): Implement a quicker subtype check, as type test
430 // arrays can grow too high, but they may be useful when optimizing 430 // arrays can grow too high, but they may be useful when optimizing
431 // code (type-feedback). 431 // code (type-feedback).
432 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup( 432 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
433 intptr_t token_pos, 433 TokenPosition token_pos,
434 const Class& type_class, 434 const Class& type_class,
435 Label* is_instance_lbl, 435 Label* is_instance_lbl,
436 Label* is_not_instance_lbl) { 436 Label* is_not_instance_lbl) {
437 __ Comment("Subtype1TestCacheLookup"); 437 __ Comment("Subtype1TestCacheLookup");
438 const Register kInstanceReg = EAX; 438 const Register kInstanceReg = EAX;
439 __ LoadClass(ECX, kInstanceReg, EDI); 439 __ LoadClass(ECX, kInstanceReg, EDI);
440 // ECX: instance class. 440 // ECX: instance class.
441 // Check immediate superclass equality. 441 // Check immediate superclass equality.
442 __ movl(EDI, FieldAddress(ECX, Class::super_type_offset())); 442 __ movl(EDI, FieldAddress(ECX, Class::super_type_offset()));
443 __ movl(EDI, FieldAddress(EDI, Type::type_class_offset())); 443 __ movl(EDI, FieldAddress(EDI, Type::type_class_offset()));
444 __ CompareObject(EDI, type_class); 444 __ CompareObject(EDI, type_class);
445 __ j(EQUAL, is_instance_lbl); 445 __ j(EQUAL, is_instance_lbl);
446 446
447 const Register kTypeArgumentsReg = kNoRegister; 447 const Register kTypeArgumentsReg = kNoRegister;
448 const Register kTempReg = EDI; 448 const Register kTempReg = EDI;
449 return GenerateCallSubtypeTestStub(kTestTypeOneArg, 449 return GenerateCallSubtypeTestStub(kTestTypeOneArg,
450 kInstanceReg, 450 kInstanceReg,
451 kTypeArgumentsReg, 451 kTypeArgumentsReg,
452 kTempReg, 452 kTempReg,
453 is_instance_lbl, 453 is_instance_lbl,
454 is_not_instance_lbl); 454 is_not_instance_lbl);
455 } 455 }
456 456
457 457
458 // Generates inlined check if 'type' is a type parameter or type itself 458 // Generates inlined check if 'type' is a type parameter or type itself
459 // EAX: instance (preserved). 459 // EAX: instance (preserved).
460 // Clobbers EDX, EDI, ECX. 460 // Clobbers EDX, EDI, ECX.
461 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest( 461 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
462 intptr_t token_pos, 462 TokenPosition token_pos,
463 const AbstractType& type, 463 const AbstractType& type,
464 Label* is_instance_lbl, 464 Label* is_instance_lbl,
465 Label* is_not_instance_lbl) { 465 Label* is_not_instance_lbl) {
466 __ Comment("UninstantiatedTypeTest"); 466 __ Comment("UninstantiatedTypeTest");
467 ASSERT(!type.IsInstantiated()); 467 ASSERT(!type.IsInstantiated());
468 // Skip check if destination is a dynamic type. 468 // Skip check if destination is a dynamic type.
469 const Immediate& raw_null = 469 const Immediate& raw_null =
470 Immediate(reinterpret_cast<intptr_t>(Object::null())); 470 Immediate(reinterpret_cast<intptr_t>(Object::null()));
471 if (type.IsTypeParameter()) { 471 if (type.IsTypeParameter()) {
472 const TypeParameter& type_param = TypeParameter::Cast(type); 472 const TypeParameter& type_param = TypeParameter::Cast(type);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 // Inputs: 537 // Inputs:
538 // - EAX: instance to test against (preserved). 538 // - EAX: instance to test against (preserved).
539 // - EDX: optional instantiator type arguments (preserved). 539 // - EDX: optional instantiator type arguments (preserved).
540 // Clobbers ECX, EDI. 540 // Clobbers ECX, EDI.
541 // Returns: 541 // Returns:
542 // - preserved instance in EAX and optional instantiator type arguments in EDX. 542 // - preserved instance in EAX and optional instantiator type arguments in EDX.
543 // Note that this inlined code must be followed by the runtime_call code, as it 543 // Note that this inlined code must be followed by the runtime_call code, as it
544 // may fall through to it. Otherwise, this inline code will jump to the label 544 // may fall through to it. Otherwise, this inline code will jump to the label
545 // is_instance or to the label is_not_instance. 545 // is_instance or to the label is_not_instance.
546 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof( 546 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
547 intptr_t token_pos, 547 TokenPosition token_pos,
548 const AbstractType& type, 548 const AbstractType& type,
549 Label* is_instance_lbl, 549 Label* is_instance_lbl,
550 Label* is_not_instance_lbl) { 550 Label* is_not_instance_lbl) {
551 __ Comment("InlineInstanceof"); 551 __ Comment("InlineInstanceof");
552 if (type.IsVoidType()) { 552 if (type.IsVoidType()) {
553 // A non-null value is returned from a void function, which will result in a 553 // A non-null value is returned from a void function, which will result in a
554 // type error. A null value is handled prior to executing this inline code. 554 // type error. A null value is handled prior to executing this inline code.
555 return SubtypeTestCache::null(); 555 return SubtypeTestCache::null();
556 } 556 }
557 if (type.IsInstantiated()) { 557 if (type.IsInstantiated()) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 // therefore eliminated, optimize it by adding inlined tests for: 591 // therefore eliminated, optimize it by adding inlined tests for:
592 // - NULL -> return false. 592 // - NULL -> return false.
593 // - Smi -> compile time subtype check (only if dst class is not parameterized). 593 // - Smi -> compile time subtype check (only if dst class is not parameterized).
594 // - Class equality (only if class is not parameterized). 594 // - Class equality (only if class is not parameterized).
595 // Inputs: 595 // Inputs:
596 // - EAX: object. 596 // - EAX: object.
597 // - EDX: instantiator type arguments or raw_null. 597 // - EDX: instantiator type arguments or raw_null.
598 // Clobbers EDX. 598 // Clobbers EDX.
599 // Returns: 599 // Returns:
600 // - true or false in EAX. 600 // - true or false in EAX.
601 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos, 601 void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
602 intptr_t deopt_id, 602 intptr_t deopt_id,
603 const AbstractType& type, 603 const AbstractType& type,
604 bool negate_result, 604 bool negate_result,
605 LocationSummary* locs) { 605 LocationSummary* locs) {
606 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); 606 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
607 607
608 const Immediate& raw_null = 608 const Immediate& raw_null =
609 Immediate(reinterpret_cast<intptr_t>(Object::null())); 609 Immediate(reinterpret_cast<intptr_t>(Object::null()));
610 Label is_instance, is_not_instance; 610 Label is_instance, is_not_instance;
611 __ pushl(EDX); // Store instantiator type arguments. 611 __ pushl(EDX); // Store instantiator type arguments.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 // - NULL -> return NULL. 673 // - NULL -> return NULL.
674 // - Smi -> compile time subtype check (only if dst class is not parameterized). 674 // - Smi -> compile time subtype check (only if dst class is not parameterized).
675 // - Class equality (only if class is not parameterized). 675 // - Class equality (only if class is not parameterized).
676 // Inputs: 676 // Inputs:
677 // - EAX: object. 677 // - EAX: object.
678 // - EDX: instantiator type arguments or raw_null. 678 // - EDX: instantiator type arguments or raw_null.
679 // Returns: 679 // Returns:
680 // - object in EAX for successful assignable check (or throws TypeError). 680 // - object in EAX for successful assignable check (or throws TypeError).
681 // Performance notes: positive checks must be quick, negative checks can be slow 681 // Performance notes: positive checks must be quick, negative checks can be slow
682 // as they throw an exception. 682 // as they throw an exception.
683 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos, 683 void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
684 intptr_t deopt_id, 684 intptr_t deopt_id,
685 const AbstractType& dst_type, 685 const AbstractType& dst_type,
686 const String& dst_name, 686 const String& dst_name,
687 LocationSummary* locs) { 687 LocationSummary* locs) {
688 ASSERT(!Token::IsClassifying(token_pos)); 688 ASSERT(!token_pos.IsClassifying());
689 ASSERT(!dst_type.IsNull()); 689 ASSERT(!dst_type.IsNull());
690 ASSERT(dst_type.IsFinalized()); 690 ASSERT(dst_type.IsFinalized());
691 // Assignable check is skipped in FlowGraphBuilder, not here. 691 // Assignable check is skipped in FlowGraphBuilder, not here.
692 ASSERT(dst_type.IsMalformedOrMalbounded() || 692 ASSERT(dst_type.IsMalformedOrMalbounded() ||
693 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); 693 (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
694 __ pushl(EDX); // Store instantiator type arguments. 694 __ pushl(EDX); // Store instantiator type arguments.
695 // A null object is always assignable and is returned as result. 695 // A null object is always assignable and is returned as result.
696 const Immediate& raw_null = 696 const Immediate& raw_null =
697 Immediate(reinterpret_cast<intptr_t>(Object::null())); 697 Immediate(reinterpret_cast<intptr_t>(Object::null()));
698 Label is_assignable, runtime_call; 698 Label is_assignable, runtime_call;
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 if (is_optimizing() && !FLAG_precompilation) { 1141 if (is_optimizing() && !FLAG_precompilation) {
1142 // Leave enough space for patching in case of lazy deoptimization from 1142 // Leave enough space for patching in case of lazy deoptimization from
1143 // deferred code. 1143 // deferred code.
1144 __ nop(CallPattern::pattern_length_in_bytes()); 1144 __ nop(CallPattern::pattern_length_in_bytes());
1145 lazy_deopt_pc_offset_ = assembler()->CodeSize(); 1145 lazy_deopt_pc_offset_ = assembler()->CodeSize();
1146 __ Jmp(*StubCode::DeoptimizeLazy_entry()); 1146 __ Jmp(*StubCode::DeoptimizeLazy_entry());
1147 } 1147 }
1148 } 1148 }
1149 1149
1150 1150
1151 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 1151 void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
1152 const StubEntry& stub_entry, 1152 const StubEntry& stub_entry,
1153 RawPcDescriptors::Kind kind, 1153 RawPcDescriptors::Kind kind,
1154 LocationSummary* locs) { 1154 LocationSummary* locs) {
1155 __ Call(stub_entry); 1155 __ Call(stub_entry);
1156 AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos); 1156 AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
1157 RecordSafepoint(locs); 1157 RecordSafepoint(locs);
1158 } 1158 }
1159 1159
1160 1160
1161 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, 1161 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
1162 intptr_t token_pos, 1162 TokenPosition token_pos,
1163 const StubEntry& stub_entry, 1163 const StubEntry& stub_entry,
1164 RawPcDescriptors::Kind kind, 1164 RawPcDescriptors::Kind kind,
1165 LocationSummary* locs) { 1165 LocationSummary* locs) {
1166 __ Call(stub_entry); 1166 __ Call(stub_entry);
1167 AddCurrentDescriptor(kind, deopt_id, token_pos); 1167 AddCurrentDescriptor(kind, deopt_id, token_pos);
1168 RecordSafepoint(locs); 1168 RecordSafepoint(locs);
1169 // Marks either the continuation point in unoptimized code or the 1169 // Marks either the continuation point in unoptimized code or the
1170 // deoptimization point in optimized code, after call. 1170 // deoptimization point in optimized code, after call.
1171 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); 1171 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
1172 if (is_optimizing()) { 1172 if (is_optimizing()) {
1173 AddDeoptIndexAtCall(deopt_id_after, token_pos); 1173 AddDeoptIndexAtCall(deopt_id_after, token_pos);
1174 } else { 1174 } else {
1175 // Add deoptimization continuation point after the call and before the 1175 // Add deoptimization continuation point after the call and before the
1176 // arguments are removed. 1176 // arguments are removed.
1177 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); 1177 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
1178 } 1178 }
1179 } 1179 }
1180 1180
1181 1181
1182 void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos, 1182 void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
1183 intptr_t deopt_id, 1183 intptr_t deopt_id,
1184 const RuntimeEntry& entry, 1184 const RuntimeEntry& entry,
1185 intptr_t argument_count, 1185 intptr_t argument_count,
1186 LocationSummary* locs) { 1186 LocationSummary* locs) {
1187 __ CallRuntime(entry, argument_count); 1187 __ CallRuntime(entry, argument_count);
1188 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos); 1188 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos);
1189 RecordSafepoint(locs); 1189 RecordSafepoint(locs);
1190 if (deopt_id != Thread::kNoDeoptId) { 1190 if (deopt_id != Thread::kNoDeoptId) {
1191 // Marks either the continuation point in unoptimized code or the 1191 // Marks either the continuation point in unoptimized code or the
1192 // deoptimization point in optimized code, after call. 1192 // deoptimization point in optimized code, after call.
1193 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); 1193 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
1194 if (is_optimizing()) { 1194 if (is_optimizing()) {
1195 AddDeoptIndexAtCall(deopt_id_after, token_pos); 1195 AddDeoptIndexAtCall(deopt_id_after, token_pos);
1196 } else { 1196 } else {
1197 // Add deoptimization continuation point after the call and before the 1197 // Add deoptimization continuation point after the call and before the
1198 // arguments are removed. 1198 // arguments are removed.
1199 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); 1199 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
1200 } 1200 }
1201 } 1201 }
1202 } 1202 }
1203 1203
1204 1204
1205 void FlowGraphCompiler::EmitUnoptimizedStaticCall( 1205 void FlowGraphCompiler::EmitUnoptimizedStaticCall(
1206 intptr_t argument_count, 1206 intptr_t argument_count,
1207 intptr_t deopt_id, 1207 intptr_t deopt_id,
1208 intptr_t token_pos, 1208 TokenPosition token_pos,
1209 LocationSummary* locs, 1209 LocationSummary* locs,
1210 const ICData& ic_data) { 1210 const ICData& ic_data) {
1211 const StubEntry& stub_entry = 1211 const StubEntry& stub_entry =
1212 *StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested()); 1212 *StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
1213 __ LoadObject(ECX, ic_data); 1213 __ LoadObject(ECX, ic_data);
1214 GenerateDartCall(deopt_id, 1214 GenerateDartCall(deopt_id,
1215 token_pos, 1215 token_pos,
1216 stub_entry, 1216 stub_entry,
1217 RawPcDescriptors::kUnoptStaticCall, 1217 RawPcDescriptors::kUnoptStaticCall,
1218 locs); 1218 locs);
(...skipping 12 matching lines...) Expand all
1231 __ LoadObject(EAX, edge_counters_array_); 1231 __ LoadObject(EAX, edge_counters_array_);
1232 __ IncrementSmiField(FieldAddress(EAX, Array::element_offset(edge_id)), 1); 1232 __ IncrementSmiField(FieldAddress(EAX, Array::element_offset(edge_id)), 1);
1233 } 1233 }
1234 1234
1235 1235
1236 void FlowGraphCompiler::EmitOptimizedInstanceCall( 1236 void FlowGraphCompiler::EmitOptimizedInstanceCall(
1237 const StubEntry& stub_entry, 1237 const StubEntry& stub_entry,
1238 const ICData& ic_data, 1238 const ICData& ic_data,
1239 intptr_t argument_count, 1239 intptr_t argument_count,
1240 intptr_t deopt_id, 1240 intptr_t deopt_id,
1241 intptr_t token_pos, 1241 TokenPosition token_pos,
1242 LocationSummary* locs) { 1242 LocationSummary* locs) {
1243 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); 1243 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
1244 // Each ICData propagated from unoptimized to optimized code contains the 1244 // Each ICData propagated from unoptimized to optimized code contains the
1245 // function that corresponds to the Dart function of that IC call. Due 1245 // function that corresponds to the Dart function of that IC call. Due
1246 // to inlining in optimized code, that function may not correspond to the 1246 // to inlining in optimized code, that function may not correspond to the
1247 // top-level function (parsed_function().function()) which could be 1247 // top-level function (parsed_function().function()) which could be
1248 // reoptimized and which counter needs to be incremented. 1248 // reoptimized and which counter needs to be incremented.
1249 // Pass the function explicitly, it is used in IC stub. 1249 // Pass the function explicitly, it is used in IC stub.
1250 __ LoadObject(EBX, parsed_function().function()); 1250 __ LoadObject(EBX, parsed_function().function());
1251 __ LoadObject(ECX, ic_data); 1251 __ LoadObject(ECX, ic_data);
1252 GenerateDartCall(deopt_id, 1252 GenerateDartCall(deopt_id,
1253 token_pos, 1253 token_pos,
1254 stub_entry, 1254 stub_entry,
1255 RawPcDescriptors::kIcCall, 1255 RawPcDescriptors::kIcCall,
1256 locs); 1256 locs);
1257 __ Drop(argument_count); 1257 __ Drop(argument_count);
1258 } 1258 }
1259 1259
1260 1260
1261 void FlowGraphCompiler::EmitInstanceCall(const StubEntry& stub_entry, 1261 void FlowGraphCompiler::EmitInstanceCall(const StubEntry& stub_entry,
1262 const ICData& ic_data, 1262 const ICData& ic_data,
1263 intptr_t argument_count, 1263 intptr_t argument_count,
1264 intptr_t deopt_id, 1264 intptr_t deopt_id,
1265 intptr_t token_pos, 1265 TokenPosition token_pos,
1266 LocationSummary* locs) { 1266 LocationSummary* locs) {
1267 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); 1267 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
1268 __ LoadObject(ECX, ic_data); 1268 __ LoadObject(ECX, ic_data);
1269 GenerateDartCall(deopt_id, 1269 GenerateDartCall(deopt_id,
1270 token_pos, 1270 token_pos,
1271 stub_entry, 1271 stub_entry,
1272 RawPcDescriptors::kIcCall, 1272 RawPcDescriptors::kIcCall,
1273 locs); 1273 locs);
1274 __ Drop(argument_count); 1274 __ Drop(argument_count);
1275 } 1275 }
1276 1276
1277 1277
1278 void FlowGraphCompiler::EmitMegamorphicInstanceCall( 1278 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
1279 const ICData& ic_data, 1279 const ICData& ic_data,
1280 intptr_t argument_count, 1280 intptr_t argument_count,
1281 intptr_t deopt_id, 1281 intptr_t deopt_id,
1282 intptr_t token_pos, 1282 TokenPosition token_pos,
1283 LocationSummary* locs, 1283 LocationSummary* locs,
1284 intptr_t try_index) { 1284 intptr_t try_index) {
1285 const String& name = String::Handle(zone(), ic_data.target_name()); 1285 const String& name = String::Handle(zone(), ic_data.target_name());
1286 const Array& arguments_descriptor = 1286 const Array& arguments_descriptor =
1287 Array::ZoneHandle(zone(), ic_data.arguments_descriptor()); 1287 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
1288 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1288 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1289 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(), 1289 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
1290 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor)); 1290 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
1291 1291
1292 __ Comment("MegamorphicCall"); 1292 __ Comment("MegamorphicCall");
(...skipping 20 matching lines...) Expand all
1313 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); 1313 AddCurrentDescriptor(RawPcDescriptors::kDeopt, 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 // Only generated with precompilation. 1325 // Only generated with precompilation.
1326 UNREACHABLE(); 1326 UNREACHABLE();
1327 } 1327 }
1328 1328
1329 1329
1330 void FlowGraphCompiler::EmitOptimizedStaticCall( 1330 void FlowGraphCompiler::EmitOptimizedStaticCall(
1331 const Function& function, 1331 const Function& function,
1332 const Array& arguments_descriptor, 1332 const Array& arguments_descriptor,
1333 intptr_t argument_count, 1333 intptr_t argument_count,
1334 intptr_t deopt_id, 1334 intptr_t deopt_id,
1335 intptr_t token_pos, 1335 TokenPosition token_pos,
1336 LocationSummary* locs) { 1336 LocationSummary* locs) {
1337 __ LoadObject(EDX, arguments_descriptor); 1337 __ LoadObject(EDX, arguments_descriptor);
1338 // Do not use the code from the function, but let the code be patched so that 1338 // Do not use the code from the function, but let the code be patched so that
1339 // we can record the outgoing edges to other code. 1339 // we can record the outgoing edges to other code.
1340 GenerateDartCall(deopt_id, 1340 GenerateDartCall(deopt_id,
1341 token_pos, 1341 token_pos,
1342 *StubCode::CallStaticFunction_entry(), 1342 *StubCode::CallStaticFunction_entry(),
1343 RawPcDescriptors::kOther, 1343 RawPcDescriptors::kOther,
1344 locs); 1344 locs);
1345 AddStaticCallTarget(function); 1345 AddStaticCallTarget(function);
1346 __ Drop(argument_count); 1346 __ Drop(argument_count);
1347 } 1347 }
1348 1348
1349 1349
1350 Condition FlowGraphCompiler::EmitEqualityRegConstCompare( 1350 Condition FlowGraphCompiler::EmitEqualityRegConstCompare(
1351 Register reg, 1351 Register reg,
1352 const Object& obj, 1352 const Object& obj,
1353 bool needs_number_check, 1353 bool needs_number_check,
1354 intptr_t token_pos) { 1354 TokenPosition token_pos) {
1355 ASSERT(!needs_number_check || 1355 ASSERT(!needs_number_check ||
1356 (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint())); 1356 (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()));
1357 1357
1358 if (obj.IsSmi() && (Smi::Cast(obj).Value() == 0)) { 1358 if (obj.IsSmi() && (Smi::Cast(obj).Value() == 0)) {
1359 ASSERT(!needs_number_check); 1359 ASSERT(!needs_number_check);
1360 __ testl(reg, reg); 1360 __ testl(reg, reg);
1361 return EQUAL; 1361 return EQUAL;
1362 } 1362 }
1363 1363
1364 if (needs_number_check) { 1364 if (needs_number_check) {
1365 __ pushl(reg); 1365 __ pushl(reg);
1366 __ PushObject(obj); 1366 __ PushObject(obj);
1367 if (is_optimizing()) { 1367 if (is_optimizing()) {
1368 __ Call(*StubCode::OptimizedIdenticalWithNumberCheck_entry()); 1368 __ Call(*StubCode::OptimizedIdenticalWithNumberCheck_entry());
1369 } else { 1369 } else {
1370 __ Call(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry()); 1370 __ Call(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
1371 } 1371 }
1372 if (token_pos >= 0) { 1372 if (token_pos.IsReal()) {
1373 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1373 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1374 Thread::kNoDeoptId, 1374 Thread::kNoDeoptId,
1375 token_pos); 1375 token_pos);
1376 } 1376 }
1377 // Stub returns result in flags (result of a cmpl, we need ZF computed). 1377 // Stub returns result in flags (result of a cmpl, we need ZF computed).
1378 __ popl(reg); // Discard constant. 1378 __ popl(reg); // Discard constant.
1379 __ popl(reg); // Restore 'reg'. 1379 __ popl(reg); // Restore 'reg'.
1380 } else { 1380 } else {
1381 __ CompareObject(reg, obj); 1381 __ CompareObject(reg, obj);
1382 } 1382 }
1383 return EQUAL; 1383 return EQUAL;
1384 } 1384 }
1385 1385
1386 1386
1387 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left, 1387 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(
1388 Register right, 1388 Register left,
1389 bool needs_number_check, 1389 Register right,
1390 intptr_t token_pos) { 1390 bool needs_number_check,
1391 TokenPosition token_pos) {
1391 if (needs_number_check) { 1392 if (needs_number_check) {
1392 __ pushl(left); 1393 __ pushl(left);
1393 __ pushl(right); 1394 __ pushl(right);
1394 if (is_optimizing()) { 1395 if (is_optimizing()) {
1395 __ Call(*StubCode::OptimizedIdenticalWithNumberCheck_entry()); 1396 __ Call(*StubCode::OptimizedIdenticalWithNumberCheck_entry());
1396 } else { 1397 } else {
1397 __ Call(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry()); 1398 __ Call(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
1398 } 1399 }
1399 if (token_pos >= 0) { 1400 if (token_pos.IsReal()) {
1400 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1401 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1401 Thread::kNoDeoptId, 1402 Thread::kNoDeoptId,
1402 token_pos); 1403 token_pos);
1403 } 1404 }
1404 // Stub returns result in flags (result of a cmpl, we need ZF computed). 1405 // Stub returns result in flags (result of a cmpl, we need ZF computed).
1405 __ popl(right); 1406 __ popl(right);
1406 __ popl(left); 1407 __ popl(left);
1407 } else { 1408 } else {
1408 __ cmpl(left, right); 1409 __ cmpl(left, right);
1409 } 1410 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 } 1487 }
1487 #endif 1488 #endif
1488 1489
1489 1490
1490 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, 1491 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
1491 intptr_t argument_count, 1492 intptr_t argument_count,
1492 const Array& argument_names, 1493 const Array& argument_names,
1493 Label* failed, 1494 Label* failed,
1494 Label* match_found, 1495 Label* match_found,
1495 intptr_t deopt_id, 1496 intptr_t deopt_id,
1496 intptr_t token_index, 1497 TokenPosition token_index,
1497 LocationSummary* locs) { 1498 LocationSummary* locs) {
1498 ASSERT(is_optimizing()); 1499 ASSERT(is_optimizing());
1499 __ Comment("EmitTestAndCall"); 1500 __ Comment("EmitTestAndCall");
1500 const Array& arguments_descriptor = 1501 const Array& arguments_descriptor =
1501 Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count, 1502 Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count,
1502 argument_names)); 1503 argument_names));
1503 // Load receiver into EAX. 1504 // Load receiver into EAX.
1504 __ movl(EAX, Address(ESP, (argument_count - 1) * kWordSize)); 1505 __ movl(EAX, Address(ESP, (argument_count - 1) * kWordSize));
1505 __ LoadObject(EDX, arguments_descriptor); 1506 __ LoadObject(EDX, arguments_descriptor);
1506 1507
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 __ movups(reg, Address(ESP, 0)); 1840 __ movups(reg, Address(ESP, 0));
1840 __ addl(ESP, Immediate(kFpuRegisterSize)); 1841 __ addl(ESP, Immediate(kFpuRegisterSize));
1841 } 1842 }
1842 1843
1843 1844
1844 #undef __ 1845 #undef __
1845 1846
1846 } // namespace dart 1847 } // namespace dart
1847 1848
1848 #endif // defined TARGET_ARCH_IA32 1849 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_arm64.cc ('k') | runtime/vm/flow_graph_compiler_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698