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

Side by Side Diff: src/compiler/arm64/code-generator-arm64.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, 8 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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 public: 272 public:
273 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Operand index, 273 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Operand index,
274 Register value, Register scratch0, Register scratch1, 274 Register value, Register scratch0, Register scratch1,
275 RecordWriteMode mode) 275 RecordWriteMode mode)
276 : OutOfLineCode(gen), 276 : OutOfLineCode(gen),
277 object_(object), 277 object_(object),
278 index_(index), 278 index_(index),
279 value_(value), 279 value_(value),
280 scratch0_(scratch0), 280 scratch0_(scratch0),
281 scratch1_(scratch1), 281 scratch1_(scratch1),
282 mode_(mode) {} 282 mode_(mode),
283 must_save_lr_(!gen->frame_access_state()->has_frame()) {}
283 284
284 void Generate() final { 285 void Generate() final {
285 if (mode_ > RecordWriteMode::kValueIsPointer) { 286 if (mode_ > RecordWriteMode::kValueIsPointer) {
286 __ JumpIfSmi(value_, exit()); 287 __ JumpIfSmi(value_, exit());
287 } 288 }
288 __ CheckPageFlagClear(value_, scratch0_, 289 __ CheckPageFlagClear(value_, scratch0_,
289 MemoryChunk::kPointersToHereAreInterestingMask, 290 MemoryChunk::kPointersToHereAreInterestingMask,
290 exit()); 291 exit());
291 RememberedSetAction const remembered_set_action = 292 RememberedSetAction const remembered_set_action =
292 mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET 293 mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET
293 : OMIT_REMEMBERED_SET; 294 : OMIT_REMEMBERED_SET;
294 SaveFPRegsMode const save_fp_mode = 295 SaveFPRegsMode const save_fp_mode =
295 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; 296 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
296 if (!frame()->needs_frame()) { 297 if (must_save_lr_) {
297 // We need to save and restore lr if the frame was elided. 298 // We need to save and restore lr if the frame was elided.
298 __ Push(lr); 299 __ Push(lr);
299 } 300 }
300 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, 301 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
301 remembered_set_action, save_fp_mode); 302 remembered_set_action, save_fp_mode);
302 __ Add(scratch1_, object_, index_); 303 __ Add(scratch1_, object_, index_);
303 __ CallStub(&stub); 304 __ CallStub(&stub);
304 if (!frame()->needs_frame()) { 305 if (must_save_lr_) {
305 __ Pop(lr); 306 __ Pop(lr);
306 } 307 }
307 } 308 }
308 309
309 private: 310 private:
310 Register const object_; 311 Register const object_;
311 Operand const index_; 312 Operand const index_;
312 Register const value_; 313 Register const value_;
313 Register const scratch0_; 314 Register const scratch0_;
314 Register const scratch1_; 315 Register const scratch1_;
315 RecordWriteMode const mode_; 316 RecordWriteMode const mode_;
317 bool must_save_lr_;
316 }; 318 };
317 319
318 320
319 Condition FlagsConditionToCondition(FlagsCondition condition) { 321 Condition FlagsConditionToCondition(FlagsCondition condition) {
320 switch (condition) { 322 switch (condition) {
321 case kEqual: 323 case kEqual:
322 return eq; 324 return eq;
323 case kNotEqual: 325 case kNotEqual:
324 return ne; 326 return ne;
325 case kSignedLessThan: 327 case kSignedLessThan:
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ 461 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \
460 i.InputRegister##width(1)); \ 462 i.InputRegister##width(1)); \
461 } else { \ 463 } else { \
462 uint32_t imm = \ 464 uint32_t imm = \
463 static_cast<uint32_t>(i.InputOperand##width(1).ImmediateValue()); \ 465 static_cast<uint32_t>(i.InputOperand##width(1).ImmediateValue()); \
464 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ 466 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \
465 imm % (width)); \ 467 imm % (width)); \
466 } \ 468 } \
467 } while (0) 469 } while (0)
468 470
471 void CodeGenerator::AssembleDeconstructFrame() {
472 const CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
473 if (descriptor->IsCFunctionCall() || descriptor->UseNativeStack()) {
474 __ Mov(csp, fp);
475 } else {
476 __ Mov(jssp, fp);
477 }
478 __ Pop(fp, lr);
479 }
469 480
470 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { 481 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
471 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); 482 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
472 if (sp_slot_delta > 0) { 483 if (sp_slot_delta > 0) {
473 __ Drop(sp_slot_delta); 484 __ Drop(sp_slot_delta);
474 } 485 }
475 frame_access_state()->SetFrameAccessToDefault(); 486 frame_access_state()->SetFrameAccessToDefault();
476 } 487 }
477 488
478 489
479 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { 490 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
480 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); 491 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
481 if (sp_slot_delta < 0) { 492 if (sp_slot_delta < 0) {
482 __ Claim(-sp_slot_delta); 493 __ Claim(-sp_slot_delta);
483 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); 494 frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
484 } 495 }
485 if (frame()->needs_frame()) { 496 if (frame_access_state()->has_frame()) {
486 __ Ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); 497 __ Ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
487 __ Ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 498 __ Ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
488 } 499 }
489 frame_access_state()->SetFrameAccessToSP(); 500 frame_access_state()->SetFrameAccessToSP();
490 } 501 }
491 502
492 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, 503 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
493 Register scratch1, 504 Register scratch1,
494 Register scratch2, 505 Register scratch2,
495 Register scratch3) { 506 Register scratch3) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 case kArchRet: 668 case kArchRet:
658 AssembleReturn(); 669 AssembleReturn();
659 break; 670 break;
660 case kArchStackPointer: 671 case kArchStackPointer:
661 __ mov(i.OutputRegister(), masm()->StackPointer()); 672 __ mov(i.OutputRegister(), masm()->StackPointer());
662 break; 673 break;
663 case kArchFramePointer: 674 case kArchFramePointer:
664 __ mov(i.OutputRegister(), fp); 675 __ mov(i.OutputRegister(), fp);
665 break; 676 break;
666 case kArchParentFramePointer: 677 case kArchParentFramePointer:
667 if (frame_access_state()->frame()->needs_frame()) { 678 if (frame_access_state()->has_frame()) {
668 __ ldr(i.OutputRegister(), MemOperand(fp, 0)); 679 __ ldr(i.OutputRegister(), MemOperand(fp, 0));
669 } else { 680 } else {
670 __ mov(i.OutputRegister(), fp); 681 __ mov(i.OutputRegister(), fp);
671 } 682 }
672 break; 683 break;
673 case kArchTruncateDoubleToI: 684 case kArchTruncateDoubleToI:
674 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); 685 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
675 break; 686 break;
676 case kArchStoreWithWriteBarrier: { 687 case kArchStoreWithWriteBarrier: {
677 RecordWriteMode mode = 688 RecordWriteMode mode =
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 } 1468 }
1458 1469
1459 1470
1460 void CodeGenerator::AssembleDeoptimizerCall( 1471 void CodeGenerator::AssembleDeoptimizerCall(
1461 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { 1472 int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
1462 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( 1473 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
1463 isolate(), deoptimization_id, bailout_type); 1474 isolate(), deoptimization_id, bailout_type);
1464 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); 1475 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
1465 } 1476 }
1466 1477
1478 void CodeGenerator::SetupStackPointer() {
danno 2016/03/24 12:53:05 If wonder if this should be called AssemblePrologu
Mircea Trofin 2016/03/24 17:46:11 Possibly. I want to restructure AssemblePrologue b
1479 const CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
1480 if (descriptor->UseNativeStack() || descriptor->IsCFunctionCall()) {
1481 __ SetStackPointer(csp);
1482 } else {
1483 __ SetStackPointer(jssp);
1484 }
1485 }
1467 1486
1468 void CodeGenerator::AssemblePrologue() { 1487 void CodeGenerator::AssemblePrologue() {
1469 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 1488 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
1470 frame()->AlignFrame(16); 1489 frame()->AlignFrame(16);
danno 2016/03/24 12:53:05 Shouldn't you remove this now?
Mircea Trofin 2016/03/24 17:46:11 Done.
1471 int stack_shrink_slots = frame()->GetSpillSlotCount(); 1490 int stack_shrink_slots = frame()->GetSpillSlotCount();
1472 if (frame()->needs_frame()) { 1491 if (frame_access_state()->has_frame()) {
1473 if (descriptor->IsJSFunctionCall()) { 1492 if (descriptor->IsJSFunctionCall()) {
1474 DCHECK(!descriptor->UseNativeStack()); 1493 DCHECK(!descriptor->UseNativeStack());
1475 __ SetStackPointer(jssp);
1476 __ Prologue(this->info()->GeneratePreagedPrologue()); 1494 __ Prologue(this->info()->GeneratePreagedPrologue());
1477 } else { 1495 } else {
1478 if (descriptor->UseNativeStack() || descriptor->IsCFunctionCall()) {
1479 __ SetStackPointer(csp);
1480 } else {
1481 __ SetStackPointer(jssp);
1482 }
1483 if (descriptor->IsCFunctionCall()) { 1496 if (descriptor->IsCFunctionCall()) {
1484 __ Push(lr, fp); 1497 __ Push(lr, fp);
1485 __ Mov(fp, masm_.StackPointer()); 1498 __ Mov(fp, masm_.StackPointer());
1486 __ Claim(stack_shrink_slots); 1499 __ Claim(stack_shrink_slots);
1487 } else { 1500 } else {
1488 __ StubPrologue(info()->GetOutputStackFrameType(), 1501 __ StubPrologue(info()->GetOutputStackFrameType(),
1489 frame()->GetTotalFrameSlotCount()); 1502 frame()->GetTotalFrameSlotCount());
1490 } 1503 }
1491 } 1504 }
1492 } else {
1493 if (descriptor->UseNativeStack()) {
1494 __ SetStackPointer(csp);
1495 } else {
1496 __ SetStackPointer(jssp);
1497 }
1498 frame()->SetElidedFrameSizeInSlots(0);
1499 } 1505 }
1500 frame_access_state()->SetFrameAccessToDefault(); 1506
1501 if (info()->is_osr()) { 1507 if (info()->is_osr()) {
1502 // TurboFan OSR-compiled functions cannot be entered directly. 1508 // TurboFan OSR-compiled functions cannot be entered directly.
1503 __ Abort(kShouldNotDirectlyEnterOsrFunction); 1509 __ Abort(kShouldNotDirectlyEnterOsrFunction);
1504 1510
1505 // Unoptimized code jumps directly to this entrypoint while the unoptimized 1511 // Unoptimized code jumps directly to this entrypoint while the unoptimized
1506 // frame is still on the stack. Optimized code uses OSR values directly from 1512 // frame is still on the stack. Optimized code uses OSR values directly from
1507 // the unoptimized frame. Thus, all that needs to be done is to allocate the 1513 // the unoptimized frame. Thus, all that needs to be done is to allocate the
1508 // remaining stack slots. 1514 // remaining stack slots.
1509 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); 1515 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
1510 osr_pc_offset_ = __ pc_offset(); 1516 osr_pc_offset_ = __ pc_offset();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1551 1557
1552 // Restore fp registers. 1558 // Restore fp registers.
1553 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, 1559 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
1554 descriptor->CalleeSavedFPRegisters()); 1560 descriptor->CalleeSavedFPRegisters());
1555 if (saves_fp.Count() != 0) { 1561 if (saves_fp.Count() != 0) {
1556 __ PopCPURegList(saves_fp); 1562 __ PopCPURegList(saves_fp);
1557 } 1563 }
1558 1564
1559 int pop_count = static_cast<int>(descriptor->StackParameterCount()); 1565 int pop_count = static_cast<int>(descriptor->StackParameterCount());
1560 if (descriptor->IsCFunctionCall()) { 1566 if (descriptor->IsCFunctionCall()) {
1561 __ Mov(csp, fp); 1567 AssembleDeconstructFrame();
1562 __ Pop(fp, lr); 1568 } else if (frame_access_state()->has_frame()) {
1563 } else if (frame()->needs_frame()) {
1564 // Canonicalize JSFunction return sites for now.
1565 if (return_label_.is_bound()) { 1569 if (return_label_.is_bound()) {
1566 __ B(&return_label_); 1570 __ B(&return_label_);
1567 return; 1571 return;
1568 } else { 1572 } else {
1569 __ Bind(&return_label_); 1573 __ Bind(&return_label_);
1570 if (descriptor->UseNativeStack()) { 1574 AssembleDeconstructFrame();
1571 __ Mov(csp, fp);
1572 pop_count += (pop_count & 1); // align
1573 } else {
1574 __ Mov(jssp, fp);
1575 }
1576 __ Pop(fp, lr);
1577 } 1575 }
1578 } else if (descriptor->UseNativeStack()) { 1576 } else if (descriptor->UseNativeStack()) {
1579 pop_count += (pop_count & 1); // align 1577 pop_count += (pop_count & 1); // align
1580 } 1578 }
1581 __ Drop(pop_count); 1579 __ Drop(pop_count);
1582 __ Ret(); 1580 __ Ret();
1583 } 1581 }
1584 1582
1585 1583
1586 void CodeGenerator::AssembleMove(InstructionOperand* source, 1584 void CodeGenerator::AssembleMove(InstructionOperand* source,
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1765 padding_size -= kInstructionSize; 1763 padding_size -= kInstructionSize;
1766 } 1764 }
1767 } 1765 }
1768 } 1766 }
1769 1767
1770 #undef __ 1768 #undef __
1771 1769
1772 } // namespace compiler 1770 } // namespace compiler
1773 } // namespace internal 1771 } // namespace internal
1774 } // namespace v8 1772 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698