| OLD | NEW |
| 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 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 } | 742 } |
| 743 AllocateRegistersLocally(instr); | 743 AllocateRegistersLocally(instr); |
| 744 } else if (instr->MayThrow() && | 744 } else if (instr->MayThrow() && |
| 745 (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) { | 745 (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) { |
| 746 // Optimized try-block: Sync locals to fixed stack locations. | 746 // Optimized try-block: Sync locals to fixed stack locations. |
| 747 EmitTrySync(instr, CurrentTryIndex()); | 747 EmitTrySync(instr, CurrentTryIndex()); |
| 748 } | 748 } |
| 749 } | 749 } |
| 750 | 750 |
| 751 | 751 |
| 752 void FlowGraphCompiler::EmitTrySyncMove(Address dest, | 752 void FlowGraphCompiler::EmitTrySyncMove(intptr_t dest_offset, |
| 753 Location loc, | 753 Location loc, |
| 754 bool* push_emitted) { | 754 bool* push_emitted) { |
| 755 const Address dest(RBP, dest_offset); |
| 755 if (loc.IsConstant()) { | 756 if (loc.IsConstant()) { |
| 756 if (!*push_emitted) { | 757 if (!*push_emitted) { |
| 757 __ pushq(RAX); | 758 __ pushq(RAX); |
| 758 *push_emitted = true; | 759 *push_emitted = true; |
| 759 } | 760 } |
| 760 __ LoadObject(RAX, loc.constant()); | 761 __ LoadObject(RAX, loc.constant()); |
| 761 __ movq(dest, RAX); | 762 __ movq(dest, RAX); |
| 762 } else if (loc.IsRegister()) { | 763 } else if (loc.IsRegister()) { |
| 763 if (*push_emitted && loc.reg() == RAX) { | 764 if (*push_emitted && loc.reg() == RAX) { |
| 764 __ movq(RAX, Address(RSP, 0)); | 765 __ movq(RAX, Address(RSP, 0)); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 787 flow_graph().graph_entry()->GetCatchEntry(try_index); | 788 flow_graph().graph_entry()->GetCatchEntry(try_index); |
| 788 const GrowableArray<Definition*>* idefs = catch_block->initial_definitions(); | 789 const GrowableArray<Definition*>* idefs = catch_block->initial_definitions(); |
| 789 // Parameters. | 790 // Parameters. |
| 790 intptr_t i = 0; | 791 intptr_t i = 0; |
| 791 bool push_emitted = false; | 792 bool push_emitted = false; |
| 792 const intptr_t num_non_copied_params = flow_graph().num_non_copied_params(); | 793 const intptr_t num_non_copied_params = flow_graph().num_non_copied_params(); |
| 793 const intptr_t param_base = kParamEndSlotFromFp + num_non_copied_params; | 794 const intptr_t param_base = kParamEndSlotFromFp + num_non_copied_params; |
| 794 for (; i < num_non_copied_params; ++i) { | 795 for (; i < num_non_copied_params; ++i) { |
| 795 if ((*idefs)[i]->IsConstant()) continue; // Common constants | 796 if ((*idefs)[i]->IsConstant()) continue; // Common constants |
| 796 Location loc = env->LocationAt(i); | 797 Location loc = env->LocationAt(i); |
| 797 Address dest(RBP, (param_base - i) * kWordSize); | 798 EmitTrySyncMove((param_base - i) * kWordSize, loc, &push_emitted); |
| 798 EmitTrySyncMove(dest, loc, &push_emitted); | |
| 799 } | 799 } |
| 800 | 800 |
| 801 // Process locals. Skip exception_var and stacktrace_var. | 801 // Process locals. Skip exception_var and stacktrace_var. |
| 802 CatchEntryInstr* catch_entry = catch_block->next()->AsCatchEntry(); | 802 CatchEntryInstr* catch_entry = catch_block->next()->AsCatchEntry(); |
| 803 intptr_t local_base = kFirstLocalSlotFromFp + num_non_copied_params; | 803 intptr_t local_base = kFirstLocalSlotFromFp + num_non_copied_params; |
| 804 intptr_t ex_idx = local_base - catch_entry->exception_var().index(); | 804 intptr_t ex_idx = local_base - catch_entry->exception_var().index(); |
| 805 intptr_t st_idx = local_base - catch_entry->stacktrace_var().index(); | 805 intptr_t st_idx = local_base - catch_entry->stacktrace_var().index(); |
| 806 for (; i < flow_graph().variable_count(); ++i) { | 806 for (; i < flow_graph().variable_count(); ++i) { |
| 807 if (i == ex_idx || i == st_idx) continue; | 807 if (i == ex_idx || i == st_idx) continue; |
| 808 if ((*idefs)[i]->IsConstant()) continue; | 808 if ((*idefs)[i]->IsConstant()) continue; |
| 809 Location loc = env->LocationAt(i); | 809 Location loc = env->LocationAt(i); |
| 810 Address dest(RBP, (local_base - i) * kWordSize); | 810 EmitTrySyncMove((local_base - i) * kWordSize, loc, &push_emitted); |
| 811 EmitTrySyncMove(dest, loc, &push_emitted); | |
| 812 // Update safepoint bitmap to indicate that the target location | 811 // Update safepoint bitmap to indicate that the target location |
| 813 // now contains a pointer. | 812 // now contains a pointer. |
| 814 instr->locs()->stack_bitmap()->Set(i - num_non_copied_params, true); | 813 instr->locs()->stack_bitmap()->Set(i - num_non_copied_params, true); |
| 815 } | 814 } |
| 816 if (push_emitted) { | 815 if (push_emitted) { |
| 817 __ popq(RAX); | 816 __ popq(RAX); |
| 818 } | 817 } |
| 819 } | 818 } |
| 820 | 819 |
| 821 | 820 |
| (...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1873 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { | 1872 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { |
| 1874 __ Exchange(reg, mem); | 1873 __ Exchange(reg, mem); |
| 1875 } | 1874 } |
| 1876 | 1875 |
| 1877 | 1876 |
| 1878 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1877 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1879 __ Exchange(mem1, mem2); | 1878 __ Exchange(mem1, mem2); |
| 1880 } | 1879 } |
| 1881 | 1880 |
| 1882 | 1881 |
| 1882 void ParallelMoveResolver::Exchange(Register reg, intptr_t stack_offset) { |
| 1883 UNREACHABLE(); |
| 1884 } |
| 1885 |
| 1886 |
| 1887 void ParallelMoveResolver::Exchange(intptr_t stack_offset1, |
| 1888 intptr_t stack_offset2) { |
| 1889 UNREACHABLE(); |
| 1890 } |
| 1891 |
| 1892 |
| 1883 void ParallelMoveResolver::SpillScratch(Register reg) { | 1893 void ParallelMoveResolver::SpillScratch(Register reg) { |
| 1884 __ pushq(reg); | 1894 __ pushq(reg); |
| 1885 } | 1895 } |
| 1886 | 1896 |
| 1887 | 1897 |
| 1888 void ParallelMoveResolver::RestoreScratch(Register reg) { | 1898 void ParallelMoveResolver::RestoreScratch(Register reg) { |
| 1889 __ popq(reg); | 1899 __ popq(reg); |
| 1890 } | 1900 } |
| 1891 | 1901 |
| 1892 | 1902 |
| 1893 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) { | 1903 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) { |
| 1894 __ subq(RSP, Immediate(kFpuRegisterSize)); | 1904 __ subq(RSP, Immediate(kFpuRegisterSize)); |
| 1895 __ movups(Address(RSP, 0), reg); | 1905 __ movups(Address(RSP, 0), reg); |
| 1896 } | 1906 } |
| 1897 | 1907 |
| 1898 | 1908 |
| 1899 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { | 1909 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { |
| 1900 __ movups(reg, Address(RSP, 0)); | 1910 __ movups(reg, Address(RSP, 0)); |
| 1901 __ addq(RSP, Immediate(kFpuRegisterSize)); | 1911 __ addq(RSP, Immediate(kFpuRegisterSize)); |
| 1902 } | 1912 } |
| 1903 | 1913 |
| 1904 | 1914 |
| 1905 #undef __ | 1915 #undef __ |
| 1906 | 1916 |
| 1907 } // namespace dart | 1917 } // namespace dart |
| 1908 | 1918 |
| 1909 #endif // defined TARGET_ARCH_X64 | 1919 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |