blob: b8f737be79386641907f6903123f592f23be838b [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
Ben Murdoch097c5b22016-05-18 11:27:45 +01008#include "src/interpreter/bytecodes.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009#include "src/zone-containers.h"
10
11namespace v8 {
12namespace internal {
13namespace interpreter {
14
15class BytecodeArrayBuilder;
16class Register;
Ben Murdoch61f157c2016-09-16 13:49:30 +010017class TemporaryRegisterObserver;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000018
Ben Murdoch097c5b22016-05-18 11:27:45 +010019class 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.
53 int allocation_base() const { return allocation_base_; }
54
55 // Returns the number of temporary register allocations made.
56 int allocation_count() const { return allocation_count_; }
57
Ben Murdoch61f157c2016-09-16 13:49:30 +010058 // Sets an observer for temporary register events.
59 void set_observer(TemporaryRegisterObserver* observer);
60
Ben Murdoch097c5b22016-05-18 11:27:45 +010061 private:
62 // Allocate a temporary register.
63 int AllocateTemporaryRegister();
64
65 ZoneSet<int> free_temporaries_;
66 int allocation_base_;
67 int allocation_count_;
Ben Murdoch61f157c2016-09-16 13:49:30 +010068 TemporaryRegisterObserver* observer_;
Ben Murdoch097c5b22016-05-18 11:27:45 +010069
70 DISALLOW_COPY_AND_ASSIGN(TemporaryRegisterAllocator);
71};
72
Ben Murdoch61f157c2016-09-16 13:49:30 +010073class TemporaryRegisterObserver {
74 public:
75 virtual ~TemporaryRegisterObserver() {}
76 virtual void TemporaryRegisterFreeEvent(Register reg) = 0;
77};
78
Ben Murdochc5610432016-08-08 18:44:38 +010079// A class that allows the instantiator to allocate temporary registers that are
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000080// cleaned up when scope is closed.
Ben Murdoch097c5b22016-05-18 11:27:45 +010081class BytecodeRegisterAllocator final {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000082 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +010083 explicit BytecodeRegisterAllocator(Zone* zone,
84 TemporaryRegisterAllocator* allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000085 ~BytecodeRegisterAllocator();
86 Register NewRegister();
87
Ben Murdoch097c5b22016-05-18 11:27:45 +010088 // Ensure |count| consecutive allocations are available.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000089 void PrepareForConsecutiveAllocations(size_t count);
Ben Murdoch097c5b22016-05-18 11:27:45 +010090
91 // Get the next consecutive allocation after calling
92 // PrepareForConsecutiveAllocations.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000093 Register NextConsecutiveRegister();
94
Ben Murdoch097c5b22016-05-18 11:27:45 +010095 // Returns true if |reg| is allocated in this allocator.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000096 bool RegisterIsAllocatedInThisScope(Register reg) const;
97
Ben Murdoch097c5b22016-05-18 11:27:45 +010098 // Returns true if unused consecutive allocations remain.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000099 bool HasConsecutiveAllocations() const { return next_consecutive_count_ > 0; }
100
101 private:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100102 TemporaryRegisterAllocator* base_allocator() const { return base_allocator_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000103
Ben Murdoch097c5b22016-05-18 11:27:45 +0100104 TemporaryRegisterAllocator* base_allocator_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000105 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_