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

Side by Side Diff: runtime/vm/flow_graph_compiler_x64.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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 // - Smi -> compile time subtype check (only if dst class is not parameterized). 454 // - Smi -> compile time subtype check (only if dst class is not parameterized).
455 // - Class equality (only if class is not parameterized). 455 // - Class equality (only if class is not parameterized).
456 // Inputs: 456 // Inputs:
457 // - RAX: object. 457 // - RAX: object.
458 // - RDX: instantiator type arguments or raw_null. 458 // - RDX: instantiator type arguments or raw_null.
459 // - RCX: instantiator or raw_null. 459 // - RCX: instantiator or raw_null.
460 // Clobbers RCX and RDX. 460 // Clobbers RCX and RDX.
461 // Returns: 461 // Returns:
462 // - true or false in RAX. 462 // - true or false in RAX.
463 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos, 463 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
464 intptr_t deopt_id,
465 const AbstractType& type, 464 const AbstractType& type,
466 bool negate_result, 465 bool negate_result,
467 LocationSummary* locs) { 466 LocationSummary* locs) {
468 ASSERT(type.IsFinalized() && !type.IsMalformed()); 467 ASSERT(type.IsFinalized() && !type.IsMalformed());
469 468
470 const Immediate& raw_null = 469 const Immediate& raw_null =
471 Immediate(reinterpret_cast<intptr_t>(Object::null())); 470 Immediate(reinterpret_cast<intptr_t>(Object::null()));
472 Label is_instance, is_not_instance; 471 Label is_instance, is_not_instance;
473 __ pushq(RCX); // Store instantiator on stack. 472 __ pushq(RCX); // Store instantiator on stack.
474 __ pushq(RDX); // Store instantiator type arguments. 473 __ pushq(RDX); // Store instantiator type arguments.
(...skipping 22 matching lines...) Expand all
497 // Generate runtime call. 496 // Generate runtime call.
498 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. 497 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments.
499 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. 498 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator.
500 __ PushObject(Object::ZoneHandle()); // Make room for the result. 499 __ PushObject(Object::ZoneHandle()); // Make room for the result.
501 __ pushq(RAX); // Push the instance. 500 __ pushq(RAX); // Push the instance.
502 __ PushObject(type); // Push the type. 501 __ PushObject(type); // Push the type.
503 __ pushq(RCX); // TODO(srdjan): Pass instantiator instead of null. 502 __ pushq(RCX); // TODO(srdjan): Pass instantiator instead of null.
504 __ pushq(RDX); // Instantiator type arguments. 503 __ pushq(RDX); // Instantiator type arguments.
505 __ LoadObject(RAX, test_cache); 504 __ LoadObject(RAX, test_cache);
506 __ pushq(RAX); 505 __ pushq(RAX);
507 GenerateCallRuntime(token_pos, deopt_id, kInstanceofRuntimeEntry, locs); 506 GenerateCallRuntime(token_pos,
507 Isolate::kNoDeoptId,
Florian Schneider 2013/04/12 09:23:55 Why kNoDeoptId here?
508 kInstanceofRuntimeEntry,
509 locs);
508 // Pop the parameters supplied to the runtime entry. The result of the 510 // Pop the parameters supplied to the runtime entry. The result of the
509 // instanceof runtime call will be left as the result of the operation. 511 // instanceof runtime call will be left as the result of the operation.
510 __ Drop(5); 512 __ Drop(5);
511 if (negate_result) { 513 if (negate_result) {
512 __ popq(RDX); 514 __ popq(RDX);
513 __ LoadObject(RAX, Bool::True()); 515 __ LoadObject(RAX, Bool::True());
514 __ cmpq(RDX, RAX); 516 __ cmpq(RDX, RAX);
515 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 517 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
516 __ LoadObject(RAX, Bool::False()); 518 __ LoadObject(RAX, Bool::False());
517 } else { 519 } else {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 __ Bind(&is_assignable); 619 __ Bind(&is_assignable);
618 __ popq(RDX); // Remove pushed instantiator type arguments. 620 __ popq(RDX); // Remove pushed instantiator type arguments.
619 __ popq(RCX); // Remove pushed instantiator. 621 __ popq(RCX); // Remove pushed instantiator.
620 } 622 }
621 623
622 624
623 void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) { 625 void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
624 if (!is_optimizing()) { 626 if (!is_optimizing()) {
625 if (FLAG_enable_type_checks && instr->IsAssertAssignable()) { 627 if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
626 AssertAssignableInstr* assert = instr->AsAssertAssignable(); 628 AssertAssignableInstr* assert = instr->AsAssertAssignable();
627 AddCurrentDescriptor(PcDescriptors::kDeoptBefore, 629 AddCurrentDescriptor(PcDescriptors::kDeopt,
628 assert->deopt_id(), 630 assert->deopt_id(),
629 assert->token_pos()); 631 assert->token_pos());
630 } else if (instr->IsGuardField()) { 632 } else if (instr->IsGuardField()) {
631 GuardFieldInstr* guard = instr->AsGuardField(); 633 GuardFieldInstr* guard = instr->AsGuardField();
632 AddCurrentDescriptor(PcDescriptors::kDeoptBefore, 634 AddCurrentDescriptor(PcDescriptors::kDeopt,
633 guard->deopt_id(), 635 guard->deopt_id(),
634 Scanner::kDummyTokenIndex); 636 Scanner::kDummyTokenIndex);
637 } else if (instr->CanBeDeoptimizationTarget()) {
638 AddCurrentDescriptor(PcDescriptors::kDeopt,
639 instr->deopt_id(),
640 Scanner::kDummyTokenIndex);
635 } 641 }
636 AllocateRegistersLocally(instr); 642 AllocateRegistersLocally(instr);
637 } 643 }
638 } 644 }
639 645
640 646
641 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { 647 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
642 if (is_optimizing()) return; 648 if (is_optimizing()) return;
643 Definition* defn = instr->AsDefinition(); 649 Definition* defn = instr->AsDefinition();
644 if ((defn != NULL) && defn->is_used()) { 650 if ((defn != NULL) && defn->is_used()) {
(...skipping 442 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 __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize)); 1233 __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize));
1230 __ movq(RAX, FieldAddress(RAX, Function::code_offset())); 1234 __ movq(RAX, FieldAddress(RAX, Function::code_offset()));
1231 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); 1235 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
1232 __ LoadObject(RBX, ic_data); 1236 __ LoadObject(RBX, ic_data);
1233 __ LoadObject(R10, arguments_descriptor); 1237 __ LoadObject(R10, arguments_descriptor);
1234 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1238 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1235 __ call(RAX); 1239 __ call(RAX);
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 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
1692 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { 1696 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) {
1693 __ Exchange(mem1, mem2); 1697 __ Exchange(mem1, mem2);
1694 } 1698 }
1695 1699
1696 1700
1697 #undef __ 1701 #undef __
1698 1702
1699 } // namespace dart 1703 } // namespace dart
1700 1704
1701 #endif // defined TARGET_ARCH_X64 1705 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698