| 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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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::AssembleSetupStackPointer() { | 
|  | 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); |  | 
| 1471   int stack_shrink_slots = frame()->GetSpillSlotCount(); | 1489   int stack_shrink_slots = frame()->GetSpillSlotCount(); | 
| 1472   if (frame()->needs_frame()) { | 1490   if (frame_access_state()->has_frame()) { | 
| 1473     if (descriptor->IsJSFunctionCall()) { | 1491     if (descriptor->IsJSFunctionCall()) { | 
| 1474       DCHECK(!descriptor->UseNativeStack()); | 1492       DCHECK(!descriptor->UseNativeStack()); | 
| 1475       __ SetStackPointer(jssp); |  | 
| 1476       __ Prologue(this->info()->GeneratePreagedPrologue()); | 1493       __ Prologue(this->info()->GeneratePreagedPrologue()); | 
| 1477     } else { | 1494     } else { | 
| 1478       if (descriptor->UseNativeStack() || descriptor->IsCFunctionCall()) { |  | 
| 1479         __ SetStackPointer(csp); |  | 
| 1480       } else { |  | 
| 1481         __ SetStackPointer(jssp); |  | 
| 1482       } |  | 
| 1483       if (descriptor->IsCFunctionCall()) { | 1495       if (descriptor->IsCFunctionCall()) { | 
| 1484         __ Push(lr, fp); | 1496         __ Push(lr, fp); | 
| 1485         __ Mov(fp, masm_.StackPointer()); | 1497         __ Mov(fp, masm_.StackPointer()); | 
| 1486         __ Claim(stack_shrink_slots); | 1498         __ Claim(stack_shrink_slots); | 
| 1487       } else { | 1499       } else { | 
| 1488         __ StubPrologue(info()->GetOutputStackFrameType(), | 1500         __ StubPrologue(info()->GetOutputStackFrameType(), | 
| 1489                         frame()->GetTotalFrameSlotCount()); | 1501                         frame()->GetTotalFrameSlotCount()); | 
| 1490       } | 1502       } | 
| 1491     } | 1503     } | 
| 1492   } else { |  | 
| 1493     if (descriptor->UseNativeStack()) { |  | 
| 1494       __ SetStackPointer(csp); |  | 
| 1495     } else { |  | 
| 1496       __ SetStackPointer(jssp); |  | 
| 1497     } |  | 
| 1498     frame()->SetElidedFrameSizeInSlots(0); |  | 
| 1499   } | 1504   } | 
| 1500   frame_access_state()->SetFrameAccessToDefault(); | 1505 | 
| 1501   if (info()->is_osr()) { | 1506   if (info()->is_osr()) { | 
| 1502     // TurboFan OSR-compiled functions cannot be entered directly. | 1507     // TurboFan OSR-compiled functions cannot be entered directly. | 
| 1503     __ Abort(kShouldNotDirectlyEnterOsrFunction); | 1508     __ Abort(kShouldNotDirectlyEnterOsrFunction); | 
| 1504 | 1509 | 
| 1505     // Unoptimized code jumps directly to this entrypoint while the unoptimized | 1510     // Unoptimized code jumps directly to this entrypoint while the unoptimized | 
| 1506     // frame is still on the stack. Optimized code uses OSR values directly from | 1511     // 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 | 1512     // the unoptimized frame. Thus, all that needs to be done is to allocate the | 
| 1508     // remaining stack slots. | 1513     // remaining stack slots. | 
| 1509     if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 1514     if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 
| 1510     osr_pc_offset_ = __ pc_offset(); | 1515     osr_pc_offset_ = __ pc_offset(); | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1551 | 1556 | 
| 1552   // Restore fp registers. | 1557   // Restore fp registers. | 
| 1553   CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, | 1558   CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, | 
| 1554                                    descriptor->CalleeSavedFPRegisters()); | 1559                                    descriptor->CalleeSavedFPRegisters()); | 
| 1555   if (saves_fp.Count() != 0) { | 1560   if (saves_fp.Count() != 0) { | 
| 1556     __ PopCPURegList(saves_fp); | 1561     __ PopCPURegList(saves_fp); | 
| 1557   } | 1562   } | 
| 1558 | 1563 | 
| 1559   int pop_count = static_cast<int>(descriptor->StackParameterCount()); | 1564   int pop_count = static_cast<int>(descriptor->StackParameterCount()); | 
| 1560   if (descriptor->IsCFunctionCall()) { | 1565   if (descriptor->IsCFunctionCall()) { | 
| 1561     __ Mov(csp, fp); | 1566     AssembleDeconstructFrame(); | 
| 1562     __ Pop(fp, lr); | 1567   } else if (frame_access_state()->has_frame()) { | 
| 1563   } else if (frame()->needs_frame()) { |  | 
| 1564     // Canonicalize JSFunction return sites for now. | 1568     // 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  Loading... | 
| 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 | 
| OLD | NEW | 
|---|