V8 Project
utils.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_UTILS_H_
6 #define V8_UTILS_H_
7 
8 #include <limits.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <cmath>
12 
13 #include "include/v8.h"
14 #include "src/allocation.h"
15 #include "src/base/bits.h"
16 #include "src/base/logging.h"
17 #include "src/base/macros.h"
19 #include "src/globals.h"
20 #include "src/list.h"
21 #include "src/vector.h"
22 
23 namespace v8 {
24 namespace internal {
25 
26 // ----------------------------------------------------------------------------
27 // General helper functions
28 
29 
30 // Same as strcmp, but can handle NULL arguments.
31 inline bool CStringEquals(const char* s1, const char* s2) {
32  return (s1 == s2) || (s1 != NULL && s2 != NULL && strcmp(s1, s2) == 0);
33 }
34 
35 
36 // X must be a power of 2. Returns the number of trailing zeros.
37 inline int WhichPowerOf2(uint32_t x) {
39  int bits = 0;
40 #ifdef DEBUG
41  int original_x = x;
42 #endif
43  if (x >= 0x10000) {
44  bits += 16;
45  x >>= 16;
46  }
47  if (x >= 0x100) {
48  bits += 8;
49  x >>= 8;
50  }
51  if (x >= 0x10) {
52  bits += 4;
53  x >>= 4;
54  }
55  switch (x) {
56  default: UNREACHABLE();
57  case 8: bits++; // Fall through.
58  case 4: bits++; // Fall through.
59  case 2: bits++; // Fall through.
60  case 1: break;
61  }
62  DCHECK_EQ(1 << bits, original_x);
63  return bits;
64  return 0;
65 }
66 
67 
69  static const int msb4[] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4};
70  int nibble = 0;
71  if (x & 0xffff0000) {
72  nibble += 16;
73  x >>= 16;
74  }
75  if (x & 0xff00) {
76  nibble += 8;
77  x >>= 8;
78  }
79  if (x & 0xf0) {
80  nibble += 4;
81  x >>= 4;
82  }
83  return nibble + msb4[x];
84 }
85 
86 
87 // The C++ standard leaves the semantics of '>>' undefined for
88 // negative signed operands. Most implementations do the right thing,
89 // though.
90 inline int ArithmeticShiftRight(int x, int s) {
91  return x >> s;
92 }
93 
94 
95 template <typename T>
96 int Compare(const T& a, const T& b) {
97  if (a == b)
98  return 0;
99  else if (a < b)
100  return -1;
101  else
102  return 1;
103 }
104 
105 
106 template <typename T>
107 int PointerValueCompare(const T* a, const T* b) {
108  return Compare<T>(*a, *b);
109 }
110 
111 
112 // Compare function to compare the object pointer value of two
113 // handlified objects. The handles are passed as pointers to the
114 // handles.
115 template<typename T> class Handle; // Forward declaration.
116 template <typename T>
118  return Compare<T*>(*(*a), *(*b));
119 }
120 
121 
122 template <typename T, typename U>
123 inline bool IsAligned(T value, U alignment) {
124  return (value & (alignment - 1)) == 0;
125 }
126 
127 
128 // Returns true if (addr + offset) is aligned.
129 inline bool IsAddressAligned(Address addr,
130  intptr_t alignment,
131  int offset = 0) {
132  intptr_t offs = OffsetFrom(addr + offset);
133  return IsAligned(offs, alignment);
134 }
135 
136 
137 // Returns the maximum of the two parameters.
138 template <typename T>
139 T Max(T a, T b) {
140  return a < b ? b : a;
141 }
142 
143 
144 // Returns the minimum of the two parameters.
145 template <typename T>
146 T Min(T a, T b) {
147  return a < b ? a : b;
148 }
149 
150 
151 // Returns the absolute value of its argument.
152 template <typename T>
153 T Abs(T a) {
154  return a < 0 ? -a : a;
155 }
156 
157 
158 // Floor(-0.0) == 0.0
159 inline double Floor(double x) {
160 #ifdef _MSC_VER
161  if (x == 0) return x; // Fix for issue 3477.
162 #endif
163  return std::floor(x);
164 }
165 
166 
167 // TODO(svenpanne) Clean up the whole power-of-2 mess.
169  return (x == kMinInt) ? 31 : WhichPowerOf2(Abs(x));
170 }
171 
172 
173 // Obtains the unsigned type corresponding to T
174 // available in C++11 as std::make_unsigned
175 template<typename T>
177  typedef T type;
178 };
179 
180 
181 // Template specializations necessary to have make_unsigned work
182 template<> struct make_unsigned<int32_t> {
183  typedef uint32_t type;
184 };
185 
186 
187 template<> struct make_unsigned<int64_t> {
188  typedef uint64_t type;
189 };
190 
191 
192 // ----------------------------------------------------------------------------
193 // BitField is a help template for encoding and decode bitfield with
194 // unsigned content.
195 
196 template<class T, int shift, int size, class U>
198  public:
199  // A type U mask of bit field. To use all bits of a type U of x bits
200  // in a bitfield without compiler warnings we have to compute 2^x
201  // without using a shift count of x in the computation.
202  static const U kOne = static_cast<U>(1U);
203  static const U kMask = ((kOne << shift) << size) - (kOne << shift);
204  static const U kShift = shift;
205  static const U kSize = size;
206  static const U kNext = kShift + kSize;
207 
208  // Value for the field with all bits set.
209  static const T kMax = static_cast<T>((1U << size) - 1);
210 
211  // Tells whether the provided value fits into the bit field.
212  static bool is_valid(T value) {
213  return (static_cast<U>(value) & ~static_cast<U>(kMax)) == 0;
214  }
215 
216  // Returns a type U with the bit field value encoded.
217  static U encode(T value) {
218  DCHECK(is_valid(value));
219  return static_cast<U>(value) << shift;
220  }
221 
222  // Returns a type U with the bit field value updated.
223  static U update(U previous, T value) {
224  return (previous & ~kMask) | encode(value);
225  }
226 
227  // Extracts the bit field from the value.
228  static T decode(U value) {
229  return static_cast<T>((value & kMask) >> shift);
230  }
231 };
232 
233 
234 template<class T, int shift, int size>
235 class BitField : public BitFieldBase<T, shift, size, uint32_t> { };
236 
237 
238 template<class T, int shift, int size>
239 class BitField64 : public BitFieldBase<T, shift, size, uint64_t> { };
240 
241 
242 // ----------------------------------------------------------------------------
243 // Hash function.
244 
245 static const uint32_t kZeroHashSeed = 0;
246 
247 // Thomas Wang, Integer Hash Functions.
248 // http://www.concentric.net/~Ttwang/tech/inthash.htm
250  uint32_t hash = key;
251  hash = hash ^ seed;
252  hash = ~hash + (hash << 15); // hash = (hash << 15) - hash - 1;
253  hash = hash ^ (hash >> 12);
254  hash = hash + (hash << 2);
255  hash = hash ^ (hash >> 4);
256  hash = hash * 2057; // hash = (hash + (hash << 3)) + (hash << 11);
257  hash = hash ^ (hash >> 16);
258  return hash;
259 }
260 
261 
262 inline uint32_t ComputeLongHash(uint64_t key) {
263  uint64_t hash = key;
264  hash = ~hash + (hash << 18); // hash = (hash << 18) - hash - 1;
265  hash = hash ^ (hash >> 31);
266  hash = hash * 21; // hash = (hash + (hash << 2)) + (hash << 4);
267  hash = hash ^ (hash >> 11);
268  hash = hash + (hash << 6);
269  hash = hash ^ (hash >> 22);
270  return static_cast<uint32_t>(hash);
271 }
272 
273 
274 inline uint32_t ComputePointerHash(void* ptr) {
275  return ComputeIntegerHash(
276  static_cast<uint32_t>(reinterpret_cast<intptr_t>(ptr)),
278 }
279 
280 
281 // ----------------------------------------------------------------------------
282 // Generated memcpy/memmove
283 
284 // Initializes the codegen support that depends on CPU features. This is
285 // called after CPU initialization.
287 
288 #if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X87)
289 // Limit below which the extra overhead of the MemCopy function is likely
290 // to outweigh the benefits of faster copying.
291 const int kMinComplexMemCopy = 64;
292 
293 // Copy memory area. No restrictions.
294 void MemMove(void* dest, const void* src, size_t size);
295 typedef void (*MemMoveFunction)(void* dest, const void* src, size_t size);
296 
297 // Keep the distinction of "move" vs. "copy" for the benefit of other
298 // architectures.
299 V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
300  MemMove(dest, src, size);
301 }
302 #elif defined(V8_HOST_ARCH_ARM)
303 typedef void (*MemCopyUint8Function)(uint8_t* dest, const uint8_t* src,
304  size_t size);
305 extern MemCopyUint8Function memcopy_uint8_function;
306 V8_INLINE void MemCopyUint8Wrapper(uint8_t* dest, const uint8_t* src,
307  size_t chars) {
308  memcpy(dest, src, chars);
309 }
310 // For values < 16, the assembler function is slower than the inlined C code.
311 const int kMinComplexMemCopy = 16;
312 V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
313  (*memcopy_uint8_function)(reinterpret_cast<uint8_t*>(dest),
314  reinterpret_cast<const uint8_t*>(src), size);
315 }
316 V8_INLINE void MemMove(void* dest, const void* src, size_t size) {
317  memmove(dest, src, size);
318 }
319 
320 typedef void (*MemCopyUint16Uint8Function)(uint16_t* dest, const uint8_t* src,
321  size_t size);
322 extern MemCopyUint16Uint8Function memcopy_uint16_uint8_function;
323 void MemCopyUint16Uint8Wrapper(uint16_t* dest, const uint8_t* src,
324  size_t chars);
325 // For values < 12, the assembler function is slower than the inlined C code.
326 const int kMinComplexConvertMemCopy = 12;
327 V8_INLINE void MemCopyUint16Uint8(uint16_t* dest, const uint8_t* src,
328  size_t size) {
329  (*memcopy_uint16_uint8_function)(dest, src, size);
330 }
331 #elif defined(V8_HOST_ARCH_MIPS)
332 typedef void (*MemCopyUint8Function)(uint8_t* dest, const uint8_t* src,
333  size_t size);
334 extern MemCopyUint8Function memcopy_uint8_function;
335 V8_INLINE void MemCopyUint8Wrapper(uint8_t* dest, const uint8_t* src,
336  size_t chars) {
337  memcpy(dest, src, chars);
338 }
339 // For values < 16, the assembler function is slower than the inlined C code.
340 const int kMinComplexMemCopy = 16;
341 V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
342  (*memcopy_uint8_function)(reinterpret_cast<uint8_t*>(dest),
343  reinterpret_cast<const uint8_t*>(src), size);
344 }
345 V8_INLINE void MemMove(void* dest, const void* src, size_t size) {
346  memmove(dest, src, size);
347 }
348 #else
349 // Copy memory area to disjoint memory area.
350 V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
351  memcpy(dest, src, size);
352 }
353 V8_INLINE void MemMove(void* dest, const void* src, size_t size) {
354  memmove(dest, src, size);
355 }
357 #endif // V8_TARGET_ARCH_IA32
358 
359 
360 // ----------------------------------------------------------------------------
361 // Miscellaneous
362 
363 // A static resource holds a static instance that can be reserved in
364 // a local scope using an instance of Access. Attempts to re-reserve
365 // the instance will cause an error.
366 template <typename T>
368  public:
370 
371  private:
372  template <typename S> friend class Access;
375 };
376 
377 
378 // Locally scoped access to a static resource.
379 template <typename T>
380 class Access {
381  public:
382  explicit Access(StaticResource<T>* resource)
383  : resource_(resource)
384  , instance_(&resource->instance_) {
385  DCHECK(!resource->is_reserved_);
386  resource->is_reserved_ = true;
387  }
388 
390  resource_->is_reserved_ = false;
391  resource_ = NULL;
392  instance_ = NULL;
393  }
394 
395  T* value() { return instance_; }
396  T* operator -> () { return instance_; }
397 
398  private:
401 };
402 
403 
404 // A pointer that can only be set once and doesn't allow NULL values.
405 template<typename T>
407  public:
409 
410  bool is_set() const { return pointer_ != NULL; }
411 
412  T* get() const {
413  DCHECK(pointer_ != NULL);
414  return pointer_;
415  }
416 
417  void set(T* value) {
418  DCHECK(pointer_ == NULL && value != NULL);
419  pointer_ = value;
420  }
421 
422  private:
424 };
425 
426 
427 template <typename T, int kSize>
428 class EmbeddedVector : public Vector<T> {
429  public:
430  EmbeddedVector() : Vector<T>(buffer_, kSize) { }
431 
432  explicit EmbeddedVector(T initial_value) : Vector<T>(buffer_, kSize) {
433  for (int i = 0; i < kSize; ++i) {
434  buffer_[i] = initial_value;
435  }
436  }
437 
438  // When copying, make underlying Vector to reference our buffer.
440  : Vector<T>(rhs) {
441  MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
442  this->set_start(buffer_);
443  }
444 
446  if (this == &rhs) return *this;
448  MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
449  this->set_start(buffer_);
450  return *this;
451  }
452 
453  private:
454  T buffer_[kSize];
455 };
456 
457 
458 /*
459  * A class that collects values into a backing store.
460  * Specialized versions of the class can allow access to the backing store
461  * in different ways.
462  * There is no guarantee that the backing store is contiguous (and, as a
463  * consequence, no guarantees that consecutively added elements are adjacent
464  * in memory). The collector may move elements unless it has guaranteed not
465  * to.
466  */
467 template <typename T, int growth_factor = 2, int max_growth = 1 * MB>
468 class Collector {
469  public:
470  explicit Collector(int initial_capacity = kMinCapacity)
471  : index_(0), size_(0) {
472  current_chunk_ = Vector<T>::New(initial_capacity);
473  }
474 
475  virtual ~Collector() {
476  // Free backing store (in reverse allocation order).
477  current_chunk_.Dispose();
478  for (int i = chunks_.length() - 1; i >= 0; i--) {
479  chunks_.at(i).Dispose();
480  }
481  }
482 
483  // Add a single element.
484  inline void Add(T value) {
485  if (index_ >= current_chunk_.length()) {
486  Grow(1);
487  }
488  current_chunk_[index_] = value;
489  index_++;
490  size_++;
491  }
492 
493  // Add a block of contiguous elements and return a Vector backed by the
494  // memory area.
495  // A basic Collector will keep this vector valid as long as the Collector
496  // is alive.
497  inline Vector<T> AddBlock(int size, T initial_value) {
498  DCHECK(size > 0);
499  if (size > current_chunk_.length() - index_) {
500  Grow(size);
501  }
502  T* position = current_chunk_.start() + index_;
503  index_ += size;
504  size_ += size;
505  for (int i = 0; i < size; i++) {
506  position[i] = initial_value;
507  }
508  return Vector<T>(position, size);
509  }
510 
511 
512  // Add a contiguous block of elements and return a vector backed
513  // by the added block.
514  // A basic Collector will keep this vector valid as long as the Collector
515  // is alive.
517  if (source.length() > current_chunk_.length() - index_) {
518  Grow(source.length());
519  }
520  T* position = current_chunk_.start() + index_;
521  index_ += source.length();
522  size_ += source.length();
523  for (int i = 0; i < source.length(); i++) {
524  position[i] = source[i];
525  }
526  return Vector<T>(position, source.length());
527  }
528 
529 
530  // Write the contents of the collector into the provided vector.
531  void WriteTo(Vector<T> destination) {
532  DCHECK(size_ <= destination.length());
533  int position = 0;
534  for (int i = 0; i < chunks_.length(); i++) {
535  Vector<T> chunk = chunks_.at(i);
536  for (int j = 0; j < chunk.length(); j++) {
537  destination[position] = chunk[j];
538  position++;
539  }
540  }
541  for (int i = 0; i < index_; i++) {
542  destination[position] = current_chunk_[i];
543  position++;
544  }
545  }
546 
547  // Allocate a single contiguous vector, copy all the collected
548  // elements to the vector, and return it.
549  // The caller is responsible for freeing the memory of the returned
550  // vector (e.g., using Vector::Dispose).
552  Vector<T> new_store = Vector<T>::New(size_);
553  WriteTo(new_store);
554  return new_store;
555  }
556 
557  // Resets the collector to be empty.
558  virtual void Reset();
559 
560  // Total number of elements added to collector so far.
561  inline int size() { return size_; }
562 
563  protected:
564  static const int kMinCapacity = 16;
566  Vector<T> current_chunk_; // Block of memory currently being written into.
567  int index_; // Current index in current chunk.
568  int size_; // Total number of elements in collector.
569 
570  // Creates a new current chunk, and stores the old chunk in the chunks_ list.
571  void Grow(int min_capacity) {
572  DCHECK(growth_factor > 1);
573  int new_capacity;
574  int current_length = current_chunk_.length();
575  if (current_length < kMinCapacity) {
576  // The collector started out as empty.
577  new_capacity = min_capacity * growth_factor;
578  if (new_capacity < kMinCapacity) new_capacity = kMinCapacity;
579  } else {
580  int growth = current_length * (growth_factor - 1);
581  if (growth > max_growth) {
582  growth = max_growth;
583  }
584  new_capacity = current_length + growth;
585  if (new_capacity < min_capacity) {
586  new_capacity = min_capacity + growth;
587  }
588  }
589  NewChunk(new_capacity);
590  DCHECK(index_ + min_capacity <= current_chunk_.length());
591  }
592 
593  // Before replacing the current chunk, give a subclass the option to move
594  // some of the current data into the new chunk. The function may update
595  // the current index_ value to represent data no longer in the current chunk.
596  // Returns the initial index of the new chunk (after copied data).
597  virtual void NewChunk(int new_capacity) {
598  Vector<T> new_chunk = Vector<T>::New(new_capacity);
599  if (index_ > 0) {
600  chunks_.Add(current_chunk_.SubVector(0, index_));
601  } else {
602  current_chunk_.Dispose();
603  }
604  current_chunk_ = new_chunk;
605  index_ = 0;
606  }
607 };
608 
609 
610 /*
611  * A collector that allows sequences of values to be guaranteed to
612  * stay consecutive.
613  * If the backing store grows while a sequence is active, the current
614  * sequence might be moved, but after the sequence is ended, it will
615  * not move again.
616  * NOTICE: Blocks allocated using Collector::AddBlock(int) can move
617  * as well, if inside an active sequence where another element is added.
618  */
619 template <typename T, int growth_factor = 2, int max_growth = 1 * MB>
620 class SequenceCollector : public Collector<T, growth_factor, max_growth> {
621  public:
622  explicit SequenceCollector(int initial_capacity)
623  : Collector<T, growth_factor, max_growth>(initial_capacity),
625 
626  virtual ~SequenceCollector() {}
627 
628  void StartSequence() {
630  sequence_start_ = this->index_;
631  }
632 
635  int sequence_start = sequence_start_;
637  if (sequence_start == this->index_) return Vector<T>();
638  return this->current_chunk_.SubVector(sequence_start, this->index_);
639  }
640 
641  // Drops the currently added sequence, and all collected elements in it.
642  void DropSequence() {
644  int sequence_length = this->index_ - sequence_start_;
645  this->index_ = sequence_start_;
646  this->size_ -= sequence_length;
648  }
649 
650  virtual void Reset() {
653  }
654 
655  private:
656  static const int kNoSequence = -1;
658 
659  // Move the currently active sequence to the new chunk.
660  virtual void NewChunk(int new_capacity) {
661  if (sequence_start_ == kNoSequence) {
662  // Fall back on default behavior if no sequence has been started.
664  return;
665  }
666  int sequence_length = this->index_ - sequence_start_;
667  Vector<T> new_chunk = Vector<T>::New(sequence_length + new_capacity);
668  DCHECK(sequence_length < new_chunk.length());
669  for (int i = 0; i < sequence_length; i++) {
670  new_chunk[i] = this->current_chunk_[sequence_start_ + i];
671  }
672  if (sequence_start_ > 0) {
673  this->chunks_.Add(this->current_chunk_.SubVector(0, sequence_start_));
674  } else {
675  this->current_chunk_.Dispose();
676  }
677  this->current_chunk_ = new_chunk;
678  this->index_ = sequence_length;
679  sequence_start_ = 0;
680  }
681 };
682 
683 
684 // Compare 8bit/16bit chars to 8bit/16bit chars.
685 template <typename lchar, typename rchar>
686 inline int CompareCharsUnsigned(const lchar* lhs,
687  const rchar* rhs,
688  int chars) {
689  const lchar* limit = lhs + chars;
690  if (sizeof(*lhs) == sizeof(char) && sizeof(*rhs) == sizeof(char)) {
691  // memcmp compares byte-by-byte, yielding wrong results for two-byte
692  // strings on little-endian systems.
693  return memcmp(lhs, rhs, chars);
694  }
695  while (lhs < limit) {
696  int r = static_cast<int>(*lhs) - static_cast<int>(*rhs);
697  if (r != 0) return r;
698  ++lhs;
699  ++rhs;
700  }
701  return 0;
702 }
703 
704 template<typename lchar, typename rchar>
705 inline int CompareChars(const lchar* lhs, const rchar* rhs, int chars) {
706  DCHECK(sizeof(lchar) <= 2);
707  DCHECK(sizeof(rchar) <= 2);
708  if (sizeof(lchar) == 1) {
709  if (sizeof(rchar) == 1) {
710  return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs),
711  reinterpret_cast<const uint8_t*>(rhs),
712  chars);
713  } else {
714  return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs),
715  reinterpret_cast<const uint16_t*>(rhs),
716  chars);
717  }
718  } else {
719  if (sizeof(rchar) == 1) {
720  return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(lhs),
721  reinterpret_cast<const uint8_t*>(rhs),
722  chars);
723  } else {
724  return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(lhs),
725  reinterpret_cast<const uint16_t*>(rhs),
726  chars);
727  }
728  }
729 }
730 
731 
732 // Calculate 10^exponent.
733 inline int TenToThe(int exponent) {
734  DCHECK(exponent <= 9);
735  DCHECK(exponent >= 1);
736  int answer = 10;
737  for (int i = 1; i < exponent; i++) answer *= 10;
738  return answer;
739 }
740 
741 
742 template<typename ElementType, int NumElements>
744  public:
746 
747  int length() const { return NumElements; }
748  const ElementType& operator[](int i) const {
749  DCHECK(i < length());
750  return elems_[i];
751  }
752  ElementType& operator[](int i) {
753  DCHECK(i < length());
754  return elems_[i];
755  }
756 
757  private:
758  ElementType elems_[NumElements];
759 };
760 
761 
762 template<typename ElementType>
763 class EmbeddedContainer<ElementType, 0> {
764  public:
765  int length() const { return 0; }
766  const ElementType& operator[](int i) const {
767  UNREACHABLE();
768  static ElementType t = 0;
769  return t;
770  }
771  ElementType& operator[](int i) {
772  UNREACHABLE();
773  static ElementType t = 0;
774  return t;
775  }
776 };
777 
778 
779 // Helper class for building result strings in a character buffer. The
780 // purpose of the class is to use safe operations that checks the
781 // buffer bounds on all operations in debug mode.
782 // This simple base class does not allow formatted output.
784  public:
785  // Create a string builder with a buffer of the given size. The
786  // buffer is allocated through NewArray<char> and must be
787  // deallocated by the caller of Finalize().
788  explicit SimpleStringBuilder(int size);
789 
790  SimpleStringBuilder(char* buffer, int size)
791  : buffer_(buffer, size), position_(0) { }
792 
794 
795  int size() const { return buffer_.length(); }
796 
797  // Get the current position in the builder.
798  int position() const {
799  DCHECK(!is_finalized());
800  return position_;
801  }
802 
803  // Reset the position.
804  void Reset() { position_ = 0; }
805 
806  // Add a single character to the builder. It is not allowed to add
807  // 0-characters; use the Finalize() method to terminate the string
808  // instead.
809  void AddCharacter(char c) {
810  DCHECK(c != '\0');
812  buffer_[position_++] = c;
813  }
814 
815  // Add an entire string to the builder. Uses strlen() internally to
816  // compute the length of the input string.
817  void AddString(const char* s);
818 
819  // Add the first 'n' characters of the given string 's' to the
820  // builder. The input string must have enough characters.
821  void AddSubstring(const char* s, int n);
822 
823  // Add character padding to the builder. If count is non-positive,
824  // nothing is added to the builder.
825  void AddPadding(char c, int count);
826 
827  // Add the decimal representation of the value.
828  void AddDecimalInteger(int value);
829 
830  // Finalize the string by 0-terminating it and returning the buffer.
831  char* Finalize();
832 
833  protected:
836 
837  bool is_finalized() const { return position_ < 0; }
838 
839  private:
841 };
842 
843 
844 // A poor man's version of STL's bitset: A bit set of enums E (without explicit
845 // values), fitting into an integral type T.
846 template <class E, class T = int>
847 class EnumSet {
848  public:
849  explicit EnumSet(T bits = 0) : bits_(bits) {}
850  bool IsEmpty() const { return bits_ == 0; }
851  bool Contains(E element) const { return (bits_ & Mask(element)) != 0; }
852  bool ContainsAnyOf(const EnumSet& set) const {
853  return (bits_ & set.bits_) != 0;
854  }
855  void Add(E element) { bits_ |= Mask(element); }
856  void Add(const EnumSet& set) { bits_ |= set.bits_; }
857  void Remove(E element) { bits_ &= ~Mask(element); }
858  void Remove(const EnumSet& set) { bits_ &= ~set.bits_; }
859  void RemoveAll() { bits_ = 0; }
860  void Intersect(const EnumSet& set) { bits_ &= set.bits_; }
861  T ToIntegral() const { return bits_; }
862  bool operator==(const EnumSet& set) { return bits_ == set.bits_; }
863  bool operator!=(const EnumSet& set) { return bits_ != set.bits_; }
864  EnumSet<E, T> operator|(const EnumSet& set) const {
865  return EnumSet<E, T>(bits_ | set.bits_);
866  }
867 
868  private:
869  T Mask(E element) const {
870  // The strange typing in DCHECK is necessary to avoid stupid warnings, see:
871  // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43680
872  DCHECK(static_cast<int>(element) < static_cast<int>(sizeof(T) * CHAR_BIT));
873  return static_cast<T>(1) << element;
874  }
875 
877 };
878 
879 // Bit field extraction.
880 inline uint32_t unsigned_bitextract_32(int msb, int lsb, uint32_t x) {
881  return (x >> lsb) & ((1 << (1 + msb - lsb)) - 1);
882 }
883 
884 inline uint64_t unsigned_bitextract_64(int msb, int lsb, uint64_t x) {
885  return (x >> lsb) & ((static_cast<uint64_t>(1) << (1 + msb - lsb)) - 1);
886 }
887 
888 inline int32_t signed_bitextract_32(int msb, int lsb, int32_t x) {
889  return (x << (31 - msb)) >> (lsb + 31 - msb);
890 }
891 
892 inline int signed_bitextract_64(int msb, int lsb, int x) {
893  // TODO(jbramley): This is broken for big bitfields.
894  return (x << (63 - msb)) >> (lsb + 63 - msb);
895 }
896 
897 // Check number width.
898 inline bool is_intn(int64_t x, unsigned n) {
899  DCHECK((0 < n) && (n < 64));
900  int64_t limit = static_cast<int64_t>(1) << (n - 1);
901  return (-limit <= x) && (x < limit);
902 }
903 
904 inline bool is_uintn(int64_t x, unsigned n) {
905  DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte)));
906  return !(x >> n);
907 }
908 
909 template <class T>
910 inline T truncate_to_intn(T x, unsigned n) {
911  DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte)));
912  return (x & ((static_cast<T>(1) << n) - 1));
913 }
914 
915 #define INT_1_TO_63_LIST(V) \
916 V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) \
917 V(9) V(10) V(11) V(12) V(13) V(14) V(15) V(16) \
918 V(17) V(18) V(19) V(20) V(21) V(22) V(23) V(24) \
919 V(25) V(26) V(27) V(28) V(29) V(30) V(31) V(32) \
920 V(33) V(34) V(35) V(36) V(37) V(38) V(39) V(40) \
921 V(41) V(42) V(43) V(44) V(45) V(46) V(47) V(48) \
922 V(49) V(50) V(51) V(52) V(53) V(54) V(55) V(56) \
923 V(57) V(58) V(59) V(60) V(61) V(62) V(63)
924 
925 #define DECLARE_IS_INT_N(N) \
926 inline bool is_int##N(int64_t x) { return is_intn(x, N); }
927 #define DECLARE_IS_UINT_N(N) \
928 template <class T> \
929 inline bool is_uint##N(T x) { return is_uintn(x, N); }
930 #define DECLARE_TRUNCATE_TO_INT_N(N) \
931 template <class T> \
932 inline T truncate_to_int##N(T x) { return truncate_to_intn(x, N); }
936 #undef DECLARE_IS_INT_N
937 #undef DECLARE_IS_UINT_N
938 #undef DECLARE_TRUNCATE_TO_INT_N
939 
941  public:
942  explicit TypeFeedbackId(int id) : id_(id) { }
943  int ToInt() const { return id_; }
944 
946  bool IsNone() const { return id_ == kNoneId; }
947 
948  private:
949  static const int kNoneId = -1;
950 
951  int id_;
952 };
953 
954 
955 class BailoutId {
956  public:
957  explicit BailoutId(int id) : id_(id) { }
958  int ToInt() const { return id_; }
959 
960  static BailoutId None() { return BailoutId(kNoneId); }
965 
966  bool IsNone() const { return id_ == kNoneId; }
967  bool operator==(const BailoutId& other) const { return id_ == other.id_; }
968  bool operator!=(const BailoutId& other) const { return id_ != other.id_; }
969 
970  private:
971  static const int kNoneId = -1;
972 
973  // Using 0 could disguise errors.
974  static const int kFunctionEntryId = 2;
975 
976  // This AST id identifies the point after the declarations have been visited.
977  // We need it to capture the environment effects of declarations that emit
978  // code (function declarations).
979  static const int kDeclarationsId = 3;
980 
981  // Every FunctionState starts with this id.
982  static const int kFirstUsableId = 4;
983 
984  // Every compiled stub starts with this id.
985  static const int kStubEntryId = 5;
986 
987  int id_;
988 };
989 
990 
991 template <class C>
993  public:
994  typedef typename C::iterator iterator;
995  typedef typename C::reverse_iterator reverse_iterator;
996  explicit ContainerPointerWrapper(C* container) : container_(container) {}
997  iterator begin() { return container_->begin(); }
998  iterator end() { return container_->end(); }
999  reverse_iterator rbegin() { return container_->rbegin(); }
1000  reverse_iterator rend() { return container_->rend(); }
1001  private:
1003 };
1004 
1005 
1006 // ----------------------------------------------------------------------------
1007 // I/O support.
1008 
1009 #if __GNUC__ >= 4
1010 // On gcc we can ask the compiler to check the types of %d-style format
1011 // specifiers and their associated arguments. TODO(erikcorry) fix this
1012 // so it works on MacOSX.
1013 #if defined(__MACH__) && defined(__APPLE__)
1014 #define PRINTF_CHECKING
1015 #define FPRINTF_CHECKING
1016 #define PRINTF_METHOD_CHECKING
1017 #define FPRINTF_METHOD_CHECKING
1018 #else // MacOsX.
1019 #define PRINTF_CHECKING __attribute__ ((format (printf, 1, 2)))
1020 #define FPRINTF_CHECKING __attribute__ ((format (printf, 2, 3)))
1021 #define PRINTF_METHOD_CHECKING __attribute__ ((format (printf, 2, 3)))
1022 #define FPRINTF_METHOD_CHECKING __attribute__ ((format (printf, 3, 4)))
1023 #endif
1024 #else
1025 #define PRINTF_CHECKING
1026 #define FPRINTF_CHECKING
1027 #define PRINTF_METHOD_CHECKING
1028 #define FPRINTF_METHOD_CHECKING
1029 #endif
1030 
1031 // Our version of printf().
1032 void PRINTF_CHECKING PrintF(const char* format, ...);
1033 void FPRINTF_CHECKING PrintF(FILE* out, const char* format, ...);
1034 
1035 // Prepends the current process ID to the output.
1036 void PRINTF_CHECKING PrintPID(const char* format, ...);
1037 
1038 // Safe formatting print. Ensures that str is always null-terminated.
1039 // Returns the number of chars written, or -1 if output was truncated.
1040 int FPRINTF_CHECKING SNPrintF(Vector<char> str, const char* format, ...);
1041 int VSNPrintF(Vector<char> str, const char* format, va_list args);
1042 
1043 void StrNCpy(Vector<char> dest, const char* src, size_t n);
1044 
1045 // Our version of fflush.
1046 void Flush(FILE* out);
1047 
1048 inline void Flush() {
1049  Flush(stdout);
1050 }
1051 
1052 
1053 // Read a line of characters after printing the prompt to stdout. The resulting
1054 // char* needs to be disposed off with DeleteArray by the caller.
1055 char* ReadLine(const char* prompt);
1056 
1057 
1058 // Read and return the raw bytes in a file. the size of the buffer is returned
1059 // in size.
1060 // The returned buffer must be freed by the caller.
1061 byte* ReadBytes(const char* filename, int* size, bool verbose = true);
1062 
1063 
1064 // Append size chars from str to the file given by filename.
1065 // The file is overwritten. Returns the number of chars written.
1066 int AppendChars(const char* filename,
1067  const char* str,
1068  int size,
1069  bool verbose = true);
1070 
1071 
1072 // Write size chars from str to the file given by filename.
1073 // The file is overwritten. Returns the number of chars written.
1074 int WriteChars(const char* filename,
1075  const char* str,
1076  int size,
1077  bool verbose = true);
1078 
1079 
1080 // Write size bytes to the file given by filename.
1081 // The file is overwritten. Returns the number of bytes written.
1082 int WriteBytes(const char* filename,
1083  const byte* bytes,
1084  int size,
1085  bool verbose = true);
1086 
1087 
1088 // Write the C code
1089 // const char* <varname> = "<str>";
1090 // const int <varname>_len = <len>;
1091 // to the file given by filename. Only the first len chars are written.
1092 int WriteAsCFile(const char* filename, const char* varname,
1093  const char* str, int size, bool verbose = true);
1094 
1095 
1096 // ----------------------------------------------------------------------------
1097 // Data structures
1098 
1099 template <typename T>
1101  int length) {
1102  return Vector< Handle<Object> >(
1103  reinterpret_cast<v8::internal::Handle<Object>*>(elms), length);
1104 }
1105 
1106 
1107 // ----------------------------------------------------------------------------
1108 // Memory
1109 
1110 // Copies words from |src| to |dst|. The data spans must not overlap.
1111 template <typename T>
1112 inline void CopyWords(T* dst, const T* src, size_t num_words) {
1113  STATIC_ASSERT(sizeof(T) == kPointerSize);
1114  // TODO(mvstanton): disabled because mac builds are bogus failing on this
1115  // assert. They are doing a signed comparison. Investigate in
1116  // the morning.
1117  // DCHECK(Min(dst, const_cast<T*>(src)) + num_words <=
1118  // Max(dst, const_cast<T*>(src)));
1119  DCHECK(num_words > 0);
1120 
1121  // Use block copying MemCopy if the segment we're copying is
1122  // enough to justify the extra call/setup overhead.
1123  static const size_t kBlockCopyLimit = 16;
1124 
1125  if (num_words < kBlockCopyLimit) {
1126  do {
1127  num_words--;
1128  *dst++ = *src++;
1129  } while (num_words > 0);
1130  } else {
1131  MemCopy(dst, src, num_words * kPointerSize);
1132  }
1133 }
1134 
1135 
1136 // Copies words from |src| to |dst|. No restrictions.
1137 template <typename T>
1138 inline void MoveWords(T* dst, const T* src, size_t num_words) {
1139  STATIC_ASSERT(sizeof(T) == kPointerSize);
1140  DCHECK(num_words > 0);
1141 
1142  // Use block copying MemCopy if the segment we're copying is
1143  // enough to justify the extra call/setup overhead.
1144  static const size_t kBlockCopyLimit = 16;
1145 
1146  if (num_words < kBlockCopyLimit &&
1147  ((dst < src) || (dst >= (src + num_words * kPointerSize)))) {
1148  T* end = dst + num_words;
1149  do {
1150  num_words--;
1151  *dst++ = *src++;
1152  } while (num_words > 0);
1153  } else {
1154  MemMove(dst, src, num_words * kPointerSize);
1155  }
1156 }
1157 
1158 
1159 // Copies data from |src| to |dst|. The data spans must not overlap.
1160 template <typename T>
1161 inline void CopyBytes(T* dst, const T* src, size_t num_bytes) {
1162  STATIC_ASSERT(sizeof(T) == 1);
1163  DCHECK(Min(dst, const_cast<T*>(src)) + num_bytes <=
1164  Max(dst, const_cast<T*>(src)));
1165  if (num_bytes == 0) return;
1166 
1167  // Use block copying MemCopy if the segment we're copying is
1168  // enough to justify the extra call/setup overhead.
1169  static const int kBlockCopyLimit = kMinComplexMemCopy;
1170 
1171  if (num_bytes < static_cast<size_t>(kBlockCopyLimit)) {
1172  do {
1173  num_bytes--;
1174  *dst++ = *src++;
1175  } while (num_bytes > 0);
1176  } else {
1177  MemCopy(dst, src, num_bytes);
1178  }
1179 }
1180 
1181 
1182 template <typename T, typename U>
1183 inline void MemsetPointer(T** dest, U* value, int counter) {
1184 #ifdef DEBUG
1185  T* a = NULL;
1186  U* b = NULL;
1187  a = b; // Fake assignment to check assignability.
1188  USE(a);
1189 #endif // DEBUG
1190 #if V8_HOST_ARCH_IA32
1191 #define STOS "stosl"
1192 #elif V8_HOST_ARCH_X64
1193 #if V8_HOST_ARCH_32_BIT
1194 #define STOS "addr32 stosl"
1195 #else
1196 #define STOS "stosq"
1197 #endif
1198 #endif
1199 #if defined(__native_client__)
1200  // This STOS sequence does not validate for x86_64 Native Client.
1201  // Here we #undef STOS to force use of the slower C version.
1202  // TODO(bradchen): Profile V8 and implement a faster REP STOS
1203  // here if the profile indicates it matters.
1204 #undef STOS
1205 #endif
1206 
1207 #if defined(MEMORY_SANITIZER)
1208  // MemorySanitizer does not understand inline assembly.
1209 #undef STOS
1210 #endif
1211 
1212 #if defined(__GNUC__) && defined(STOS)
1213  asm volatile(
1214  "cld;"
1215  "rep ; " STOS
1216  : "+&c" (counter), "+&D" (dest)
1217  : "a" (value)
1218  : "memory", "cc");
1219 #else
1220  for (int i = 0; i < counter; i++) {
1221  dest[i] = value;
1222  }
1223 #endif
1224 
1225 #undef STOS
1226 }
1227 
1228 
1229 // Simple support to read a file into a 0-terminated C-string.
1230 // The returned buffer must be freed by the caller.
1231 // On return, *exits tells whether the file existed.
1232 Vector<const char> ReadFile(const char* filename,
1233  bool* exists,
1234  bool verbose = true);
1235 Vector<const char> ReadFile(FILE* file,
1236  bool* exists,
1237  bool verbose = true);
1238 
1239 
1240 template <typename sourcechar, typename sinkchar>
1241 INLINE(static void CopyCharsUnsigned(sinkchar* dest,
1242  const sourcechar* src,
1243  int chars));
1244 #if defined(V8_HOST_ARCH_ARM)
1245 INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
1246 INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars));
1247 INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
1248 #elif defined(V8_HOST_ARCH_MIPS)
1249 INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
1250 INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
1251 #endif
1252 
1253 // Copy from 8bit/16bit chars to 8bit/16bit chars.
1254 template <typename sourcechar, typename sinkchar>
1255 INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars));
1256 
1257 template<typename sourcechar, typename sinkchar>
1258 void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
1259  DCHECK(sizeof(sourcechar) <= 2);
1260  DCHECK(sizeof(sinkchar) <= 2);
1261  if (sizeof(sinkchar) == 1) {
1262  if (sizeof(sourcechar) == 1) {
1263  CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
1264  reinterpret_cast<const uint8_t*>(src),
1265  chars);
1266  } else {
1267  CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
1268  reinterpret_cast<const uint16_t*>(src),
1269  chars);
1270  }
1271  } else {
1272  if (sizeof(sourcechar) == 1) {
1273  CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
1274  reinterpret_cast<const uint8_t*>(src),
1275  chars);
1276  } else {
1277  CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
1278  reinterpret_cast<const uint16_t*>(src),
1279  chars);
1280  }
1281  }
1282 }
1283 
1284 template <typename sourcechar, typename sinkchar>
1285 void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) {
1286  sinkchar* limit = dest + chars;
1287  if ((sizeof(*dest) == sizeof(*src)) &&
1288  (chars >= static_cast<int>(kMinComplexMemCopy / sizeof(*dest)))) {
1289  MemCopy(dest, src, chars * sizeof(*dest));
1290  } else {
1291  while (dest < limit) *dest++ = static_cast<sinkchar>(*src++);
1292  }
1293 }
1294 
1295 
1296 #if defined(V8_HOST_ARCH_ARM)
1297 void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
1298  switch (static_cast<unsigned>(chars)) {
1299  case 0:
1300  break;
1301  case 1:
1302  *dest = *src;
1303  break;
1304  case 2:
1305  memcpy(dest, src, 2);
1306  break;
1307  case 3:
1308  memcpy(dest, src, 3);
1309  break;
1310  case 4:
1311  memcpy(dest, src, 4);
1312  break;
1313  case 5:
1314  memcpy(dest, src, 5);
1315  break;
1316  case 6:
1317  memcpy(dest, src, 6);
1318  break;
1319  case 7:
1320  memcpy(dest, src, 7);
1321  break;
1322  case 8:
1323  memcpy(dest, src, 8);
1324  break;
1325  case 9:
1326  memcpy(dest, src, 9);
1327  break;
1328  case 10:
1329  memcpy(dest, src, 10);
1330  break;
1331  case 11:
1332  memcpy(dest, src, 11);
1333  break;
1334  case 12:
1335  memcpy(dest, src, 12);
1336  break;
1337  case 13:
1338  memcpy(dest, src, 13);
1339  break;
1340  case 14:
1341  memcpy(dest, src, 14);
1342  break;
1343  case 15:
1344  memcpy(dest, src, 15);
1345  break;
1346  default:
1347  MemCopy(dest, src, chars);
1348  break;
1349  }
1350 }
1351 
1352 
1353 void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars) {
1354  if (chars >= kMinComplexConvertMemCopy) {
1355  MemCopyUint16Uint8(dest, src, chars);
1356  } else {
1357  MemCopyUint16Uint8Wrapper(dest, src, chars);
1358  }
1359 }
1360 
1361 
1362 void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
1363  switch (static_cast<unsigned>(chars)) {
1364  case 0:
1365  break;
1366  case 1:
1367  *dest = *src;
1368  break;
1369  case 2:
1370  memcpy(dest, src, 4);
1371  break;
1372  case 3:
1373  memcpy(dest, src, 6);
1374  break;
1375  case 4:
1376  memcpy(dest, src, 8);
1377  break;
1378  case 5:
1379  memcpy(dest, src, 10);
1380  break;
1381  case 6:
1382  memcpy(dest, src, 12);
1383  break;
1384  case 7:
1385  memcpy(dest, src, 14);
1386  break;
1387  default:
1388  MemCopy(dest, src, chars * sizeof(*dest));
1389  break;
1390  }
1391 }
1392 
1393 
1394 #elif defined(V8_HOST_ARCH_MIPS)
1395 void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
1396  if (chars < kMinComplexMemCopy) {
1397  memcpy(dest, src, chars);
1398  } else {
1399  MemCopy(dest, src, chars);
1400  }
1401 }
1402 
1403 void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
1404  if (chars < kMinComplexMemCopy) {
1405  memcpy(dest, src, chars * sizeof(*dest));
1406  } else {
1407  MemCopy(dest, src, chars * sizeof(*dest));
1408  }
1409 }
1410 #endif
1411 
1412 
1414  public:
1416  StringBuilder(char* buffer, int size) : SimpleStringBuilder(buffer, size) { }
1417 
1418  // Add formatted contents to the builder just like printf().
1419  void AddFormatted(const char* format, ...);
1420 
1421  // Add formatted contents like printf based on a va_list.
1422  void AddFormattedList(const char* format, va_list list);
1423  private:
1425 };
1426 
1427 
1428 bool DoubleToBoolean(double d);
1429 
1430 template <typename Stream>
1431 bool StringToArrayIndex(Stream* stream, uint32_t* index) {
1432  uint16_t ch = stream->GetNext();
1433 
1434  // If the string begins with a '0' character, it must only consist
1435  // of it to be a legal array index.
1436  if (ch == '0') {
1437  *index = 0;
1438  return !stream->HasMore();
1439  }
1440 
1441  // Convert string to uint32 array index; character by character.
1442  int d = ch - '0';
1443  if (d < 0 || d > 9) return false;
1444  uint32_t result = d;
1445  while (stream->HasMore()) {
1446  d = stream->GetNext() - '0';
1447  if (d < 0 || d > 9) return false;
1448  // Check that the new result is below the 32 bit limit.
1449  if (result > 429496729U - ((d > 5) ? 1 : 0)) return false;
1450  result = (result * 10) + d;
1451  }
1452 
1453  *index = result;
1454  return true;
1455 }
1456 
1457 
1458 // Returns current value of top of the stack. Works correctly with ASAN.
1461  // Takes the address of the limit variable in order to find out where
1462  // the top of stack is right now.
1463  uintptr_t limit = reinterpret_cast<uintptr_t>(&limit);
1464  return limit;
1465 }
1466 
1467 } // namespace internal
1468 } // namespace v8
1469 
1470 #endif // V8_UTILS_H_
An object reference managed by the v8 garbage collector.
Definition: v8.h:198
Access(StaticResource< T > *resource)
Definition: utils.h:382
StaticResource< T > * resource_
Definition: utils.h:399
static const int kFirstUsableId
Definition: utils.h:982
static const int kDeclarationsId
Definition: utils.h:979
static BailoutId Declarations()
Definition: utils.h:962
static BailoutId StubEntry()
Definition: utils.h:964
static const int kNoneId
Definition: utils.h:971
bool IsNone() const
Definition: utils.h:966
static BailoutId FirstUsable()
Definition: utils.h:963
static BailoutId FunctionEntry()
Definition: utils.h:961
static const int kStubEntryId
Definition: utils.h:985
bool operator!=(const BailoutId &other) const
Definition: utils.h:968
int ToInt() const
Definition: utils.h:958
static const int kFunctionEntryId
Definition: utils.h:974
bool operator==(const BailoutId &other) const
Definition: utils.h:967
static BailoutId None()
Definition: utils.h:960
static const U kShift
Definition: utils.h:204
static U update(U previous, T value)
Definition: utils.h:223
static const U kMask
Definition: utils.h:203
static bool is_valid(T value)
Definition: utils.h:212
static const U kSize
Definition: utils.h:205
static const T kMax
Definition: utils.h:209
static U encode(T value)
Definition: utils.h:217
static T decode(U value)
Definition: utils.h:228
static const U kNext
Definition: utils.h:206
static const U kOne
Definition: utils.h:202
virtual void Reset()
Definition: utils-inl.h:14
virtual ~Collector()
Definition: utils.h:475
void WriteTo(Vector< T > destination)
Definition: utils.h:531
Vector< T > AddBlock(int size, T initial_value)
Definition: utils.h:497
Collector(int initial_capacity=kMinCapacity)
Definition: utils.h:470
static const int kMinCapacity
Definition: utils.h:564
void Grow(int min_capacity)
Definition: utils.h:571
Vector< T > AddBlock(Vector< const T > source)
Definition: utils.h:516
List< Vector< T > > chunks_
Definition: utils.h:565
Vector< T > ToVector()
Definition: utils.h:551
void Add(T value)
Definition: utils.h:484
Vector< T > current_chunk_
Definition: utils.h:566
virtual void NewChunk(int new_capacity)
Definition: utils.h:597
ContainerPointerWrapper(C *container)
Definition: utils.h:996
C::reverse_iterator reverse_iterator
Definition: utils.h:995
const ElementType & operator[](int i) const
Definition: utils.h:766
ElementType & operator[](int i)
Definition: utils.h:752
ElementType elems_[NumElements]
Definition: utils.h:758
const ElementType & operator[](int i) const
Definition: utils.h:748
EmbeddedVector(T initial_value)
Definition: utils.h:432
EmbeddedVector(const EmbeddedVector &rhs)
Definition: utils.h:439
EmbeddedVector & operator=(const EmbeddedVector &rhs)
Definition: utils.h:445
void Remove(const EnumSet &set)
Definition: utils.h:858
void Remove(E element)
Definition: utils.h:857
bool Contains(E element) const
Definition: utils.h:851
EnumSet< E, T > operator|(const EnumSet &set) const
Definition: utils.h:864
T ToIntegral() const
Definition: utils.h:861
void Add(const EnumSet &set)
Definition: utils.h:856
bool operator==(const EnumSet &set)
Definition: utils.h:862
bool operator!=(const EnumSet &set)
Definition: utils.h:863
bool ContainsAnyOf(const EnumSet &set) const
Definition: utils.h:852
void Intersect(const EnumSet &set)
Definition: utils.h:860
EnumSet(T bits=0)
Definition: utils.h:849
T Mask(E element) const
Definition: utils.h:869
bool IsEmpty() const
Definition: utils.h:850
void Add(E element)
Definition: utils.h:855
static const int kNoSequence
Definition: utils.h:656
Vector< T > EndSequence()
Definition: utils.h:633
SequenceCollector(int initial_capacity)
Definition: utils.h:622
virtual void NewChunk(int new_capacity)
Definition: utils.h:660
void set(T *value)
Definition: utils.h:417
void AddDecimalInteger(int value)
Definition: utils.cc:44
SimpleStringBuilder(char *buffer, int size)
Definition: utils.h:790
DISALLOW_IMPLICIT_CONSTRUCTORS(SimpleStringBuilder)
void AddPadding(char c, int count)
Definition: utils.cc:37
void AddSubstring(const char *s, int n)
Definition: utils.cc:29
void AddString(const char *s)
Definition: utils.cc:24
DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder)
void AddFormattedList(const char *format, va_list list)
Definition: utils.cc:325
void AddFormatted(const char *format,...)
Definition: utils.cc:317
StringBuilder(char *buffer, int size)
Definition: utils.h:1416
static TypeFeedbackId None()
Definition: utils.h:945
static const int kNoneId
Definition: utils.h:949
int length() const
Definition: vector.h:41
void set_start(T *start)
Definition: vector.h:115
static Vector< T > New(int length)
Definition: vector.h:27
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes A file to write the raw context snapshot bytes Write V8 startup blob file(mksnapshot only)") DEFINE_BOOL(profile_hydrogen_code_stub_compilation
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
enable harmony numeric enable harmony object literal extensions Optimize object Array shift
#define UNREACHABLE()
Definition: logging.h:30
#define DCHECK(condition)
Definition: logging.h:205
#define DCHECK_EQ(v1, v2)
Definition: logging.h:206
void USE(T)
Definition: macros.h:322
intptr_t OffsetFrom(T x)
Definition: macros.h:383
#define DISABLE_ASAN
Definition: macros.h:280
unsigned short uint16_t
Definition: unicode.cc:23
int int32_t
Definition: unicode.cc:24
bool IsPowerOfTwo32(uint32_t value)
Definition: bits.h:77
int WhichPowerOf2(uint32_t x)
Definition: utils.h:37
const int kPointerSize
Definition: globals.h:129
void CopyChars(sinkchar *dest, const sourcechar *src, int chars)
Definition: utils.h:1258
int signed_bitextract_64(int msb, int lsb, int x)
Definition: utils.h:892
char * ReadLine(const char *prompt)
Definition: utils.cc:129
void StrNCpy(Vector< char > dest, const char *src, size_t n)
Definition: utils.cc:119
bool IsAddressAligned(Address addr, intptr_t alignment, int offset=0)
Definition: utils.h:129
void PrintPID(const char *format,...)
Definition: utils.cc:96
int PointerValueCompare(const T *a, const T *b)
Definition: utils.h:107
int Compare(const T &a, const T &b)
Definition: utils.h:96
uint32_t ComputeLongHash(uint64_t key)
Definition: utils.h:262
static LifetimePosition Min(LifetimePosition a, LifetimePosition b)
int MostSignificantBit(uint32_t x)
Definition: utils.h:68
bool is_uintn(int64_t x, unsigned n)
Definition: utils.h:904
const SwVfpRegister s1
int CompareChars(const lchar *lhs, const rchar *rhs, int chars)
Definition: utils.h:705
bool DoubleToBoolean(double d)
Definition: utils.cc:397
const SwVfpRegister s2
void MemsetPointer(T **dest, U *value, int counter)
Definition: utils.h:1183
static const uint32_t kZeroHashSeed
Definition: utils.h:245
bool CStringEquals(const char *s1, const char *s2)
Definition: utils.h:31
int SNPrintF(Vector< char > str, const char *format,...)
Definition: utils.cc:105
void MemMove(void *dest, const void *src, size_t size)
Definition: utils.h:353
void Flush(FILE *out)
Definition: utils.cc:124
int AppendChars(const char *filename, const char *str, int size, bool verbose)
Definition: utils.cc:273
double Floor(double x)
Definition: utils.h:159
int32_t WhichPowerOf2Abs(int32_t x)
Definition: utils.h:168
uint32_t ComputePointerHash(void *ptr)
Definition: utils.h:274
DISABLE_ASAN uintptr_t GetCurrentStackPosition()
Definition: utils.h:1460
int WriteChars(const char *filename, const char *str, int size, bool verbose)
Definition: utils.cc:290
int ArithmeticShiftRight(int x, int s)
Definition: utils.h:90
static LifetimePosition Max(LifetimePosition a, LifetimePosition b)
const int kMinInt
Definition: globals.h:110
T Abs(T a)
Definition: utils.h:153
INLINE(static HeapObject *EnsureDoubleAligned(Heap *heap, HeapObject *object, int size))
byte * Address
Definition: globals.h:101
void PrintF(const char *format,...)
Definition: utils.cc:80
Vector< Handle< Object > > HandleVector(v8::internal::Handle< T > *elms, int length)
Definition: utils.h:1100
const int kMinComplexMemCopy
Definition: utils.h:356
int WriteAsCFile(const char *filename, const char *varname, const char *str, int size, bool verbose=true)
int HandleObjectPointerCompare(const Handle< T > *a, const Handle< T > *b)
Definition: utils.h:117
int CompareCharsUnsigned(const lchar *lhs, const rchar *rhs, int chars)
Definition: utils.h:686
void CopyCharsUnsigned(sinkchar *dest, const sourcechar *src, int chars)
Definition: utils.h:1285
void CopyWords(T *dst, const T *src, size_t num_words)
Definition: utils.h:1112
int VSNPrintF(Vector< char > str, const char *format, va_list args)
Definition: utils.cc:114
uint32_t ComputeIntegerHash(uint32_t key, uint32_t seed)
Definition: utils.h:249
int TenToThe(int exponent)
Definition: utils.h:733
int32_t signed_bitextract_32(int msb, int lsb, int32_t x)
Definition: utils.h:888
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
const int kBitsPerByte
Definition: globals.h:162
void MoveWords(T *dst, const T *src, size_t num_words)
Definition: utils.h:1138
uint64_t unsigned_bitextract_64(int msb, int lsb, uint64_t x)
Definition: utils.h:884
T truncate_to_intn(T x, unsigned n)
Definition: utils.h:910
bool is_intn(int64_t x, unsigned n)
Definition: utils.h:898
byte * ReadBytes(const char *filename, int *size, bool verbose)
Definition: utils.cc:222
bool StringToArrayIndex(Stream *stream, uint32_t *index)
Definition: utils.h:1431
Vector< const char > ReadFile(const char *filename, bool *exists, bool verbose)
Definition: utils.cc:241
int WriteBytes(const char *filename, const byte *bytes, int size, bool verbose)
Definition: utils.cc:307
bool IsAligned(T value, U alignment)
Definition: utils.h:123
void MemCopy(void *dest, const void *src, size_t size)
Definition: utils.h:350
void init_memcopy_functions()
Definition: utils.cc:381
void CopyBytes(uint8_t *target, uint8_t *source)
uint32_t unsigned_bitextract_32(int msb, int lsb, uint32_t x)
Definition: utils.h:880
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define T(name, string, precedence)
Definition: token.cc:25
#define DECLARE_IS_UINT_N(N)
Definition: utils.h:927
#define FPRINTF_CHECKING
Definition: utils.h:1026
#define PRINTF_CHECKING
Definition: utils.h:1025
#define INT_1_TO_63_LIST(V)
Definition: utils.h:915
#define DECLARE_TRUNCATE_TO_INT_N(N)
Definition: utils.h:930
#define DECLARE_IS_INT_N(N)
Definition: utils.h:925
#define V8_INLINE
Definition: v8config.h:306