blob: 3703f28d91d84813301aebd4ebbcadbbea678a27 [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/allocation.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009#include "src/zone.h"
Leon Clarke4515c472010-02-03 11:58:03 +000010
11namespace v8 {
12namespace internal {
13
Emily Bernierd0a1eb72015-03-24 16:35:39 -040014class BitVector : public ZoneObject {
Steve Block6ded16b2010-05-10 14:33:55 +010015 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +010016 // Iterator for the elements of this BitVector.
17 class Iterator BASE_EMBEDDED {
18 public:
19 explicit Iterator(BitVector* target)
20 : target_(target),
21 current_index_(0),
22 current_value_(target->data_[0]),
23 current_(-1) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000024 DCHECK(target->data_length_ > 0);
Ben Murdochb0fe1622011-05-05 13:52:32 +010025 Advance();
26 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040027 ~Iterator() {}
Kristian Monsen80d68ea2010-09-08 11:05:35 +010028
Ben Murdochb0fe1622011-05-05 13:52:32 +010029 bool Done() const { return current_index_ >= target_->data_length_; }
30 void Advance();
31
32 int Current() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033 DCHECK(!Done());
Ben Murdochb0fe1622011-05-05 13:52:32 +010034 return current_;
35 }
36
37 private:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040038 uintptr_t SkipZeroBytes(uintptr_t val) {
Ben Murdochb0fe1622011-05-05 13:52:32 +010039 while ((val & 0xFF) == 0) {
40 val >>= 8;
41 current_ += 8;
42 }
43 return val;
44 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040045 uintptr_t SkipZeroBits(uintptr_t val) {
Ben Murdochb0fe1622011-05-05 13:52:32 +010046 while ((val & 0x1) == 0) {
47 val >>= 1;
48 current_++;
49 }
50 return val;
51 }
52
53 BitVector* target_;
54 int current_index_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040055 uintptr_t current_value_;
Ben Murdochb0fe1622011-05-05 13:52:32 +010056 int current_;
57
58 friend class BitVector;
59 };
60
Emily Bernierd0a1eb72015-03-24 16:35:39 -040061 static const int kDataBits = kPointerSize * 8;
62 static const int kDataBitShift = kPointerSize == 8 ? 6 : 5;
63 static const uintptr_t kOne = 1; // This saves some static_casts.
64
Ben Murdoch3ef787d2012-04-12 10:51:47 +010065 BitVector(int length, Zone* zone)
Ben Murdochb0fe1622011-05-05 13:52:32 +010066 : length_(length),
67 data_length_(SizeFor(length)),
Emily Bernierd0a1eb72015-03-24 16:35:39 -040068 data_(zone->NewArray<uintptr_t>(data_length_)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000069 DCHECK_LE(0, length);
Ben Murdochb0fe1622011-05-05 13:52:32 +010070 Clear();
Steve Block6ded16b2010-05-10 14:33:55 +010071 }
72
Ben Murdoch3ef787d2012-04-12 10:51:47 +010073 BitVector(const BitVector& other, Zone* zone)
Steve Block6ded16b2010-05-10 14:33:55 +010074 : length_(other.length()),
75 data_length_(SizeFor(length_)),
Emily Bernierd0a1eb72015-03-24 16:35:39 -040076 data_(zone->NewArray<uintptr_t>(data_length_)) {
Steve Block6ded16b2010-05-10 14:33:55 +010077 CopyFrom(other);
78 }
79
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000080 static int SizeFor(int length) {
81 if (length == 0) return 1;
82 return 1 + ((length - 1) / kDataBits);
83 }
Steve Block6ded16b2010-05-10 14:33:55 +010084
85 void CopyFrom(const BitVector& other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000086 DCHECK(other.length() <= length());
Steve Block9fac8402011-05-12 15:51:54 +010087 for (int i = 0; i < other.data_length_; i++) {
Steve Block6ded16b2010-05-10 14:33:55 +010088 data_[i] = other.data_[i];
89 }
Steve Block9fac8402011-05-12 15:51:54 +010090 for (int i = other.data_length_; i < data_length_; i++) {
91 data_[i] = 0;
92 }
Steve Block6ded16b2010-05-10 14:33:55 +010093 }
94
Ben Murdochb0fe1622011-05-05 13:52:32 +010095 bool Contains(int i) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000096 DCHECK(i >= 0 && i < length());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040097 uintptr_t block = data_[i / kDataBits];
98 return (block & (kOne << (i % kDataBits))) != 0;
Steve Block6ded16b2010-05-10 14:33:55 +010099 }
100
101 void Add(int i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000102 DCHECK(i >= 0 && i < length());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400103 data_[i / kDataBits] |= (kOne << (i % kDataBits));
Steve Block6ded16b2010-05-10 14:33:55 +0100104 }
105
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000106 void AddAll() { memset(data_, -1, sizeof(uintptr_t) * data_length_); }
107
Steve Block6ded16b2010-05-10 14:33:55 +0100108 void Remove(int i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000109 DCHECK(i >= 0 && i < length());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400110 data_[i / kDataBits] &= ~(kOne << (i % kDataBits));
Steve Block6ded16b2010-05-10 14:33:55 +0100111 }
112
113 void Union(const BitVector& other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000114 DCHECK(other.length() == length());
Steve Block6ded16b2010-05-10 14:33:55 +0100115 for (int i = 0; i < data_length_; i++) {
116 data_[i] |= other.data_[i];
117 }
118 }
119
Ben Murdochb0fe1622011-05-05 13:52:32 +0100120 bool UnionIsChanged(const BitVector& other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000121 DCHECK(other.length() == length());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100122 bool changed = false;
123 for (int i = 0; i < data_length_; i++) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400124 uintptr_t old_data = data_[i];
Ben Murdochb0fe1622011-05-05 13:52:32 +0100125 data_[i] |= other.data_[i];
126 if (data_[i] != old_data) changed = true;
127 }
128 return changed;
129 }
130
Steve Block6ded16b2010-05-10 14:33:55 +0100131 void Intersect(const BitVector& other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000132 DCHECK(other.length() == length());
Steve Block6ded16b2010-05-10 14:33:55 +0100133 for (int i = 0; i < data_length_; i++) {
134 data_[i] &= other.data_[i];
135 }
136 }
137
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000138 bool IntersectIsChanged(const BitVector& other) {
139 DCHECK(other.length() == length());
140 bool changed = false;
141 for (int i = 0; i < data_length_; i++) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400142 uintptr_t old_data = data_[i];
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000143 data_[i] &= other.data_[i];
144 if (data_[i] != old_data) changed = true;
145 }
146 return changed;
147 }
148
Steve Block6ded16b2010-05-10 14:33:55 +0100149 void Subtract(const BitVector& other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000150 DCHECK(other.length() == length());
Steve Block6ded16b2010-05-10 14:33:55 +0100151 for (int i = 0; i < data_length_; i++) {
152 data_[i] &= ~other.data_[i];
153 }
154 }
155
156 void Clear() {
157 for (int i = 0; i < data_length_; i++) {
158 data_[i] = 0;
159 }
160 }
161
162 bool IsEmpty() const {
163 for (int i = 0; i < data_length_; i++) {
164 if (data_[i] != 0) return false;
165 }
166 return true;
167 }
168
169 bool Equals(const BitVector& other) {
170 for (int i = 0; i < data_length_; i++) {
171 if (data_[i] != other.data_[i]) return false;
172 }
173 return true;
174 }
175
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000176 int Count() const;
177
Steve Block6ded16b2010-05-10 14:33:55 +0100178 int length() const { return length_; }
179
180#ifdef DEBUG
181 void Print();
182#endif
183
184 private:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400185 const int length_;
186 const int data_length_;
187 uintptr_t* const data_;
188
189 DISALLOW_COPY_AND_ASSIGN(BitVector);
Steve Block6ded16b2010-05-10 14:33:55 +0100190};
191
Leon Clarke4515c472010-02-03 11:58:03 +0000192
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000193class GrowableBitVector BASE_EMBEDDED {
194 public:
195 class Iterator BASE_EMBEDDED {
196 public:
197 Iterator(const GrowableBitVector* target, Zone* zone)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400198 : it_(target->bits_ == NULL ? new (zone) BitVector(1, zone)
199 : target->bits_) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000200 bool Done() const { return it_.Done(); }
201 void Advance() { it_.Advance(); }
202 int Current() const { return it_.Current(); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400203
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000204 private:
205 BitVector::Iterator it_;
206 };
207
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400208 GrowableBitVector() : bits_(NULL) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000209 GrowableBitVector(int length, Zone* zone)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400210 : bits_(new (zone) BitVector(length, zone)) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000211
212 bool Contains(int value) const {
213 if (!InBitsRange(value)) return false;
214 return bits_->Contains(value);
215 }
216
217 void Add(int value, Zone* zone) {
218 EnsureCapacity(value, zone);
219 bits_->Add(value);
220 }
221
222 void Union(const GrowableBitVector& other, Zone* zone) {
223 for (Iterator it(&other, zone); !it.Done(); it.Advance()) {
224 Add(it.Current(), zone);
225 }
226 }
227
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400228 void Clear() {
229 if (bits_ != NULL) bits_->Clear();
230 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000231
232 private:
233 static const int kInitialLength = 1024;
234
235 bool InBitsRange(int value) const {
236 return bits_ != NULL && bits_->length() > value;
237 }
238
239 void EnsureCapacity(int value, Zone* zone) {
240 if (InBitsRange(value)) return;
241 int new_length = bits_ == NULL ? kInitialLength : bits_->length();
242 while (new_length <= value) new_length *= 2;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400243 BitVector* new_bits = new (zone) BitVector(new_length, zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000244 if (bits_ != NULL) new_bits->CopyFrom(*bits_);
245 bits_ = new_bits;
246 }
247
248 BitVector* bits_;
249};
250
251} // namespace internal
252} // namespace v8
Andrei Popescu402d9372010-02-26 13:31:12 +0000253
Leon Clarke4515c472010-02-03 11:58:03 +0000254#endif // V8_DATAFLOW_H_