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

Side by Side Diff: runtime/vm/flow_graph_compiler_ia32.cc

Issue 12457034: Ensure that all goto instructions have deoptimization target. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
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 "lib/error.h" 10 #include "lib/error.h"
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 // - Smi -> compile time subtype check (only if dst class is not parameterized). 455 // - Smi -> compile time subtype check (only if dst class is not parameterized).
456 // - Class equality (only if class is not parameterized). 456 // - Class equality (only if class is not parameterized).
457 // Inputs: 457 // Inputs:
458 // - EAX: object. 458 // - EAX: object.
459 // - EDX: instantiator type arguments or raw_null. 459 // - EDX: instantiator type arguments or raw_null.
460 // - ECX: instantiator or raw_null. 460 // - ECX: instantiator or raw_null.
461 // Clobbers ECX and EDX. 461 // Clobbers ECX and EDX.
462 // Returns: 462 // Returns:
463 // - true or false in EAX. 463 // - true or false in EAX.
464 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos, 464 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
465 intptr_t deopt_id,
466 const AbstractType& type, 465 const AbstractType& type,
467 bool negate_result, 466 bool negate_result,
468 LocationSummary* locs) { 467 LocationSummary* locs) {
469 ASSERT(type.IsFinalized() && !type.IsMalformed()); 468 ASSERT(type.IsFinalized() && !type.IsMalformed());
470 469
471 const Immediate& raw_null = 470 const Immediate& raw_null =
472 Immediate(reinterpret_cast<intptr_t>(Object::null())); 471 Immediate(reinterpret_cast<intptr_t>(Object::null()));
473 Label is_instance, is_not_instance; 472 Label is_instance, is_not_instance;
474 __ pushl(ECX); // Store instantiator on stack. 473 __ pushl(ECX); // Store instantiator on stack.
475 __ pushl(EDX); // Store instantiator type arguments. 474 __ pushl(EDX); // Store instantiator type arguments.
(...skipping 22 matching lines...) Expand all
498 // Generate runtime call. 497 // Generate runtime call.
499 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. 498 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments.
500 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. 499 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator.
501 __ PushObject(Object::ZoneHandle()); // Make room for the result. 500 __ PushObject(Object::ZoneHandle()); // Make room for the result.
502 __ pushl(EAX); // Push the instance. 501 __ pushl(EAX); // Push the instance.
503 __ PushObject(type); // Push the type. 502 __ PushObject(type); // Push the type.
504 __ pushl(ECX); // Instantiator. 503 __ pushl(ECX); // Instantiator.
505 __ pushl(EDX); // Instantiator type arguments. 504 __ pushl(EDX); // Instantiator type arguments.
506 __ LoadObject(EAX, test_cache); 505 __ LoadObject(EAX, test_cache);
507 __ pushl(EAX); 506 __ pushl(EAX);
508 GenerateCallRuntime(token_pos, deopt_id, kInstanceofRuntimeEntry, locs); 507 GenerateCallRuntime(token_pos,
508 Isolate::kNoDeoptId,
Florian Schneider 2013/04/12 09:23:55 Why kNoDeoptId here?
509 kInstanceofRuntimeEntry,
510 locs);
509 // Pop the parameters supplied to the runtime entry. The result of the 511 // Pop the parameters supplied to the runtime entry. The result of the
510 // instanceof runtime call will be left as the result of the operation. 512 // instanceof runtime call will be left as the result of the operation.
511 __ Drop(5); 513 __ Drop(5);
512 if (negate_result) { 514 if (negate_result) {
513 __ popl(EDX); 515 __ popl(EDX);
514 __ LoadObject(EAX, Bool::True()); 516 __ LoadObject(EAX, Bool::True());
515 __ cmpl(EDX, EAX); 517 __ cmpl(EDX, EAX);
516 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 518 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
517 __ LoadObject(EAX, Bool::False()); 519 __ LoadObject(EAX, Bool::False());
518 } else { 520 } else {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 __ Bind(&is_assignable); 623 __ Bind(&is_assignable);
622 __ popl(EDX); // Remove pushed instantiator type arguments. 624 __ popl(EDX); // Remove pushed instantiator type arguments.
623 __ popl(ECX); // Remove pushed instantiator. 625 __ popl(ECX); // Remove pushed instantiator.
624 } 626 }
625 627
626 628
627 void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) { 629 void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
628 if (!is_optimizing()) { 630 if (!is_optimizing()) {
629 if (FLAG_enable_type_checks && instr->IsAssertAssignable()) { 631 if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
630 AssertAssignableInstr* assert = instr->AsAssertAssignable(); 632 AssertAssignableInstr* assert = instr->AsAssertAssignable();
631 AddCurrentDescriptor(PcDescriptors::kDeoptBefore, 633 AddCurrentDescriptor(PcDescriptors::kDeopt,
632 assert->deopt_id(), 634 assert->deopt_id(),
633 assert->token_pos()); 635 assert->token_pos());
634 } else if (instr->IsGuardField()) { 636 } else if (instr->IsGuardField()) {
635 GuardFieldInstr* guard = instr->AsGuardField(); 637 GuardFieldInstr* guard = instr->AsGuardField();
636 AddCurrentDescriptor(PcDescriptors::kDeoptBefore, 638 AddCurrentDescriptor(PcDescriptors::kDeopt,
637 guard->deopt_id(), 639 guard->deopt_id(),
638 Scanner::kDummyTokenIndex); 640 Scanner::kDummyTokenIndex);
641 } else if (instr->CanBeDeoptimizationTarget()) {
642 AddCurrentDescriptor(PcDescriptors::kDeopt,
643 instr->deopt_id(),
644 Scanner::kDummyTokenIndex);
639 } 645 }
640 AllocateRegistersLocally(instr); 646 AllocateRegistersLocally(instr);
641 } 647 }
642 } 648 }
643 649
644 650
645 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { 651 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
646 if (is_optimizing()) return; 652 if (is_optimizing()) return;
647 Definition* defn = instr->AsDefinition(); 653 Definition* defn = instr->AsDefinition();
648 if ((defn != NULL) && defn->is_used()) { 654 if ((defn != NULL) && defn->is_used()) {
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, 1093 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
1088 intptr_t token_pos, 1094 intptr_t token_pos,
1089 const ExternalLabel* label, 1095 const ExternalLabel* label,
1090 PcDescriptors::Kind kind, 1096 PcDescriptors::Kind kind,
1091 LocationSummary* locs) { 1097 LocationSummary* locs) {
1092 __ call(label); 1098 __ call(label);
1093 AddCurrentDescriptor(kind, deopt_id, token_pos); 1099 AddCurrentDescriptor(kind, deopt_id, token_pos);
1094 RecordSafepoint(locs); 1100 RecordSafepoint(locs);
1095 // Marks either the continuation point in unoptimized code or the 1101 // Marks either the continuation point in unoptimized code or the
1096 // deoptimization point in optimized code, after call. 1102 // deoptimization point in optimized code, after call.
1103 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id);
1097 if (is_optimizing()) { 1104 if (is_optimizing()) {
1098 AddDeoptIndexAtCall(deopt_id, token_pos); 1105 AddDeoptIndexAtCall(deopt_id_after, token_pos);
1099 } else { 1106 } else {
1100 // Add deoptimization continuation point after the call and before the 1107 // Add deoptimization continuation point after the call and before the
1101 // arguments are removed. 1108 // arguments are removed.
1102 AddCurrentDescriptor(PcDescriptors::kDeoptAfter, 1109 AddCurrentDescriptor(PcDescriptors::kDeopt, deopt_id_after, token_pos);
1103 deopt_id,
1104 token_pos);
1105 } 1110 }
1106 } 1111 }
1107 1112
1108 1113
1109 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos, 1114 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
1110 intptr_t deopt_id, 1115 intptr_t deopt_id,
1111 const RuntimeEntry& entry, 1116 const RuntimeEntry& entry,
1112 LocationSummary* locs) { 1117 LocationSummary* locs) {
1113 __ CallRuntime(entry); 1118 __ CallRuntime(entry);
1114 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos); 1119 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos);
1115 RecordSafepoint(locs); 1120 RecordSafepoint(locs);
1116 if (deopt_id != Isolate::kNoDeoptId) { 1121 if (deopt_id != Isolate::kNoDeoptId) {
1117 // Marks either the continuation point in unoptimized code or the 1122 // Marks either the continuation point in unoptimized code or the
1118 // deoptimization point in optimized code, after call. 1123 // deoptimization point in optimized code, after call.
1124 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id);
1119 if (is_optimizing()) { 1125 if (is_optimizing()) {
1120 AddDeoptIndexAtCall(deopt_id, token_pos); 1126 AddDeoptIndexAtCall(deopt_id_after, token_pos);
1121 } else { 1127 } else {
1122 // Add deoptimization continuation point after the call and before the 1128 // Add deoptimization continuation point after the call and before the
1123 // arguments are removed. 1129 // arguments are removed.
1124 AddCurrentDescriptor(PcDescriptors::kDeoptAfter, 1130 AddCurrentDescriptor(PcDescriptors::kDeopt, deopt_id_after, token_pos);
1125 deopt_id,
1126 token_pos);
1127 } 1131 }
1128 } 1132 }
1129 } 1133 }
1130 1134
1131 1135
1132 void FlowGraphCompiler::EmitOptimizedInstanceCall( 1136 void FlowGraphCompiler::EmitOptimizedInstanceCall(
1133 ExternalLabel* target_label, 1137 ExternalLabel* target_label,
1134 const ICData& ic_data, 1138 const ICData& ic_data,
1135 const Array& arguments_descriptor, 1139 const Array& arguments_descriptor,
1136 intptr_t argument_count, 1140 intptr_t argument_count,
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 // be invoked as a normal Dart function. 1232 // be invoked as a normal Dart function.
1229 __ movl(EAX, FieldAddress(EDI, ECX, TIMES_4, base + kWordSize)); 1233 __ movl(EAX, FieldAddress(EDI, ECX, TIMES_4, base + kWordSize));
1230 __ movl(EAX, FieldAddress(EAX, Function::code_offset())); 1234 __ movl(EAX, FieldAddress(EAX, Function::code_offset()));
1231 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); 1235 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset()));
1232 __ LoadObject(ECX, ic_data); 1236 __ LoadObject(ECX, ic_data);
1233 __ LoadObject(EDX, arguments_descriptor); 1237 __ LoadObject(EDX, arguments_descriptor);
1234 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1238 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1235 __ call(EAX); 1239 __ call(EAX);
1236 AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos); 1240 AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos);
1237 RecordSafepoint(locs); 1241 RecordSafepoint(locs);
1238 AddDeoptIndexAtCall(deopt_id, token_pos); 1242 AddDeoptIndexAtCall(Isolate::ToDeoptAfter(deopt_id), token_pos);
1239 __ Drop(argument_count); 1243 __ Drop(argument_count);
1240 } 1244 }
1241 1245
1242 1246
1243 void FlowGraphCompiler::EmitStaticCall(const Function& function, 1247 void FlowGraphCompiler::EmitStaticCall(const Function& function,
1244 const Array& arguments_descriptor, 1248 const Array& arguments_descriptor,
1245 intptr_t argument_count, 1249 intptr_t argument_count,
1246 intptr_t deopt_id, 1250 intptr_t deopt_id,
1247 intptr_t token_pos, 1251 intptr_t token_pos,
1248 LocationSummary* locs) { 1252 LocationSummary* locs) {
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
1718 __ popl(ECX); 1722 __ popl(ECX);
1719 __ popl(EAX); 1723 __ popl(EAX);
1720 } 1724 }
1721 1725
1722 1726
1723 #undef __ 1727 #undef __
1724 1728
1725 } // namespace dart 1729 } // namespace dart
1726 1730
1727 #endif // defined TARGET_ARCH_IA32 1731 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698