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

Side by Side Diff: src/compiler/arm64/code-generator-arm64.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 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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698