OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/arm64/macro-assembler-arm64.h" | 8 #include "src/arm64/macro-assembler-arm64.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/compiler/code-generator-impl.h" | 10 #include "src/compiler/code-generator-impl.h" |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 | 296 |
297 private: | 297 private: |
298 Register const result_; | 298 Register const result_; |
299 }; | 299 }; |
300 | 300 |
301 | 301 |
302 class OutOfLineRecordWrite final : public OutOfLineCode { | 302 class OutOfLineRecordWrite final : public OutOfLineCode { |
303 public: | 303 public: |
304 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Operand index, | 304 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Operand index, |
305 Register value, Register scratch0, Register scratch1, | 305 Register value, Register scratch0, Register scratch1, |
306 RecordWriteMode mode) | 306 RecordWriteMode mode, |
| 307 UnwindingInfoWriter* unwinding_info_writer) |
307 : OutOfLineCode(gen), | 308 : OutOfLineCode(gen), |
308 object_(object), | 309 object_(object), |
309 index_(index), | 310 index_(index), |
310 value_(value), | 311 value_(value), |
311 scratch0_(scratch0), | 312 scratch0_(scratch0), |
312 scratch1_(scratch1), | 313 scratch1_(scratch1), |
313 mode_(mode), | 314 mode_(mode), |
314 must_save_lr_(!gen->frame_access_state()->has_frame()) {} | 315 must_save_lr_(!gen->frame_access_state()->has_frame()), |
| 316 unwinding_info_writer_(unwinding_info_writer) {} |
315 | 317 |
316 void Generate() final { | 318 void Generate() final { |
317 if (mode_ > RecordWriteMode::kValueIsPointer) { | 319 if (mode_ > RecordWriteMode::kValueIsPointer) { |
318 __ JumpIfSmi(value_, exit()); | 320 __ JumpIfSmi(value_, exit()); |
319 } | 321 } |
320 __ CheckPageFlagClear(value_, scratch0_, | 322 __ CheckPageFlagClear(value_, scratch0_, |
321 MemoryChunk::kPointersToHereAreInterestingMask, | 323 MemoryChunk::kPointersToHereAreInterestingMask, |
322 exit()); | 324 exit()); |
323 RememberedSetAction const remembered_set_action = | 325 RememberedSetAction const remembered_set_action = |
324 mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET | 326 mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET |
325 : OMIT_REMEMBERED_SET; | 327 : OMIT_REMEMBERED_SET; |
326 SaveFPRegsMode const save_fp_mode = | 328 SaveFPRegsMode const save_fp_mode = |
327 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; | 329 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; |
328 if (must_save_lr_) { | 330 if (must_save_lr_) { |
329 // We need to save and restore lr if the frame was elided. | 331 // We need to save and restore lr if the frame was elided. |
330 __ Push(lr); | 332 __ Push(lr); |
| 333 if (unwinding_info_writer_) { |
| 334 unwinding_info_writer_->MarkLinkRegisterOnTopOfStack(__ pc_offset()); |
| 335 } |
331 } | 336 } |
332 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, | 337 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, |
333 remembered_set_action, save_fp_mode); | 338 remembered_set_action, save_fp_mode); |
334 __ Add(scratch1_, object_, index_); | 339 __ Add(scratch1_, object_, index_); |
335 __ CallStub(&stub); | 340 __ CallStub(&stub); |
336 if (must_save_lr_) { | 341 if (must_save_lr_) { |
337 __ Pop(lr); | 342 __ Pop(lr); |
| 343 if (unwinding_info_writer_) { |
| 344 unwinding_info_writer_->MarkPopLinkRegisterFromTopOfStack( |
| 345 __ pc_offset()); |
| 346 } |
338 } | 347 } |
339 } | 348 } |
340 | 349 |
341 private: | 350 private: |
342 Register const object_; | 351 Register const object_; |
343 Operand const index_; | 352 Operand const index_; |
344 Register const value_; | 353 Register const value_; |
345 Register const scratch0_; | 354 Register const scratch0_; |
346 Register const scratch1_; | 355 Register const scratch1_; |
347 RecordWriteMode const mode_; | 356 RecordWriteMode const mode_; |
348 bool must_save_lr_; | 357 bool must_save_lr_; |
| 358 UnwindingInfoWriter* const unwinding_info_writer_; |
349 }; | 359 }; |
350 | 360 |
351 | 361 |
352 Condition FlagsConditionToCondition(FlagsCondition condition) { | 362 Condition FlagsConditionToCondition(FlagsCondition condition) { |
353 switch (condition) { | 363 switch (condition) { |
354 case kEqual: | 364 case kEqual: |
355 return eq; | 365 return eq; |
356 case kNotEqual: | 366 case kNotEqual: |
357 return ne; | 367 return ne; |
358 case kSignedLessThan: | 368 case kSignedLessThan: |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 } while (0) | 542 } while (0) |
533 | 543 |
534 void CodeGenerator::AssembleDeconstructFrame() { | 544 void CodeGenerator::AssembleDeconstructFrame() { |
535 const CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 545 const CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
536 if (descriptor->IsCFunctionCall() || descriptor->UseNativeStack()) { | 546 if (descriptor->IsCFunctionCall() || descriptor->UseNativeStack()) { |
537 __ Mov(csp, fp); | 547 __ Mov(csp, fp); |
538 } else { | 548 } else { |
539 __ Mov(jssp, fp); | 549 __ Mov(jssp, fp); |
540 } | 550 } |
541 __ Pop(fp, lr); | 551 __ Pop(fp, lr); |
| 552 |
| 553 if (!unwinding_info_writer_.is_empty()) { |
| 554 unwinding_info_writer_->MarkFrameDeconstructed(__ pc_offset()); |
| 555 } |
542 } | 556 } |
543 | 557 |
544 void CodeGenerator::AssemblePrepareTailCall() { | 558 void CodeGenerator::AssemblePrepareTailCall() { |
545 if (frame_access_state()->has_frame()) { | 559 if (frame_access_state()->has_frame()) { |
546 __ Ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); | 560 __ Ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); |
547 __ Ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 561 __ Ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
548 } | 562 } |
549 frame_access_state()->SetFrameAccessToSP(); | 563 frame_access_state()->SetFrameAccessToSP(); |
550 } | 564 } |
551 | 565 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 i.TempRegister(2)); | 661 i.TempRegister(2)); |
648 } | 662 } |
649 if (instr->InputAt(0)->IsImmediate()) { | 663 if (instr->InputAt(0)->IsImmediate()) { |
650 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), | 664 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), |
651 RelocInfo::CODE_TARGET); | 665 RelocInfo::CODE_TARGET); |
652 } else { | 666 } else { |
653 Register target = i.InputRegister(0); | 667 Register target = i.InputRegister(0); |
654 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); | 668 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); |
655 __ Jump(target); | 669 __ Jump(target); |
656 } | 670 } |
| 671 if (!unwinding_info_writer_.is_empty()) { |
| 672 unwinding_info_writer_->MarkBlockWillExit(); |
| 673 } |
657 frame_access_state()->ClearSPDelta(); | 674 frame_access_state()->ClearSPDelta(); |
658 frame_access_state()->SetFrameAccessToDefault(); | 675 frame_access_state()->SetFrameAccessToDefault(); |
659 break; | 676 break; |
660 } | 677 } |
661 case kArchTailCallAddress: { | 678 case kArchTailCallAddress: { |
662 CHECK(!instr->InputAt(0)->IsImmediate()); | 679 CHECK(!instr->InputAt(0)->IsImmediate()); |
663 __ Jump(i.InputRegister(0)); | 680 __ Jump(i.InputRegister(0)); |
| 681 if (!unwinding_info_writer_.is_empty()) { |
| 682 unwinding_info_writer_->MarkBlockWillExit(); |
| 683 } |
664 frame_access_state()->ClearSPDelta(); | 684 frame_access_state()->ClearSPDelta(); |
665 frame_access_state()->SetFrameAccessToDefault(); | 685 frame_access_state()->SetFrameAccessToDefault(); |
666 break; | 686 break; |
667 } | 687 } |
668 case kArchCallJSFunction: { | 688 case kArchCallJSFunction: { |
669 EnsureSpaceForLazyDeopt(); | 689 EnsureSpaceForLazyDeopt(); |
670 Register func = i.InputRegister(0); | 690 Register func = i.InputRegister(0); |
671 if (FLAG_debug_code) { | 691 if (FLAG_debug_code) { |
672 // Check the function's context matches the context argument. | 692 // Check the function's context matches the context argument. |
673 UseScratchRegisterScope scope(masm()); | 693 UseScratchRegisterScope scope(masm()); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 Operand index(0); | 818 Operand index(0); |
799 if (addressing_mode == kMode_MRI) { | 819 if (addressing_mode == kMode_MRI) { |
800 index = Operand(i.InputInt64(1)); | 820 index = Operand(i.InputInt64(1)); |
801 } else { | 821 } else { |
802 DCHECK_EQ(addressing_mode, kMode_MRR); | 822 DCHECK_EQ(addressing_mode, kMode_MRR); |
803 index = Operand(i.InputRegister(1)); | 823 index = Operand(i.InputRegister(1)); |
804 } | 824 } |
805 Register value = i.InputRegister(2); | 825 Register value = i.InputRegister(2); |
806 Register scratch0 = i.TempRegister(0); | 826 Register scratch0 = i.TempRegister(0); |
807 Register scratch1 = i.TempRegister(1); | 827 Register scratch1 = i.TempRegister(1); |
808 auto ool = new (zone()) OutOfLineRecordWrite(this, object, index, value, | 828 auto ool = new (zone()) |
809 scratch0, scratch1, mode); | 829 OutOfLineRecordWrite(this, object, index, value, scratch0, scratch1, |
| 830 mode, unwinding_info_writer_.get()); |
810 __ Str(value, MemOperand(object, index)); | 831 __ Str(value, MemOperand(object, index)); |
811 __ CheckPageFlagSet(object, scratch0, | 832 __ CheckPageFlagSet(object, scratch0, |
812 MemoryChunk::kPointersFromHereAreInterestingMask, | 833 MemoryChunk::kPointersFromHereAreInterestingMask, |
813 ool->entry()); | 834 ool->entry()); |
814 __ Bind(ool->exit()); | 835 __ Bind(ool->exit()); |
815 break; | 836 break; |
816 } | 837 } |
817 case kArchStackSlot: { | 838 case kArchStackSlot: { |
818 FrameOffset offset = | 839 FrameOffset offset = |
819 frame_access_state()->GetFrameOffset(i.InputInt32(0)); | 840 frame_access_state()->GetFrameOffset(i.InputInt32(0)); |
(...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1786 } else { | 1807 } else { |
1787 if (descriptor->IsCFunctionCall()) { | 1808 if (descriptor->IsCFunctionCall()) { |
1788 __ Push(lr, fp); | 1809 __ Push(lr, fp); |
1789 __ Mov(fp, masm_.StackPointer()); | 1810 __ Mov(fp, masm_.StackPointer()); |
1790 __ Claim(frame()->GetSpillSlotCount()); | 1811 __ Claim(frame()->GetSpillSlotCount()); |
1791 } else { | 1812 } else { |
1792 __ StubPrologue(info()->GetOutputStackFrameType(), | 1813 __ StubPrologue(info()->GetOutputStackFrameType(), |
1793 frame()->GetTotalFrameSlotCount()); | 1814 frame()->GetTotalFrameSlotCount()); |
1794 } | 1815 } |
1795 } | 1816 } |
| 1817 |
| 1818 if (!unwinding_info_writer_.is_empty() && |
| 1819 !info()->GeneratePreagedPrologue()) { |
| 1820 unwinding_info_writer_->MarkFrameConstructed(__ pc_offset()); |
| 1821 } |
1796 } | 1822 } |
1797 | 1823 |
1798 int shrink_slots = frame()->GetSpillSlotCount(); | 1824 int shrink_slots = frame()->GetSpillSlotCount(); |
1799 | 1825 |
1800 if (info()->is_osr()) { | 1826 if (info()->is_osr()) { |
1801 // TurboFan OSR-compiled functions cannot be entered directly. | 1827 // TurboFan OSR-compiled functions cannot be entered directly. |
1802 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 1828 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
1803 | 1829 |
1804 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 1830 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
1805 // frame is still on the stack. Optimized code uses OSR values directly from | 1831 // frame is still on the stack. Optimized code uses OSR values directly from |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1845 __ PopCPURegList(saves); | 1871 __ PopCPURegList(saves); |
1846 } | 1872 } |
1847 | 1873 |
1848 // Restore fp registers. | 1874 // Restore fp registers. |
1849 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, | 1875 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, |
1850 descriptor->CalleeSavedFPRegisters()); | 1876 descriptor->CalleeSavedFPRegisters()); |
1851 if (saves_fp.Count() != 0) { | 1877 if (saves_fp.Count() != 0) { |
1852 __ PopCPURegList(saves_fp); | 1878 __ PopCPURegList(saves_fp); |
1853 } | 1879 } |
1854 | 1880 |
| 1881 if (!unwinding_info_writer_.is_empty()) { |
| 1882 unwinding_info_writer_->MarkBlockWillExit(); |
| 1883 } |
| 1884 |
1855 int pop_count = static_cast<int>(descriptor->StackParameterCount()); | 1885 int pop_count = static_cast<int>(descriptor->StackParameterCount()); |
1856 if (descriptor->IsCFunctionCall()) { | 1886 if (descriptor->IsCFunctionCall()) { |
1857 AssembleDeconstructFrame(); | 1887 AssembleDeconstructFrame(); |
1858 } else if (frame_access_state()->has_frame()) { | 1888 } else if (frame_access_state()->has_frame()) { |
1859 // Canonicalize JSFunction return sites for now. | 1889 // Canonicalize JSFunction return sites for now. |
1860 if (return_label_.is_bound()) { | 1890 if (return_label_.is_bound()) { |
1861 __ B(&return_label_); | 1891 __ B(&return_label_); |
1862 return; | 1892 return; |
1863 } else { | 1893 } else { |
1864 __ Bind(&return_label_); | 1894 __ Bind(&return_label_); |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2058 padding_size -= kInstructionSize; | 2088 padding_size -= kInstructionSize; |
2059 } | 2089 } |
2060 } | 2090 } |
2061 } | 2091 } |
2062 | 2092 |
2063 #undef __ | 2093 #undef __ |
2064 | 2094 |
2065 } // namespace compiler | 2095 } // namespace compiler |
2066 } // namespace internal | 2096 } // namespace internal |
2067 } // namespace v8 | 2097 } // namespace v8 |
OLD | NEW |