Chromium Code Reviews| 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 |