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

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

Issue 26823006: Record a correct deoptimization environment for slow-path code. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Use an environment value's representation to decide its size. Created 7 years, 2 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 "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 // Generate runtime call. 592 // Generate runtime call.
593 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. 593 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments.
594 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. 594 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator.
595 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result. 595 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result.
596 __ pushq(RAX); // Push the instance. 596 __ pushq(RAX); // Push the instance.
597 __ PushObject(type, PP); // Push the type. 597 __ PushObject(type, PP); // Push the type.
598 __ pushq(RCX); // TODO(srdjan): Pass instantiator instead of null. 598 __ pushq(RCX); // TODO(srdjan): Pass instantiator instead of null.
599 __ pushq(RDX); // Instantiator type arguments. 599 __ pushq(RDX); // Instantiator type arguments.
600 __ LoadObject(RAX, test_cache, PP); 600 __ LoadObject(RAX, test_cache, PP);
601 __ pushq(RAX); 601 __ pushq(RAX);
602 GenerateCallRuntime(token_pos, 602 GenerateRuntimeCall(token_pos,
603 deopt_id, 603 deopt_id,
604 kInstanceofRuntimeEntry, 604 kInstanceofRuntimeEntry,
605 5, 605 5,
606 locs); 606 locs);
607 // Pop the parameters supplied to the runtime entry. The result of the 607 // Pop the parameters supplied to the runtime entry. The result of the
608 // instanceof runtime call will be left as the result of the operation. 608 // instanceof runtime call will be left as the result of the operation.
609 __ Drop(5); 609 __ Drop(5);
610 if (negate_result) { 610 if (negate_result) {
611 __ popq(RDX); 611 __ popq(RDX);
612 __ LoadObject(RAX, Bool::True(), PP); 612 __ LoadObject(RAX, Bool::True(), PP);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 } else { 675 } else {
676 const bool is_malbounded = dst_type.IsMalboundedWithError(&error); 676 const bool is_malbounded = dst_type.IsMalboundedWithError(&error);
677 ASSERT(is_malbounded); 677 ASSERT(is_malbounded);
678 } 678 }
679 const String& error_message = String::ZoneHandle( 679 const String& error_message = String::ZoneHandle(
680 Symbols::New(error.ToErrorCString())); 680 Symbols::New(error.ToErrorCString()));
681 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result. 681 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result.
682 __ pushq(RAX); // Push the source object. 682 __ pushq(RAX); // Push the source object.
683 __ PushObject(dst_name, PP); // Push the name of the destination. 683 __ PushObject(dst_name, PP); // Push the name of the destination.
684 __ PushObject(error_message, PP); 684 __ PushObject(error_message, PP);
685 GenerateCallRuntime(token_pos, 685 GenerateRuntimeCall(token_pos,
686 deopt_id, 686 deopt_id,
687 kMalformedTypeErrorRuntimeEntry, 687 kMalformedTypeErrorRuntimeEntry,
688 3, 688 3,
689 locs); 689 locs);
690 // We should never return here. 690 // We should never return here.
691 __ int3(); 691 __ int3();
692 692
693 __ Bind(&is_assignable); // For a null object. 693 __ Bind(&is_assignable); // For a null object.
694 __ popq(RDX); // Remove pushed instantiator type arguments. 694 __ popq(RDX); // Remove pushed instantiator type arguments.
695 __ popq(RCX); // Remove pushed instantiator. 695 __ popq(RCX); // Remove pushed instantiator.
696 return; 696 return;
697 } 697 }
698 698
699 // Generate inline type check, linking to runtime call if not assignable. 699 // Generate inline type check, linking to runtime call if not assignable.
700 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); 700 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
701 test_cache = GenerateInlineInstanceof(token_pos, dst_type, 701 test_cache = GenerateInlineInstanceof(token_pos, dst_type,
702 &is_assignable, &runtime_call); 702 &is_assignable, &runtime_call);
703 703
704 __ Bind(&runtime_call); 704 __ Bind(&runtime_call);
705 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. 705 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments.
706 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. 706 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator.
707 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result. 707 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result.
708 __ pushq(RAX); // Push the source object. 708 __ pushq(RAX); // Push the source object.
709 __ PushObject(dst_type, PP); // Push the type of the destination. 709 __ PushObject(dst_type, PP); // Push the type of the destination.
710 __ pushq(RCX); // Instantiator. 710 __ pushq(RCX); // Instantiator.
711 __ pushq(RDX); // Instantiator type arguments. 711 __ pushq(RDX); // Instantiator type arguments.
712 __ PushObject(dst_name, PP); // Push the name of the destination. 712 __ PushObject(dst_name, PP); // Push the name of the destination.
713 __ LoadObject(RAX, test_cache, PP); 713 __ LoadObject(RAX, test_cache, PP);
714 __ pushq(RAX); 714 __ pushq(RAX);
715 GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs); 715 GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
716 // Pop the parameters supplied to the runtime entry. The result of the 716 // Pop the parameters supplied to the runtime entry. The result of the
717 // type check runtime call is the checked value. 717 // type check runtime call is the checked value.
718 __ Drop(6); 718 __ Drop(6);
719 __ popq(RAX); 719 __ popq(RAX);
720 720
721 __ Bind(&is_assignable); 721 __ Bind(&is_assignable);
722 __ popq(RDX); // Remove pushed instantiator type arguments. 722 __ popq(RDX); // Remove pushed instantiator type arguments.
723 __ popq(RCX); // Remove pushed instantiator. 723 __ popq(RCX); // Remove pushed instantiator.
724 } 724 }
725 725
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
1265 if (is_optimizing()) { 1265 if (is_optimizing()) {
1266 AddDeoptIndexAtCall(deopt_id_after, token_pos); 1266 AddDeoptIndexAtCall(deopt_id_after, token_pos);
1267 } else { 1267 } else {
1268 // Add deoptimization continuation point after the call and before the 1268 // Add deoptimization continuation point after the call and before the
1269 // arguments are removed. 1269 // arguments are removed.
1270 AddCurrentDescriptor(PcDescriptors::kDeopt, deopt_id_after, token_pos); 1270 AddCurrentDescriptor(PcDescriptors::kDeopt, deopt_id_after, token_pos);
1271 } 1271 }
1272 } 1272 }
1273 1273
1274 1274
1275 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos, 1275 void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos,
1276 intptr_t deopt_id, 1276 intptr_t deopt_id,
1277 const RuntimeEntry& entry, 1277 const RuntimeEntry& entry,
1278 intptr_t argument_count, 1278 intptr_t argument_count,
1279 LocationSummary* locs) { 1279 LocationSummary* locs) {
1280 __ CallRuntime(entry, argument_count); 1280 __ CallRuntime(entry, argument_count);
1281 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos); 1281 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos);
1282 RecordSafepoint(locs); 1282 RecordSafepoint(locs);
1283 if (deopt_id != Isolate::kNoDeoptId) { 1283 if (deopt_id != Isolate::kNoDeoptId) {
1284 // Marks either the continuation point in unoptimized code or the 1284 // Marks either the continuation point in unoptimized code or the
1285 // deoptimization point in optimized code, after call. 1285 // deoptimization point in optimized code, after call.
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1534 token_pos); 1534 token_pos);
1535 // Stub returns result in flags (result of a cmpl, we need ZF computed). 1535 // Stub returns result in flags (result of a cmpl, we need ZF computed).
1536 __ popq(right); 1536 __ popq(right);
1537 __ popq(left); 1537 __ popq(left);
1538 } else { 1538 } else {
1539 __ cmpl(left, right); 1539 __ cmpl(left, right);
1540 } 1540 }
1541 } 1541 }
1542 1542
1543 1543
1544 // This function must be in sync with FlowGraphCompiler::RecordSafepoint. 1544 // This function must be in sync with FlowGraphCompiler::RecordSafepoint and
1545 // FlowGraphCompiler::SlowPathEnvironmentFor.
1545 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) { 1546 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
1546 // TODO(vegorov): consider saving only caller save (volatile) registers. 1547 // TODO(vegorov): consider saving only caller save (volatile) registers.
1547 const intptr_t xmm_regs_count = locs->live_registers()->fpu_regs_count(); 1548 const intptr_t xmm_regs_count = locs->live_registers()->FpuRegisterCount();
1548 if (xmm_regs_count > 0) { 1549 if (xmm_regs_count > 0) {
1549 __ AddImmediate(RSP, Immediate(-xmm_regs_count * kFpuRegisterSize), PP); 1550 __ AddImmediate(RSP, Immediate(-xmm_regs_count * kFpuRegisterSize), PP);
1550 // Store XMM registers with the lowest register number at the lowest 1551 // Store XMM registers with the lowest register number at the lowest
1551 // address. 1552 // address.
1552 intptr_t offset = 0; 1553 intptr_t offset = 0;
1553 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { 1554 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
1554 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); 1555 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
1555 if (locs->live_registers()->ContainsFpuRegister(xmm_reg)) { 1556 if (locs->live_registers()->ContainsFpuRegister(xmm_reg)) {
1556 __ movups(Address(RSP, offset), xmm_reg); 1557 __ movups(Address(RSP, offset), xmm_reg);
1557 offset += kFpuRegisterSize; 1558 offset += kFpuRegisterSize;
(...skipping 16 matching lines...) Expand all
1574 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) { 1575 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
1575 // General purpose registers have the highest register number at the 1576 // General purpose registers have the highest register number at the
1576 // lowest address. 1577 // lowest address.
1577 for (intptr_t reg_idx = kNumberOfCpuRegisters - 1; reg_idx >= 0; --reg_idx) { 1578 for (intptr_t reg_idx = kNumberOfCpuRegisters - 1; reg_idx >= 0; --reg_idx) {
1578 Register reg = static_cast<Register>(reg_idx); 1579 Register reg = static_cast<Register>(reg_idx);
1579 if (locs->live_registers()->ContainsRegister(reg)) { 1580 if (locs->live_registers()->ContainsRegister(reg)) {
1580 __ popq(reg); 1581 __ popq(reg);
1581 } 1582 }
1582 } 1583 }
1583 1584
1584 const intptr_t xmm_regs_count = locs->live_registers()->fpu_regs_count(); 1585 const intptr_t xmm_regs_count = locs->live_registers()->FpuRegisterCount();
1585 if (xmm_regs_count > 0) { 1586 if (xmm_regs_count > 0) {
1586 // XMM registers have the lowest register number at the lowest address. 1587 // XMM registers have the lowest register number at the lowest address.
1587 intptr_t offset = 0; 1588 intptr_t offset = 0;
1588 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { 1589 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
1589 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); 1590 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
1590 if (locs->live_registers()->ContainsFpuRegister(xmm_reg)) { 1591 if (locs->live_registers()->ContainsFpuRegister(xmm_reg)) {
1591 __ movups(xmm_reg, Address(RSP, offset)); 1592 __ movups(xmm_reg, Address(RSP, offset));
1592 offset += kFpuRegisterSize; 1593 offset += kFpuRegisterSize;
1593 } 1594 }
1594 } 1595 }
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
1934 __ movups(reg, Address(RSP, 0)); 1935 __ movups(reg, Address(RSP, 0));
1935 __ AddImmediate(RSP, Immediate(kFpuRegisterSize), PP); 1936 __ AddImmediate(RSP, Immediate(kFpuRegisterSize), PP);
1936 } 1937 }
1937 1938
1938 1939
1939 #undef __ 1940 #undef __
1940 1941
1941 } // namespace dart 1942 } // namespace dart
1942 1943
1943 #endif // defined TARGET_ARCH_X64 1944 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698