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

Side by Side Diff: runtime/vm/flow_graph_compiler_ia32.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_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 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 // Generate runtime call. 605 // Generate runtime call.
606 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. 606 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments.
607 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. 607 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator.
608 __ PushObject(Object::ZoneHandle()); // Make room for the result. 608 __ PushObject(Object::ZoneHandle()); // Make room for the result.
609 __ pushl(EAX); // Push the instance. 609 __ pushl(EAX); // Push the instance.
610 __ PushObject(type); // Push the type. 610 __ PushObject(type); // Push the type.
611 __ pushl(ECX); // Instantiator. 611 __ pushl(ECX); // Instantiator.
612 __ pushl(EDX); // Instantiator type arguments. 612 __ pushl(EDX); // Instantiator type arguments.
613 __ LoadObject(EAX, test_cache); 613 __ LoadObject(EAX, test_cache);
614 __ pushl(EAX); 614 __ pushl(EAX);
615 GenerateCallRuntime(token_pos, 615 GenerateRuntimeCall(token_pos,
616 deopt_id, 616 deopt_id,
617 kInstanceofRuntimeEntry, 617 kInstanceofRuntimeEntry,
618 5, 618 5,
619 locs); 619 locs);
620 // Pop the parameters supplied to the runtime entry. The result of the 620 // Pop the parameters supplied to the runtime entry. The result of the
621 // instanceof runtime call will be left as the result of the operation. 621 // instanceof runtime call will be left as the result of the operation.
622 __ Drop(5); 622 __ Drop(5);
623 if (negate_result) { 623 if (negate_result) {
624 __ popl(EDX); 624 __ popl(EDX);
625 __ LoadObject(EAX, Bool::True()); 625 __ LoadObject(EAX, Bool::True());
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 } else { 693 } else {
694 const bool is_malbounded = dst_type.IsMalboundedWithError(&error); 694 const bool is_malbounded = dst_type.IsMalboundedWithError(&error);
695 ASSERT(is_malbounded); 695 ASSERT(is_malbounded);
696 } 696 }
697 const String& error_message = String::ZoneHandle( 697 const String& error_message = String::ZoneHandle(
698 Symbols::New(error.ToErrorCString())); 698 Symbols::New(error.ToErrorCString()));
699 __ PushObject(Object::ZoneHandle()); // Make room for the result. 699 __ PushObject(Object::ZoneHandle()); // Make room for the result.
700 __ pushl(EAX); // Push the source object. 700 __ pushl(EAX); // Push the source object.
701 __ PushObject(dst_name); // Push the name of the destination. 701 __ PushObject(dst_name); // Push the name of the destination.
702 __ PushObject(error_message); 702 __ PushObject(error_message);
703 GenerateCallRuntime(token_pos, 703 GenerateRuntimeCall(token_pos,
704 deopt_id, 704 deopt_id,
705 kMalformedTypeErrorRuntimeEntry, 705 kMalformedTypeErrorRuntimeEntry,
706 3, 706 3,
707 locs); 707 locs);
708 // We should never return here. 708 // We should never return here.
709 __ int3(); 709 __ int3();
710 710
711 __ Bind(&is_assignable); // For a null object. 711 __ Bind(&is_assignable); // For a null object.
712 __ popl(EDX); // Remove pushed instantiator type arguments. 712 __ popl(EDX); // Remove pushed instantiator type arguments.
713 __ popl(ECX); // Remove pushed instantiator. 713 __ popl(ECX); // Remove pushed instantiator.
714 return; 714 return;
715 } 715 }
716 716
717 // Generate inline type check, linking to runtime call if not assignable. 717 // Generate inline type check, linking to runtime call if not assignable.
718 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); 718 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
719 test_cache = GenerateInlineInstanceof(token_pos, dst_type, 719 test_cache = GenerateInlineInstanceof(token_pos, dst_type,
720 &is_assignable, &runtime_call); 720 &is_assignable, &runtime_call);
721 721
722 __ Bind(&runtime_call); 722 __ Bind(&runtime_call);
723 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. 723 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments.
724 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. 724 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator.
725 __ PushObject(Object::ZoneHandle()); // Make room for the result. 725 __ PushObject(Object::ZoneHandle()); // Make room for the result.
726 __ pushl(EAX); // Push the source object. 726 __ pushl(EAX); // Push the source object.
727 __ PushObject(dst_type); // Push the type of the destination. 727 __ PushObject(dst_type); // Push the type of the destination.
728 __ pushl(ECX); // Instantiator. 728 __ pushl(ECX); // Instantiator.
729 __ pushl(EDX); // Instantiator type arguments. 729 __ pushl(EDX); // Instantiator type arguments.
730 __ PushObject(dst_name); // Push the name of the destination. 730 __ PushObject(dst_name); // Push the name of the destination.
731 __ LoadObject(EAX, test_cache); 731 __ LoadObject(EAX, test_cache);
732 __ pushl(EAX); 732 __ pushl(EAX);
733 GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs); 733 GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
734 // Pop the parameters supplied to the runtime entry. The result of the 734 // Pop the parameters supplied to the runtime entry. The result of the
735 // type check runtime call is the checked value. 735 // type check runtime call is the checked value.
736 __ Drop(6); 736 __ Drop(6);
737 __ popl(EAX); 737 __ popl(EAX);
738 738
739 __ Bind(&is_assignable); 739 __ Bind(&is_assignable);
740 __ popl(EDX); // Remove pushed instantiator type arguments. 740 __ popl(EDX); // Remove pushed instantiator type arguments.
741 __ popl(ECX); // Remove pushed instantiator. 741 __ popl(ECX); // Remove pushed instantiator.
742 } 742 }
743 743
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 if (is_optimizing()) { 1230 if (is_optimizing()) {
1231 AddDeoptIndexAtCall(deopt_id_after, token_pos); 1231 AddDeoptIndexAtCall(deopt_id_after, token_pos);
1232 } else { 1232 } else {
1233 // Add deoptimization continuation point after the call and before the 1233 // Add deoptimization continuation point after the call and before the
1234 // arguments are removed. 1234 // arguments are removed.
1235 AddCurrentDescriptor(PcDescriptors::kDeopt, deopt_id_after, token_pos); 1235 AddCurrentDescriptor(PcDescriptors::kDeopt, deopt_id_after, token_pos);
1236 } 1236 }
1237 } 1237 }
1238 1238
1239 1239
1240 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos, 1240 void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos,
1241 intptr_t deopt_id, 1241 intptr_t deopt_id,
1242 const RuntimeEntry& entry, 1242 const RuntimeEntry& entry,
1243 intptr_t argument_count, 1243 intptr_t argument_count,
1244 LocationSummary* locs) { 1244 LocationSummary* locs) {
1245 __ CallRuntime(entry, argument_count); 1245 __ CallRuntime(entry, argument_count);
1246 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos); 1246 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos);
1247 RecordSafepoint(locs); 1247 RecordSafepoint(locs);
1248 if (deopt_id != Isolate::kNoDeoptId) { 1248 if (deopt_id != Isolate::kNoDeoptId) {
1249 // Marks either the continuation point in unoptimized code or the 1249 // Marks either the continuation point in unoptimized code or the
1250 // deoptimization point in optimized code, after call. 1250 // deoptimization point in optimized code, after call.
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1498 token_pos); 1498 token_pos);
1499 // Stub returns result in flags (result of a cmpl, we need ZF computed). 1499 // Stub returns result in flags (result of a cmpl, we need ZF computed).
1500 __ popl(right); 1500 __ popl(right);
1501 __ popl(left); 1501 __ popl(left);
1502 } else { 1502 } else {
1503 __ cmpl(left, right); 1503 __ cmpl(left, right);
1504 } 1504 }
1505 } 1505 }
1506 1506
1507 1507
1508 // This function must be in sync with FlowGraphCompiler::RecordSafepoint. 1508 // This function must be in sync with FlowGraphCompiler::RecordSafepoint and
1509 // FlowGraphCompiler::SlowPathEnvironmentFor.
1509 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) { 1510 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
1510 // TODO(vegorov): consider saving only caller save (volatile) registers. 1511 // TODO(vegorov): consider saving only caller save (volatile) registers.
1511 const intptr_t xmm_regs_count = locs->live_registers()->fpu_regs_count(); 1512 const intptr_t xmm_regs_count = locs->live_registers()->FpuRegisterCount();
1512 if (xmm_regs_count > 0) { 1513 if (xmm_regs_count > 0) {
1513 __ subl(ESP, Immediate(xmm_regs_count * kFpuRegisterSize)); 1514 __ subl(ESP, Immediate(xmm_regs_count * kFpuRegisterSize));
1514 // Store XMM registers with the lowest register number at the lowest 1515 // Store XMM registers with the lowest register number at the lowest
1515 // address. 1516 // address.
1516 intptr_t offset = 0; 1517 intptr_t offset = 0;
1517 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { 1518 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
1518 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); 1519 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
1519 if (locs->live_registers()->ContainsFpuRegister(xmm_reg)) { 1520 if (locs->live_registers()->ContainsFpuRegister(xmm_reg)) {
1520 __ movups(Address(ESP, offset), xmm_reg); 1521 __ movups(Address(ESP, offset), xmm_reg);
1521 offset += kFpuRegisterSize; 1522 offset += kFpuRegisterSize;
(...skipping 16 matching lines...) Expand all
1538 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) { 1539 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
1539 // General purpose registers have the highest register number at the 1540 // General purpose registers have the highest register number at the
1540 // lowest address. 1541 // lowest address.
1541 for (intptr_t reg_idx = kNumberOfCpuRegisters - 1; reg_idx >= 0; --reg_idx) { 1542 for (intptr_t reg_idx = kNumberOfCpuRegisters - 1; reg_idx >= 0; --reg_idx) {
1542 Register reg = static_cast<Register>(reg_idx); 1543 Register reg = static_cast<Register>(reg_idx);
1543 if (locs->live_registers()->ContainsRegister(reg)) { 1544 if (locs->live_registers()->ContainsRegister(reg)) {
1544 __ popl(reg); 1545 __ popl(reg);
1545 } 1546 }
1546 } 1547 }
1547 1548
1548 const intptr_t xmm_regs_count = locs->live_registers()->fpu_regs_count(); 1549 const intptr_t xmm_regs_count = locs->live_registers()->FpuRegisterCount();
1549 if (xmm_regs_count > 0) { 1550 if (xmm_regs_count > 0) {
1550 // XMM registers have the lowest register number at the lowest address. 1551 // XMM registers have the lowest register number at the lowest address.
1551 intptr_t offset = 0; 1552 intptr_t offset = 0;
1552 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { 1553 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
1553 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); 1554 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
1554 if (locs->live_registers()->ContainsFpuRegister(xmm_reg)) { 1555 if (locs->live_registers()->ContainsFpuRegister(xmm_reg)) {
1555 __ movups(xmm_reg, Address(ESP, offset)); 1556 __ movups(xmm_reg, Address(ESP, offset));
1556 offset += kFpuRegisterSize; 1557 offset += kFpuRegisterSize;
1557 } 1558 }
1558 } 1559 }
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
1915 __ movups(reg, Address(ESP, 0)); 1916 __ movups(reg, Address(ESP, 0));
1916 __ addl(ESP, Immediate(kFpuRegisterSize)); 1917 __ addl(ESP, Immediate(kFpuRegisterSize));
1917 } 1918 }
1918 1919
1919 1920
1920 #undef __ 1921 #undef __
1921 1922
1922 } // namespace dart 1923 } // namespace dart
1923 1924
1924 #endif // defined TARGET_ARCH_IA32 1925 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698