V8 Project
types.cc
Go to the documentation of this file.
1 // Copyright 2014 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 #include "src/types.h"
6 
7 #include "src/ostreams.h"
8 #include "src/types-inl.h"
9 
10 namespace v8 {
11 namespace internal {
12 
13 
14 // NOTE: If code is marked as being a "shortcut", this means that removing
15 // the code won't affect the semantics of the surrounding function definition.
16 
17 
18 // -----------------------------------------------------------------------------
19 // Range-related helper functions.
20 
21 // The result may be invalid (max < min).
22 template<class Config>
24  Limits lhs, Limits rhs) {
25  DisallowHeapAllocation no_allocation;
26  Limits result(lhs);
27  if (lhs.min->Number() < rhs.min->Number()) result.min = rhs.min;
28  if (lhs.max->Number() > rhs.max->Number()) result.max = rhs.max;
29  return result;
30 }
31 
32 
33 template<class Config>
35  Limits lhs, Limits rhs) {
36  DisallowHeapAllocation no_allocation;
37  Limits result(lhs);
38  if (lhs.min->Number() > rhs.min->Number()) result.min = rhs.min;
39  if (lhs.max->Number() < rhs.max->Number()) result.max = rhs.max;
40  return result;
41 }
42 
43 
44 template<class Config>
46  typename TypeImpl<Config>::RangeType* lhs,
47  typename TypeImpl<Config>::RangeType* rhs) {
48  DisallowHeapAllocation no_allocation;
49  typename TypeImpl<Config>::Limits lim = Intersect(Limits(lhs), Limits(rhs));
50  return lim.min->Number() <= lim.max->Number();
51 }
52 
53 
54 template<class Config>
56  typename TypeImpl<Config>::RangeType* lhs,
57  typename TypeImpl<Config>::RangeType* rhs) {
58  DisallowHeapAllocation no_allocation;
59  return lhs->Min()->Number() <= rhs->Min()->Number()
60  && rhs->Max()->Number() <= lhs->Max()->Number();
61 }
62 
63 
64 template<class Config>
66  typename TypeImpl<Config>::RangeType* range, i::Object* val) {
67  DisallowHeapAllocation no_allocation;
68  return IsInteger(val)
69  && range->Min()->Number() <= val->Number()
70  && val->Number() <= range->Max()->Number();
71 }
72 
73 
74 // -----------------------------------------------------------------------------
75 // Min and Max computation.
76 
77 template<class Config>
79  DCHECK(this->Is(Number()));
80  if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
81  if (this->IsUnion()) {
82  double min = +V8_INFINITY;
83  for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
84  min = std::min(min, this->AsUnion()->Get(i)->Min());
85  }
86  return min;
87  }
88  if (this->IsRange()) return this->AsRange()->Min()->Number();
89  if (this->IsConstant()) return this->AsConstant()->Value()->Number();
90  UNREACHABLE();
91  return 0;
92 }
93 
94 
95 template<class Config>
97  DCHECK(this->Is(Number()));
98  if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
99  if (this->IsUnion()) {
100  double max = -V8_INFINITY;
101  for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
102  max = std::max(max, this->AsUnion()->Get(i)->Max());
103  }
104  return max;
105  }
106  if (this->IsRange()) return this->AsRange()->Max()->Number();
107  if (this->IsConstant()) return this->AsConstant()->Value()->Number();
108  UNREACHABLE();
109  return 0;
110 }
111 
112 
113 // -----------------------------------------------------------------------------
114 // Glb and lub computation.
115 
116 
117 // The largest bitset subsumed by this type.
118 template<class Config>
121  DisallowHeapAllocation no_allocation;
122  if (type->IsBitset()) {
123  return type->AsBitset();
124  } else if (type->IsUnion()) {
125  SLOW_DCHECK(type->AsUnion()->Wellformed());
126  return type->AsUnion()->Get(0)->BitsetGlb(); // Shortcut.
127  // (The remaining BitsetGlb's are None anyway).
128  } else {
129  return kNone;
130  }
131 }
132 
133 
134 // The smallest bitset subsuming this type.
135 template<class Config>
138  DisallowHeapAllocation no_allocation;
139  if (type->IsBitset()) return type->AsBitset();
140  if (type->IsUnion()) {
141  int bitset = kNone;
142  for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
143  bitset |= type->AsUnion()->Get(i)->BitsetLub();
144  }
145  return bitset;
146  }
147  if (type->IsClass()) {
148  // Little hack to avoid the need for a region for handlification here...
149  return Config::is_class(type) ? Lub(*Config::as_class(type)) :
150  type->AsClass()->Bound(NULL)->AsBitset();
151  }
152  if (type->IsConstant()) return type->AsConstant()->Bound()->AsBitset();
153  if (type->IsRange()) return type->AsRange()->BitsetLub();
154  if (type->IsContext()) return kInternal & kTaggedPtr;
155  if (type->IsArray()) return kArray;
156  if (type->IsFunction()) return kFunction;
157  UNREACHABLE();
158  return kNone;
159 }
160 
161 
162 template<class Config>
165  DisallowHeapAllocation no_allocation;
166  switch (map->instance_type()) {
167  case STRING_TYPE:
169  case CONS_STRING_TYPE:
171  case SLICED_STRING_TYPE:
179  return kOtherString;
188  return kInternalizedString;
189  case SYMBOL_TYPE:
190  return kSymbol;
191  case ODDBALL_TYPE: {
192  Heap* heap = map->GetHeap();
193  if (map == heap->undefined_map()) return kUndefined;
194  if (map == heap->null_map()) return kNull;
195  if (map == heap->boolean_map()) return kBoolean;
196  DCHECK(map == heap->the_hole_map() ||
197  map == heap->uninitialized_map() ||
198  map == heap->no_interceptor_result_sentinel_map() ||
199  map == heap->termination_exception_map() ||
200  map == heap->arguments_marker_map());
201  return kInternal & kTaggedPtr;
202  }
203  case HEAP_NUMBER_TYPE:
204  return kNumber & kTaggedPtr;
205  case JS_VALUE_TYPE:
206  case JS_DATE_TYPE:
207  case JS_OBJECT_TYPE:
210  case JS_MODULE_TYPE:
215  case JS_TYPED_ARRAY_TYPE:
216  case JS_DATA_VIEW_TYPE:
217  case JS_SET_TYPE:
218  case JS_MAP_TYPE:
221  case JS_WEAK_MAP_TYPE:
222  case JS_WEAK_SET_TYPE:
223  if (map->is_undetectable()) return kUndetectable;
224  return kOtherObject;
225  case JS_ARRAY_TYPE:
226  return kArray;
227  case JS_FUNCTION_TYPE:
228  return kFunction;
229  case JS_REGEXP_TYPE:
230  return kRegExp;
231  case JS_PROXY_TYPE:
233  return kProxy;
234  case MAP_TYPE:
235  // When compiling stub templates, the meta map is used as a place holder
236  // for the actual map with which the template is later instantiated.
237  // We treat it as a kind of type variable whose upper bound is Any.
238  // TODO(rossberg): for caching of CompareNilIC stubs to work correctly,
239  // we must exclude Undetectable here. This makes no sense, really,
240  // because it means that the template isn't actually parametric.
241  // Also, it doesn't apply elsewhere. 8-(
242  // We ought to find a cleaner solution for compiling stubs parameterised
243  // over type or class variables, esp ones with bounds...
244  return kDetectable;
248  case ACCESSOR_PAIR_TYPE:
249  case FIXED_ARRAY_TYPE:
250  case FOREIGN_TYPE:
251  case CODE_TYPE:
252  return kInternal & kTaggedPtr;
253  default:
254  UNREACHABLE();
255  return kNone;
256  }
257 }
258 
259 
260 template<class Config>
263  DisallowHeapAllocation no_allocation;
264  if (value->IsNumber()) {
265  return Lub(value->Number()) & (value->IsSmi() ? kTaggedInt : kTaggedPtr);
266  }
267  return Lub(i::HeapObject::cast(value)->map());
268 }
269 
270 
271 template<class Config>
274  DisallowHeapAllocation no_allocation;
275  if (i::IsMinusZero(value)) return kMinusZero;
276  if (std::isnan(value)) return kNaN;
277  if (IsUint32Double(value)) return Lub(FastD2UI(value));
278  if (IsInt32Double(value)) return Lub(FastD2I(value));
279  return kOtherNumber;
280 }
281 
282 
283 template<class Config>
286  DisallowHeapAllocation no_allocation;
287  if (value >= 0x40000000) {
288  return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall;
289  }
290  if (value >= 0) return kUnsignedSmall;
291  if (value >= -0x40000000) return kOtherSignedSmall;
292  return i::SmiValuesAre31Bits() ? kOtherSigned32 : kOtherSignedSmall;
293 }
294 
295 
296 template<class Config>
299  DisallowHeapAllocation no_allocation;
300  if (value >= 0x80000000u) return kOtherUnsigned32;
301  if (value >= 0x40000000u) {
302  return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall;
303  }
304  return kUnsignedSmall;
305 }
306 
307 
308 // Minimum values of regular numeric bitsets when SmiValuesAre31Bits.
309 template<class Config>
312  {kOtherNumber, -V8_INFINITY},
313  {kOtherSigned32, kMinInt},
314  {kOtherSignedSmall, -0x40000000},
315  {kUnsignedSmall, 0},
316  {kOtherUnsigned31, 0x40000000},
317  {kOtherUnsigned32, 0x80000000},
318  {kOtherNumber, static_cast<double>(kMaxUInt32) + 1}
319 };
320 
321 
322 // Minimum values of regular numeric bitsets when SmiValuesAre32Bits.
323 // OtherSigned32 and OtherUnsigned31 are empty (see the diagrams in types.h).
324 template<class Config>
325 const typename TypeImpl<Config>::BitsetType::BitsetMin
327  {kOtherNumber, -V8_INFINITY},
328  {kOtherSignedSmall, kMinInt},
329  {kUnsignedSmall, 0},
330  {kOtherUnsigned32, 0x80000000},
331  {kOtherNumber, static_cast<double>(kMaxUInt32) + 1}
332 };
333 
334 
335 template<class Config>
338  DisallowHeapAllocation no_allocation;
339  double min = lim.min->Number();
340  double max = lim.max->Number();
341  int lub = kNone;
342  const BitsetMin* mins = BitsetMins();
343 
344  for (size_t i = 1; i < BitsetMinsSize(); ++i) {
345  if (min < mins[i].min) {
346  lub |= mins[i-1].bits;
347  if (max < mins[i].min) return lub;
348  }
349  }
350  return lub |= mins[BitsetMinsSize()-1].bits;
351 }
352 
353 
354 template<class Config>
356  DisallowHeapAllocation no_allocation;
357  DCHECK(Is(bits, kNumber));
358  const BitsetMin* mins = BitsetMins();
359  bool mz = SEMANTIC(bits & kMinusZero);
360  for (size_t i = 0; i < BitsetMinsSize(); ++i) {
361  if (Is(SEMANTIC(mins[i].bits), bits)) {
362  return mz ? std::min(0.0, mins[i].min) : mins[i].min;
363  }
364  }
365  if (mz) return 0;
366  return base::OS::nan_value();
367 }
368 
369 
370 template<class Config>
372  DisallowHeapAllocation no_allocation;
373  DCHECK(Is(bits, kNumber));
374  const BitsetMin* mins = BitsetMins();
375  bool mz = bits & kMinusZero;
376  if (BitsetType::Is(mins[BitsetMinsSize()-1].bits, bits)) {
377  return +V8_INFINITY;
378  }
379  for (size_t i = BitsetMinsSize()-1; i-- > 0; ) {
380  if (Is(SEMANTIC(mins[i].bits), bits)) {
381  return mz ?
382  std::max(0.0, mins[i+1].min - 1) : mins[i+1].min - 1;
383  }
384  }
385  if (mz) return 0;
386  return base::OS::nan_value();
387 }
388 
389 
390 // -----------------------------------------------------------------------------
391 // Predicates.
392 
393 
394 template<class Config>
396  DisallowHeapAllocation no_allocation;
397  if (this->IsClass()) {
398  return that->IsClass()
399  && *this->AsClass()->Map() == *that->AsClass()->Map();
400  }
401  if (this->IsConstant()) {
402  return that->IsConstant()
403  && *this->AsConstant()->Value() == *that->AsConstant()->Value();
404  }
405  if (this->IsContext()) {
406  return that->IsContext()
407  && this->AsContext()->Outer()->Equals(that->AsContext()->Outer());
408  }
409  if (this->IsArray()) {
410  return that->IsArray()
411  && this->AsArray()->Element()->Equals(that->AsArray()->Element());
412  }
413  if (this->IsFunction()) {
414  if (!that->IsFunction()) return false;
415  FunctionType* this_fun = this->AsFunction();
416  FunctionType* that_fun = that->AsFunction();
417  if (this_fun->Arity() != that_fun->Arity() ||
418  !this_fun->Result()->Equals(that_fun->Result()) ||
419  !this_fun->Receiver()->Equals(that_fun->Receiver())) {
420  return false;
421  }
422  for (int i = 0, n = this_fun->Arity(); i < n; ++i) {
423  if (!this_fun->Parameter(i)->Equals(that_fun->Parameter(i))) return false;
424  }
425  return true;
426  }
427  UNREACHABLE();
428  return false;
429 }
430 
431 
432 // Check if [this] <= [that].
433 template<class Config>
435  DisallowHeapAllocation no_allocation;
436 
437  if (that->IsBitset()) {
438  return BitsetType::Is(this->BitsetLub(), that->AsBitset());
439  }
440  if (this->IsBitset()) {
441  return BitsetType::Is(this->AsBitset(), that->BitsetGlb());
442  }
443 
444  // (T1 \/ ... \/ Tn) <= T if (T1 <= T) /\ ... /\ (Tn <= T)
445  if (this->IsUnion()) {
446  for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
447  if (!this->AsUnion()->Get(i)->Is(that)) return false;
448  }
449  return true;
450  }
451 
452  // T <= (T1 \/ ... \/ Tn) if (T <= T1) \/ ... \/ (T <= Tn)
453  if (that->IsUnion()) {
454  for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
455  if (this->Is(that->AsUnion()->Get(i))) return true;
456  if (i > 1 && this->IsRange()) return false; // Shortcut.
457  }
458  return false;
459  }
460 
461  if (that->IsRange()) {
462  return (this->IsRange() && Contains(that->AsRange(), this->AsRange()))
463  || (this->IsConstant() &&
464  Contains(that->AsRange(), *this->AsConstant()->Value()));
465  }
466  if (this->IsRange()) return false;
467  return this->SimplyEquals(that);
468 }
469 
470 
471 template<class Config>
473  DisallowHeapAllocation no_allocation;
474 
475  // TODO(rossberg): this is incorrect for
476  // Union(Constant(V), T)->NowIs(Class(M))
477  // but fuzzing does not cover that!
478  if (this->IsConstant()) {
479  i::Object* object = *this->AsConstant()->Value();
480  if (object->IsHeapObject()) {
481  i::Map* map = i::HeapObject::cast(object)->map();
482  for (Iterator<i::Map> it = that->Classes(); !it.Done(); it.Advance()) {
483  if (*it.Current() == map) return true;
484  }
485  }
486  }
487  return this->Is(that);
488 }
489 
490 
491 // Check if [this] contains only (currently) stable classes.
492 template<class Config>
494  DisallowHeapAllocation no_allocation;
495  for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
496  if (!it.Current()->is_stable()) return false;
497  }
498  return true;
499 }
500 
501 
502 // Check if [this] and [that] overlap.
503 template<class Config>
505  DisallowHeapAllocation no_allocation;
506 
507  // (T1 \/ ... \/ Tn) overlaps T if (T1 overlaps T) \/ ... \/ (Tn overlaps T)
508  if (this->IsUnion()) {
509  for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
510  if (this->AsUnion()->Get(i)->Maybe(that)) return true;
511  }
512  return false;
513  }
514 
515  // T overlaps (T1 \/ ... \/ Tn) if (T overlaps T1) \/ ... \/ (T overlaps Tn)
516  if (that->IsUnion()) {
517  for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
518  if (this->Maybe(that->AsUnion()->Get(i))) return true;
519  }
520  return false;
521  }
522 
523  if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub()))
524  return false;
525  if (this->IsBitset() || that->IsBitset()) return true;
526 
527  if (this->IsClass() != that->IsClass()) return true;
528 
529  if (this->IsRange()) {
530  if (that->IsConstant()) {
531  return Contains(this->AsRange(), *that->AsConstant()->Value());
532  }
533  return that->IsRange() && Overlap(this->AsRange(), that->AsRange());
534  }
535  if (that->IsRange()) {
536  if (this->IsConstant()) {
537  return Contains(that->AsRange(), *this->AsConstant()->Value());
538  }
539  return this->IsRange() && Overlap(this->AsRange(), that->AsRange());
540  }
541 
542  return this->SimplyEquals(that);
543 }
544 
545 
546 // Return the range in [this], or [NULL].
547 template<class Config>
549  DisallowHeapAllocation no_allocation;
550  if (this->IsRange()) return this->AsRange();
551  if (this->IsUnion() && this->AsUnion()->Get(1)->IsRange()) {
552  return this->AsUnion()->Get(1)->AsRange();
553  }
554  return NULL;
555 }
556 
557 
558 template<class Config>
560  DisallowHeapAllocation no_allocation;
561  for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) {
562  if (*it.Current() == value) return true;
563  }
564  if (IsInteger(value)) {
565  RangeType* range = this->GetRange();
566  if (range != NULL && Contains(range, value)) return true;
567  }
568  return BitsetType::New(BitsetType::Lub(value))->Is(this);
569 }
570 
571 
572 template<class Config>
574  DisallowHeapAllocation no_allocation;
575  // This checks the invariants of the union representation:
576  // 1. There are at least two elements.
577  // 2. At most one element is a bitset, and it must be the first one.
578  // 3. At most one element is a range, and it must be the second one
579  // (even when the first element is not a bitset).
580  // 4. No element is itself a union.
581  // 5. No element is a subtype of any other.
582  DCHECK(this->Length() >= 2); // (1)
583  for (int i = 0; i < this->Length(); ++i) {
584  if (i != 0) DCHECK(!this->Get(i)->IsBitset()); // (2)
585  if (i != 1) DCHECK(!this->Get(i)->IsRange()); // (3)
586  DCHECK(!this->Get(i)->IsUnion()); // (4)
587  for (int j = 0; j < this->Length(); ++j) {
588  if (i != j) DCHECK(!this->Get(i)->Is(this->Get(j))); // (5)
589  }
590  }
591  return true;
592 }
593 
594 
595 // -----------------------------------------------------------------------------
596 // Union and intersection
597 
598 
599 static bool AddIsSafe(int x, int y) {
600  return x >= 0 ?
601  y <= std::numeric_limits<int>::max() - x :
603 }
604 
605 
606 template<class Config>
608  TypeHandle type1, TypeHandle type2, Region* region) {
609  bitset bits = type1->BitsetGlb() & type2->BitsetGlb();
610  if (!BitsetType::IsInhabited(bits)) bits = BitsetType::kNone;
611 
612  // Fast case: bit sets.
613  if (type1->IsBitset() && type2->IsBitset()) {
614  return BitsetType::New(bits, region);
615  }
616 
617  // Fast case: top or bottom types.
618  if (type1->IsNone() || type2->IsAny()) return type1; // Shortcut.
619  if (type2->IsNone() || type1->IsAny()) return type2; // Shortcut.
620 
621  // Semi-fast case.
622  if (type1->Is(type2)) return type1;
623  if (type2->Is(type1)) return type2;
624 
625  // Slow case: create union.
626  int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
627  int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
628  if (!AddIsSafe(size1, size2)) return Any(region);
629  int size = size1 + size2;
630  if (!AddIsSafe(size, 2)) return Any(region);
631  size += 2;
632  UnionHandle result = UnionType::New(size, region);
633  size = 0;
634 
635  // Deal with bitsets.
636  result->Set(size++, BitsetType::New(bits, region));
637 
638  // Deal with ranges.
639  TypeHandle range = None(region);
640  RangeType* range1 = type1->GetRange();
641  RangeType* range2 = type2->GetRange();
642  if (range1 != NULL && range2 != NULL) {
643  Limits lim = Intersect(Limits(range1), Limits(range2));
644  if (lim.min->Number() <= lim.max->Number()) {
645  range = RangeType::New(lim, region);
646  }
647  }
648  result->Set(size++, range);
649 
650  size = IntersectAux(type1, type2, result, size, region);
651  return NormalizeUnion(result, size);
652 }
653 
654 
655 template<class Config>
657  RangeHandle range, UnionHandle result, int size, Region* region) {
658  TypeHandle old_range = result->Get(1);
659  DCHECK(old_range->IsRange() || old_range->IsNone());
660  if (range->Is(old_range)) return size;
661  if (!old_range->Is(range->unhandle())) {
662  range = RangeType::New(
663  Union(Limits(range->AsRange()), Limits(old_range->AsRange())), region);
664  }
665  result->Set(1, range);
666 
667  // Remove any components that just got subsumed.
668  for (int i = 2; i < size; ) {
669  if (result->Get(i)->Is(range->unhandle())) {
670  result->Set(i, result->Get(--size));
671  } else {
672  ++i;
673  }
674  }
675  return size;
676 }
677 
678 
679 template<class Config>
681  TypeHandle lhs, TypeHandle rhs,
682  UnionHandle result, int size, Region* region) {
683  if (lhs->IsUnion()) {
684  for (int i = 0, n = lhs->AsUnion()->Length(); i < n; ++i) {
685  size = IntersectAux(lhs->AsUnion()->Get(i), rhs, result, size, region);
686  }
687  return size;
688  }
689  if (rhs->IsUnion()) {
690  for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) {
691  size = IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, region);
692  }
693  return size;
694  }
695 
696  if (!BitsetType::IsInhabited(lhs->BitsetLub() & rhs->BitsetLub())) {
697  return size;
698  }
699 
700  if (lhs->IsRange()) {
701  if (rhs->IsBitset() || rhs->IsClass()) {
702  return UpdateRange(
703  Config::template cast<RangeType>(lhs), result, size, region);
704  }
705  if (rhs->IsConstant() &&
706  Contains(lhs->AsRange(), *rhs->AsConstant()->Value())) {
707  return AddToUnion(rhs, result, size, region);
708  }
709  return size;
710  }
711  if (rhs->IsRange()) {
712  if (lhs->IsBitset() || lhs->IsClass()) {
713  return UpdateRange(
714  Config::template cast<RangeType>(rhs), result, size, region);
715  }
716  if (lhs->IsConstant() &&
717  Contains(rhs->AsRange(), *lhs->AsConstant()->Value())) {
718  return AddToUnion(lhs, result, size, region);
719  }
720  return size;
721  }
722 
723  if (lhs->IsBitset() || rhs->IsBitset()) {
724  return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, region);
725  }
726  if (lhs->IsClass() != rhs->IsClass()) {
727  return AddToUnion(lhs->IsClass() ? rhs : lhs, result, size, region);
728  }
729  if (lhs->SimplyEquals(rhs->unhandle())) {
730  return AddToUnion(lhs, result, size, region);
731  }
732  return size;
733 }
734 
735 
736 template<class Config>
738  TypeHandle type1, TypeHandle type2, Region* region) {
739 
740  // Fast case: bit sets.
741  if (type1->IsBitset() && type2->IsBitset()) {
742  return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region);
743  }
744 
745  // Fast case: top or bottom types.
746  if (type1->IsAny() || type2->IsNone()) return type1;
747  if (type2->IsAny() || type1->IsNone()) return type2;
748 
749  // Semi-fast case.
750  if (type1->Is(type2)) return type2;
751  if (type2->Is(type1)) return type1;
752 
753  // Slow case: create union.
754  int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
755  int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
756  if (!AddIsSafe(size1, size2)) return Any(region);
757  int size = size1 + size2;
758  if (!AddIsSafe(size, 2)) return Any(region);
759  size += 2;
760  UnionHandle result = UnionType::New(size, region);
761  size = 0;
762 
763  // Deal with bitsets.
765  type1->BitsetGlb() | type2->BitsetGlb(), region);
766  result->Set(size++, bits);
767 
768  // Deal with ranges.
769  TypeHandle range = None(region);
770  RangeType* range1 = type1->GetRange();
771  RangeType* range2 = type2->GetRange();
772  if (range1 != NULL && range2 != NULL) {
773  range = RangeType::New(Union(Limits(range1), Limits(range2)), region);
774  } else if (range1 != NULL) {
775  range = handle(range1);
776  } else if (range2 != NULL) {
777  range = handle(range2);
778  }
779  result->Set(size++, range);
780 
781  size = AddToUnion(type1, result, size, region);
782  size = AddToUnion(type2, result, size, region);
783  return NormalizeUnion(result, size);
784 }
785 
786 
787 // Add [type] to [result] unless [type] is bitset, range, or already subsumed.
788 // Return new size of [result].
789 template<class Config>
791  TypeHandle type, UnionHandle result, int size, Region* region) {
792  if (type->IsBitset() || type->IsRange()) return size;
793  if (type->IsUnion()) {
794  for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
795  size = AddToUnion(type->AsUnion()->Get(i), result, size, region);
796  }
797  return size;
798  }
799  for (int i = 0; i < size; ++i) {
800  if (type->Is(result->Get(i))) return size;
801  }
802  result->Set(size++, type);
803  return size;
804 }
805 
806 
807 template<class Config>
809  UnionHandle unioned, int size) {
810  DCHECK(size >= 2);
811  // If range is subsumed by bitset, use its place for a different type.
812  if (unioned->Get(1)->Is(unioned->Get(0))) {
813  unioned->Set(1, unioned->Get(--size));
814  }
815  // If bitset is None, use its place for a different type.
816  if (size >= 2 && unioned->Get(0)->IsNone()) {
817  unioned->Set(0, unioned->Get(--size));
818  }
819  if (size == 1) return unioned->Get(0);
820  unioned->Shrink(size);
821  SLOW_DCHECK(unioned->Wellformed());
822  return unioned;
823 }
824 
825 
826 // -----------------------------------------------------------------------------
827 // Iteration.
828 
829 template<class Config>
831  DisallowHeapAllocation no_allocation;
832  if (this->IsClass()) {
833  return 1;
834  } else if (this->IsUnion()) {
835  int result = 0;
836  for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
837  if (this->AsUnion()->Get(i)->IsClass()) ++result;
838  }
839  return result;
840  } else {
841  return 0;
842  }
843 }
844 
845 
846 template<class Config>
848  DisallowHeapAllocation no_allocation;
849  if (this->IsConstant()) {
850  return 1;
851  } else if (this->IsUnion()) {
852  int result = 0;
853  for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
854  if (this->AsUnion()->Get(i)->IsConstant()) ++result;
855  }
856  return result;
857  } else {
858  return 0;
859  }
860 }
861 
862 
863 template<class Config> template<class T>
866  DCHECK(!Done());
867  return type_->IsUnion() ? type_->AsUnion()->Get(index_) : type_;
868 }
869 
870 
871 // C++ cannot specialise nested templates, so we have to go through this
872 // contortion with an auxiliary template to simulate it.
873 template<class Config, class T>
875  static bool matches(typename TypeImpl<Config>::TypeHandle type);
877 };
878 
879 template<class Config>
880 struct TypeImplIteratorAux<Config, i::Map> {
881  static bool matches(typename TypeImpl<Config>::TypeHandle type) {
882  return type->IsClass();
883  }
884  static i::Handle<i::Map> current(typename TypeImpl<Config>::TypeHandle type) {
885  return type->AsClass()->Map();
886  }
887 };
888 
889 template<class Config>
890 struct TypeImplIteratorAux<Config, i::Object> {
891  static bool matches(typename TypeImpl<Config>::TypeHandle type) {
892  return type->IsConstant();
893  }
896  return type->AsConstant()->Value();
897  }
898 };
899 
900 template<class Config> template<class T>
903 }
904 
905 template<class Config> template<class T>
907  return TypeImplIteratorAux<Config, T>::current(get_type());
908 }
909 
910 
911 template<class Config> template<class T>
913  DisallowHeapAllocation no_allocation;
914  ++index_;
915  if (type_->IsUnion()) {
916  for (int n = type_->AsUnion()->Length(); index_ < n; ++index_) {
917  if (matches(type_->AsUnion()->Get(index_))) return;
918  }
919  } else if (index_ == 0 && matches(type_)) {
920  return;
921  }
922  index_ = -1;
923 }
924 
925 
926 // -----------------------------------------------------------------------------
927 // Conversion between low-level representations.
928 
929 template<class Config>
930 template<class OtherType>
932  typename OtherType::TypeHandle type, Region* region) {
933  if (type->IsBitset()) {
934  return BitsetType::New(type->AsBitset(), region);
935  } else if (type->IsClass()) {
936  return ClassType::New(type->AsClass()->Map(), region);
937  } else if (type->IsConstant()) {
938  return ConstantType::New(type->AsConstant()->Value(), region);
939  } else if (type->IsRange()) {
940  return RangeType::New(
941  type->AsRange()->Min(), type->AsRange()->Max(), region);
942  } else if (type->IsContext()) {
943  TypeHandle outer = Convert<OtherType>(type->AsContext()->Outer(), region);
944  return ContextType::New(outer, region);
945  } else if (type->IsUnion()) {
946  int length = type->AsUnion()->Length();
947  UnionHandle unioned = UnionType::New(length, region);
948  for (int i = 0; i < length; ++i) {
949  TypeHandle t = Convert<OtherType>(type->AsUnion()->Get(i), region);
950  unioned->Set(i, t);
951  }
952  return unioned;
953  } else if (type->IsArray()) {
954  TypeHandle element = Convert<OtherType>(type->AsArray()->Element(), region);
955  return ArrayType::New(element, region);
956  } else if (type->IsFunction()) {
957  TypeHandle res = Convert<OtherType>(type->AsFunction()->Result(), region);
958  TypeHandle rcv = Convert<OtherType>(type->AsFunction()->Receiver(), region);
960  res, rcv, type->AsFunction()->Arity(), region);
961  for (int i = 0; i < function->Arity(); ++i) {
962  TypeHandle param = Convert<OtherType>(
963  type->AsFunction()->Parameter(i), region);
964  function->InitParameter(i, param);
965  }
966  return function;
967  } else {
968  UNREACHABLE();
969  return None(region);
970  }
971 }
972 
973 
974 // -----------------------------------------------------------------------------
975 // Printing.
976 
977 template<class Config>
979  switch (bits) {
980  case REPRESENTATION(kAny): return "Any";
981  #define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \
982  case REPRESENTATION(k##type): return #type;
984  #undef RETURN_NAMED_REPRESENTATION_TYPE
985 
986  #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \
987  case SEMANTIC(k##type): return #type;
989  #undef RETURN_NAMED_SEMANTIC_TYPE
990 
991  default:
992  return NULL;
993  }
994 }
995 
996 
997 template <class Config>
999  bitset bits) {
1000  DisallowHeapAllocation no_allocation;
1001  const char* name = Name(bits);
1002  if (name != NULL) {
1003  os << name;
1004  return;
1005  }
1006 
1007  static const bitset named_bitsets[] = {
1008 #define BITSET_CONSTANT(type, value) REPRESENTATION(k##type),
1010 #undef BITSET_CONSTANT
1011 
1012 #define BITSET_CONSTANT(type, value) SEMANTIC(k##type),
1014 #undef BITSET_CONSTANT
1015  };
1016 
1017  bool is_first = true;
1018  os << "(";
1019  for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) {
1020  bitset subset = named_bitsets[i];
1021  if ((bits & subset) == subset) {
1022  if (!is_first) os << " | ";
1023  is_first = false;
1024  os << Name(subset);
1025  bits -= subset;
1026  }
1027  }
1028  DCHECK(bits == 0);
1029  os << ")";
1030 }
1031 
1032 
1033 template <class Config>
1035  DisallowHeapAllocation no_allocation;
1036  if (dim != REPRESENTATION_DIM) {
1037  if (this->IsBitset()) {
1038  BitsetType::Print(os, SEMANTIC(this->AsBitset()));
1039  } else if (this->IsClass()) {
1040  os << "Class(" << static_cast<void*>(*this->AsClass()->Map()) << " < ";
1041  BitsetType::New(BitsetType::Lub(this))->PrintTo(os, dim);
1042  os << ")";
1043  } else if (this->IsConstant()) {
1044  os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")";
1045  } else if (this->IsRange()) {
1046  os << "Range(" << this->AsRange()->Min()->Number()
1047  << ", " << this->AsRange()->Max()->Number() << ")";
1048  } else if (this->IsContext()) {
1049  os << "Context(";
1050  this->AsContext()->Outer()->PrintTo(os, dim);
1051  os << ")";
1052  } else if (this->IsUnion()) {
1053  os << "(";
1054  for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1055  TypeHandle type_i = this->AsUnion()->Get(i);
1056  if (i > 0) os << " | ";
1057  type_i->PrintTo(os, dim);
1058  }
1059  os << ")";
1060  } else if (this->IsArray()) {
1061  os << "Array(";
1062  AsArray()->Element()->PrintTo(os, dim);
1063  os << ")";
1064  } else if (this->IsFunction()) {
1065  if (!this->AsFunction()->Receiver()->IsAny()) {
1066  this->AsFunction()->Receiver()->PrintTo(os, dim);
1067  os << ".";
1068  }
1069  os << "(";
1070  for (int i = 0; i < this->AsFunction()->Arity(); ++i) {
1071  if (i > 0) os << ", ";
1072  this->AsFunction()->Parameter(i)->PrintTo(os, dim);
1073  }
1074  os << ")->";
1075  this->AsFunction()->Result()->PrintTo(os, dim);
1076  } else {
1077  UNREACHABLE();
1078  }
1079  }
1080  if (dim == BOTH_DIMS) os << "/";
1081  if (dim != SEMANTIC_DIM) {
1083  }
1084 }
1085 
1086 
1087 #ifdef DEBUG
1088 template <class Config>
1089 void TypeImpl<Config>::Print() {
1090  OFStream os(stdout);
1091  PrintTo(os);
1092  os << endl;
1093 }
1094 template <class Config>
1096  OFStream os(stdout);
1097  Print(os, bits);
1098  os << endl;
1099 }
1100 #endif
1101 
1102 
1103 // -----------------------------------------------------------------------------
1104 // Instantiations.
1105 
1106 template class TypeImpl<ZoneTypeConfig>;
1109 
1110 template class TypeImpl<HeapTypeConfig>;
1113 
1115  TypeImpl<ZoneTypeConfig>::Convert<HeapType>(
1118  TypeImpl<HeapTypeConfig>::Convert<Type>(
1120 
1121 } } // namespace v8::internal
#define SLOW_DCHECK(condition)
Definition: checks.h:30
A JavaScript number value (ECMA-262, 4.3.20)
Definition: v8.h:2162
The superclass of all JavaScript values and objects.
Definition: v8.h:1440
static double nan_value()
static ArrayHandle New(TypeHandle element, Region *region)
Definition: types.h:833
static const char * Name(bitset)
Definition: types.cc:978
static bool Is(bitset bits1, bitset bits2)
Definition: types.h:592
static const BitsetMin BitsetMins32[]
Definition: types.h:620
static TypeImpl * New(bitset bits)
Definition: types.h:577
static void Print(OStream &os, bitset)
Definition: types.cc:998
static bitset Lub(TypeImpl *type)
Definition: types.cc:137
static bitset Glb(TypeImpl *type)
Definition: types.cc:120
i::Handle< i::Map > Map()
Definition: types.h:719
static ClassHandle New(i::Handle< i::Map > map, Region *region)
Definition: types.h:724
TypeHandle Bound(Region *region)
Definition: types.h:714
static ConstantHandle New(i::Handle< i::Object > value, Region *region)
Definition: types.h:752
i::Handle< i::Object > Value()
Definition: types.h:750
static ContextHandle New(TypeHandle outer, Region *region)
Definition: types.h:811
static FunctionHandle New(TypeHandle result, TypeHandle receiver, int arity, Region *region)
Definition: types.h:860
TypeHandle Parameter(int i)
Definition: types.h:856
i::Handle< i::Object > Min()
Definition: types.h:776
i::Handle< i::Object > Max()
Definition: types.h:777
static RangeHandle New(i::Handle< i::Object > min, i::Handle< i::Object > max, Region *region)
Definition: types.h:779
static UnionHandle New(int length, Region *region)
Definition: types.h:694
static bool IsInteger(double x)
Definition: types.h:521
UnionType * AsUnion()
Definition: types.h:512
Config::template Handle< RangeType >::type RangeHandle
Definition: types.h:308
Config::template Handle< FunctionType >::type FunctionHandle
Definition: types.h:311
static Config::template Handle< T >::type handle(T *type)
Definition: types.h:496
bool NowIs(TypeImpl *that)
Definition: types.cc:472
static TypeHandle Convert(typename OtherTypeImpl::TypeHandle type, Region *region)
RangeType * AsRange()
Definition: types.h:444
bitset AsBitset()
Definition: types.h:508
ContextType * AsContext()
Definition: types.h:445
static TypeHandle NormalizeUnion(UnionHandle unioned, int size)
Definition: types.cc:808
Config::template Handle< TypeImpl >::type TypeHandle
Definition: types.h:303
ConstantType * AsConstant()
Definition: types.h:443
Iterator< i::Map > Classes()
Definition: types.h:460
bool Is(TypeImpl *that)
Definition: types.h:390
bool SlowIs(TypeImpl *that)
Definition: types.cc:434
ClassType * AsClass()
Definition: types.h:442
bool Contains(i::Object *val)
Definition: types.cc:559
void PrintTo(OStream &os, PrintDimension dim=BOTH_DIMS)
Definition: types.cc:1034
RangeType * GetRange()
Definition: types.cc:548
bool SimplyEquals(TypeImpl *that)
Definition: types.cc:395
static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region *reg)
Definition: types.cc:607
Config::template Handle< UnionType >::type UnionHandle
Definition: types.h:312
ArrayType * AsArray()
Definition: types.h:446
FunctionType * AsFunction()
Definition: types.h:447
bitset BitsetLub()
Definition: types.h:517
Iterator< i::Object > Constants()
Definition: types.h:464
static int IntersectAux(TypeHandle type, TypeHandle other, UnionHandle result, int size, Region *region)
Definition: types.cc:680
static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region *reg)
Definition: types.cc:737
static int AddToUnion(TypeHandle type, UnionHandle result, int size, Region *region)
Definition: types.cc:790
static bool Overlap(RangeType *lhs, RangeType *rhs)
Definition: types.cc:45
bool Maybe(TypeImpl *that)
Definition: types.cc:504
static int UpdateRange(RangeHandle type, UnionHandle result, int size, Region *region)
Definition: types.cc:656
bitset BitsetGlb()
Definition: types.h:516
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 map
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 name
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
#define V8_INFINITY
Definition: globals.h:25
#define UNREACHABLE()
Definition: logging.h:30
#define DCHECK(condition)
Definition: logging.h:205
#define arraysize(array)
Definition: macros.h:86
int int32_t
Definition: unicode.cc:24
static LifetimePosition Max(LifetimePosition a, LifetimePosition b)
static LifetimePosition Min(LifetimePosition a, LifetimePosition b)
bool Is(Object *obj)
static bool IsUint32Double(double value)
Definition: conversions.h:180
PerThreadAssertScopeDebugOnly< HEAP_ALLOCATION_ASSERT, false > DisallowHeapAllocation
Definition: assert-scope.h:110
static int min(int a, int b)
Definition: liveedit.cc:273
static LifetimePosition Min(LifetimePosition a, LifetimePosition b)
static bool IsInt32Double(double value)
Definition: conversions.h:169
unsigned int FastD2UI(double x)
OStream & endl(OStream &os)
Definition: ostreams.cc:112
@ EXTERNAL_STRING_TYPE
Definition: objects.h:642
@ JS_REGEXP_TYPE
Definition: objects.h:748
@ SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE
Definition: objects.h:623
@ SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE
Definition: objects.h:626
@ SLICED_STRING_TYPE
Definition: objects.h:638
@ JS_VALUE_TYPE
Definition: objects.h:728
@ JS_DATE_TYPE
Definition: objects.h:730
@ JS_GLOBAL_PROXY_TYPE
Definition: objects.h:737
@ DECLARED_ACCESSOR_INFO_TYPE
Definition: objects.h:697
@ JS_ARRAY_TYPE
Definition: objects.h:738
@ FIXED_ARRAY_TYPE
Definition: objects.h:717
@ JS_MODULE_TYPE
Definition: objects.h:734
@ JS_OBJECT_TYPE
Definition: objects.h:731
@ JS_TYPED_ARRAY_TYPE
Definition: objects.h:740
@ CONS_ONE_BYTE_STRING_TYPE
Definition: objects.h:636
@ JS_DATA_VIEW_TYPE
Definition: objects.h:741
@ JS_GENERATOR_OBJECT_TYPE
Definition: objects.h:733
@ EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE
Definition: objects.h:646
@ JS_WEAK_SET_TYPE
Definition: objects.h:747
@ ODDBALL_TYPE
Definition: objects.h:663
@ SLICED_ONE_BYTE_STRING_TYPE
Definition: objects.h:640
@ JS_CONTEXT_EXTENSION_OBJECT_TYPE
Definition: objects.h:732
@ ONE_BYTE_STRING_TYPE
Definition: objects.h:633
@ HEAP_NUMBER_TYPE
Definition: objects.h:669
@ JS_MAP_ITERATOR_TYPE
Definition: objects.h:745
@ EXECUTABLE_ACCESSOR_INFO_TYPE
Definition: objects.h:698
@ JS_FUNCTION_TYPE
Definition: objects.h:749
@ JS_FUNCTION_PROXY_TYPE
Definition: objects.h:726
@ SHARED_FUNCTION_INFO_TYPE
Definition: objects.h:719
@ JS_SET_ITERATOR_TYPE
Definition: objects.h:744
@ EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE
Definition: objects.h:620
@ INTERNALIZED_STRING_TYPE
Definition: objects.h:612
@ ACCESSOR_PAIR_TYPE
Definition: objects.h:699
@ JS_GLOBAL_OBJECT_TYPE
Definition: objects.h:735
@ SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE
Definition: objects.h:653
@ EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE
Definition: objects.h:618
@ SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE
Definition: objects.h:629
@ EXTERNAL_INTERNALIZED_STRING_TYPE
Definition: objects.h:616
@ CONS_STRING_TYPE
Definition: objects.h:635
@ JS_ARRAY_BUFFER_TYPE
Definition: objects.h:739
@ JS_PROXY_TYPE
Definition: objects.h:727
@ EXTERNAL_ONE_BYTE_STRING_TYPE
Definition: objects.h:644
@ SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE
Definition: objects.h:651
@ JS_BUILTINS_OBJECT_TYPE
Definition: objects.h:736
@ ONE_BYTE_INTERNALIZED_STRING_TYPE
Definition: objects.h:614
@ FOREIGN_TYPE
Definition: objects.h:671
@ SHORT_EXTERNAL_STRING_TYPE
Definition: objects.h:649
@ JS_WEAK_MAP_TYPE
Definition: objects.h:746
static LifetimePosition Max(LifetimePosition a, LifetimePosition b)
const int kMinInt
Definition: globals.h:110
static bool AddIsSafe(int x, int y)
Definition: types.cc:599
int FastD2I(double x)
Definition: conversions.h:57
static bool SmiValuesAre31Bits()
Definition: v8.h:5807
static bool IsMinusZero(double value)
Definition: conversions.h:154
const uint32_t kMaxUInt32
Definition: globals.h:120
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
@ None
Definition: v8.h:2211
static bool matches(typename TypeImpl< Config >::TypeHandle type)
Definition: types.cc:881
static bool matches(typename TypeImpl< Config >::TypeHandle type)
Definition: types.cc:891
static i::Handle< i::Object > current(typename TypeImpl< Config >::TypeHandle type)
Definition: types.cc:894
static bool matches(typename TypeImpl< Config >::TypeHandle type)
static i::Handle< T > current(typename TypeImpl< Config >::TypeHandle type)
i::Handle< i::Object > max
Definition: types.h:530
i::Handle< i::Object > min
Definition: types.h:529
#define RETURN_NAMED_SEMANTIC_TYPE(type, value)
#define BITSET_CONSTANT(type, value)
#define RETURN_NAMED_REPRESENTATION_TYPE(type, value)
#define REPRESENTATION_BITSET_TYPE_LIST(V)
Definition: types.h:163
#define REPRESENTATION(k)
Definition: types.h:160
#define SEMANTIC_BITSET_TYPE_LIST(V)
Definition: types.h:182
#define SEMANTIC(k)
Definition: types.h:161