v8  3.14.5(node0.10.28)
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  static const uint32_t kShift = shift;
252 
253  // Value for the field with all bits set.
254  static const T kMax = static_cast<T>((1U << size) - 1);
255 
256  // Tells whether the provided value fits into the bit field.
257  static bool is_valid(T value) {
258  return (static_cast<uint32_t>(value) & ~static_cast<uint32_t>(kMax)) == 0;
259  }
260 
261  // Returns a uint32_t with the bit field value encoded.
262  static uint32_t encode(T value) {
263  ASSERT(is_valid(value));
264  return static_cast<uint32_t>(value) << shift;
265  }
266 
267  // Returns a uint32_t with the bit field value updated.
268  static uint32_t update(uint32_t previous, T value) {
269  return (previous & ~kMask) | encode(value);
270  }
271 
272  // Extracts the bit field from the value.
273  static T decode(uint32_t value) {
274  return static_cast<T>((value & kMask) >> shift);
275  }
276 };
277 
278 
279 // ----------------------------------------------------------------------------
280 // Hash function.
281 
282 static const uint32_t kZeroHashSeed = 0;
283 
284 // Thomas Wang, Integer Hash Functions.
285 // http://www.concentric.net/~Ttwang/tech/inthash.htm
286 inline uint32_t ComputeIntegerHash(uint32_t key, uint32_t seed) {
287  uint32_t hash = key;
288  hash = hash ^ seed;
289  hash = ~hash + (hash << 15); // hash = (hash << 15) - hash - 1;
290  hash = hash ^ (hash >> 12);
291  hash = hash + (hash << 2);
292  hash = hash ^ (hash >> 4);
293  hash = hash * 2057; // hash = (hash + (hash << 3)) + (hash << 11);
294  hash = hash ^ (hash >> 16);
295  return hash;
296 }
297 
298 
299 inline uint32_t ComputeLongHash(uint64_t key) {
300  uint64_t hash = key;
301  hash = ~hash + (hash << 18); // hash = (hash << 18) - hash - 1;
302  hash = hash ^ (hash >> 31);
303  hash = hash * 21; // hash = (hash + (hash << 2)) + (hash << 4);
304  hash = hash ^ (hash >> 11);
305  hash = hash + (hash << 6);
306  hash = hash ^ (hash >> 22);
307  return (uint32_t) hash;
308 }
309 
310 
311 inline uint32_t ComputePointerHash(void* ptr) {
312  return ComputeIntegerHash(
313  static_cast<uint32_t>(reinterpret_cast<intptr_t>(ptr)),
314  v8::internal::kZeroHashSeed);
315 }
316 
317 
318 // ----------------------------------------------------------------------------
319 // Miscellaneous
320 
321 // A static resource holds a static instance that can be reserved in
322 // a local scope using an instance of Access. Attempts to re-reserve
323 // the instance will cause an error.
324 template <typename T>
326  public:
327  StaticResource() : is_reserved_(false) {}
328 
329  private:
330  template <typename S> friend class Access;
331  T instance_;
332  bool is_reserved_;
333 };
334 
335 
336 // Locally scoped access to a static resource.
337 template <typename T>
338 class Access {
339  public:
340  explicit Access(StaticResource<T>* resource)
341  : resource_(resource)
342  , instance_(&resource->instance_) {
343  ASSERT(!resource->is_reserved_);
344  resource->is_reserved_ = true;
345  }
346 
348  resource_->is_reserved_ = false;
349  resource_ = NULL;
350  instance_ = NULL;
351  }
352 
353  T* value() { return instance_; }
354  T* operator -> () { return instance_; }
355 
356  private:
357  StaticResource<T>* resource_;
358  T* instance_;
359 };
360 
361 
362 template <typename T>
363 class Vector {
364  public:
365  Vector() : start_(NULL), length_(0) {}
366  Vector(T* data, int length) : start_(data), length_(length) {
367  ASSERT(length == 0 || (length > 0 && data != NULL));
368  }
369 
370  static Vector<T> New(int length) {
371  return Vector<T>(NewArray<T>(length), length);
372  }
373 
374  // Returns a vector using the same backing storage as this one,
375  // spanning from and including 'from', to but not including 'to'.
376  Vector<T> SubVector(int from, int to) {
377  ASSERT(to <= length_);
378  ASSERT(from < to);
379  ASSERT(0 <= from);
380  return Vector<T>(start() + from, to - from);
381  }
382 
383  // Returns the length of the vector.
384  int length() const { return length_; }
385 
386  // Returns whether or not the vector is empty.
387  bool is_empty() const { return length_ == 0; }
388 
389  // Returns the pointer to the start of the data in the vector.
390  T* start() const { return start_; }
391 
392  // Access individual vector elements - checks bounds in debug mode.
393  T& operator[](int index) const {
394  ASSERT(0 <= index && index < length_);
395  return start_[index];
396  }
397 
398  const T& at(int index) const { return operator[](index); }
399 
400  T& first() { return start_[0]; }
401 
402  T& last() { return start_[length_ - 1]; }
403 
404  // Returns a clone of this vector with a new backing store.
405  Vector<T> Clone() const {
406  T* result = NewArray<T>(length_);
407  for (int i = 0; i < length_; i++) result[i] = start_[i];
408  return Vector<T>(result, length_);
409  }
410 
411  void Sort(int (*cmp)(const T*, const T*)) {
412  typedef int (*RawComparer)(const void*, const void*);
413  qsort(start(),
414  length(),
415  sizeof(T),
416  reinterpret_cast<RawComparer>(cmp));
417  }
418 
419  void Sort() {
420  Sort(PointerValueCompare<T>);
421  }
422 
423  void Truncate(int length) {
424  ASSERT(length <= length_);
425  length_ = length;
426  }
427 
428  // Releases the array underlying this vector. Once disposed the
429  // vector is empty.
430  void Dispose() {
431  DeleteArray(start_);
432  start_ = NULL;
433  length_ = 0;
434  }
435 
436  inline Vector<T> operator+(int offset) {
437  ASSERT(offset < length_);
438  return Vector<T>(start_ + offset, length_ - offset);
439  }
440 
441  // Factory method for creating empty vectors.
442  static Vector<T> empty() { return Vector<T>(NULL, 0); }
443 
444  template<typename S>
445  static Vector<T> cast(Vector<S> input) {
446  return Vector<T>(reinterpret_cast<T*>(input.start()),
447  input.length() * sizeof(S) / sizeof(T));
448  }
449 
450  protected:
451  void set_start(T* start) { start_ = start; }
452 
453  private:
454  T* start_;
455  int length_;
456 };
457 
458 
459 // A pointer that can only be set once and doesn't allow NULL values.
460 template<typename T>
462  public:
463  SetOncePointer() : pointer_(NULL) { }
464 
465  bool is_set() const { return pointer_ != NULL; }
466 
467  T* get() const {
468  ASSERT(pointer_ != NULL);
469  return pointer_;
470  }
471 
472  void set(T* value) {
473  ASSERT(pointer_ == NULL && value != NULL);
474  pointer_ = value;
475  }
476 
477  private:
478  T* pointer_;
479 };
480 
481 
482 template <typename T, int kSize>
483 class EmbeddedVector : public Vector<T> {
484  public:
485  EmbeddedVector() : Vector<T>(buffer_, kSize) { }
486 
487  explicit EmbeddedVector(T initial_value) : Vector<T>(buffer_, kSize) {
488  for (int i = 0; i < kSize; ++i) {
489  buffer_[i] = initial_value;
490  }
491  }
492 
493  // When copying, make underlying Vector to reference our buffer.
495  : Vector<T>(rhs) {
496  memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize);
497  set_start(buffer_);
498  }
499 
501  if (this == &rhs) return *this;
503  memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize);
504  this->set_start(buffer_);
505  return *this;
506  }
507 
508  private:
509  T buffer_[kSize];
510 };
511 
512 
513 template <typename T>
514 class ScopedVector : public Vector<T> {
515  public:
516  explicit ScopedVector(int length) : Vector<T>(NewArray<T>(length), length) { }
518  DeleteArray(this->start());
519  }
520 
521  private:
522  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedVector);
523 };
524 
525 
526 inline Vector<const char> CStrVector(const char* data) {
527  return Vector<const char>(data, StrLength(data));
528 }
529 
530 inline Vector<char> MutableCStrVector(char* data) {
531  return Vector<char>(data, StrLength(data));
532 }
533 
534 inline Vector<char> MutableCStrVector(char* data, int max) {
535  int length = StrLength(data);
536  return Vector<char>(data, (length < max) ? length : max);
537 }
538 
539 
540 /*
541  * A class that collects values into a backing store.
542  * Specialized versions of the class can allow access to the backing store
543  * in different ways.
544  * There is no guarantee that the backing store is contiguous (and, as a
545  * consequence, no guarantees that consecutively added elements are adjacent
546  * in memory). The collector may move elements unless it has guaranteed not
547  * to.
548  */
549 template <typename T, int growth_factor = 2, int max_growth = 1 * MB>
550 class Collector {
551  public:
552  explicit Collector(int initial_capacity = kMinCapacity)
553  : index_(0), size_(0) {
554  current_chunk_ = Vector<T>::New(initial_capacity);
555  }
556 
557  virtual ~Collector() {
558  // Free backing store (in reverse allocation order).
559  current_chunk_.Dispose();
560  for (int i = chunks_.length() - 1; i >= 0; i--) {
561  chunks_.at(i).Dispose();
562  }
563  }
564 
565  // Add a single element.
566  inline void Add(T value) {
567  if (index_ >= current_chunk_.length()) {
568  Grow(1);
569  }
570  current_chunk_[index_] = value;
571  index_++;
572  size_++;
573  }
574 
575  // Add a block of contiguous elements and return a Vector backed by the
576  // memory area.
577  // A basic Collector will keep this vector valid as long as the Collector
578  // is alive.
579  inline Vector<T> AddBlock(int size, T initial_value) {
580  ASSERT(size > 0);
581  if (size > current_chunk_.length() - index_) {
582  Grow(size);
583  }
584  T* position = current_chunk_.start() + index_;
585  index_ += size;
586  size_ += size;
587  for (int i = 0; i < size; i++) {
588  position[i] = initial_value;
589  }
590  return Vector<T>(position, size);
591  }
592 
593 
594  // Add a contiguous block of elements and return a vector backed
595  // by the added block.
596  // A basic Collector will keep this vector valid as long as the Collector
597  // is alive.
599  if (source.length() > current_chunk_.length() - index_) {
600  Grow(source.length());
601  }
602  T* position = current_chunk_.start() + index_;
603  index_ += source.length();
604  size_ += source.length();
605  for (int i = 0; i < source.length(); i++) {
606  position[i] = source[i];
607  }
608  return Vector<T>(position, source.length());
609  }
610 
611 
612  // Write the contents of the collector into the provided vector.
613  void WriteTo(Vector<T> destination) {
614  ASSERT(size_ <= destination.length());
615  int position = 0;
616  for (int i = 0; i < chunks_.length(); i++) {
617  Vector<T> chunk = chunks_.at(i);
618  for (int j = 0; j < chunk.length(); j++) {
619  destination[position] = chunk[j];
620  position++;
621  }
622  }
623  for (int i = 0; i < index_; i++) {
624  destination[position] = current_chunk_[i];
625  position++;
626  }
627  }
628 
629  // Allocate a single contiguous vector, copy all the collected
630  // elements to the vector, and return it.
631  // The caller is responsible for freeing the memory of the returned
632  // vector (e.g., using Vector::Dispose).
634  Vector<T> new_store = Vector<T>::New(size_);
635  WriteTo(new_store);
636  return new_store;
637  }
638 
639  // Resets the collector to be empty.
640  virtual void Reset();
641 
642  // Total number of elements added to collector so far.
643  inline int size() { return size_; }
644 
645  protected:
646  static const int kMinCapacity = 16;
648  Vector<T> current_chunk_; // Block of memory currently being written into.
649  int index_; // Current index in current chunk.
650  int size_; // Total number of elements in collector.
651 
652  // Creates a new current chunk, and stores the old chunk in the chunks_ list.
653  void Grow(int min_capacity) {
654  ASSERT(growth_factor > 1);
655  int new_capacity;
656  int current_length = current_chunk_.length();
657  if (current_length < kMinCapacity) {
658  // The collector started out as empty.
659  new_capacity = min_capacity * growth_factor;
660  if (new_capacity < kMinCapacity) new_capacity = kMinCapacity;
661  } else {
662  int growth = current_length * (growth_factor - 1);
663  if (growth > max_growth) {
664  growth = max_growth;
665  }
666  new_capacity = current_length + growth;
667  if (new_capacity < min_capacity) {
668  new_capacity = min_capacity + growth;
669  }
670  }
671  NewChunk(new_capacity);
672  ASSERT(index_ + min_capacity <= current_chunk_.length());
673  }
674 
675  // Before replacing the current chunk, give a subclass the option to move
676  // some of the current data into the new chunk. The function may update
677  // the current index_ value to represent data no longer in the current chunk.
678  // Returns the initial index of the new chunk (after copied data).
679  virtual void NewChunk(int new_capacity) {
680  Vector<T> new_chunk = Vector<T>::New(new_capacity);
681  if (index_ > 0) {
682  chunks_.Add(current_chunk_.SubVector(0, index_));
683  } else {
684  current_chunk_.Dispose();
685  }
686  current_chunk_ = new_chunk;
687  index_ = 0;
688  }
689 };
690 
691 
692 /*
693  * A collector that allows sequences of values to be guaranteed to
694  * stay consecutive.
695  * If the backing store grows while a sequence is active, the current
696  * sequence might be moved, but after the sequence is ended, it will
697  * not move again.
698  * NOTICE: Blocks allocated using Collector::AddBlock(int) can move
699  * as well, if inside an active sequence where another element is added.
700  */
701 template <typename T, int growth_factor = 2, int max_growth = 1 * MB>
702 class SequenceCollector : public Collector<T, growth_factor, max_growth> {
703  public:
704  explicit SequenceCollector(int initial_capacity)
705  : Collector<T, growth_factor, max_growth>(initial_capacity),
706  sequence_start_(kNoSequence) { }
707 
708  virtual ~SequenceCollector() {}
709 
710  void StartSequence() {
711  ASSERT(sequence_start_ == kNoSequence);
712  sequence_start_ = this->index_;
713  }
714 
716  ASSERT(sequence_start_ != kNoSequence);
717  int sequence_start = sequence_start_;
718  sequence_start_ = kNoSequence;
719  if (sequence_start == this->index_) return Vector<T>();
720  return this->current_chunk_.SubVector(sequence_start, this->index_);
721  }
722 
723  // Drops the currently added sequence, and all collected elements in it.
724  void DropSequence() {
725  ASSERT(sequence_start_ != kNoSequence);
726  int sequence_length = this->index_ - sequence_start_;
727  this->index_ = sequence_start_;
728  this->size_ -= sequence_length;
729  sequence_start_ = kNoSequence;
730  }
731 
732  virtual void Reset() {
733  sequence_start_ = kNoSequence;
735  }
736 
737  private:
738  static const int kNoSequence = -1;
739  int sequence_start_;
740 
741  // Move the currently active sequence to the new chunk.
742  virtual void NewChunk(int new_capacity) {
743  if (sequence_start_ == kNoSequence) {
744  // Fall back on default behavior if no sequence has been started.
746  return;
747  }
748  int sequence_length = this->index_ - sequence_start_;
749  Vector<T> new_chunk = Vector<T>::New(sequence_length + new_capacity);
750  ASSERT(sequence_length < new_chunk.length());
751  for (int i = 0; i < sequence_length; i++) {
752  new_chunk[i] = this->current_chunk_[sequence_start_ + i];
753  }
754  if (sequence_start_ > 0) {
755  this->chunks_.Add(this->current_chunk_.SubVector(0, sequence_start_));
756  } else {
757  this->current_chunk_.Dispose();
758  }
759  this->current_chunk_ = new_chunk;
760  this->index_ = sequence_length;
761  sequence_start_ = 0;
762  }
763 };
764 
765 
766 // Compare ASCII/16bit chars to ASCII/16bit chars.
767 template <typename lchar, typename rchar>
768 inline int CompareChars(const lchar* lhs, const rchar* rhs, int chars) {
769  const lchar* limit = lhs + chars;
770 #ifdef V8_HOST_CAN_READ_UNALIGNED
771  if (sizeof(*lhs) == sizeof(*rhs)) {
772  // Number of characters in a uintptr_t.
773  static const int kStepSize = sizeof(uintptr_t) / sizeof(*lhs); // NOLINT
774  while (lhs <= limit - kStepSize) {
775  if (*reinterpret_cast<const uintptr_t*>(lhs) !=
776  *reinterpret_cast<const uintptr_t*>(rhs)) {
777  break;
778  }
779  lhs += kStepSize;
780  rhs += kStepSize;
781  }
782  }
783 #endif
784  while (lhs < limit) {
785  int r = static_cast<int>(*lhs) - static_cast<int>(*rhs);
786  if (r != 0) return r;
787  ++lhs;
788  ++rhs;
789  }
790  return 0;
791 }
792 
793 
794 // Calculate 10^exponent.
795 inline int TenToThe(int exponent) {
796  ASSERT(exponent <= 9);
797  ASSERT(exponent >= 1);
798  int answer = 10;
799  for (int i = 1; i < exponent; i++) answer *= 10;
800  return answer;
801 }
802 
803 
804 // The type-based aliasing rule allows the compiler to assume that pointers of
805 // different types (for some definition of different) never alias each other.
806 // Thus the following code does not work:
807 //
808 // float f = foo();
809 // int fbits = *(int*)(&f);
810 //
811 // The compiler 'knows' that the int pointer can't refer to f since the types
812 // don't match, so the compiler may cache f in a register, leaving random data
813 // in fbits. Using C++ style casts makes no difference, however a pointer to
814 // char data is assumed to alias any other pointer. This is the 'memcpy
815 // exception'.
816 //
817 // Bit_cast uses the memcpy exception to move the bits from a variable of one
818 // type of a variable of another type. Of course the end result is likely to
819 // be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005)
820 // will completely optimize BitCast away.
821 //
822 // There is an additional use for BitCast.
823 // Recent gccs will warn when they see casts that may result in breakage due to
824 // the type-based aliasing rule. If you have checked that there is no breakage
825 // you can use BitCast to cast one pointer type to another. This confuses gcc
826 // enough that it can no longer see that you have cast one pointer type to
827 // another thus avoiding the warning.
828 
829 // We need different implementations of BitCast for pointer and non-pointer
830 // values. We use partial specialization of auxiliary struct to work around
831 // issues with template functions overloading.
832 template <class Dest, class Source>
834  STATIC_ASSERT(sizeof(Dest) == sizeof(Source));
835 
836  INLINE(static Dest cast(const Source& source)) {
837  Dest dest;
838  memcpy(&dest, &source, sizeof(dest));
839  return dest;
840  }
841 };
842 
843 template <class Dest, class Source>
844 struct BitCastHelper<Dest, Source*> {
845  INLINE(static Dest cast(Source* source)) {
847  cast(reinterpret_cast<uintptr_t>(source));
848  }
849 };
850 
851 template <class Dest, class Source>
852 INLINE(Dest BitCast(const Source& source));
853 
854 template <class Dest, class Source>
855 inline Dest BitCast(const Source& source) {
856  return BitCastHelper<Dest, Source>::cast(source);
857 }
858 
859 
860 template<typename ElementType, int NumElements>
862  public:
863  EmbeddedContainer() : elems_() { }
864 
865  int length() const { return NumElements; }
866  const ElementType& operator[](int i) const {
867  ASSERT(i < length());
868  return elems_[i];
869  }
870  ElementType& operator[](int i) {
871  ASSERT(i < length());
872  return elems_[i];
873  }
874 
875  private:
876  ElementType elems_[NumElements];
877 };
878 
879 
880 template<typename ElementType>
881 class EmbeddedContainer<ElementType, 0> {
882  public:
883  int length() const { return 0; }
884  const ElementType& operator[](int i) const {
885  UNREACHABLE();
886  static ElementType t = 0;
887  return t;
888  }
889  ElementType& operator[](int i) {
890  UNREACHABLE();
891  static ElementType t = 0;
892  return t;
893  }
894 };
895 
896 
897 // Helper class for building result strings in a character buffer. The
898 // purpose of the class is to use safe operations that checks the
899 // buffer bounds on all operations in debug mode.
900 // This simple base class does not allow formatted output.
902  public:
903  // Create a string builder with a buffer of the given size. The
904  // buffer is allocated through NewArray<char> and must be
905  // deallocated by the caller of Finalize().
906  explicit SimpleStringBuilder(int size);
907 
908  SimpleStringBuilder(char* buffer, int size)
909  : buffer_(buffer, size), position_(0) { }
910 
912 
913  int size() const { return buffer_.length(); }
914 
915  // Get the current position in the builder.
916  int position() const {
917  ASSERT(!is_finalized());
918  return position_;
919  }
920 
921  // Reset the position.
922  void Reset() { position_ = 0; }
923 
924  // Add a single character to the builder. It is not allowed to add
925  // 0-characters; use the Finalize() method to terminate the string
926  // instead.
927  void AddCharacter(char c) {
928  ASSERT(c != '\0');
930  buffer_[position_++] = c;
931  }
932 
933  // Add an entire string to the builder. Uses strlen() internally to
934  // compute the length of the input string.
935  void AddString(const char* s);
936 
937  // Add the first 'n' characters of the given string 's' to the
938  // builder. The input string must have enough characters.
939  void AddSubstring(const char* s, int n);
940 
941  // Add character padding to the builder. If count is non-positive,
942  // nothing is added to the builder.
943  void AddPadding(char c, int count);
944 
945  // Add the decimal representation of the value.
946  void AddDecimalInteger(int value);
947 
948  // Finalize the string by 0-terminating it and returning the buffer.
949  char* Finalize();
950 
951  protected:
954 
955  bool is_finalized() const { return position_ < 0; }
956 
957  private:
958  DISALLOW_IMPLICIT_CONSTRUCTORS(SimpleStringBuilder);
959 };
960 
961 
962 // A poor man's version of STL's bitset: A bit set of enums E (without explicit
963 // values), fitting into an integral type T.
964 template <class E, class T = int>
965 class EnumSet {
966  public:
967  explicit EnumSet(T bits = 0) : bits_(bits) {}
968  bool IsEmpty() const { return bits_ == 0; }
969  bool Contains(E element) const { return (bits_ & Mask(element)) != 0; }
970  bool ContainsAnyOf(const EnumSet& set) const {
971  return (bits_ & set.bits_) != 0;
972  }
973  void Add(E element) { bits_ |= Mask(element); }
974  void Add(const EnumSet& set) { bits_ |= set.bits_; }
975  void Remove(E element) { bits_ &= ~Mask(element); }
976  void Remove(const EnumSet& set) { bits_ &= ~set.bits_; }
977  void RemoveAll() { bits_ = 0; }
978  void Intersect(const EnumSet& set) { bits_ &= set.bits_; }
979  T ToIntegral() const { return bits_; }
980  bool operator==(const EnumSet& set) { return bits_ == set.bits_; }
981 
982  private:
983  T Mask(E element) const {
984  // The strange typing in ASSERT is necessary to avoid stupid warnings, see:
985  // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43680
986  ASSERT(static_cast<int>(element) < static_cast<int>(sizeof(T) * CHAR_BIT));
987  return 1 << element;
988  }
989 
990  T bits_;
991 };
992 
993 
995  public:
996  explicit TypeFeedbackId(int id) : id_(id) { }
997  int ToInt() const { return id_; }
998 
999  static TypeFeedbackId None() { return TypeFeedbackId(kNoneId); }
1000  bool IsNone() const { return id_ == kNoneId; }
1001 
1002  private:
1003  static const int kNoneId = -1;
1004 
1005  int id_;
1006 };
1007 
1008 
1009 class BailoutId {
1010  public:
1011  explicit BailoutId(int id) : id_(id) { }
1012  int ToInt() const { return id_; }
1013 
1014  static BailoutId None() { return BailoutId(kNoneId); }
1015  static BailoutId FunctionEntry() { return BailoutId(kFunctionEntryId); }
1016  static BailoutId Declarations() { return BailoutId(kDeclarationsId); }
1017  static BailoutId FirstUsable() { return BailoutId(kFirstUsableId); }
1018 
1019  bool IsNone() const { return id_ == kNoneId; }
1020  bool operator==(const BailoutId& other) const { return id_ == other.id_; }
1021 
1022  private:
1023  static const int kNoneId = -1;
1024 
1025  // Using 0 could disguise errors.
1026  static const int kFunctionEntryId = 2;
1027 
1028  // This AST id identifies the point after the declarations have been visited.
1029  // We need it to capture the environment effects of declarations that emit
1030  // code (function declarations).
1031  static const int kDeclarationsId = 3;
1032 
1033  // Ever FunctionState starts with this id.
1034  static const int kFirstUsableId = 4;
1035 
1036  int id_;
1037 };
1038 
1039 } } // namespace v8::internal
1040 
1041 #endif // V8_UTILS_H_
byte * Address
Definition: globals.h:157
const DivMagicNumbers DivMagicNumberFor625
Definition: utils.h:109
bool operator==(const BailoutId &other) const
Definition: utils.h:1020
ElementType & operator[](int i)
Definition: utils.h:870
Vector(T *data, int length)
Definition: utils.h:366
bool IsAddressAligned(Address addr, intptr_t alignment, int offset=0)
Definition: utils.h:212
Vector< T > AddBlock(Vector< const T > source)
Definition: utils.h:598
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:967
void Sort(int(*cmp)(const T *, const T *))
Definition: utils.h:411
const DivMagicNumbers DivMagicNumberFor3
Definition: utils.h:102
static uint32_t encode(T value)
Definition: utils.h:262
static TypeFeedbackId None()
Definition: utils.h:999
const DivMagicNumbers DivMagicNumberFor5
Definition: utils.h:103
const ElementType & operator[](int i) const
Definition: utils.h:884
T Max(T a, T b)
Definition: utils.h:222
Vector< char > MutableCStrVector(char *data)
Definition: utils.h:530
const DivMagicNumbers DivMagicNumberFor9
Definition: utils.h:105
Access(StaticResource< T > *resource)
Definition: utils.h:340
void Grow(int min_capacity)
Definition: utils.h:653
Vector< T > SubVector(int from, int to)
Definition: utils.h:376
int int32_t
Definition: unicode.cc:47
SimpleStringBuilder(char *buffer, int size)
Definition: utils.h:908
static const uint32_t kMask
Definition: utils.h:250
bool IsNone() const
Definition: utils.h:1000
void Add(T value)
Definition: utils.h:566
#define ASSERT(condition)
Definition: checks.h:270
T & operator[](int index) const
Definition: utils.h:393
const ElementType & operator[](int i) const
Definition: utils.h:866
bool IsEmpty() const
Definition: utils.h:968
STATIC_ASSERT(sizeof(Dest)==sizeof(Source))
bool ContainsAnyOf(const EnumSet &set) const
Definition: utils.h:970
void Add(const EnumSet &set)
Definition: utils.h:974
int WhichPowerOf2(uint32_t x)
Definition: utils.h:56
static uint32_t update(uint32_t previous, T value)
Definition: utils.h:268
void set(T *value)
Definition: utils.h:472
ScopedVector(int length)
Definition: utils.h:516
int ToInt() const
Definition: utils.h:1012
int HandleObjectPointerCompare(const Handle< T > *a, const Handle< T > *b)
Definition: utils.h:177
unsigned int seed
Definition: test-strings.cc:18
bool is_empty() const
Definition: utils.h:387
SequenceCollector(int initial_capacity)
Definition: utils.h:704
uint32_t ComputePointerHash(void *ptr)
Definition: utils.h:311
void set_start(T *start)
Definition: utils.h:451
#define UNREACHABLE()
Definition: checks.h:50
INLINE(static Dest cast(Source *source))
Definition: utils.h:845
Vector< T > AddBlock(int size, T initial_value)
Definition: utils.h:579
T * start() const
Definition: utils.h:390
static const uint32_t kShift
Definition: utils.h:251
EmbeddedVector(T initial_value)
Definition: utils.h:487
static BailoutId Declarations()
Definition: utils.h:1016
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:254
bool IsAligned(T value, U alignment)
Definition: utils.h:206
INLINE(static Dest cast(const Source &source))
Definition: utils.h:836
bool IsNone() const
Definition: utils.h:1019
static T decode(uint32_t value)
Definition: utils.h:273
int length() const
Definition: utils.h:384
EmbeddedVector(const EmbeddedVector &rhs)
Definition: utils.h:494
void Intersect(const EnumSet &set)
Definition: utils.h:978
T RoundUp(T x, intptr_t m)
Definition: utils.h:150
Vector< T > ToVector()
Definition: utils.h:633
const DivMagicNumbers DivMagicNumberFor125
Definition: utils.h:108
void Remove(const EnumSet &set)
Definition: utils.h:976
Definition: v8.h:105
bool IsPowerOf2(T x)
Definition: utils.h:50
int CompareChars(const lchar *lhs, const rchar *rhs, int chars)
Definition: utils.h:768
int TenToThe(int exponent)
Definition: utils.h:795
void Truncate(int length)
Definition: utils.h:423
static BailoutId FunctionEntry()
Definition: utils.h:1015
static Vector< T > New(int length)
Definition: utils.h:370
activate correct semantics for inheriting readonliness false
Definition: flags.cc:141
static BailoutId None()
Definition: utils.h:1014
Vector< const char > CStrVector(const char *data)
Definition: utils.h:526
int StrLength(const char *string)
Definition: utils.h:234
List< Vector< T > > chunks_
Definition: utils.h:647
#define T(name, string, precedence)
Definition: token.cc:48
Vector< T > Clone() const
Definition: utils.h:405
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:715
static BailoutId FirstUsable()
Definition: utils.h:1017
void AddSubstring(const char *s, int n)
Definition: utils.cc:48
uint32_t ComputeIntegerHash(uint32_t key, uint32_t seed)
Definition: utils.h:286
bool Contains(E element) const
Definition: utils.h:969
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:557
static Vector< T > cast(Vector< S > input)
Definition: utils.h:445
T ToIntegral() const
Definition: utils.h:979
uint32_t ComputeLongHash(uint64_t key)
Definition: utils.h:299
Collector(int initial_capacity=kMinCapacity)
Definition: utils.h:552
#define ASSERT_EQ(v1, v2)
Definition: checks.h:271
virtual void NewChunk(int new_capacity)
Definition: utils.h:679
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:648
static Vector< T > empty()
Definition: utils.h:442
Vector< T > operator+(int offset)
Definition: utils.h:436
const T & at(int index) const
Definition: utils.h:398
void AddPadding(char c, int count)
Definition: utils.cc:56
bool operator==(const EnumSet &set)
Definition: utils.h:980
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra 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 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
static const int kMinCapacity
Definition: utils.h:646
static bool is_valid(T value)
Definition: utils.h:257
void WriteTo(Vector< T > destination)
Definition: utils.h:613
Dest BitCast(const Source &source)
Definition: utils.h:855
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:975
void Add(E element)
Definition: utils.h:973
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:500
const DivMagicNumbers DivMagicNumberFor7
Definition: utils.h:104
bool is_set() const
Definition: utils.h:465