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

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, 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/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 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 __ JumpIfSmi(value_, exit()); 286 __ JumpIfSmi(value_, exit());
287 } 287 }
288 __ CheckPageFlagClear(value_, scratch0_, 288 __ CheckPageFlagClear(value_, scratch0_,
289 MemoryChunk::kPointersToHereAreInterestingMask, 289 MemoryChunk::kPointersToHereAreInterestingMask,
290 exit()); 290 exit());
291 RememberedSetAction const remembered_set_action = 291 RememberedSetAction const remembered_set_action =
292 mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET 292 mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET
293 : OMIT_REMEMBERED_SET; 293 : OMIT_REMEMBERED_SET;
294 SaveFPRegsMode const save_fp_mode = 294 SaveFPRegsMode const save_fp_mode =
295 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; 295 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
296 if (!frame()->needs_frame()) { 296 if (!frame_access_state()->access_frame_with_fp()) {
297 // We need to save and restore lr if the frame was elided. 297 // We need to save and restore lr if the frame was elided.
298 __ Push(lr); 298 __ Push(lr);
299 } 299 }
300 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, 300 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
301 remembered_set_action, save_fp_mode); 301 remembered_set_action, save_fp_mode);
302 __ Add(scratch1_, object_, index_); 302 __ Add(scratch1_, object_, index_);
303 __ CallStub(&stub); 303 __ CallStub(&stub);
304 if (!frame()->needs_frame()) { 304 if (!frame_access_state()->access_frame_with_fp()) {
305 __ Pop(lr); 305 __ Pop(lr);
306 } 306 }
307 } 307 }
308 308
309 private: 309 private:
310 Register const object_; 310 Register const object_;
311 Operand const index_; 311 Operand const index_;
312 Register const value_; 312 Register const value_;
313 Register const scratch0_; 313 Register const scratch0_;
314 Register const scratch1_; 314 Register const scratch1_;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ 459 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \
460 i.InputRegister##width(1)); \ 460 i.InputRegister##width(1)); \
461 } else { \ 461 } else { \
462 uint32_t imm = \ 462 uint32_t imm = \
463 static_cast<uint32_t>(i.InputOperand##width(1).ImmediateValue()); \ 463 static_cast<uint32_t>(i.InputOperand##width(1).ImmediateValue()); \
464 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ 464 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \
465 imm % (width)); \ 465 imm % (width)); \
466 } \ 466 } \
467 } while (0) 467 } while (0)
468 468
469 void CodeGenerator::AssembleDeconstructFrame() {
470 const CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
471 if (descriptor->IsCFunctionCall() || descriptor->UseNativeStack()) {
472 __ Mov(csp, fp);
473 } else {
474 __ Mov(jssp, fp);
475 }
476 __ Pop(fp, lr);
477 }
469 478
470 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { 479 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
471 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); 480 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
472 if (sp_slot_delta > 0) { 481 if (sp_slot_delta > 0) {
473 __ Drop(sp_slot_delta); 482 __ Drop(sp_slot_delta);
474 } 483 }
475 frame_access_state()->SetFrameAccessToDefault(); 484 frame_access_state()->SetFrameAccessToDefault();
476 } 485 }
477 486
478 487
479 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { 488 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
480 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); 489 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
481 if (sp_slot_delta < 0) { 490 if (sp_slot_delta < 0) {
482 __ Claim(-sp_slot_delta); 491 __ Claim(-sp_slot_delta);
483 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); 492 frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
484 } 493 }
485 if (frame()->needs_frame()) { 494 if (frame_access_state()->access_frame_with_fp()) {
486 __ Ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); 495 __ Ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
487 __ Ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 496 __ Ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
488 } 497 }
489 frame_access_state()->SetFrameAccessToSP(); 498 frame_access_state()->SetFrameAccessToSP();
490 } 499 }
491 500
492 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, 501 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
493 Register scratch1, 502 Register scratch1,
494 Register scratch2, 503 Register scratch2,
495 Register scratch3) { 504 Register scratch3) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 case kArchRet: 666 case kArchRet:
658 AssembleReturn(); 667 AssembleReturn();
659 break; 668 break;
660 case kArchStackPointer: 669 case kArchStackPointer:
661 __ mov(i.OutputRegister(), masm()->StackPointer()); 670 __ mov(i.OutputRegister(), masm()->StackPointer());
662 break; 671 break;
663 case kArchFramePointer: 672 case kArchFramePointer:
664 __ mov(i.OutputRegister(), fp); 673 __ mov(i.OutputRegister(), fp);
665 break; 674 break;
666 case kArchParentFramePointer: 675 case kArchParentFramePointer:
667 if (frame_access_state()->frame()->needs_frame()) { 676 if (frame_access_state()->access_frame_with_fp()) {
668 __ ldr(i.OutputRegister(), MemOperand(fp, 0)); 677 __ ldr(i.OutputRegister(), MemOperand(fp, 0));
669 } else { 678 } else {
670 __ mov(i.OutputRegister(), fp); 679 __ mov(i.OutputRegister(), fp);
671 } 680 }
672 break; 681 break;
673 case kArchTruncateDoubleToI: 682 case kArchTruncateDoubleToI:
674 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); 683 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
675 break; 684 break;
676 case kArchStoreWithWriteBarrier: { 685 case kArchStoreWithWriteBarrier: {
677 RecordWriteMode mode = 686 RecordWriteMode mode =
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 } 1409 }
1401 } else { 1410 } else {
1402 Condition cc = FlagsConditionToCondition(condition); 1411 Condition cc = FlagsConditionToCondition(condition);
1403 __ B(cc, tlabel); 1412 __ B(cc, tlabel);
1404 } 1413 }
1405 if (!branch->fallthru) __ B(flabel); // no fallthru to flabel. 1414 if (!branch->fallthru) __ B(flabel); // no fallthru to flabel.
1406 } 1415 }
1407 1416
1408 1417
1409 void CodeGenerator::AssembleArchJump(RpoNumber target) { 1418 void CodeGenerator::AssembleArchJump(RpoNumber target) {
1419 AssembleDeconstructFrameBetweenBlocks();
1410 if (!IsNextInAssemblyOrder(target)) __ B(GetLabel(target)); 1420 if (!IsNextInAssemblyOrder(target)) __ B(GetLabel(target));
1411 } 1421 }
1412 1422
1413 1423
1414 // Assemble boolean materializations after this instruction. 1424 // Assemble boolean materializations after this instruction.
1415 void CodeGenerator::AssembleArchBoolean(Instruction* instr, 1425 void CodeGenerator::AssembleArchBoolean(Instruction* instr,
1416 FlagsCondition condition) { 1426 FlagsCondition condition) {
1417 Arm64OperandConverter i(this, instr); 1427 Arm64OperandConverter i(this, instr);
1418 1428
1419 // Materialize a full 64-bit 1 or 0 value. The result register is always the 1429 // Materialize a full 64-bit 1 or 0 value. The result register is always the
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 } 1467 }
1458 1468
1459 1469
1460 void CodeGenerator::AssembleDeoptimizerCall( 1470 void CodeGenerator::AssembleDeoptimizerCall(
1461 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { 1471 int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
1462 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( 1472 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
1463 isolate(), deoptimization_id, bailout_type); 1473 isolate(), deoptimization_id, bailout_type);
1464 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); 1474 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
1465 } 1475 }
1466 1476
1477 void CodeGenerator::SetupStackPointer() {
1478 if (linkage()->GetIncomingDescriptor()->UseNativeStack()) {
1479 __ SetStackPointer(csp);
1480 } else {
1481 __ SetStackPointer(jssp);
1482 }
1483 }
1467 1484
1468 void CodeGenerator::AssemblePrologue() { 1485 void CodeGenerator::AssemblePrologue() {
1469 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 1486 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
1470 frame()->AlignFrame(16);
1471 int stack_shrink_slots = frame()->GetSpillSlotCount(); 1487 int stack_shrink_slots = frame()->GetSpillSlotCount();
1472 if (frame()->needs_frame()) { 1488 if (frame_access_state()->access_frame_with_fp()) {
1473 if (descriptor->IsJSFunctionCall()) { 1489 if (descriptor->IsJSFunctionCall()) {
1474 DCHECK(!descriptor->UseNativeStack()); 1490 DCHECK(!descriptor->UseNativeStack());
1475 __ SetStackPointer(jssp); 1491 __ SetStackPointer(jssp);
1476 __ Prologue(this->info()->GeneratePreagedPrologue()); 1492 __ Prologue(this->info()->GeneratePreagedPrologue());
1477 } else { 1493 } else {
1478 if (descriptor->UseNativeStack() || descriptor->IsCFunctionCall()) { 1494 if (descriptor->UseNativeStack() || descriptor->IsCFunctionCall()) {
1479 __ SetStackPointer(csp); 1495 __ SetStackPointer(csp);
1480 } else { 1496 } else {
1481 __ SetStackPointer(jssp); 1497 __ SetStackPointer(jssp);
1482 } 1498 }
1483 if (descriptor->IsCFunctionCall()) { 1499 if (descriptor->IsCFunctionCall()) {
1484 __ Push(lr, fp); 1500 __ Push(lr, fp);
1485 __ Mov(fp, masm_.StackPointer()); 1501 __ Mov(fp, masm_.StackPointer());
1486 __ Claim(stack_shrink_slots); 1502 __ Claim(stack_shrink_slots);
1487 } else { 1503 } else {
1488 __ StubPrologue(info()->GetOutputStackFrameType(), 1504 __ StubPrologue(info()->GetOutputStackFrameType(),
1489 frame()->GetTotalFrameSlotCount()); 1505 frame()->GetTotalFrameSlotCount());
1490 } 1506 }
1491 } 1507 }
1492 } else {
1493 if (descriptor->UseNativeStack()) {
1494 __ SetStackPointer(csp);
1495 } else {
1496 __ SetStackPointer(jssp);
1497 }
1498 frame()->SetElidedFrameSizeInSlots(0);
1499 } 1508 }
1500 frame_access_state()->SetFrameAccessToDefault(); 1509
1501 if (info()->is_osr()) { 1510 if (info()->is_osr()) {
1502 // TurboFan OSR-compiled functions cannot be entered directly. 1511 // TurboFan OSR-compiled functions cannot be entered directly.
1503 __ Abort(kShouldNotDirectlyEnterOsrFunction); 1512 __ Abort(kShouldNotDirectlyEnterOsrFunction);
1504 1513
1505 // Unoptimized code jumps directly to this entrypoint while the unoptimized 1514 // Unoptimized code jumps directly to this entrypoint while the unoptimized
1506 // frame is still on the stack. Optimized code uses OSR values directly from 1515 // 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 1516 // the unoptimized frame. Thus, all that needs to be done is to allocate the
1508 // remaining stack slots. 1517 // remaining stack slots.
1509 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); 1518 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
1510 osr_pc_offset_ = __ pc_offset(); 1519 osr_pc_offset_ = __ pc_offset();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1551 1560
1552 // Restore fp registers. 1561 // Restore fp registers.
1553 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, 1562 CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
1554 descriptor->CalleeSavedFPRegisters()); 1563 descriptor->CalleeSavedFPRegisters());
1555 if (saves_fp.Count() != 0) { 1564 if (saves_fp.Count() != 0) {
1556 __ PopCPURegList(saves_fp); 1565 __ PopCPURegList(saves_fp);
1557 } 1566 }
1558 1567
1559 int pop_count = static_cast<int>(descriptor->StackParameterCount()); 1568 int pop_count = static_cast<int>(descriptor->StackParameterCount());
1560 if (descriptor->IsCFunctionCall()) { 1569 if (descriptor->IsCFunctionCall()) {
1561 __ Mov(csp, fp); 1570 AssembleDeconstructFrameWhenLeaving();
1562 __ Pop(fp, lr); 1571 } else if (frame_access_state()->access_frame_with_fp()) {
1563 } else if (frame()->needs_frame()) {
1564 // Canonicalize JSFunction return sites for now. 1572 // Canonicalize JSFunction return sites for now.
1565 if (return_label_.is_bound()) { 1573 if (return_label_.is_bound()) {
1574 AssembleDeconstructFrameBetweenBlocks();
1566 __ B(&return_label_); 1575 __ B(&return_label_);
1567 return; 1576 return;
1568 } else { 1577 } else {
1569 __ Bind(&return_label_); 1578 __ Bind(&return_label_);
1570 if (descriptor->UseNativeStack()) { 1579 AssembleDeconstructFrameWhenLeaving();
1571 __ Mov(csp, fp);
1572 pop_count += (pop_count & 1); // align
1573 } else {
1574 __ Mov(jssp, fp);
1575 }
1576 __ Pop(fp, lr);
1577 } 1580 }
1578 } else if (descriptor->UseNativeStack()) { 1581 } else if (descriptor->UseNativeStack()) {
1579 pop_count += (pop_count & 1); // align 1582 pop_count += (pop_count & 1); // align
1580 } 1583 }
1581 __ Drop(pop_count); 1584 __ Drop(pop_count);
1582 __ Ret(); 1585 __ Ret();
1583 } 1586 }
1584 1587
1585 1588
1586 void CodeGenerator::AssembleMove(InstructionOperand* source, 1589 void CodeGenerator::AssembleMove(InstructionOperand* source,
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1765 padding_size -= kInstructionSize; 1768 padding_size -= kInstructionSize;
1766 } 1769 }
1767 } 1770 }
1768 } 1771 }
1769 1772
1770 #undef __ 1773 #undef __
1771 1774
1772 } // namespace compiler 1775 } // namespace compiler
1773 } // namespace internal 1776 } // namespace internal
1774 } // namespace v8 1777 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698