• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 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_DATAFLOW_H_
6 #define V8_DATAFLOW_H_
7 
8 #include "src/allocation.h"
9 #include "src/zone.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 class BitVector : public ZoneObject {
15  public:
16   // Iterator for the elements of this BitVector.
17   class Iterator BASE_EMBEDDED {
18    public:
Iterator(BitVector * target)19     explicit Iterator(BitVector* target)
20         : target_(target),
21           current_index_(0),
22           current_value_(target->data_[0]),
23           current_(-1) {
24       DCHECK(target->data_length_ > 0);
25       Advance();
26     }
~Iterator()27     ~Iterator() {}
28 
Done()29     bool Done() const { return current_index_ >= target_->data_length_; }
30     void Advance();
31 
Current()32     int Current() const {
33       DCHECK(!Done());
34       return current_;
35     }
36 
37    private:
SkipZeroBytes(uintptr_t val)38     uintptr_t SkipZeroBytes(uintptr_t val) {
39       while ((val & 0xFF) == 0) {
40         val >>= 8;
41         current_ += 8;
42       }
43       return val;
44     }
SkipZeroBits(uintptr_t val)45     uintptr_t SkipZeroBits(uintptr_t val) {
46       while ((val & 0x1) == 0) {
47         val >>= 1;
48         current_++;
49       }
50       return val;
51     }
52 
53     BitVector* target_;
54     int current_index_;
55     uintptr_t current_value_;
56     int current_;
57 
58     friend class BitVector;
59   };
60 
61   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 
BitVector(int length,Zone * zone)65   BitVector(int length, Zone* zone)
66       : length_(length),
67         data_length_(SizeFor(length)),
68         data_(zone->NewArray<uintptr_t>(data_length_)) {
69     DCHECK_LE(0, length);
70     Clear();
71   }
72 
BitVector(const BitVector & other,Zone * zone)73   BitVector(const BitVector& other, Zone* zone)
74       : length_(other.length()),
75         data_length_(SizeFor(length_)),
76         data_(zone->NewArray<uintptr_t>(data_length_)) {
77     CopyFrom(other);
78   }
79 
SizeFor(int length)80   static int SizeFor(int length) {
81     if (length == 0) return 1;
82     return 1 + ((length - 1) / kDataBits);
83   }
84 
CopyFrom(const BitVector & other)85   void CopyFrom(const BitVector& other) {
86     DCHECK(other.length() <= length());
87     for (int i = 0; i < other.data_length_; i++) {
88       data_[i] = other.data_[i];
89     }
90     for (int i = other.data_length_; i < data_length_; i++) {
91       data_[i] = 0;
92     }
93   }
94 
Contains(int i)95   bool Contains(int i) const {
96     DCHECK(i >= 0 && i < length());
97     uintptr_t block = data_[i / kDataBits];
98     return (block & (kOne << (i % kDataBits))) != 0;
99   }
100 
Add(int i)101   void Add(int i) {
102     DCHECK(i >= 0 && i < length());
103     data_[i / kDataBits] |= (kOne << (i % kDataBits));
104   }
105 
AddAll()106   void AddAll() { memset(data_, -1, sizeof(uintptr_t) * data_length_); }
107 
Remove(int i)108   void Remove(int i) {
109     DCHECK(i >= 0 && i < length());
110     data_[i / kDataBits] &= ~(kOne << (i % kDataBits));
111   }
112 
Union(const BitVector & other)113   void Union(const BitVector& other) {
114     DCHECK(other.length() == length());
115     for (int i = 0; i < data_length_; i++) {
116       data_[i] |= other.data_[i];
117     }
118   }
119 
UnionIsChanged(const BitVector & other)120   bool UnionIsChanged(const BitVector& other) {
121     DCHECK(other.length() == length());
122     bool changed = false;
123     for (int i = 0; i < data_length_; i++) {
124       uintptr_t old_data = data_[i];
125       data_[i] |= other.data_[i];
126       if (data_[i] != old_data) changed = true;
127     }
128     return changed;
129   }
130 
Intersect(const BitVector & other)131   void Intersect(const BitVector& other) {
132     DCHECK(other.length() == length());
133     for (int i = 0; i < data_length_; i++) {
134       data_[i] &= other.data_[i];
135     }
136   }
137 
IntersectIsChanged(const BitVector & other)138   bool IntersectIsChanged(const BitVector& other) {
139     DCHECK(other.length() == length());
140     bool changed = false;
141     for (int i = 0; i < data_length_; i++) {
142       uintptr_t old_data = data_[i];
143       data_[i] &= other.data_[i];
144       if (data_[i] != old_data) changed = true;
145     }
146     return changed;
147   }
148 
Subtract(const BitVector & other)149   void Subtract(const BitVector& other) {
150     DCHECK(other.length() == length());
151     for (int i = 0; i < data_length_; i++) {
152       data_[i] &= ~other.data_[i];
153     }
154   }
155 
Clear()156   void Clear() {
157     for (int i = 0; i < data_length_; i++) {
158       data_[i] = 0;
159     }
160   }
161 
IsEmpty()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 
Equals(const BitVector & other)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 
176   int Count() const;
177 
length()178   int length() const { return length_; }
179 
180 #ifdef DEBUG
181   void Print();
182 #endif
183 
184  private:
185   const int length_;
186   const int data_length_;
187   uintptr_t* const data_;
188 
189   DISALLOW_COPY_AND_ASSIGN(BitVector);
190 };
191 
192 
193 class GrowableBitVector BASE_EMBEDDED {
194  public:
195   class Iterator BASE_EMBEDDED {
196    public:
Iterator(const GrowableBitVector * target,Zone * zone)197     Iterator(const GrowableBitVector* target, Zone* zone)
198         : it_(target->bits_ == NULL ? new (zone) BitVector(1, zone)
199                                     : target->bits_) {}
Done()200     bool Done() const { return it_.Done(); }
Advance()201     void Advance() { it_.Advance(); }
Current()202     int Current() const { return it_.Current(); }
203 
204    private:
205     BitVector::Iterator it_;
206   };
207 
GrowableBitVector()208   GrowableBitVector() : bits_(NULL) {}
GrowableBitVector(int length,Zone * zone)209   GrowableBitVector(int length, Zone* zone)
210       : bits_(new (zone) BitVector(length, zone)) {}
211 
Contains(int value)212   bool Contains(int value) const {
213     if (!InBitsRange(value)) return false;
214     return bits_->Contains(value);
215   }
216 
Add(int value,Zone * zone)217   void Add(int value, Zone* zone) {
218     EnsureCapacity(value, zone);
219     bits_->Add(value);
220   }
221 
Union(const GrowableBitVector & other,Zone * zone)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 
Clear()228   void Clear() {
229     if (bits_ != NULL) bits_->Clear();
230   }
231 
232  private:
233   static const int kInitialLength = 1024;
234 
InBitsRange(int value)235   bool InBitsRange(int value) const {
236     return bits_ != NULL && bits_->length() > value;
237   }
238 
EnsureCapacity(int value,Zone * zone)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;
243     BitVector* new_bits = new (zone) BitVector(new_length, zone);
244     if (bits_ != NULL) new_bits->CopyFrom(*bits_);
245     bits_ = new_bits;
246   }
247 
248   BitVector* bits_;
249 };
250 
251 }  // namespace internal
252 }  // namespace v8
253 
254 #endif  // V8_DATAFLOW_H_
255