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

Side by Side Diff: src/compiler/x64/code-generator-x64.cc

Issue 2026313002: Emit unwinding information for TurboFan code. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@eh-frame
Patch Set: Clarify assumptions on frame ction/dtion routines in arm/arm64. Created 4 years, 5 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
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698