v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
utils.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_UTILS_H_
29 #define V8_UTILS_H_
30 
31 #include <stdlib.h>
32 #include <string.h>
33 #include <climits>
34 
35 #include "globals.h"
36 #include "checks.h"
37 #include "allocation.h"
38 
39 namespace v8 {
40 namespace internal {
41 
42 // ----------------------------------------------------------------------------
43 // General helper functions
44 
45 #define IS_POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0)
46 
47 // Returns true iff x is a power of 2 (or zero). Cannot be used with the
48 // maximally negative value of the type T (the -1 overflows).
49 template <typename T>
50 inline bool IsPowerOf2(T x) {
51  return IS_POWER_OF_TWO(x);
52 }
53 
54 
55 // X must be a power of 2. Returns the number of trailing zeros.
56 inline int WhichPowerOf2(uint32_t x) {
57  ASSERT(IsPowerOf2(x));
58  ASSERT(x != 0);
59  int bits = 0;
60 #ifdef DEBUG
61  int original_x = x;
62 #endif
63  if (x >= 0x10000) {
64  bits += 16;
65  x >>= 16;
66  }
67  if (x >= 0x100) {
68  bits += 8;
69  x >>= 8;
70  }
71  if (x >= 0x10) {
72  bits += 4;
73  x >>= 4;
74  }
75  switch (x) {
76  default: UNREACHABLE();
77  case 8: bits++; // Fall through.
78  case 4: bits++; // Fall through.
79  case 2: bits++; // Fall through.
80  case 1: break;
81  }
82  ASSERT_EQ(1 << bits, original_x);
83  return bits;
84  return 0;
85 }
86 
87 
88 // Magic numbers for integer division.
89 // These are kind of 2's complement reciprocal of the divisors.
90 // Details and proofs can be found in:
91 // - Hacker's Delight, Henry S. Warren, Jr.
92 // - The PowerPC Compiler Writer’s Guide
93 // and probably many others.
94 // See details in the implementation of the algorithm in
95 // lithium-codegen-arm.cc : LCodeGen::TryEmitSignedIntegerDivisionByConstant().
97  unsigned M;
98  unsigned s;
99 };
100 
102 const DivMagicNumbers DivMagicNumberFor3 = {0x55555556, 0};
103 const DivMagicNumbers DivMagicNumberFor5 = {0x66666667, 1};
104 const DivMagicNumbers DivMagicNumberFor7 = {0x92492493, 2};
105 const DivMagicNumbers DivMagicNumberFor9 = {0x38e38e39, 1};
106 const DivMagicNumbers DivMagicNumberFor11 = {0x2e8ba2e9, 1};
107 const DivMagicNumbers DivMagicNumberFor25 = {0x51eb851f, 3};
108 const DivMagicNumbers DivMagicNumberFor125 = {0x10624dd3, 3};
109 const DivMagicNumbers DivMagicNumberFor625 = {0x68db8bad, 8};
110 
111 const DivMagicNumbers DivMagicNumberFor(int32_t divisor);
112 
113 
114 // The C++ standard leaves the semantics of '>>' undefined for
115 // negative signed operands. Most implementations do the right thing,
116 // though.
117 inline int ArithmeticShiftRight(int x, int s) {
118  return x >> s;
119 }
120 
121 
122 // Compute the 0-relative offset of some absolute value x of type T.
123 // This allows conversion of Addresses and integral types into
124 // 0-relative int offsets.
125 template <typename T>
126 inline intptr_t OffsetFrom(T x) {
127  return x - static_cast<T>(0);
128 }
129 
130 
131 // Compute the absolute value of type T for some 0-relative offset x.
132 // This allows conversion of 0-relative int offsets into Addresses and
133 // integral types.
134 template <typename T>
135 inline T AddressFrom(intptr_t x) {
136  return static_cast<T>(static_cast<T>(0) + x);
137 }
138 
139 
140 // Return the largest multiple of m which is <= x.
141 template <typename T>
142 inline T RoundDown(T x, intptr_t m) {
143  ASSERT(IsPowerOf2(m));
144  return AddressFrom<T>(OffsetFrom(x) & -m);
145 }
146 
147 
148 // Return the smallest multiple of m which is >= x.
149 template <typename T>
150 inline T RoundUp(T x, intptr_t m) {
151  return RoundDown<T>(static_cast<T>(x + m - 1), m);
152 }
153 
154 
155 template <typename T>
156 int Compare(const T& a, const T& b) {
157  if (a == b)
158  return 0;
159  else if (a < b)
160  return -1;
161  else
162  return 1;
163 }
164 
165 
166 template <typename T>
167 int PointerValueCompare(const T* a, const T* b) {
168  return Compare<T>(*a, *b);
169 }
170 
171 
172 // Compare function to compare the object pointer value of two
173 // handlified objects. The handles are passed as pointers to the
174 // handles.
175 template<typename T> class Handle; // Forward declaration.
176 template <typename T>
178  return Compare<T*>(*(*a), *(*b));
179 }
180 
181 
182 // Returns the smallest power of two which is >= x. If you pass in a
183 // number that is already a power of two, it is returned as is.
184 // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
185 // figure 3-3, page 48, where the function is called clp2.
186 inline uint32_t RoundUpToPowerOf2(uint32_t x) {
187  ASSERT(x <= 0x80000000u);
188  x = x - 1;
189  x = x | (x >> 1);
190  x = x | (x >> 2);
191  x = x | (x >> 4);
192  x = x | (x >> 8);
193  x = x | (x >> 16);
194  return x + 1;
195 }
196 
197 
198 inline uint32_t RoundDownToPowerOf2(uint32_t x) {
199  uint32_t rounded_up = RoundUpToPowerOf2(x);
200  if (rounded_up > x) return rounded_up >> 1;
201  return rounded_up;
202 }
203 
204 
205 template <typename T, typename U>
206 inline bool IsAligned(T value, U alignment) {
207  return (value & (alignment - 1)) == 0;
208 }
209 
210 
211 // Returns true if (addr + offset) is aligned.
212 inline bool IsAddressAligned(Address addr,
213  intptr_t alignment,
214  int offset = 0) {
215  intptr_t offs = OffsetFrom(addr + offset);
216  return IsAligned(offs, alignment);
217 }
218 
219 
220 // Returns the maximum of the two parameters.
221 template <typename T>
222 T Max(T a, T b) {
223  return a < b ? b : a;
224 }
225 
226 
227 // Returns the minimum of the two parameters.
228 template <typename T>
229 T Min(T a, T b) {
230  return a < b ? a : b;
231 }
232 
233 
234 inline int StrLength(const char* string) {
235  size_t length = strlen(string);
236  ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
237  return static_cast<int>(length);
238 }
239 
240 
241 // ----------------------------------------------------------------------------
242 // BitField is a help template for encoding and decode bitfield with
243 // unsigned content.
244 template<class T, int shift, int size>
245 class BitField {
246  public:
247  // A uint32_t mask of bit field. To use all bits of a uint32 in a
248  // bitfield without compiler warnings we have to compute 2^32 without
249  // using a shift count of 32.
250  static const uint32_t kMask = ((1U << shift) << size) - (1U << shift);
251 
252  // Value for the field with all bits set.
253  static const T kMax = static_cast<T>((1U << size) - 1);
254 
255  // Tells whether the provided value fits into the bit field.
256  static bool is_valid(T value) {
257  return (static_cast<uint32_t>(value) & ~static_cast<uint32_t>(kMax)) == 0;
258  }
259 
260  // Returns a uint32_t with the bit field value encoded.
261  static uint32_t encode(T value) {
262  ASSERT(is_valid(value));
263  return static_cast<uint32_t>(value) << shift;
264  }
265 
266  // Returns a uint32_t with the bit field value updated.
267  static uint32_t update(uint32_t previous, T value) {
268  return (previous & ~kMask) | encode(value);
269  }
270 
271  // Extracts the bit field from the value.
272  static T decode(uint32_t value) {
273  return static_cast<T>((value & kMask) >> shift);
274  }
275 };
276 
277 
278 // ----------------------------------------------------------------------------
279 // Hash function.
280 
281 static const uint32_t kZeroHashSeed = 0;
282 
283 // Thomas Wang, Integer Hash Functions.
284 // http://www.concentric.net/~Ttwang/tech/inthash.htm
285 inline uint32_t ComputeIntegerHash(uint32_t key, uint32_t seed) {
286  uint32_t hash = key;
287  hash = hash ^ seed;
288  hash = ~hash + (hash << 15); // hash = (hash << 15) - hash - 1;
289  hash = hash ^ (hash >> 12);
290  hash = hash + (hash << 2);
291  hash = hash ^ (hash >> 4);
292  hash = hash * 2057; // hash = (hash + (hash << 3)) + (hash << 11);
293  hash = hash ^ (hash >> 16);
294  return hash;
295 }
296 
297 
298 inline uint32_t ComputeLongHash(uint64_t key) {
299  uint64_t hash = key;
300  hash = ~hash + (hash << 18); // hash = (hash << 18) - hash - 1;
301  hash = hash ^ (hash >> 31);
302  hash = hash * 21; // hash = (hash + (hash << 2)) + (hash << 4);
303  hash = hash ^ (hash >> 11);
304  hash = hash + (hash << 6);
305  hash = hash ^ (hash >> 22);
306  return (uint32_t) hash;
307 }
308 
309 
310 inline uint32_t ComputePointerHash(void* ptr) {
311  return ComputeIntegerHash(
312  static_cast<uint32_t>(reinterpret_cast<intptr_t>(ptr)),
313  v8::internal::kZeroHashSeed);
314 }
315 
316 
317 // ----------------------------------------------------------------------------
318 // Miscellaneous
319 
320 // A static resource holds a static instance that can be reserved in
321 // a local scope using an instance of Access. Attempts to re-reserve
322 // the instance will cause an error.
323 template <typename T>
325  public:
326  StaticResource() : is_reserved_(false) {}
327 
328  private:
329  template <typename S> friend class Access;
330  T instance_;
331  bool is_reserved_;
332 };
333 
334 
335 // Locally scoped access to a static resource.
336 template <typename T>
337 class Access {
338  public:
339  explicit Access(StaticResource<T>* resource)
340  : resource_(resource)
341  , instance_(&resource->instance_) {
342  ASSERT(!resource->is_reserved_);
343  resource->is_reserved_ = true;
344  }
345 
347  resource_->is_reserved_ = false;
348  resource_ = NULL;
349  instance_ = NULL;
350  }
351 
352  T* value() { return instance_; }
353  T* operator -> () { return instance_; }
354 
355  private:
356  StaticResource<T>* resource_;
357  T* instance_;
358 };
359 
360 
361 template <typename T>
362 class Vector {
363  public:
364  Vector() : start_(NULL), length_(0) {}
365  Vector(T* data, int length) : start_(data), length_(length) {
366  ASSERT(length == 0 || (length > 0 && data != NULL));
367  }
368 
369  static Vector<T> New(int length) {
370  return Vector<T>(NewArray<T>(length), length);
371  }
372 
373  // Returns a vector using the same backing storage as this one,
374  // spanning from and including 'from', to but not including 'to'.
375  Vector<T> SubVector(int from, int to) {
376  ASSERT(to <= length_);
377  ASSERT(from < to);
378  ASSERT(0 <= from);
379  return Vector<T>(start() + from, to - from);
380  }
381 
382  // Returns the length of the vector.
383  int length() const { return length_; }
384 
385  // Returns whether or not the vector is empty.
386  bool is_empty() const { return length_ == 0; }
387 
388  // Returns the pointer to the start of the data in the vector.
389  T* start() const { return start_; }
390 
391  // Access individual vector elements - checks bounds in debug mode.
392  T& operator[](int index) const {
393  ASSERT(0 <= index && index < length_);
394  return start_[index];
395  }
396 
397  const T& at(int index) const { return operator[](index); }
398 
399  T& first() { return start_[0]; }
400 
401  T& last() { return start_[length_ - 1]; }
402 
403  // Returns a clone of this vector with a new backing store.
404  Vector<T> Clone() const {
405  T* result = NewArray<T>(length_);
406  for (int i = 0; i < length_; i++) result[i] = start_[i];
407  return Vector<T>(result, length_);
408  }
409 
410  void Sort(int (*cmp)(const T*, const T*)) {
411  typedef int (*RawComparer)(const void*, const void*);
412  qsort(start(),
413  length(),
414  sizeof(T),
415  reinterpret_cast<RawComparer>(cmp));
416  }
417 
418  void Sort() {
419  Sort(PointerValueCompare<T>);
420  }
421 
422  void Truncate(int length) {
423  ASSERT(length <= length_);
424  length_ = length;
425  }
426 
427  // Releases the array underlying this vector. Once disposed the
428  // vector is empty.
429  void Dispose() {
430  DeleteArray(start_);
431  start_ = NULL;
432  length_ = 0;
433  }
434 
435  inline Vector<T> operator+(int offset) {
436  ASSERT(offset < length_);
437  return Vector<T>(start_ + offset, length_ - offset);
438  }
439 
440  // Factory method for creating empty vectors.
441  static Vector<T> empty() { return Vector<T>(NULL, 0); }
442 
443  template<typename S>
444  static Vector<T> cast(Vector<S> input) {
445  return Vector<T>(reinterpret_cast<T*>(input.start()),
446  input.length() * sizeof(S) / sizeof(T));
447  }
448 
449  protected:
450  void set_start(T* start) { start_ = start; }
451 
452  private:
453  T* start_;
454  int length_;
455 };
456 
457 
458 // A pointer that can only be set once and doesn't allow NULL values.
459 template<typename T>
461  public:
462  SetOncePointer() : pointer_(NULL) { }
463 
464  bool is_set() const { return pointer_ != NULL; }
465 
466  T* get() const {
467  ASSERT(pointer_ != NULL);
468  return pointer_;
469  }
470 
471  void set(T* value) {
472  ASSERT(pointer_ == NULL && value != NULL);
473  pointer_ = value;
474  }
475 
476  private:
477  T* pointer_;
478 };
479 
480 
481 template <typename T, int kSize>
482 class EmbeddedVector : public Vector<T> {
483  public:
484  EmbeddedVector() : Vector<T>(buffer_, kSize) { }
485 
486  explicit EmbeddedVector(T initial_value) : Vector<T>(buffer_, kSize) {
487  for (int i = 0; i < kSize; ++i) {
488  buffer_[i] = initial_value;
489  }
490  }
491 
492  // When copying, make underlying Vector to reference our buffer.
494  : Vector<T>(rhs) {
495  memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize);
496  set_start(buffer_);
497  }
498 
500  if (this == &rhs) return *this;
502  memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize);
503  this->set_start(buffer_);
504  return *this;
505  }
506 
507  private:
508  T buffer_[kSize];
509 };
510 
511 
512 template <typename T>
513 class ScopedVector : public Vector<T> {
514  public:
515  explicit ScopedVector(int length) : Vector<T>(NewArray<T>(length), length) { }
517  DeleteArray(this->start());
518  }
519 
520  private:
521  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedVector);
522 };
523 
524 
525 inline Vector<const char> CStrVector(const char* data) {
526  return Vector<const char>(data, StrLength(data));
527 }
528 
529 inline Vector<char> MutableCStrVector(char* data) {
530  return Vector<char>(data, StrLength(data));
531 }
532 
533 inline Vector<char> MutableCStrVector(char* data, int max) {
534  int length = StrLength(data);
535  return Vector<char>(data, (length < max) ? length : max);
536 }
537 
538 
539 /*
540  * A class that collects values into a backing store.
541  * Specialized versions of the class can allow access to the backing store
542  * in different ways.
543  * There is no guarantee that the backing store is contiguous (and, as a
544  * consequence, no guarantees that consecutively added elements are adjacent
545  * in memory). The collector may move elements unless it has guaranteed not
546  * to.
547  */
548 template <typename T, int growth_factor = 2, int max_growth = 1 * MB>
549 class Collector {
550  public:
551  explicit Collector(int initial_capacity = kMinCapacity)
552  : index_(0), size_(0) {
553  current_chunk_ = Vector<T>::New(initial_capacity);
554  }
555 
556  virtual ~Collector() {
557  // Free backing store (in reverse allocation order).
558  current_chunk_.Dispose();
559  for (int i = chunks_.length() - 1; i >= 0; i--) {
560  chunks_.at(i).Dispose();
561  }
562  }
563 
564  // Add a single element.
565  inline void Add(T value) {
566  if (index_ >= current_chunk_.length()) {
567  Grow(1);
568  }
569  current_chunk_[index_] = value;
570  index_++;
571  size_++;
572  }
573 
574  // Add a block of contiguous elements and return a Vector backed by the
575  // memory area.
576  // A basic Collector will keep this vector valid as long as the Collector
577  // is alive.
578  inline Vector<T> AddBlock(int size, T initial_value) {
579  ASSERT(size > 0);
580  if (size > current_chunk_.length() - index_) {
581  Grow(size);
582  }
583  T* position = current_chunk_.start() + index_;
584  index_ += size;
585  size_ += size;
586  for (int i = 0; i < size; i++) {
587  position[i] = initial_value;
588  }
589  return Vector<T>(position, size);
590  }
591 
592 
593  // Add a contiguous block of elements and return a vector backed
594  // by the added block.
595  // A basic Collector will keep this vector valid as long as the Collector
596  // is alive.
598  if (source.length() > current_chunk_.length() - index_) {
599  Grow(source.length());
600  }
601  T* position = current_chunk_.start() + index_;
602  index_ += source.length();
603  size_ += source.length();
604  for (int i = 0; i < source.length(); i++) {
605  position[i] = source[i];
606  }
607  return Vector<T>(position, source.length());
608  }
609 
610 
611  // Write the contents of the collector into the provided vector.
612  void WriteTo(Vector<T> destination) {
613  ASSERT(size_ <= destination.length());
614  int position = 0;
615  for (int i = 0; i < chunks_.length(); i++) {
616  Vector<T> chunk = chunks_.at(i);
617  for (int j = 0; j < chunk.length(); j++) {
618  destination[position] = chunk[j];
619  position++;
620  }
621  }
622  for (int i = 0; i < index_; i++) {
623  destination[position] = current_chunk_[i];
624  position++;
625  }
626  }
627 
628  // Allocate a single contiguous vector, copy all the collected
629  // elements to the vector, and return it.
630  // The caller is responsible for freeing the memory of the returned
631  // vector (e.g., using Vector::Dispose).
633  Vector<T> new_store = Vector<T>::New(size_);
634  WriteTo(new_store);
635  return new_store;
636  }
637 
638  // Resets the collector to be empty.
639  virtual void Reset();
640 
641  // Total number of elements added to collector so far.
642  inline int size() { return size_; }
643 
644  protected:
645  static const int kMinCapacity = 16;
647  Vector<T> current_chunk_; // Block of memory currently being written into.
648  int index_; // Current index in current chunk.
649  int size_; // Total number of elements in collector.
650 
651  // Creates a new current chunk, and stores the old chunk in the chunks_ list.
652  void Grow(int min_capacity) {
653  ASSERT(growth_factor > 1);
654  int new_capacity;
655  int current_length = current_chunk_.length();
656  if (current_length < kMinCapacity) {
657  // The collector started out as empty.
658  new_capacity = min_capacity * growth_factor;
659  if (new_capacity < kMinCapacity) new_capacity = kMinCapacity;
660  } else {
661  int growth = current_length * (growth_factor - 1);
662  if (growth > max_growth) {
663  growth = max_growth;
664  }
665  new_capacity = current_length + growth;
666  if (new_capacity < min_capacity) {
667  new_capacity = min_capacity + growth;
668  }
669  }
670  NewChunk(new_capacity);
671  ASSERT(index_ + min_capacity <= current_chunk_.length());
672  }
673 
674  // Before replacing the current chunk, give a subclass the option to move
675  // some of the current data into the new chunk. The function may update
676  // the current index_ value to represent data no longer in the current chunk.
677  // Returns the initial index of the new chunk (after copied data).
678  virtual void NewChunk(int new_capacity) {
679  Vector<T> new_chunk = Vector<T>::New(new_capacity);
680  if (index_ > 0) {
681  chunks_.Add(current_chunk_.SubVector(0, index_));
682  } else {
683  current_chunk_.Dispose();
684  }
685  current_chunk_ = new_chunk;
686  index_ = 0;
687  }
688 };
689 
690 
691 /*
692  * A collector that allows sequences of values to be guaranteed to
693  * stay consecutive.
694  * If the backing store grows while a sequence is active, the current
695  * sequence might be moved, but after the sequence is ended, it will
696  * not move again.
697  * NOTICE: Blocks allocated using Collector::AddBlock(int) can move
698  * as well, if inside an active sequence where another element is added.
699  */
700 template <typename T, int growth_factor = 2, int max_growth = 1 * MB>
701 class SequenceCollector : public Collector<T, growth_factor, max_growth> {
702  public:
703  explicit SequenceCollector(int initial_capacity)
704  : Collector<T, growth_factor, max_growth>(initial_capacity),
705  sequence_start_(kNoSequence) { }
706 
707  virtual ~SequenceCollector() {}
708 
709  void StartSequence() {
710  ASSERT(sequence_start_ == kNoSequence);
711  sequence_start_ = this->index_;
712  }
713 
715  ASSERT(sequence_start_ != kNoSequence);
716  int sequence_start = sequence_start_;
717  sequence_start_ = kNoSequence;
718  if (sequence_start == this->index_) return Vector<T>();
719  return this->current_chunk_.SubVector(sequence_start, this->index_);
720  }
721 
722  // Drops the currently added sequence, and all collected elements in it.
723  void DropSequence() {
724  ASSERT(sequence_start_ != kNoSequence);
725  int sequence_length = this->index_ - sequence_start_;
726  this->index_ = sequence_start_;
727  this->size_ -= sequence_length;
728  sequence_start_ = kNoSequence;
729  }
730 
731  virtual void Reset() {
732  sequence_start_ = kNoSequence;
734  }
735 
736  private:
737  static const int kNoSequence = -1;
738  int sequence_start_;
739 
740  // Move the currently active sequence to the new chunk.
741  virtual void NewChunk(int new_capacity) {
742  if (sequence_start_ == kNoSequence) {
743  // Fall back on default behavior if no sequence has been started.
745  return;
746  }
747  int sequence_length = this->index_ - sequence_start_;
748  Vector<T> new_chunk = Vector<T>::New(sequence_length + new_capacity);
749  ASSERT(sequence_length < new_chunk.length());
750  for (int i = 0; i < sequence_length; i++) {
751  new_chunk[i] = this->current_chunk_[sequence_start_ + i];
752  }
753  if (sequence_start_ > 0) {
754  this->chunks_.Add(this->current_chunk_.SubVector(0, sequence_start_));
755  } else {
756  this->current_chunk_.Dispose();
757  }
758  this->current_chunk_ = new_chunk;
759  this->index_ = sequence_length;
760  sequence_start_ = 0;
761  }
762 };
763 
764 
765 // Compare ASCII/16bit chars to ASCII/16bit chars.
766 template <typename lchar, typename rchar>
767 inline int CompareChars(const lchar* lhs, const rchar* rhs, int chars) {
768  const lchar* limit = lhs + chars;
769 #ifdef V8_HOST_CAN_READ_UNALIGNED
770  if (sizeof(*lhs) == sizeof(*rhs)) {
771  // Number of characters in a uintptr_t.
772  static const int kStepSize = sizeof(uintptr_t) / sizeof(*lhs); // NOLINT
773  while (lhs <= limit - kStepSize) {
774  if (*reinterpret_cast<const uintptr_t*>(lhs) !=
775  *reinterpret_cast<const uintptr_t*>(rhs)) {
776  break;
777  }
778  lhs += kStepSize;
779  rhs += kStepSize;
780  }
781  }
782 #endif
783  while (lhs < limit) {
784  int r = static_cast<int>(*lhs) - static_cast<int>(*rhs);
785  if (r != 0) return r;
786  ++lhs;
787  ++rhs;
788  }
789  return 0;
790 }
791 
792 
793 // Calculate 10^exponent.
794 inline int TenToThe(int exponent) {
795  ASSERT(exponent <= 9);
796  ASSERT(exponent >= 1);
797  int answer = 10;
798  for (int i = 1; i < exponent; i++) answer *= 10;
799  return answer;
800 }
801 
802 
803 // The type-based aliasing rule allows the compiler to assume that pointers of
804 // different types (for some definition of different) never alias each other.
805 // Thus the following code does not work:
806 //
807 // float f = foo();
808 // int fbits = *(int*)(&f);
809 //
810 // The compiler 'knows' that the int pointer can't refer to f since the types
811 // don't match, so the compiler may cache f in a register, leaving random data
812 // in fbits. Using C++ style casts makes no difference, however a pointer to
813 // char data is assumed to alias any other pointer. This is the 'memcpy
814 // exception'.
815 //
816 // Bit_cast uses the memcpy exception to move the bits from a variable of one
817 // type of a variable of another type. Of course the end result is likely to
818 // be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005)
819 // will completely optimize BitCast away.
820 //
821 // There is an additional use for BitCast.
822 // Recent gccs will warn when they see casts that may result in breakage due to
823 // the type-based aliasing rule. If you have checked that there is no breakage
824 // you can use BitCast to cast one pointer type to another. This confuses gcc
825 // enough that it can no longer see that you have cast one pointer type to
826 // another thus avoiding the warning.
827 
828 // We need different implementations of BitCast for pointer and non-pointer
829 // values. We use partial specialization of auxiliary struct to work around
830 // issues with template functions overloading.
831 template <class Dest, class Source>
833  STATIC_ASSERT(sizeof(Dest) == sizeof(Source));
834 
835  INLINE(static Dest cast(const Source& source)) {
836  Dest dest;
837  memcpy(&dest, &source, sizeof(dest));
838  return dest;
839  }
840 };
841 
842 template <class Dest, class Source>
843 struct BitCastHelper<Dest, Source*> {
844  INLINE(static Dest cast(Source* source)) {
846  cast(reinterpret_cast<uintptr_t>(source));
847  }
848 };
849 
850 template <class Dest, class Source>
851 INLINE(Dest BitCast(const Source& source));
852 
853 template <class Dest, class Source>
854 inline Dest BitCast(const Source& source) {
855  return BitCastHelper<Dest, Source>::cast(source);
856 }
857 
858 
859 template<typename ElementType, int NumElements>
861  public:
862  EmbeddedContainer() : elems_() { }
863 
864  int length() { return NumElements; }
865  ElementType& operator[](int i) {
866  ASSERT(i < length());
867  return elems_[i];
868  }
869 
870  private:
871  ElementType elems_[NumElements];
872 };
873 
874 
875 template<typename ElementType>
876 class EmbeddedContainer<ElementType, 0> {
877  public:
878  int length() { return 0; }
879  ElementType& operator[](int i) {
880  UNREACHABLE();
881  static ElementType t = 0;
882  return t;
883  }
884 };
885 
886 
887 // Helper class for building result strings in a character buffer. The
888 // purpose of the class is to use safe operations that checks the
889 // buffer bounds on all operations in debug mode.
890 // This simple base class does not allow formatted output.
892  public:
893  // Create a string builder with a buffer of the given size. The
894  // buffer is allocated through NewArray<char> and must be
895  // deallocated by the caller of Finalize().
896  explicit SimpleStringBuilder(int size);
897 
898  SimpleStringBuilder(char* buffer, int size)
899  : buffer_(buffer, size), position_(0) { }
900 
902 
903  int size() const { return buffer_.length(); }
904 
905  // Get the current position in the builder.
906  int position() const {
907  ASSERT(!is_finalized());
908  return position_;
909  }
910 
911  // Reset the position.
912  void Reset() { position_ = 0; }
913 
914  // Add a single character to the builder. It is not allowed to add
915  // 0-characters; use the Finalize() method to terminate the string
916  // instead.
917  void AddCharacter(char c) {
918  ASSERT(c != '\0');
920  buffer_[position_++] = c;
921  }
922 
923  // Add an entire string to the builder. Uses strlen() internally to
924  // compute the length of the input string.
925  void AddString(const char* s);
926 
927  // Add the first 'n' characters of the given string 's' to the
928  // builder. The input string must have enough characters.
929  void AddSubstring(const char* s, int n);
930 
931  // Add character padding to the builder. If count is non-positive,
932  // nothing is added to the builder.
933  void AddPadding(char c, int count);
934 
935  // Add the decimal representation of the value.
936  void AddDecimalInteger(int value);
937 
938  // Finalize the string by 0-terminating it and returning the buffer.
939  char* Finalize();
940 
941  protected:
944 
945  bool is_finalized() const { return position_ < 0; }
946 
947  private:
948  DISALLOW_IMPLICIT_CONSTRUCTORS(SimpleStringBuilder);
949 };
950 
951 
952 // A poor man's version of STL's bitset: A bit set of enums E (without explicit
953 // values), fitting into an integral type T.
954 template <class E, class T = int>
955 class EnumSet {
956  public:
957  explicit EnumSet(T bits = 0) : bits_(bits) {}
958  bool IsEmpty() const { return bits_ == 0; }
959  bool Contains(E element) const { return (bits_ & Mask(element)) != 0; }
960  bool ContainsAnyOf(const EnumSet& set) const {
961  return (bits_ & set.bits_) != 0;
962  }
963  void Add(E element) { bits_ |= Mask(element); }
964  void Add(const EnumSet& set) { bits_ |= set.bits_; }
965  void Remove(E element) { bits_ &= ~Mask(element); }
966  void Remove(const EnumSet& set) { bits_ &= ~set.bits_; }
967  void RemoveAll() { bits_ = 0; }
968  void Intersect(const EnumSet& set) { bits_ &= set.bits_; }
969  T ToIntegral() const { return bits_; }
970  bool operator==(const EnumSet& set) { return bits_ == set.bits_; }
971 
972  private:
973  T Mask(E element) const {
974  // The strange typing in ASSERT is necessary to avoid stupid warnings, see:
975  // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43680
976  ASSERT(element < static_cast<int>(sizeof(T) * CHAR_BIT));
977  return 1 << element;
978  }
979 
980  T bits_;
981 };
982 
983 } } // namespace v8::internal
984 
985 #endif // V8_UTILS_H_
byte * Address
Definition: globals.h:172
const DivMagicNumbers DivMagicNumberFor625
Definition: utils.h:109
ElementType & operator[](int i)
Definition: utils.h:865
Vector(T *data, int length)
Definition: utils.h:365
bool IsAddressAligned(Address addr, intptr_t alignment, int offset=0)
Definition: utils.h:212
Vector< T > AddBlock(Vector< const T > source)
Definition: utils.h:597
uint32_t RoundDownToPowerOf2(uint32_t x)
Definition: utils.h:198
const DivMagicNumbers DivMagicNumberFor(int32_t divisor)
Definition: utils.cc:93
void AddString(const char *s)
Definition: utils.cc:43
EnumSet(T bits=0)
Definition: utils.h:957
void Sort(int(*cmp)(const T *, const T *))
Definition: utils.h:410
const DivMagicNumbers DivMagicNumberFor3
Definition: utils.h:102
static uint32_t encode(T value)
Definition: utils.h:261
const DivMagicNumbers DivMagicNumberFor5
Definition: utils.h:103
T Max(T a, T b)
Definition: utils.h:222
Vector< char > MutableCStrVector(char *data)
Definition: utils.h:529
const DivMagicNumbers DivMagicNumberFor9
Definition: utils.h:105
Access(StaticResource< T > *resource)
Definition: utils.h:339
void Grow(int min_capacity)
Definition: utils.h:652
Vector< T > SubVector(int from, int to)
Definition: utils.h:375
int int32_t
Definition: unicode.cc:47
SimpleStringBuilder(char *buffer, int size)
Definition: utils.h:898
static const uint32_t kMask
Definition: utils.h:250
void Add(T value)
Definition: utils.h:565
#define ASSERT(condition)
Definition: checks.h:270
T & operator[](int index) const
Definition: utils.h:392
bool IsEmpty() const
Definition: utils.h:958
STATIC_ASSERT(sizeof(Dest)==sizeof(Source))
bool ContainsAnyOf(const EnumSet &set) const
Definition: utils.h:960
void Add(const EnumSet &set)
Definition: utils.h:964
int WhichPowerOf2(uint32_t x)
Definition: utils.h:56
static uint32_t update(uint32_t previous, T value)
Definition: utils.h:267
void set(T *value)
Definition: utils.h:471
ScopedVector(int length)
Definition: utils.h:515
int HandleObjectPointerCompare(const Handle< T > *a, const Handle< T > *b)
Definition: utils.h:177
unsigned int seed
Definition: test-strings.cc:17
bool is_empty() const
Definition: utils.h:386
SequenceCollector(int initial_capacity)
Definition: utils.h:703
uint32_t ComputePointerHash(void *ptr)
Definition: utils.h:310
void set_start(T *start)
Definition: utils.h:450
#define UNREACHABLE()
Definition: checks.h:50
INLINE(static Dest cast(Source *source))
Definition: utils.h:844
Vector< T > AddBlock(int size, T initial_value)
Definition: utils.h:578
T * start() const
Definition: utils.h:389
EmbeddedVector(T initial_value)
Definition: utils.h:486
T * NewArray(size_t size)
Definition: allocation.h:83
int Compare(const T &a, const T &b)
Definition: utils.h:156
intptr_t OffsetFrom(T x)
Definition: utils.h:126
static const T kMax
Definition: utils.h:253
bool IsAligned(T value, U alignment)
Definition: utils.h:206
INLINE(static Dest cast(const Source &source))
Definition: utils.h:835
static T decode(uint32_t value)
Definition: utils.h:272
int length() const
Definition: utils.h:383
EmbeddedVector(const EmbeddedVector &rhs)
Definition: utils.h:493
void Intersect(const EnumSet &set)
Definition: utils.h:968
T RoundUp(T x, intptr_t m)
Definition: utils.h:150
Vector< T > ToVector()
Definition: utils.h:632
const DivMagicNumbers DivMagicNumberFor125
Definition: utils.h:108
void Remove(const EnumSet &set)
Definition: utils.h:966
Definition: v8.h:104
bool IsPowerOf2(T x)
Definition: utils.h:50
int CompareChars(const lchar *lhs, const rchar *rhs, int chars)
Definition: utils.h:767
int TenToThe(int exponent)
Definition: utils.h:794
void Truncate(int length)
Definition: utils.h:422
static Vector< T > New(int length)
Definition: utils.h:369
Vector< const char > CStrVector(const char *data)
Definition: utils.h:525
int StrLength(const char *string)
Definition: utils.h:234
List< Vector< T > > chunks_
Definition: utils.h:646
#define T(name, string, precedence)
Definition: token.cc:48
Vector< T > Clone() const
Definition: utils.h:404
int PointerValueCompare(const T *a, const T *b)
Definition: utils.h:167
int ArithmeticShiftRight(int x, int s)
Definition: utils.h:117
const DivMagicNumbers DivMagicNumberFor11
Definition: utils.h:106
Vector< T > EndSequence()
Definition: utils.h:714
void AddSubstring(const char *s, int n)
Definition: utils.cc:48
uint32_t ComputeIntegerHash(uint32_t key, uint32_t seed)
Definition: utils.h:285
bool Contains(E element) const
Definition: utils.h:959
const DivMagicNumbers DivMagicNumberFor25
Definition: utils.h:107
#define IS_POWER_OF_TWO(x)
Definition: utils.h:45
T AddressFrom(intptr_t x)
Definition: utils.h:135
INLINE(static HeapObject *EnsureDoubleAligned(Heap *heap, HeapObject *object, int size))
virtual ~Collector()
Definition: utils.h:556
static Vector< T > cast(Vector< S > input)
Definition: utils.h:444
T ToIntegral() const
Definition: utils.h:969
uint32_t ComputeLongHash(uint64_t key)
Definition: utils.h:298
Collector(int initial_capacity=kMinCapacity)
Definition: utils.h:551
#define ASSERT_EQ(v1, v2)
Definition: checks.h:271
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
virtual void NewChunk(int new_capacity)
Definition: utils.h:678
void AddDecimalInteger(int value)
Definition: utils.cc:63
T RoundDown(T x, intptr_t m)
Definition: utils.h:142
Vector< T > current_chunk_
Definition: utils.h:647
static Vector< T > empty()
Definition: utils.h:441
Vector< T > operator+(int offset)
Definition: utils.h:435
const T & at(int index) const
Definition: utils.h:397
void AddPadding(char c, int count)
Definition: utils.cc:56
bool operator==(const EnumSet &set)
Definition: utils.h:970
static const int kMinCapacity
Definition: utils.h:645
static bool is_valid(T value)
Definition: utils.h:256
void WriteTo(Vector< T > destination)
Definition: utils.h:612
Dest BitCast(const Source &source)
Definition: utils.h:854
void DeleteArray(T *array)
Definition: allocation.h:91
T Min(T a, T b)
Definition: utils.h:229
void Remove(E element)
Definition: utils.h:965
void Add(E element)
Definition: utils.h:963
const DivMagicNumbers InvalidDivMagicNumber
Definition: utils.h:101
uint32_t RoundUpToPowerOf2(uint32_t x)
Definition: utils.h:186
virtual void Reset()
Definition: utils-inl.h:37
EmbeddedVector & operator=(const EmbeddedVector &rhs)
Definition: utils.h:499
const DivMagicNumbers DivMagicNumberFor7
Definition: utils.h:104
bool is_set() const
Definition: utils.h:464