| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 #include "zone-inl.h" | 35 #include "zone-inl.h" |
| 36 | 36 |
| 37 namespace v8 { | 37 namespace v8 { |
| 38 namespace internal { | 38 namespace internal { |
| 39 | 39 |
| 40 // Forward declarations. | 40 // Forward declarations. |
| 41 class Node; | 41 class Node; |
| 42 | 42 |
| 43 class BitVector: public ZoneObject { | 43 class BitVector: public ZoneObject { |
| 44 public: | 44 public: |
| 45 BitVector() : length_(0), data_length_(0), data_(NULL) { } | 45 // Iterator for the elements of this BitVector. |
| 46 class Iterator BASE_EMBEDDED { |
| 47 public: |
| 48 explicit Iterator(BitVector* target) |
| 49 : target_(target), |
| 50 current_index_(0), |
| 51 current_value_(target->data_[0]), |
| 52 current_(-1) { |
| 53 ASSERT(target->data_length_ > 0); |
| 54 Advance(); |
| 55 } |
| 56 ~Iterator() { } |
| 46 | 57 |
| 47 explicit BitVector(int length) { | 58 bool Done() const { return current_index_ >= target_->data_length_; } |
| 48 ExpandTo(length); | 59 void Advance(); |
| 60 |
| 61 int Current() const { |
| 62 ASSERT(!Done()); |
| 63 return current_; |
| 64 } |
| 65 |
| 66 private: |
| 67 uint32_t SkipZeroBytes(uint32_t val) { |
| 68 while ((val & 0xFF) == 0) { |
| 69 val >>= 8; |
| 70 current_ += 8; |
| 71 } |
| 72 return val; |
| 73 } |
| 74 uint32_t SkipZeroBits(uint32_t val) { |
| 75 while ((val & 0x1) == 0) { |
| 76 val >>= 1; |
| 77 current_++; |
| 78 } |
| 79 return val; |
| 80 } |
| 81 |
| 82 BitVector* target_; |
| 83 int current_index_; |
| 84 uint32_t current_value_; |
| 85 int current_; |
| 86 |
| 87 friend class BitVector; |
| 88 }; |
| 89 |
| 90 explicit BitVector(int length) |
| 91 : length_(length), |
| 92 data_length_(SizeFor(length)), |
| 93 data_(ZONE->NewArray<uint32_t>(data_length_)) { |
| 94 ASSERT(length > 0); |
| 95 Clear(); |
| 49 } | 96 } |
| 50 | 97 |
| 51 BitVector(const BitVector& other) | 98 BitVector(const BitVector& other) |
| 52 : length_(other.length()), | 99 : length_(other.length()), |
| 53 data_length_(SizeFor(length_)), | 100 data_length_(SizeFor(length_)), |
| 54 data_(ZONE->NewArray<uint32_t>(data_length_)) { | 101 data_(ZONE->NewArray<uint32_t>(data_length_)) { |
| 55 CopyFrom(other); | 102 CopyFrom(other); |
| 56 } | 103 } |
| 57 | 104 |
| 58 void ExpandTo(int length) { | 105 static int SizeFor(int length) { |
| 59 ASSERT(length > 0); | 106 return 1 + ((length - 1) / 32); |
| 60 length_ = length; | |
| 61 data_length_ = SizeFor(length); | |
| 62 data_ = ZONE->NewArray<uint32_t>(data_length_); | |
| 63 Clear(); | |
| 64 } | 107 } |
| 65 | 108 |
| 66 BitVector& operator=(const BitVector& rhs) { | 109 BitVector& operator=(const BitVector& rhs) { |
| 67 if (this != &rhs) CopyFrom(rhs); | 110 if (this != &rhs) CopyFrom(rhs); |
| 68 return *this; | 111 return *this; |
| 69 } | 112 } |
| 70 | 113 |
| 71 void CopyFrom(const BitVector& other) { | 114 void CopyFrom(const BitVector& other) { |
| 72 ASSERT(other.length() == length()); | 115 ASSERT(other.length() == length()); |
| 73 for (int i = 0; i < data_length_; i++) { | 116 for (int i = 0; i < data_length_; i++) { |
| 74 data_[i] = other.data_[i]; | 117 data_[i] = other.data_[i]; |
| 75 } | 118 } |
| 76 } | 119 } |
| 77 | 120 |
| 78 bool Contains(int i) { | 121 bool Contains(int i) const { |
| 79 ASSERT(i >= 0 && i < length()); | 122 ASSERT(i >= 0 && i < length()); |
| 80 uint32_t block = data_[i / 32]; | 123 uint32_t block = data_[i / 32]; |
| 81 return (block & (1U << (i % 32))) != 0; | 124 return (block & (1U << (i % 32))) != 0; |
| 82 } | 125 } |
| 83 | 126 |
| 84 void Add(int i) { | 127 void Add(int i) { |
| 85 ASSERT(i >= 0 && i < length()); | 128 ASSERT(i >= 0 && i < length()); |
| 86 data_[i / 32] |= (1U << (i % 32)); | 129 data_[i / 32] |= (1U << (i % 32)); |
| 87 } | 130 } |
| 88 | 131 |
| 89 void Remove(int i) { | 132 void Remove(int i) { |
| 90 ASSERT(i >= 0 && i < length()); | 133 ASSERT(i >= 0 && i < length()); |
| 91 data_[i / 32] &= ~(1U << (i % 32)); | 134 data_[i / 32] &= ~(1U << (i % 32)); |
| 92 } | 135 } |
| 93 | 136 |
| 94 void Union(const BitVector& other) { | 137 void Union(const BitVector& other) { |
| 95 ASSERT(other.length() == length()); | 138 ASSERT(other.length() == length()); |
| 96 for (int i = 0; i < data_length_; i++) { | 139 for (int i = 0; i < data_length_; i++) { |
| 97 data_[i] |= other.data_[i]; | 140 data_[i] |= other.data_[i]; |
| 98 } | 141 } |
| 99 } | 142 } |
| 100 | 143 |
| 144 bool UnionIsChanged(const BitVector& other) { |
| 145 ASSERT(other.length() == length()); |
| 146 bool changed = false; |
| 147 for (int i = 0; i < data_length_; i++) { |
| 148 uint32_t old_data = data_[i]; |
| 149 data_[i] |= other.data_[i]; |
| 150 if (data_[i] != old_data) changed = true; |
| 151 } |
| 152 return changed; |
| 153 } |
| 154 |
| 101 void Intersect(const BitVector& other) { | 155 void Intersect(const BitVector& other) { |
| 102 ASSERT(other.length() == length()); | 156 ASSERT(other.length() == length()); |
| 103 for (int i = 0; i < data_length_; i++) { | 157 for (int i = 0; i < data_length_; i++) { |
| 104 data_[i] &= other.data_[i]; | 158 data_[i] &= other.data_[i]; |
| 105 } | 159 } |
| 106 } | 160 } |
| 107 | 161 |
| 108 void Subtract(const BitVector& other) { | 162 void Subtract(const BitVector& other) { |
| 109 ASSERT(other.length() == length()); | 163 ASSERT(other.length() == length()); |
| 110 for (int i = 0; i < data_length_; i++) { | 164 for (int i = 0; i < data_length_; i++) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 132 return true; | 186 return true; |
| 133 } | 187 } |
| 134 | 188 |
| 135 int length() const { return length_; } | 189 int length() const { return length_; } |
| 136 | 190 |
| 137 #ifdef DEBUG | 191 #ifdef DEBUG |
| 138 void Print(); | 192 void Print(); |
| 139 #endif | 193 #endif |
| 140 | 194 |
| 141 private: | 195 private: |
| 142 static int SizeFor(int length) { | |
| 143 return 1 + ((length - 1) / 32); | |
| 144 } | |
| 145 | |
| 146 int length_; | 196 int length_; |
| 147 int data_length_; | 197 int data_length_; |
| 148 uint32_t* data_; | 198 uint32_t* data_; |
| 149 }; | 199 }; |
| 150 | 200 |
| 151 | 201 |
| 202 // An implementation of a sparse set whose elements are drawn from integers |
| 203 // in the range [0..universe_size[. It supports constant-time Contains, |
| 204 // destructive Add, and destructuve Remove operations and linear-time (in |
| 205 // the number of elements) destructive Union. |
| 206 class SparseSet: public ZoneObject { |
| 207 public: |
| 208 // Iterator for sparse set elements. Elements should not be added or |
| 209 // removed during iteration. |
| 210 class Iterator BASE_EMBEDDED { |
| 211 public: |
| 212 explicit Iterator(SparseSet* target) : target_(target), current_(0) { |
| 213 ASSERT(++target->iterator_count_ > 0); |
| 214 } |
| 215 ~Iterator() { |
| 216 ASSERT(target_->iterator_count_-- > 0); |
| 217 } |
| 218 bool Done() const { return current_ >= target_->dense_.length(); } |
| 219 void Advance() { |
| 220 ASSERT(!Done()); |
| 221 ++current_; |
| 222 } |
| 223 int Current() { |
| 224 ASSERT(!Done()); |
| 225 return target_->dense_[current_]; |
| 226 } |
| 227 |
| 228 private: |
| 229 SparseSet* target_; |
| 230 int current_; |
| 231 |
| 232 friend class SparseSet; |
| 233 }; |
| 234 |
| 235 explicit SparseSet(int universe_size) |
| 236 : dense_(4), |
| 237 sparse_(ZONE->NewArray<int>(universe_size)) { |
| 238 #ifdef DEBUG |
| 239 size_ = universe_size; |
| 240 iterator_count_ = 0; |
| 241 #endif |
| 242 } |
| 243 |
| 244 bool Contains(int n) const { |
| 245 ASSERT(0 <= n && n < size_); |
| 246 int dense_index = sparse_[n]; |
| 247 return (0 <= dense_index) && |
| 248 (dense_index < dense_.length()) && |
| 249 (dense_[dense_index] == n); |
| 250 } |
| 251 |
| 252 void Add(int n) { |
| 253 ASSERT(0 <= n && n < size_); |
| 254 ASSERT(iterator_count_ == 0); |
| 255 if (!Contains(n)) { |
| 256 sparse_[n] = dense_.length(); |
| 257 dense_.Add(n); |
| 258 } |
| 259 } |
| 260 |
| 261 void Remove(int n) { |
| 262 ASSERT(0 <= n && n < size_); |
| 263 ASSERT(iterator_count_ == 0); |
| 264 if (Contains(n)) { |
| 265 int dense_index = sparse_[n]; |
| 266 int last = dense_.RemoveLast(); |
| 267 if (dense_index < dense_.length()) { |
| 268 dense_[dense_index] = last; |
| 269 sparse_[last] = dense_index; |
| 270 } |
| 271 } |
| 272 } |
| 273 |
| 274 void Union(const SparseSet& other) { |
| 275 for (int i = 0; i < other.dense_.length(); ++i) { |
| 276 Add(other.dense_[i]); |
| 277 } |
| 278 } |
| 279 |
| 280 private: |
| 281 // The set is implemented as a pair of a growable dense list and an |
| 282 // uninitialized sparse array. |
| 283 ZoneList<int> dense_; |
| 284 int* sparse_; |
| 285 #ifdef DEBUG |
| 286 int size_; |
| 287 int iterator_count_; |
| 288 #endif |
| 289 }; |
| 290 |
| 291 |
| 152 // Simple fixed-capacity list-based worklist (managed as a queue) of | 292 // Simple fixed-capacity list-based worklist (managed as a queue) of |
| 153 // pointers to T. | 293 // pointers to T. |
| 154 template<typename T> | 294 template<typename T> |
| 155 class WorkList BASE_EMBEDDED { | 295 class WorkList BASE_EMBEDDED { |
| 156 public: | 296 public: |
| 157 // The worklist cannot grow bigger than size. We keep one item empty to | 297 // The worklist cannot grow bigger than size. We keep one item empty to |
| 158 // distinguish between empty and full. | 298 // distinguish between empty and full. |
| 159 explicit WorkList(int size) | 299 explicit WorkList(int size) |
| 160 : capacity_(size + 1), head_(0), tail_(0), queue_(capacity_) { | 300 : capacity_(size + 1), head_(0), tail_(0), queue_(capacity_) { |
| 161 for (int i = 0; i < capacity_; i++) queue_.Add(NULL); | 301 for (int i = 0; i < capacity_; i++) queue_.Add(NULL); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 191 int tail_; // Where the next inserted item will go. | 331 int tail_; // Where the next inserted item will go. |
| 192 List<T*> queue_; | 332 List<T*> queue_; |
| 193 }; | 333 }; |
| 194 | 334 |
| 195 | 335 |
| 196 // Computes the set of assigned variables and annotates variables proxies | 336 // Computes the set of assigned variables and annotates variables proxies |
| 197 // that are trivial sub-expressions and for-loops where the loop variable | 337 // that are trivial sub-expressions and for-loops where the loop variable |
| 198 // is guaranteed to be a smi. | 338 // is guaranteed to be a smi. |
| 199 class AssignedVariablesAnalyzer : public AstVisitor { | 339 class AssignedVariablesAnalyzer : public AstVisitor { |
| 200 public: | 340 public: |
| 201 explicit AssignedVariablesAnalyzer() : info_(NULL) { } | 341 static bool Analyze(CompilationInfo* info); |
| 202 bool Analyze(CompilationInfo* info); | |
| 203 | 342 |
| 204 private: | 343 private: |
| 344 AssignedVariablesAnalyzer(CompilationInfo* info, int bits); |
| 345 bool Analyze(); |
| 346 |
| 205 Variable* FindSmiLoopVariable(ForStatement* stmt); | 347 Variable* FindSmiLoopVariable(ForStatement* stmt); |
| 206 | 348 |
| 207 int BitIndex(Variable* var); | 349 int BitIndex(Variable* var); |
| 208 | 350 |
| 209 void RecordAssignedVar(Variable* var); | 351 void RecordAssignedVar(Variable* var); |
| 210 | 352 |
| 211 void MarkIfTrivial(Expression* expr); | 353 void MarkIfTrivial(Expression* expr); |
| 212 | 354 |
| 213 // Visits an expression saving the accumulator before, clearing | 355 // Visits an expression saving the accumulator before, clearing |
| 214 // it before visting and restoring it after visiting. | 356 // it before visting and restoring it after visiting. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 225 BitVector av_; | 367 BitVector av_; |
| 226 | 368 |
| 227 DISALLOW_COPY_AND_ASSIGN(AssignedVariablesAnalyzer); | 369 DISALLOW_COPY_AND_ASSIGN(AssignedVariablesAnalyzer); |
| 228 }; | 370 }; |
| 229 | 371 |
| 230 | 372 |
| 231 } } // namespace v8::internal | 373 } } // namespace v8::internal |
| 232 | 374 |
| 233 | 375 |
| 234 #endif // V8_DATAFLOW_H_ | 376 #endif // V8_DATAFLOW_H_ |
| OLD | NEW |