| 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 |