• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_
6 #define V8_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_
7 
8 #include "src/interpreter/bytecodes.h"
9 #include "src/zone-containers.h"
10 
11 namespace v8 {
12 namespace internal {
13 namespace interpreter {
14 
15 class BytecodeArrayBuilder;
16 class Register;
17 class TemporaryRegisterObserver;
18 
19 class TemporaryRegisterAllocator final {
20  public:
21   TemporaryRegisterAllocator(Zone* zone, int start_index);
22 
23   // Borrow a temporary register.
24   int BorrowTemporaryRegister();
25 
26   // Borrow a temporary register from the register range outside of
27   // |start_index| to |end_index|.
28   int BorrowTemporaryRegisterNotInRange(int start_index, int end_index);
29 
30   // Return a temporary register when no longer used.
31   void ReturnTemporaryRegister(int reg_index);
32 
33   // Ensure a run of consecutive registers is available. Each register in
34   // the range should be borrowed with BorrowConsecutiveTemporaryRegister().
35   // Returns the start index of the run.
36   int PrepareForConsecutiveTemporaryRegisters(size_t count);
37 
38   // Borrow a register from a range prepared with
39   // PrepareForConsecutiveTemporaryRegisters().
40   void BorrowConsecutiveTemporaryRegister(int reg_index);
41 
42   // Returns true if |reg| is a temporary register and is currently
43   // borrowed.
44   bool RegisterIsLive(Register reg) const;
45 
46   // Returns the first register in the range of temporary registers.
47   Register first_temporary_register() const;
48 
49   // Returns the last register in the range of temporary registers.
50   Register last_temporary_register() const;
51 
52   // Returns the start index of temporary register allocations.
allocation_base()53   int allocation_base() const { return allocation_base_; }
54 
55   // Returns the number of temporary register allocations made.
allocation_count()56   int allocation_count() const { return allocation_count_; }
57 
58   // Sets an observer for temporary register events.
59   void set_observer(TemporaryRegisterObserver* observer);
60 
61  private:
62   // Allocate a temporary register.
63   int AllocateTemporaryRegister();
64 
65   ZoneSet<int> free_temporaries_;
66   int allocation_base_;
67   int allocation_count_;
68   TemporaryRegisterObserver* observer_;
69 
70   DISALLOW_COPY_AND_ASSIGN(TemporaryRegisterAllocator);
71 };
72 
73 class TemporaryRegisterObserver {
74  public:
~TemporaryRegisterObserver()75   virtual ~TemporaryRegisterObserver() {}
76   virtual void TemporaryRegisterFreeEvent(Register reg) = 0;
77 };
78 
79 // A class that allows the instantiator to allocate temporary registers that are
80 // cleaned up when scope is closed.
81 class BytecodeRegisterAllocator final {
82  public:
83   explicit BytecodeRegisterAllocator(Zone* zone,
84                                      TemporaryRegisterAllocator* allocator);
85   ~BytecodeRegisterAllocator();
86   Register NewRegister();
87 
88   // Ensure |count| consecutive allocations are available.
89   void PrepareForConsecutiveAllocations(size_t count);
90 
91   // Get the next consecutive allocation after calling
92   // PrepareForConsecutiveAllocations.
93   Register NextConsecutiveRegister();
94 
95   // Returns true if |reg| is allocated in this allocator.
96   bool RegisterIsAllocatedInThisScope(Register reg) const;
97 
98   // Returns true if unused consecutive allocations remain.
HasConsecutiveAllocations()99   bool HasConsecutiveAllocations() const { return next_consecutive_count_ > 0; }
100 
101  private:
base_allocator()102   TemporaryRegisterAllocator* base_allocator() const { return base_allocator_; }
103 
104   TemporaryRegisterAllocator* base_allocator_;
105   ZoneVector<int> allocated_;
106   int next_consecutive_register_;
107   int next_consecutive_count_;
108 
109   DISALLOW_COPY_AND_ASSIGN(BytecodeRegisterAllocator);
110 };
111 
112 }  // namespace interpreter
113 }  // namespace internal
114 }  // namespace v8
115 
116 
117 #endif  // V8_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_
118