• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_CRANKSHAFT_ARM64_LITHIUM_GAP_RESOLVER_ARM64_H_
6 #define V8_CRANKSHAFT_ARM64_LITHIUM_GAP_RESOLVER_ARM64_H_
7 
8 #include "src/crankshaft/arm64/delayed-masm-arm64.h"
9 #include "src/crankshaft/lithium.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 class LCodeGen;
15 class LGapResolver;
16 
17 class DelayedGapMasm : public DelayedMasm {
18  public:
DelayedGapMasm(LCodeGen * owner,MacroAssembler * masm)19   DelayedGapMasm(LCodeGen* owner, MacroAssembler* masm)
20     : DelayedMasm(owner, masm, root) {
21     // We use the root register as an extra scratch register.
22     // The root register has two advantages:
23     //  - It is not in crankshaft allocatable registers list, so it can't
24     //    interfere with the allocatable registers.
25     //  - We don't need to push it on the stack, as we can reload it with its
26     //    value once we have finish.
27   }
28   void EndDelayedUse();
29 };
30 
31 
32 class LGapResolver BASE_EMBEDDED {
33  public:
34   explicit LGapResolver(LCodeGen* owner);
35 
36   // Resolve a set of parallel moves, emitting assembler instructions.
37   void Resolve(LParallelMove* parallel_move);
38 
39  private:
40   // Build the initial list of moves.
41   void BuildInitialMoveList(LParallelMove* parallel_move);
42 
43   // Perform the move at the moves_ index in question (possibly requiring
44   // other moves to satisfy dependencies).
45   void PerformMove(int index);
46 
47   // If a cycle is found in the series of moves, save the blocking value to
48   // a scratch register.  The cycle must be found by hitting the root of the
49   // depth-first search.
50   void BreakCycle(int index);
51 
52   // After a cycle has been resolved, restore the value from the scratch
53   // register to its proper destination.
54   void RestoreValue();
55 
56   // Emit a move and remove it from the move graph.
57   void EmitMove(int index);
58 
59   // Emit a move from one stack slot to another.
EmitStackSlotMove(int index)60   void EmitStackSlotMove(int index) {
61     masm_.StackSlotMove(moves_[index].source(), moves_[index].destination());
62   }
63 
64   // Verify the move list before performing moves.
65   void Verify();
66 
67   // Registers used to solve cycles.
SavedValueRegister()68   const Register& SavedValueRegister() {
69     DCHECK(!RegisterConfiguration::Crankshaft()->IsAllocatableGeneralCode(
70         masm_.ScratchRegister().code()));
71     return masm_.ScratchRegister();
72   }
73   // The scratch register is used to break cycles and to store constant.
74   // These two methods switch from one mode to the other.
AcquireSavedValueRegister()75   void AcquireSavedValueRegister() { masm_.AcquireScratchRegister(); }
ReleaseSavedValueRegister()76   void ReleaseSavedValueRegister() { masm_.ReleaseScratchRegister(); }
SavedFPValueRegister()77   const FPRegister& SavedFPValueRegister() {
78     // We use the Crankshaft floating-point scratch register to break a cycle
79     // involving double values as the MacroAssembler will not need it for the
80     // operations performed by the gap resolver.
81     DCHECK(!RegisterConfiguration::Crankshaft()->IsAllocatableGeneralCode(
82         crankshaft_fp_scratch.code()));
83     return crankshaft_fp_scratch;
84   }
85 
86   LCodeGen* cgen_;
87   DelayedGapMasm masm_;
88 
89   // List of moves not yet resolved.
90   ZoneList<LMoveOperands> moves_;
91 
92   int root_index_;
93   bool in_cycle_;
94   LOperand* saved_destination_;
95 };
96 
97 }  // namespace internal
98 }  // namespace v8
99 
100 #endif  // V8_CRANKSHAFT_ARM64_LITHIUM_GAP_RESOLVER_ARM64_H_
101