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

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

Issue 1775323002: [turbofan] Frame elision for code stubs (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 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/ast/scopes.h" 5 #include "src/ast/scopes.h"
6 #include "src/compiler/code-generator.h" 6 #include "src/compiler/code-generator.h"
7 #include "src/compiler/code-generator-impl.h" 7 #include "src/compiler/code-generator-impl.h"
8 #include "src/compiler/gap-resolver.h" 8 #include "src/compiler/gap-resolver.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/osr.h" 10 #include "src/compiler/osr.h"
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 public: 217 public:
218 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index, 218 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index,
219 Register value, Register scratch0, Register scratch1, 219 Register value, Register scratch0, Register scratch1,
220 RecordWriteMode mode) 220 RecordWriteMode mode)
221 : OutOfLineCode(gen), 221 : OutOfLineCode(gen),
222 object_(object), 222 object_(object),
223 index_(index), 223 index_(index),
224 value_(value), 224 value_(value),
225 scratch0_(scratch0), 225 scratch0_(scratch0),
226 scratch1_(scratch1), 226 scratch1_(scratch1),
227 mode_(mode) {} 227 mode_(mode),
228 must_save_lr_(gen->frame_access_state()->has_frame()) {}
228 229
229 void Generate() final { 230 void Generate() final {
230 if (mode_ > RecordWriteMode::kValueIsPointer) { 231 if (mode_ > RecordWriteMode::kValueIsPointer) {
231 __ JumpIfSmi(value_, exit()); 232 __ JumpIfSmi(value_, exit());
232 } 233 }
233 __ CheckPageFlag(value_, scratch0_, 234 __ CheckPageFlag(value_, scratch0_,
234 MemoryChunk::kPointersToHereAreInterestingMask, eq, 235 MemoryChunk::kPointersToHereAreInterestingMask, eq,
235 exit()); 236 exit());
236 RememberedSetAction const remembered_set_action = 237 RememberedSetAction const remembered_set_action =
237 mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET 238 mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET
238 : OMIT_REMEMBERED_SET; 239 : OMIT_REMEMBERED_SET;
239 SaveFPRegsMode const save_fp_mode = 240 SaveFPRegsMode const save_fp_mode =
240 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; 241 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
241 if (!frame()->needs_frame()) { 242 if (must_save_lr_) {
242 // We need to save and restore ra if the frame was elided. 243 // We need to save and restore ra if the frame was elided.
243 __ Push(ra); 244 __ Push(ra);
244 } 245 }
245 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, 246 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
246 remembered_set_action, save_fp_mode); 247 remembered_set_action, save_fp_mode);
247 __ Daddu(scratch1_, object_, index_); 248 __ Daddu(scratch1_, object_, index_);
248 __ CallStub(&stub); 249 __ CallStub(&stub);
249 if (!frame()->needs_frame()) { 250 if (must_save_lr_) {
250 __ Pop(ra); 251 __ Pop(ra);
251 } 252 }
252 } 253 }
253 254
254 private: 255 private:
255 Register const object_; 256 Register const object_;
256 Register const index_; 257 Register const index_;
257 Register const value_; 258 Register const value_;
258 Register const scratch0_; 259 Register const scratch0_;
259 Register const scratch1_; 260 Register const scratch1_;
260 RecordWriteMode const mode_; 261 RecordWriteMode const mode_;
262 bool must_save_lr_;
261 }; 263 };
262 264
263 265
264 Condition FlagsConditionToConditionCmp(FlagsCondition condition) { 266 Condition FlagsConditionToConditionCmp(FlagsCondition condition) {
265 switch (condition) { 267 switch (condition) {
266 case kEqual: 268 case kEqual:
267 return eq; 269 return eq;
268 case kNotEqual: 270 case kNotEqual:
269 return ne; 271 return ne;
270 case kSignedLessThan: 272 case kSignedLessThan:
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 Operand(kFloat32ExponentBias + kFloat32MantissaBits)); \ 477 Operand(kFloat32ExponentBias + kFloat32MantissaBits)); \
476 __ mov_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ 478 __ mov_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
477 __ mode##_w_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ 479 __ mode##_w_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
478 __ mfc1(at, i.OutputDoubleRegister()); \ 480 __ mfc1(at, i.OutputDoubleRegister()); \
479 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ 481 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \
480 __ cvt_s_w(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ 482 __ cvt_s_w(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \
481 __ bind(ool->exit()); \ 483 __ bind(ool->exit()); \
482 __ bind(&done); \ 484 __ bind(&done); \
483 } 485 }
484 486
487 void CodeGenerator::AssembleDeconstructFrame() {
488 __ mov(sp, fp);
489 __ Pop(ra, fp);
490 }
491
492 void CodeGenerator::SetupStackPointer() {}
493
485 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { 494 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
486 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); 495 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
487 if (sp_slot_delta > 0) { 496 if (sp_slot_delta > 0) {
488 __ daddiu(sp, sp, sp_slot_delta * kPointerSize); 497 __ daddiu(sp, sp, sp_slot_delta * kPointerSize);
489 } 498 }
490 frame_access_state()->SetFrameAccessToDefault(); 499 frame_access_state()->SetFrameAccessToDefault();
491 } 500 }
492 501
493 502
494 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { 503 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
495 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); 504 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
496 if (sp_slot_delta < 0) { 505 if (sp_slot_delta < 0) {
497 __ Dsubu(sp, sp, Operand(-sp_slot_delta * kPointerSize)); 506 __ Dsubu(sp, sp, Operand(-sp_slot_delta * kPointerSize));
498 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); 507 frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
499 } 508 }
500 if (frame()->needs_frame()) { 509 if (frame_access_state()->has_frame()) {
501 __ ld(ra, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); 510 __ ld(ra, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
502 __ ld(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 511 __ ld(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
503 } 512 }
504 frame_access_state()->SetFrameAccessToSP(); 513 frame_access_state()->SetFrameAccessToSP();
505 } 514 }
506 515
507 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, 516 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
508 Register scratch1, 517 Register scratch1,
509 Register scratch2, 518 Register scratch2,
510 Register scratch3) { 519 Register scratch3) {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 case kArchRet: 657 case kArchRet:
649 AssembleReturn(); 658 AssembleReturn();
650 break; 659 break;
651 case kArchStackPointer: 660 case kArchStackPointer:
652 __ mov(i.OutputRegister(), sp); 661 __ mov(i.OutputRegister(), sp);
653 break; 662 break;
654 case kArchFramePointer: 663 case kArchFramePointer:
655 __ mov(i.OutputRegister(), fp); 664 __ mov(i.OutputRegister(), fp);
656 break; 665 break;
657 case kArchParentFramePointer: 666 case kArchParentFramePointer:
658 if (frame_access_state()->frame()->needs_frame()) { 667 if (frame_access_state()->has_frame()) {
659 __ ld(i.OutputRegister(), MemOperand(fp, 0)); 668 __ ld(i.OutputRegister(), MemOperand(fp, 0));
660 } else { 669 } else {
661 __ mov(i.OutputRegister(), fp); 670 __ mov(i.OutputRegister(), fp);
662 } 671 }
663 break; 672 break;
664 case kArchTruncateDoubleToI: 673 case kArchTruncateDoubleToI:
665 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); 674 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
666 break; 675 break;
667 case kArchStoreWithWriteBarrier: { 676 case kArchStoreWithWriteBarrier: {
668 RecordWriteMode mode = 677 RecordWriteMode mode =
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 return true; 1587 return true;
1579 default: 1588 default:
1580 break; 1589 break;
1581 } 1590 }
1582 return false; 1591 return false;
1583 } 1592 }
1584 1593
1585 1594
1586 // Assembles branches after an instruction. 1595 // Assembles branches after an instruction.
1587 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 1596 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
1597 AssembleDeconstructFrameIfNeeded();
1588 MipsOperandConverter i(this, instr); 1598 MipsOperandConverter i(this, instr);
1589 Label* tlabel = branch->true_label; 1599 Label* tlabel = branch->true_label;
1590 Label* flabel = branch->false_label; 1600 Label* flabel = branch->false_label;
1591 Condition cc = kNoCondition; 1601 Condition cc = kNoCondition;
1592 // MIPS does not have condition code flags, so compare and branch are 1602 // MIPS does not have condition code flags, so compare and branch are
1593 // implemented differently than on the other arch's. The compare operations 1603 // implemented differently than on the other arch's. The compare operations
1594 // emit mips psuedo-instructions, which are handled here by branch 1604 // emit mips psuedo-instructions, which are handled here by branch
1595 // instructions that do the actual comparison. Essential that the input 1605 // instructions that do the actual comparison. Essential that the input
1596 // registers to compare pseudo-op are not modified before this branch op, as 1606 // registers to compare pseudo-op are not modified before this branch op, as
1597 // they are tested here. 1607 // they are tested here.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1662 } else { 1672 } else {
1663 PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n", 1673 PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n",
1664 instr->arch_opcode()); 1674 instr->arch_opcode());
1665 UNIMPLEMENTED(); 1675 UNIMPLEMENTED();
1666 } 1676 }
1667 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. 1677 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel.
1668 } 1678 }
1669 1679
1670 1680
1671 void CodeGenerator::AssembleArchJump(RpoNumber target) { 1681 void CodeGenerator::AssembleArchJump(RpoNumber target) {
1682 AssembleDeconstructFrameIfNeeded();
1672 if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target)); 1683 if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
1673 } 1684 }
1674 1685
1675 1686
1676 // Assembles boolean materializations after an instruction. 1687 // Assembles boolean materializations after an instruction.
1677 void CodeGenerator::AssembleArchBoolean(Instruction* instr, 1688 void CodeGenerator::AssembleArchBoolean(Instruction* instr,
1678 FlagsCondition condition) { 1689 FlagsCondition condition) {
1679 MipsOperandConverter i(this, instr); 1690 MipsOperandConverter i(this, instr);
1680 Label done; 1691 Label done;
1681 1692
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1863 void CodeGenerator::AssembleDeoptimizerCall( 1874 void CodeGenerator::AssembleDeoptimizerCall(
1864 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { 1875 int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
1865 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( 1876 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
1866 isolate(), deoptimization_id, bailout_type); 1877 isolate(), deoptimization_id, bailout_type);
1867 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); 1878 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
1868 } 1879 }
1869 1880
1870 1881
1871 void CodeGenerator::AssemblePrologue() { 1882 void CodeGenerator::AssemblePrologue() {
1872 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 1883 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
1873 if (frame()->needs_frame()) { 1884 if (frame_access_state()->has_frame()) {
1874 if (descriptor->IsCFunctionCall()) { 1885 if (descriptor->IsCFunctionCall()) {
1875 __ Push(ra, fp); 1886 __ Push(ra, fp);
1876 __ mov(fp, sp); 1887 __ mov(fp, sp);
1877 } else if (descriptor->IsJSFunctionCall()) { 1888 } else if (descriptor->IsJSFunctionCall()) {
1878 __ Prologue(this->info()->GeneratePreagedPrologue()); 1889 __ Prologue(this->info()->GeneratePreagedPrologue());
1879 } else { 1890 } else {
1880 __ StubPrologue(info()->GetOutputStackFrameType()); 1891 __ StubPrologue(info()->GetOutputStackFrameType());
1881 } 1892 }
1882 } else {
1883 frame()->SetElidedFrameSizeInSlots(0);
1884 } 1893 }
1885 frame_access_state()->SetFrameAccessToDefault();
1886 1894
1887 int stack_shrink_slots = frame()->GetSpillSlotCount(); 1895 int stack_shrink_slots = frame()->GetSpillSlotCount();
1888 if (info()->is_osr()) { 1896 if (info()->is_osr()) {
1889 // TurboFan OSR-compiled functions cannot be entered directly. 1897 // TurboFan OSR-compiled functions cannot be entered directly.
1890 __ Abort(kShouldNotDirectlyEnterOsrFunction); 1898 __ Abort(kShouldNotDirectlyEnterOsrFunction);
1891 1899
1892 // Unoptimized code jumps directly to this entrypoint while the unoptimized 1900 // Unoptimized code jumps directly to this entrypoint while the unoptimized
1893 // frame is still on the stack. Optimized code uses OSR values directly from 1901 // frame is still on the stack. Optimized code uses OSR values directly from
1894 // the unoptimized frame. Thus, all that needs to be done is to allocate the 1902 // the unoptimized frame. Thus, all that needs to be done is to allocate the
1895 // remaining stack slots. 1903 // remaining stack slots.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1934 __ MultiPop(saves); 1942 __ MultiPop(saves);
1935 } 1943 }
1936 1944
1937 // Restore FPU registers. 1945 // Restore FPU registers.
1938 const RegList saves_fpu = descriptor->CalleeSavedFPRegisters(); 1946 const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
1939 if (saves_fpu != 0) { 1947 if (saves_fpu != 0) {
1940 __ MultiPopFPU(saves_fpu); 1948 __ MultiPopFPU(saves_fpu);
1941 } 1949 }
1942 1950
1943 if (descriptor->IsCFunctionCall()) { 1951 if (descriptor->IsCFunctionCall()) {
1944 __ mov(sp, fp); 1952 AssembleDeconstructFrameIfNeeded();
1945 __ Pop(ra, fp); 1953 } else if (frame_access_state()->has_frame()) {
1946 } else if (frame()->needs_frame()) { 1954 if (AssembleDeconstructFrameUsingReturnLabel()) return;
1947 // Canonicalize JSFunction return sites for now.
1948 if (return_label_.is_bound()) {
1949 __ Branch(&return_label_);
1950 return;
1951 } else {
1952 __ bind(&return_label_);
1953 __ mov(sp, fp);
1954 __ Pop(ra, fp);
1955 }
1956 } 1955 }
1957 int pop_count = static_cast<int>(descriptor->StackParameterCount()); 1956 int pop_count = static_cast<int>(descriptor->StackParameterCount());
1958 if (pop_count != 0) { 1957 if (pop_count != 0) {
1959 __ DropAndRet(pop_count); 1958 __ DropAndRet(pop_count);
1960 } else { 1959 } else {
1961 __ Ret(); 1960 __ Ret();
1962 } 1961 }
1963 } 1962 }
1964 1963
1965 1964
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
2169 padding_size -= v8::internal::Assembler::kInstrSize; 2168 padding_size -= v8::internal::Assembler::kInstrSize;
2170 } 2169 }
2171 } 2170 }
2172 } 2171 }
2173 2172
2174 #undef __ 2173 #undef __
2175 2174
2176 } // namespace compiler 2175 } // namespace compiler
2177 } // namespace internal 2176 } // namespace internal
2178 } // namespace v8 2177 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698