blob: 9fc747d06fae6ea0cf454a7d14047a595f832966 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Leon Clarke4515c472010-02-03 11:58:03 +00004
5#ifndef V8_DATAFLOW_H_
6#define V8_DATAFLOW_H_
7
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/v8.h"
Steve Block6ded16b2010-05-10 14:33:55 +01009
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/allocation.h"
11#include "src/ast.h"
12#include "src/compiler.h"
13#include "src/zone-inl.h"
Leon Clarke4515c472010-02-03 11:58:03 +000014
15namespace v8 {
16namespace internal {
17
Emily Bernierd0a1eb72015-03-24 16:35:39 -040018class BitVector : public ZoneObject {
Steve Block6ded16b2010-05-10 14:33:55 +010019 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +010020 // Iterator for the elements of this BitVector.
21 class Iterator BASE_EMBEDDED {
22 public:
23 explicit Iterator(BitVector* target)
24 : target_(target),
25 current_index_(0),
26 current_value_(target->data_[0]),
27 current_(-1) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000028 DCHECK(target->data_length_ > 0);
Ben Murdochb0fe1622011-05-05 13:52:32 +010029 Advance();
30 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040031 ~Iterator() {}
Kristian Monsen80d68ea2010-09-08 11:05:35 +010032
Ben Murdochb0fe1622011-05-05 13:52:32 +010033 bool Done() const { return current_index_ >= target_->data_length_; }
34 void Advance();
35
36 int Current() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000037 DCHECK(!Done());
Ben Murdochb0fe1622011-05-05 13:52:32 +010038 return current_;
39 }
40
41 private:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040042 uintptr_t SkipZeroBytes(uintptr_t val) {
Ben Murdochb0fe1622011-05-05 13:52:32 +010043 while ((val & 0xFF) == 0) {
44 val >>= 8;
45 current_ += 8;
46 }
47 return val;
48 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040049 uintptr_t SkipZeroBits(uintptr_t val) {
Ben Murdochb0fe1622011-05-05 13:52:32 +010050 while ((val & 0x1) == 0) {
51 val >>= 1;
52 current_++;
53 }
54 return val;
55 }
56
57 BitVector* target_;
58 int current_index_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040059 uintptr_t current_value_;
Ben Murdochb0fe1622011-05-05 13:52:32 +010060 int current_;
61
62 friend class BitVector;
63 };
64
Emily Bernierd0a1eb72015-03-24 16:35:39 -040065 static const int kDataBits = kPointerSize * 8;
66 static const int kDataBitShift = kPointerSize == 8 ? 6 : 5;
67 static const uintptr_t kOne = 1; // This saves some static_casts.
68
Ben Murdoch3ef787d2012-04-12 10:51:47 +010069 BitVector(int length, Zone* zone)
Ben Murdochb0fe1622011-05-05 13:52:32 +010070 : length_(length),
71 data_length_(SizeFor(length)),
Emily Bernierd0a1eb72015-03-24 16:35:39 -040072 data_(zone->NewArray<uintptr_t>(data_length_)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000073 DCHECK(length > 0);
Ben Murdochb0fe1622011-05-05 13:52:32 +010074 Clear();
Steve Block6ded16b2010-05-10 14:33:55 +010075 }
76
Ben Murdoch3ef787d2012-04-12 10:51:47 +010077 BitVector(const BitVector& other, Zone* zone)
Steve Block6ded16b2010-05-10 14:33:55 +010078 : length_(other.length()),
79 data_length_(SizeFor(length_)),
Emily Bernierd0a1eb72015-03-24 16:35:39 -040080 data_(zone->NewArray<uintptr_t>(data_length_)) {
Steve Block6ded16b2010-05-10 14:33:55 +010081 CopyFrom(other);
82 }
83
Emily Bernierd0a1eb72015-03-24 16:35:39 -040084 static int SizeFor(int length) { return 1 + ((length - 1) / kDataBits); }
Steve Block6ded16b2010-05-10 14:33:55 +010085
86 void CopyFrom(const BitVector& other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000087 DCHECK(other.length() <= length());
Steve Block9fac8402011-05-12 15:51:54 +010088 for (int i = 0; i < other.data_length_; i++) {
Steve Block6ded16b2010-05-10 14:33:55 +010089 data_[i] = other.data_[i];
90 }
Steve Block9fac8402011-05-12 15:51:54 +010091 for (int i = other.data_length_; i < data_length_; i++) {
92 data_[i] = 0;
93 }
Steve Block6ded16b2010-05-10 14:33:55 +010094 }
95
Ben Murdochb0fe1622011-05-05 13:52:32 +010096 bool Contains(int i) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000097 DCHECK(i >= 0 && i < length());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040098 uintptr_t block = data_[i / kDataBits];
99 return (block & (kOne << (i % kDataBits))) != 0;
Steve Block6ded16b2010-05-10 14:33:55 +0100100 }
101
102 void Add(int i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000103 DCHECK(i >= 0 && i < length());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400104 data_[i / kDataBits] |= (kOne << (i % kDataBits));
Steve Block6ded16b2010-05-10 14:33:55 +0100105 }
106
107 void Remove(int i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000108 DCHECK(i >= 0 && i < length());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400109 data_[i / kDataBits] &= ~(kOne << (i % kDataBits));
Steve Block6ded16b2010-05-10 14:33:55 +0100110 }
111
112 void Union(const BitVector& other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000113 DCHECK(other.length() == length());
Steve Block6ded16b2010-05-10 14:33:55 +0100114 for (int i = 0; i < data_length_; i++) {
115 data_[i] |= other.data_[i];
116 }
117 }
118
Ben Murdochb0fe1622011-05-05 13:52:32 +0100119 bool UnionIsChanged(const BitVector& other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000120 DCHECK(other.length() == length());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100121 bool changed = false;
122 for (int i = 0; i < data_length_; i++) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400123 uintptr_t old_data = data_[i];
Ben Murdochb0fe1622011-05-05 13:52:32 +0100124 data_[i] |= other.data_[i];
125 if (data_[i] != old_data) changed = true;
126 }
127 return changed;
128 }
129
Steve Block6ded16b2010-05-10 14:33:55 +0100130 void Intersect(const BitVector& other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000131 DCHECK(other.length() == length());
Steve Block6ded16b2010-05-10 14:33:55 +0100132 for (int i = 0; i < data_length_; i++) {
133 data_[i] &= other.data_[i];
134 }
135 }
136
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000137 bool IntersectIsChanged(const BitVector& other) {
138 DCHECK(other.length() == length());
139 bool changed = false;
140 for (int i = 0; i < data_length_; i++) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400141 uintptr_t old_data = data_[i];
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000142 data_[i] &= other.data_[i];
143 if (data_[i] != old_data) changed = true;
144 }
145 return changed;
146 }
147
Steve Block6ded16b2010-05-10 14:33:55 +0100148 void Subtract(const BitVector& other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149 DCHECK(other.length() == length());
Steve Block6ded16b2010-05-10 14:33:55 +0100150 for (int i = 0; i < data_length_; i++) {
151 data_[i] &= ~other.data_[i];
152 }
153 }
154
155 void Clear() {
156 for (int i = 0; i < data_length_; i++) {
157 data_[i] = 0;
158 }
159 }
160
161 bool IsEmpty() const {
162 for (int i = 0; i < data_length_; i++) {
163 if (data_[i] != 0) return false;
164 }
165 return true;
166 }
167
168 bool Equals(const BitVector& other) {
169 for (int i = 0; i < data_length_; i++) {
170 if (data_[i] != other.data_[i]) return false;
171 }
172 return true;
173 }
174
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175 int Count() const;
176
Steve Block6ded16b2010-05-10 14:33:55 +0100177 int length() const { return length_; }
178
179#ifdef DEBUG
180 void Print();
181#endif
182
183 private:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400184 const int length_;
185 const int data_length_;
186 uintptr_t* const data_;
187
188 DISALLOW_COPY_AND_ASSIGN(BitVector);
Steve Block6ded16b2010-05-10 14:33:55 +0100189};
190
Leon Clarke4515c472010-02-03 11:58:03 +0000191
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000192class GrowableBitVector BASE_EMBEDDED {
193 public:
194 class Iterator BASE_EMBEDDED {
195 public:
196 Iterator(const GrowableBitVector* target, Zone* zone)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400197 : it_(target->bits_ == NULL ? new (zone) BitVector(1, zone)
198 : target->bits_) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000199 bool Done() const { return it_.Done(); }
200 void Advance() { it_.Advance(); }
201 int Current() const { return it_.Current(); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400202
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000203 private:
204 BitVector::Iterator it_;
205 };
206
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400207 GrowableBitVector() : bits_(NULL) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208 GrowableBitVector(int length, Zone* zone)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400209 : bits_(new (zone) BitVector(length, zone)) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000210
211 bool Contains(int value) const {
212 if (!InBitsRange(value)) return false;
213 return bits_->Contains(value);
214 }
215
216 void Add(int value, Zone* zone) {
217 EnsureCapacity(value, zone);
218 bits_->Add(value);
219 }
220
221 void Union(const GrowableBitVector& other, Zone* zone) {
222 for (Iterator it(&other, zone); !it.Done(); it.Advance()) {
223 Add(it.Current(), zone);
224 }
225 }
226
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400227 void Clear() {
228 if (bits_ != NULL) bits_->Clear();
229 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000230
231 private:
232 static const int kInitialLength = 1024;
233
234 bool InBitsRange(int value) const {
235 return bits_ != NULL && bits_->length() > value;
236 }
237
238 void EnsureCapacity(int value, Zone* zone) {
239 if (InBitsRange(value)) return;
240 int new_length = bits_ == NULL ? kInitialLength : bits_->length();
241 while (new_length <= value) new_length *= 2;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400242 BitVector* new_bits = new (zone) BitVector(new_length, zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000243 if (bits_ != NULL) new_bits->CopyFrom(*bits_);
244 bits_ = new_bits;
245 }
246
247 BitVector* bits_;
248};
249
250} // namespace internal
251} // namespace v8
Andrei Popescu402d9372010-02-26 13:31:12 +0000252
Leon Clarke4515c472010-02-03 11:58:03 +0000253#endif // V8_DATAFLOW_H_