OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
173 void Generate() final { __ Pcmpeqd(result_, result_); } | 173 void Generate() final { __ Pcmpeqd(result_, result_); } |
174 | 174 |
175 private: | 175 private: |
176 XMMRegister const result_; | 176 XMMRegister const result_; |
177 }; | 177 }; |
178 | 178 |
179 | 179 |
180 class OutOfLineTruncateDoubleToI final : public OutOfLineCode { | 180 class OutOfLineTruncateDoubleToI final : public OutOfLineCode { |
181 public: | 181 public: |
182 OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result, | 182 OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result, |
183 XMMRegister input) | 183 XMMRegister input, |
184 : OutOfLineCode(gen), result_(result), input_(input) {} | 184 UnwindingInfoWriter* unwinding_info_writer) |
185 : OutOfLineCode(gen), | |
186 result_(result), | |
187 input_(input), | |
188 unwinding_info_writer_(unwinding_info_writer) {} | |
185 | 189 |
186 void Generate() final { | 190 void Generate() final { |
187 __ subp(rsp, Immediate(kDoubleSize)); | 191 __ subp(rsp, Immediate(kDoubleSize)); |
192 if (unwinding_info_writer_) { | |
193 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), | |
194 kDoubleSize); | |
195 } | |
188 __ Movsd(MemOperand(rsp, 0), input_); | 196 __ Movsd(MemOperand(rsp, 0), input_); |
189 __ SlowTruncateToI(result_, rsp, 0); | 197 __ SlowTruncateToI(result_, rsp, 0); |
190 __ addp(rsp, Immediate(kDoubleSize)); | 198 __ addp(rsp, Immediate(kDoubleSize)); |
199 if (unwinding_info_writer_) { | |
200 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), | |
201 -kDoubleSize); | |
202 } | |
191 } | 203 } |
192 | 204 |
193 private: | 205 private: |
194 Register const result_; | 206 Register const result_; |
195 XMMRegister const input_; | 207 XMMRegister const input_; |
208 UnwindingInfoWriter* const unwinding_info_writer_; | |
196 }; | 209 }; |
197 | 210 |
198 | 211 |
199 class OutOfLineRecordWrite final : public OutOfLineCode { | 212 class OutOfLineRecordWrite final : public OutOfLineCode { |
200 public: | 213 public: |
201 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Operand operand, | 214 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Operand operand, |
202 Register value, Register scratch0, Register scratch1, | 215 Register value, Register scratch0, Register scratch1, |
203 RecordWriteMode mode) | 216 RecordWriteMode mode) |
204 : OutOfLineCode(gen), | 217 : OutOfLineCode(gen), |
205 object_(object), | 218 object_(object), |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
615 } while (false) | 628 } while (false) |
616 | 629 |
617 #define ASSEMBLE_IEEE754_UNOP(name) \ | 630 #define ASSEMBLE_IEEE754_UNOP(name) \ |
618 do { \ | 631 do { \ |
619 __ PrepareCallCFunction(1); \ | 632 __ PrepareCallCFunction(1); \ |
620 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ | 633 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ |
621 1); \ | 634 1); \ |
622 } while (false) | 635 } while (false) |
623 | 636 |
624 void CodeGenerator::AssembleDeconstructFrame() { | 637 void CodeGenerator::AssembleDeconstructFrame() { |
638 if (!unwinding_info_writer_.is_empty()) { | |
639 unwinding_info_writer_->MarkFrameDeconstructed(__ pc_offset()); | |
640 } | |
625 __ movq(rsp, rbp); | 641 __ movq(rsp, rbp); |
626 __ popq(rbp); | 642 __ popq(rbp); |
627 } | 643 } |
628 | 644 |
629 void CodeGenerator::AssemblePrepareTailCall() { | 645 void CodeGenerator::AssemblePrepareTailCall() { |
630 if (frame_access_state()->has_frame()) { | 646 if (frame_access_state()->has_frame()) { |
631 __ movq(rbp, MemOperand(rbp, 0)); | 647 __ movq(rbp, MemOperand(rbp, 0)); |
632 } | 648 } |
633 frame_access_state()->SetFrameAccessToSP(); | 649 frame_access_state()->SetFrameAccessToSP(); |
634 } | 650 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
749 i.TempRegister(2)); | 765 i.TempRegister(2)); |
750 } | 766 } |
751 if (HasImmediateInput(instr, 0)) { | 767 if (HasImmediateInput(instr, 0)) { |
752 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 768 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
753 __ jmp(code, RelocInfo::CODE_TARGET); | 769 __ jmp(code, RelocInfo::CODE_TARGET); |
754 } else { | 770 } else { |
755 Register reg = i.InputRegister(0); | 771 Register reg = i.InputRegister(0); |
756 __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 772 __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
757 __ jmp(reg); | 773 __ jmp(reg); |
758 } | 774 } |
775 if (!unwinding_info_writer_.is_empty()) { | |
776 unwinding_info_writer_->MarkBlockWillExit(); | |
777 } | |
759 frame_access_state()->ClearSPDelta(); | 778 frame_access_state()->ClearSPDelta(); |
760 frame_access_state()->SetFrameAccessToDefault(); | 779 frame_access_state()->SetFrameAccessToDefault(); |
761 break; | 780 break; |
762 } | 781 } |
763 case kArchTailCallAddress: { | 782 case kArchTailCallAddress: { |
764 CHECK(!HasImmediateInput(instr, 0)); | 783 CHECK(!HasImmediateInput(instr, 0)); |
765 Register reg = i.InputRegister(0); | 784 Register reg = i.InputRegister(0); |
766 __ jmp(reg); | 785 __ jmp(reg); |
786 if (!unwinding_info_writer_.is_empty()) { | |
787 unwinding_info_writer_->MarkBlockWillExit(); | |
788 } | |
767 frame_access_state()->ClearSPDelta(); | 789 frame_access_state()->ClearSPDelta(); |
768 frame_access_state()->SetFrameAccessToDefault(); | 790 frame_access_state()->SetFrameAccessToDefault(); |
769 break; | 791 break; |
770 } | 792 } |
771 case kArchCallJSFunction: { | 793 case kArchCallJSFunction: { |
772 EnsureSpaceForLazyDeopt(); | 794 EnsureSpaceForLazyDeopt(); |
773 Register func = i.InputRegister(0); | 795 Register func = i.InputRegister(0); |
774 if (FLAG_debug_code) { | 796 if (FLAG_debug_code) { |
775 // Check the function's context matches the context argument. | 797 // Check the function's context matches the context argument. |
776 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); | 798 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
865 case kArchParentFramePointer: | 887 case kArchParentFramePointer: |
866 if (frame_access_state()->has_frame()) { | 888 if (frame_access_state()->has_frame()) { |
867 __ movq(i.OutputRegister(), Operand(rbp, 0)); | 889 __ movq(i.OutputRegister(), Operand(rbp, 0)); |
868 } else { | 890 } else { |
869 __ movq(i.OutputRegister(), rbp); | 891 __ movq(i.OutputRegister(), rbp); |
870 } | 892 } |
871 break; | 893 break; |
872 case kArchTruncateDoubleToI: { | 894 case kArchTruncateDoubleToI: { |
873 auto result = i.OutputRegister(); | 895 auto result = i.OutputRegister(); |
874 auto input = i.InputDoubleRegister(0); | 896 auto input = i.InputDoubleRegister(0); |
875 auto ool = new (zone()) OutOfLineTruncateDoubleToI(this, result, input); | 897 auto ool = new (zone()) OutOfLineTruncateDoubleToI( |
898 this, result, input, unwinding_info_writer_.get()); | |
876 // We use Cvttsd2siq instead of Cvttsd2si due to performance reasons. The | 899 // We use Cvttsd2siq instead of Cvttsd2si due to performance reasons. The |
877 // use of Cvttsd2siq requires the movl below to avoid sign extension. | 900 // use of Cvttsd2siq requires the movl below to avoid sign extension. |
878 __ Cvttsd2siq(result, input); | 901 __ Cvttsd2siq(result, input); |
879 __ cmpq(result, Immediate(1)); | 902 __ cmpq(result, Immediate(1)); |
880 __ j(overflow, ool->entry()); | 903 __ j(overflow, ool->entry()); |
881 __ bind(ool->exit()); | 904 __ bind(ool->exit()); |
882 __ movl(result, result); | 905 __ movl(result, result); |
883 break; | 906 break; |
884 } | 907 } |
885 case kArchStoreWithWriteBarrier: { | 908 case kArchStoreWithWriteBarrier: { |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1227 ASSEMBLE_SSE_BINOP(mulsd); | 1250 ASSEMBLE_SSE_BINOP(mulsd); |
1228 break; | 1251 break; |
1229 case kSSEFloat64Div: | 1252 case kSSEFloat64Div: |
1230 ASSEMBLE_SSE_BINOP(divsd); | 1253 ASSEMBLE_SSE_BINOP(divsd); |
1231 // Don't delete this mov. It may improve performance on some CPUs, | 1254 // Don't delete this mov. It may improve performance on some CPUs, |
1232 // when there is a (v)mulsd depending on the result. | 1255 // when there is a (v)mulsd depending on the result. |
1233 __ Movapd(i.OutputDoubleRegister(), i.OutputDoubleRegister()); | 1256 __ Movapd(i.OutputDoubleRegister(), i.OutputDoubleRegister()); |
1234 break; | 1257 break; |
1235 case kSSEFloat64Mod: { | 1258 case kSSEFloat64Mod: { |
1236 __ subq(rsp, Immediate(kDoubleSize)); | 1259 __ subq(rsp, Immediate(kDoubleSize)); |
1260 if (!unwinding_info_writer_.is_empty()) { | |
1261 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), | |
1262 kDoubleSize); | |
1263 } | |
1237 // Move values to st(0) and st(1). | 1264 // Move values to st(0) and st(1). |
1238 __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(1)); | 1265 __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(1)); |
1239 __ fld_d(Operand(rsp, 0)); | 1266 __ fld_d(Operand(rsp, 0)); |
1240 __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0)); | 1267 __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0)); |
1241 __ fld_d(Operand(rsp, 0)); | 1268 __ fld_d(Operand(rsp, 0)); |
1242 // Loop while fprem isn't done. | 1269 // Loop while fprem isn't done. |
1243 Label mod_loop; | 1270 Label mod_loop; |
1244 __ bind(&mod_loop); | 1271 __ bind(&mod_loop); |
1245 // This instructions traps on all kinds inputs, but we are assuming the | 1272 // This instructions traps on all kinds inputs, but we are assuming the |
1246 // floating point control word is set to ignore them all. | 1273 // floating point control word is set to ignore them all. |
1247 __ fprem(); | 1274 __ fprem(); |
1248 // The following 2 instruction implicitly use rax. | 1275 // The following 2 instruction implicitly use rax. |
1249 __ fnstsw_ax(); | 1276 __ fnstsw_ax(); |
1250 if (CpuFeatures::IsSupported(SAHF)) { | 1277 if (CpuFeatures::IsSupported(SAHF)) { |
1251 CpuFeatureScope sahf_scope(masm(), SAHF); | 1278 CpuFeatureScope sahf_scope(masm(), SAHF); |
1252 __ sahf(); | 1279 __ sahf(); |
1253 } else { | 1280 } else { |
1254 __ shrl(rax, Immediate(8)); | 1281 __ shrl(rax, Immediate(8)); |
1255 __ andl(rax, Immediate(0xFF)); | 1282 __ andl(rax, Immediate(0xFF)); |
1256 __ pushq(rax); | 1283 __ pushq(rax); |
1284 if (!unwinding_info_writer_.is_empty()) { | |
1285 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), | |
1286 kInt64Size); | |
1287 } | |
1257 __ popfq(); | 1288 __ popfq(); |
1289 if (!unwinding_info_writer_.is_empty()) { | |
1290 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), | |
1291 -kInt64Size); | |
1292 } | |
1258 } | 1293 } |
1259 __ j(parity_even, &mod_loop); | 1294 __ j(parity_even, &mod_loop); |
1260 // Move output to stack and clean up. | 1295 // Move output to stack and clean up. |
1261 __ fstp(1); | 1296 __ fstp(1); |
1262 __ fstp_d(Operand(rsp, 0)); | 1297 __ fstp_d(Operand(rsp, 0)); |
1263 __ Movsd(i.OutputDoubleRegister(), Operand(rsp, 0)); | 1298 __ Movsd(i.OutputDoubleRegister(), Operand(rsp, 0)); |
1264 __ addq(rsp, Immediate(kDoubleSize)); | 1299 __ addq(rsp, Immediate(kDoubleSize)); |
1300 if (!unwinding_info_writer_.is_empty()) { | |
1301 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), | |
1302 -kDoubleSize); | |
1303 } | |
1265 break; | 1304 break; |
1266 } | 1305 } |
1267 case kSSEFloat64Max: | 1306 case kSSEFloat64Max: |
1268 ASSEMBLE_SSE_BINOP(maxsd); | 1307 ASSEMBLE_SSE_BINOP(maxsd); |
1269 break; | 1308 break; |
1270 case kSSEFloat64Min: | 1309 case kSSEFloat64Min: |
1271 ASSEMBLE_SSE_BINOP(minsd); | 1310 ASSEMBLE_SSE_BINOP(minsd); |
1272 break; | 1311 break; |
1273 case kSSEFloat64Abs: { | 1312 case kSSEFloat64Abs: { |
1274 // TODO(bmeurer): Use RIP relative 128-bit constants. | 1313 // TODO(bmeurer): Use RIP relative 128-bit constants. |
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1836 case kX64Dec32: | 1875 case kX64Dec32: |
1837 __ decl(i.OutputRegister()); | 1876 __ decl(i.OutputRegister()); |
1838 break; | 1877 break; |
1839 case kX64Inc32: | 1878 case kX64Inc32: |
1840 __ incl(i.OutputRegister()); | 1879 __ incl(i.OutputRegister()); |
1841 break; | 1880 break; |
1842 case kX64Push: | 1881 case kX64Push: |
1843 if (HasImmediateInput(instr, 0)) { | 1882 if (HasImmediateInput(instr, 0)) { |
1844 __ pushq(i.InputImmediate(0)); | 1883 __ pushq(i.InputImmediate(0)); |
1845 frame_access_state()->IncreaseSPDelta(1); | 1884 frame_access_state()->IncreaseSPDelta(1); |
1885 if (!unwinding_info_writer_.is_empty()) { | |
1886 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), | |
1887 kInt64Size); | |
Jarin
2016/07/06 07:09:42
kInt64Size ==> kPointerSize (here and below)
Stefano Sanfilippo
2016/07/06 13:25:10
Done.
| |
1888 } | |
1846 } else { | 1889 } else { |
1847 if (instr->InputAt(0)->IsRegister()) { | 1890 if (instr->InputAt(0)->IsRegister()) { |
1848 __ pushq(i.InputRegister(0)); | 1891 __ pushq(i.InputRegister(0)); |
1849 frame_access_state()->IncreaseSPDelta(1); | 1892 frame_access_state()->IncreaseSPDelta(1); |
1893 if (!unwinding_info_writer_.is_empty()) { | |
1894 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt( | |
1895 __ pc_offset(), kInt64Size); | |
1896 } | |
1850 } else if (instr->InputAt(0)->IsFPRegister()) { | 1897 } else if (instr->InputAt(0)->IsFPRegister()) { |
1851 // TODO(titzer): use another machine instruction? | 1898 // TODO(titzer): use another machine instruction? |
1852 __ subq(rsp, Immediate(kDoubleSize)); | 1899 __ subq(rsp, Immediate(kDoubleSize)); |
1853 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); | 1900 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); |
1901 if (!unwinding_info_writer_.is_empty()) { | |
1902 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt( | |
1903 __ pc_offset(), kDoubleSize); | |
1904 } | |
1854 __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0)); | 1905 __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0)); |
1855 } else { | 1906 } else { |
1856 __ pushq(i.InputOperand(0)); | 1907 __ pushq(i.InputOperand(0)); |
1857 frame_access_state()->IncreaseSPDelta(1); | 1908 frame_access_state()->IncreaseSPDelta(1); |
1909 if (!unwinding_info_writer_.is_empty()) { | |
1910 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt( | |
1911 __ pc_offset(), kInt64Size); | |
1912 } | |
1858 } | 1913 } |
1859 } | 1914 } |
1860 break; | 1915 break; |
1861 case kX64Poke: { | 1916 case kX64Poke: { |
1862 int const slot = MiscField::decode(instr->opcode()); | 1917 int const slot = MiscField::decode(instr->opcode()); |
1863 if (HasImmediateInput(instr, 0)) { | 1918 if (HasImmediateInput(instr, 0)) { |
1864 __ movq(Operand(rsp, slot * kPointerSize), i.InputImmediate(0)); | 1919 __ movq(Operand(rsp, slot * kPointerSize), i.InputImmediate(0)); |
1865 } else { | 1920 } else { |
1866 __ movq(Operand(rsp, slot * kPointerSize), i.InputRegister(0)); | 1921 __ movq(Operand(rsp, slot * kPointerSize), i.InputRegister(0)); |
1867 } | 1922 } |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2140 ++count; | 2195 ++count; |
2141 } | 2196 } |
2142 } | 2197 } |
2143 frame->AllocateSavedCalleeRegisterSlots(count); | 2198 frame->AllocateSavedCalleeRegisterSlots(count); |
2144 } | 2199 } |
2145 } | 2200 } |
2146 | 2201 |
2147 void CodeGenerator::AssembleConstructFrame() { | 2202 void CodeGenerator::AssembleConstructFrame() { |
2148 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 2203 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
2149 if (frame_access_state()->has_frame()) { | 2204 if (frame_access_state()->has_frame()) { |
2205 int pc_base = __ pc_offset(); | |
2206 | |
2150 if (descriptor->IsCFunctionCall()) { | 2207 if (descriptor->IsCFunctionCall()) { |
2151 __ pushq(rbp); | 2208 __ pushq(rbp); |
2152 __ movq(rbp, rsp); | 2209 __ movq(rbp, rsp); |
2153 } else if (descriptor->IsJSFunctionCall()) { | 2210 } else if (descriptor->IsJSFunctionCall()) { |
2154 __ Prologue(this->info()->GeneratePreagedPrologue()); | 2211 __ Prologue(this->info()->GeneratePreagedPrologue()); |
2155 } else { | 2212 } else { |
2156 __ StubPrologue(info()->GetOutputStackFrameType()); | 2213 __ StubPrologue(info()->GetOutputStackFrameType()); |
2157 } | 2214 } |
2215 | |
2216 if (!unwinding_info_writer_.is_empty() && | |
2217 (!descriptor->IsJSFunctionCall() || | |
2218 !info()->GeneratePreagedPrologue())) { | |
2219 unwinding_info_writer_->MarkFrameConstructed(pc_base); | |
2220 } | |
2158 } | 2221 } |
2159 int shrink_slots = frame()->GetSpillSlotCount(); | 2222 int shrink_slots = frame()->GetSpillSlotCount(); |
2160 | 2223 |
2161 if (info()->is_osr()) { | 2224 if (info()->is_osr()) { |
2162 // TurboFan OSR-compiled functions cannot be entered directly. | 2225 // TurboFan OSR-compiled functions cannot be entered directly. |
2163 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 2226 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
2164 | 2227 |
2165 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 2228 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
2166 // frame is still on the stack. Optimized code uses OSR values directly from | 2229 // frame is still on the stack. Optimized code uses OSR values directly from |
2167 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 2230 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2221 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | 2284 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { |
2222 if (!((1 << i) & saves_fp)) continue; | 2285 if (!((1 << i) & saves_fp)) continue; |
2223 __ movdqu(XMMRegister::from_code(i), | 2286 __ movdqu(XMMRegister::from_code(i), |
2224 Operand(rsp, kQuadWordSize * slot_idx)); | 2287 Operand(rsp, kQuadWordSize * slot_idx)); |
2225 slot_idx++; | 2288 slot_idx++; |
2226 } | 2289 } |
2227 // Adjust the stack pointer. | 2290 // Adjust the stack pointer. |
2228 __ addp(rsp, Immediate(stack_size)); | 2291 __ addp(rsp, Immediate(stack_size)); |
2229 } | 2292 } |
2230 | 2293 |
2294 if (!unwinding_info_writer_.is_empty()) { | |
2295 unwinding_info_writer_->MarkBlockWillExit(); | |
2296 } | |
2297 | |
2231 if (descriptor->IsCFunctionCall()) { | 2298 if (descriptor->IsCFunctionCall()) { |
2232 AssembleDeconstructFrame(); | 2299 AssembleDeconstructFrame(); |
2233 } else if (frame_access_state()->has_frame()) { | 2300 } else if (frame_access_state()->has_frame()) { |
2234 // Canonicalize JSFunction return sites for now. | 2301 // Canonicalize JSFunction return sites for now. |
2235 if (return_label_.is_bound()) { | 2302 if (return_label_.is_bound()) { |
2236 __ jmp(&return_label_); | 2303 __ jmp(&return_label_); |
2237 return; | 2304 return; |
2238 } else { | 2305 } else { |
2239 __ bind(&return_label_); | 2306 __ bind(&return_label_); |
2240 AssembleDeconstructFrame(); | 2307 AssembleDeconstructFrame(); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2393 // Register-register. | 2460 // Register-register. |
2394 Register src = g.ToRegister(source); | 2461 Register src = g.ToRegister(source); |
2395 Register dst = g.ToRegister(destination); | 2462 Register dst = g.ToRegister(destination); |
2396 __ movq(kScratchRegister, src); | 2463 __ movq(kScratchRegister, src); |
2397 __ movq(src, dst); | 2464 __ movq(src, dst); |
2398 __ movq(dst, kScratchRegister); | 2465 __ movq(dst, kScratchRegister); |
2399 } else if (source->IsRegister() && destination->IsStackSlot()) { | 2466 } else if (source->IsRegister() && destination->IsStackSlot()) { |
2400 Register src = g.ToRegister(source); | 2467 Register src = g.ToRegister(source); |
2401 __ pushq(src); | 2468 __ pushq(src); |
2402 frame_access_state()->IncreaseSPDelta(1); | 2469 frame_access_state()->IncreaseSPDelta(1); |
2470 if (!unwinding_info_writer_.is_empty()) { | |
2471 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), | |
2472 kInt64Size); | |
2473 } | |
2403 Operand dst = g.ToOperand(destination); | 2474 Operand dst = g.ToOperand(destination); |
2404 __ movq(src, dst); | 2475 __ movq(src, dst); |
2405 frame_access_state()->IncreaseSPDelta(-1); | 2476 frame_access_state()->IncreaseSPDelta(-1); |
2406 dst = g.ToOperand(destination); | 2477 dst = g.ToOperand(destination); |
2407 __ popq(dst); | 2478 __ popq(dst); |
2479 if (!unwinding_info_writer_.is_empty()) { | |
2480 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), | |
2481 -kInt64Size); | |
2482 } | |
2408 } else if ((source->IsStackSlot() && destination->IsStackSlot()) || | 2483 } else if ((source->IsStackSlot() && destination->IsStackSlot()) || |
2409 (source->IsFPStackSlot() && destination->IsFPStackSlot())) { | 2484 (source->IsFPStackSlot() && destination->IsFPStackSlot())) { |
2410 // Memory-memory. | 2485 // Memory-memory. |
2411 Register tmp = kScratchRegister; | 2486 Register tmp = kScratchRegister; |
2412 Operand src = g.ToOperand(source); | 2487 Operand src = g.ToOperand(source); |
2413 Operand dst = g.ToOperand(destination); | 2488 Operand dst = g.ToOperand(destination); |
2414 __ movq(tmp, dst); | 2489 __ movq(tmp, dst); |
2415 __ pushq(src); | 2490 __ pushq(src); |
2491 if (!unwinding_info_writer_.is_empty()) { | |
2492 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), | |
2493 kInt64Size); | |
2494 } | |
2416 frame_access_state()->IncreaseSPDelta(1); | 2495 frame_access_state()->IncreaseSPDelta(1); |
2417 src = g.ToOperand(source); | 2496 src = g.ToOperand(source); |
2418 __ movq(src, tmp); | 2497 __ movq(src, tmp); |
2419 frame_access_state()->IncreaseSPDelta(-1); | 2498 frame_access_state()->IncreaseSPDelta(-1); |
2420 dst = g.ToOperand(destination); | 2499 dst = g.ToOperand(destination); |
2421 __ popq(dst); | 2500 __ popq(dst); |
2501 if (!unwinding_info_writer_.is_empty()) { | |
2502 unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), | |
2503 -kInt64Size); | |
2504 } | |
2422 } else if (source->IsFPRegister() && destination->IsFPRegister()) { | 2505 } else if (source->IsFPRegister() && destination->IsFPRegister()) { |
2423 // XMM register-register swap. | 2506 // XMM register-register swap. |
2424 XMMRegister src = g.ToDoubleRegister(source); | 2507 XMMRegister src = g.ToDoubleRegister(source); |
2425 XMMRegister dst = g.ToDoubleRegister(destination); | 2508 XMMRegister dst = g.ToDoubleRegister(destination); |
2426 __ Movapd(kScratchDoubleReg, src); | 2509 __ Movapd(kScratchDoubleReg, src); |
2427 __ Movapd(src, dst); | 2510 __ Movapd(src, dst); |
2428 __ Movapd(dst, kScratchDoubleReg); | 2511 __ Movapd(dst, kScratchDoubleReg); |
2429 } else if (source->IsFPRegister() && destination->IsFPStackSlot()) { | 2512 } else if (source->IsFPRegister() && destination->IsFPStackSlot()) { |
2430 // XMM register-memory swap. | 2513 // XMM register-memory swap. |
2431 XMMRegister src = g.ToDoubleRegister(source); | 2514 XMMRegister src = g.ToDoubleRegister(source); |
(...skipping 16 matching lines...) Expand all Loading... | |
2448 | 2531 |
2449 | 2532 |
2450 void CodeGenerator::EnsureSpaceForLazyDeopt() { | 2533 void CodeGenerator::EnsureSpaceForLazyDeopt() { |
2451 if (!info()->ShouldEnsureSpaceForLazyDeopt()) { | 2534 if (!info()->ShouldEnsureSpaceForLazyDeopt()) { |
2452 return; | 2535 return; |
2453 } | 2536 } |
2454 | 2537 |
2455 int space_needed = Deoptimizer::patch_size(); | 2538 int space_needed = Deoptimizer::patch_size(); |
2456 // Ensure that we have enough space after the previous lazy-bailout | 2539 // Ensure that we have enough space after the previous lazy-bailout |
2457 // instruction for patching the code here. | 2540 // instruction for patching the code here. |
2458 int current_pc = masm()->pc_offset(); | 2541 int current_pc = __ pc_offset(); |
2459 if (current_pc < last_lazy_deopt_pc_ + space_needed) { | 2542 if (current_pc < last_lazy_deopt_pc_ + space_needed) { |
2460 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2543 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
2461 __ Nop(padding_size); | 2544 __ Nop(padding_size); |
2462 } | 2545 } |
2463 } | 2546 } |
2464 | 2547 |
2465 #undef __ | 2548 #undef __ |
2466 | 2549 |
2467 } // namespace compiler | 2550 } // namespace compiler |
2468 } // namespace internal | 2551 } // namespace internal |
2469 } // namespace v8 | 2552 } // namespace v8 |
OLD | NEW |