Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 35 namespace v8 { | 35 namespace v8 { |
| 36 namespace internal { | 36 namespace internal { |
| 37 | 37 |
| 38 | 38 |
| 39 // A simple type system for compiler-internal use. It is based entirely on | 39 // A simple type system for compiler-internal use. It is based entirely on |
| 40 // union types, and all subtyping hence amounts to set inclusion. Besides the | 40 // union types, and all subtyping hence amounts to set inclusion. Besides the |
| 41 // obvious primitive types and some predefined unions, the type language also | 41 // obvious primitive types and some predefined unions, the type language also |
| 42 // can express class types (a.k.a. specific maps) and singleton types (i.e., | 42 // can express class types (a.k.a. specific maps) and singleton types (i.e., |
| 43 // concrete constants). | 43 // concrete constants). |
| 44 // | 44 // |
| 45 // The following equations and inequations hold: | 45 // Types consist of two dimensions: semantic (value range) and representation. |
| 46 // Both are related through subtyping. | |
| 47 // | |
| 48 // The following equations and inequations hold for the semantic axis: | |
| 46 // | 49 // |
| 47 // None <= T | 50 // None <= T |
| 48 // T <= Any | 51 // T <= Any |
| 49 // | 52 // |
| 50 // Oddball = Boolean \/ Null \/ Undefined | 53 // Oddball = Boolean \/ Null \/ Undefined |
| 51 // Number = Signed32 \/ Unsigned32 \/ Double | 54 // Number = Signed32 \/ Unsigned32 \/ Double |
| 52 // Smi <= Signed32 | 55 // Smi <= Signed32 |
| 53 // Name = String \/ Symbol | 56 // Name = String \/ Symbol |
| 54 // UniqueName = InternalizedString \/ Symbol | 57 // UniqueName = InternalizedString \/ Symbol |
| 55 // InternalizedString < String | 58 // InternalizedString < String |
| 56 // | 59 // |
| 57 // Allocated = Receiver \/ Number \/ Name | 60 // Allocated = Receiver \/ Number \/ Name |
| 58 // Detectable = Allocated - Undetectable | 61 // Detectable = Allocated - Undetectable |
| 59 // Undetectable < Object | 62 // Undetectable < Object |
| 60 // Receiver = Object \/ Proxy | 63 // Receiver = Object \/ Proxy |
| 61 // Array < Object | 64 // Array < Object |
| 62 // Function < Object | 65 // Function < Object |
| 63 // RegExp < Object | 66 // RegExp < Object |
| 64 // | 67 // |
| 65 // Class(map) < T iff instance_type(map) < T | 68 // Class(map) < T iff instance_type(map) < T |
| 66 // Constant(x) < T iff instance_type(map(x)) < T | 69 // Constant(x) < T iff instance_type(map(x)) < T |
| 67 // | 70 // |
| 68 // Note that Constant(x) < Class(map(x)) does _not_ hold, since x's map can | 71 // Note that Constant(x) < Class(map(x)) does _not_ hold, since x's map can |
| 69 // change! (Its instance type cannot, however.) | 72 // change! (Its instance type cannot, however.) |
| 70 // TODO(rossberg): the latter is not currently true for proxies, because of fix, | 73 // TODO(rossberg): the latter is not currently true for proxies, because of fix, |
| 71 // but will hold once we implement direct proxies. | 74 // but will hold once we implement direct proxies. |
| 72 // | 75 // |
| 76 // For the representation axis, the following holds: | |
| 77 // | |
| 78 // None <= R | |
| 79 // R <= Representation | |
| 80 // | |
| 81 // UntaggedInt <= UntaggedInt8 \/ UntaggedInt16 \/ UntaggedInt32) | |
| 82 // UntaggedFloat <= UntaggedFloat32 \/ UntaggedFloat64 | |
| 83 // UntaggedNumber <= UntaggedInt \/ UntaggedFloat | |
| 84 // Untagged <= UntaggedNumber \/ UntaggedPtr | |
| 85 // Tagged <= TaggedInt \/ TaggedPtr | |
| 86 // | |
| 87 // Subtyping relates the two dimensions, for example: | |
| 88 // | |
| 89 // Number <= Tagged \/ UntaggedNumber | |
| 90 // Object <= TaggedPtr \/ UntaggedPtr | |
| 91 // | |
| 92 // Representations can be narrowed for a given semantic type using intersection: | |
| 93 // | |
| 94 // SignedSmall /\ TaggedInt (a 'smi') | |
| 95 // Number /\ TaggedPtr (a heap number) | |
| 96 // | |
| 73 // There are two main functions for testing types: | 97 // There are two main functions for testing types: |
| 74 // | 98 // |
| 75 // T1->Is(T2) -- tests whether T1 is included in T2 (i.e., T1 <= T2) | 99 // T1->Is(T2) -- tests whether T1 is included in T2 (i.e., T1 <= T2) |
| 76 // T1->Maybe(T2) -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0) | 100 // T1->Maybe(T2) -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0) |
| 77 // | 101 // |
| 78 // Typically, the former is to be used to select representations (e.g., via | 102 // Typically, the former is to be used to select representations (e.g., via |
| 79 // T->Is(Integer31())), and the to check whether a specific case needs handling | 103 // T->Is(SignedSmall())), and the to check whether a specific case needs |
|
Michael Starzinger
2014/03/04 11:59:58
nit: Seems to be a "latter" missing.
rossberg
2014/03/04 13:53:11
Done.
| |
| 80 // (e.g., via T->Maybe(Number())). | 104 // handling (e.g., via T->Maybe(Number())). |
| 81 // | 105 // |
| 82 // There is no functionality to discover whether a type is a leaf in the | 106 // There is no functionality to discover whether a type is a leaf in the |
| 83 // lattice. That is intentional. It should always be possible to refine the | 107 // lattice. That is intentional. It should always be possible to refine the |
| 84 // lattice (e.g., splitting up number types further) without invalidating any | 108 // lattice (e.g., splitting up number types further) without invalidating any |
| 85 // existing assumptions or tests. | 109 // existing assumptions or tests. |
| 86 // | |
| 87 // Consequently, do not use pointer equality for type tests, always use Is! | 110 // Consequently, do not use pointer equality for type tests, always use Is! |
| 88 // | 111 // |
| 89 // Internally, all 'primitive' types, and their unions, are represented as | 112 // Internally, all 'primitive' types, and their unions, are represented as |
| 90 // bitsets via smis. Class is a heap pointer to the respective map. Only | 113 // bitsets. Class is a heap pointer to the respective map. Only Constant's, or |
| 91 // Constant's, or unions containing Class'es or Constant's, require allocation. | 114 // unions containing Class'es or Constant's, currently require allocation. |
| 92 // Note that the bitset representation is closed under both Union and Intersect. | 115 // Note that the bitset representation is closed under both Union and Intersect. |
| 93 // | 116 // |
| 94 // The type representation is heap-allocated, so cannot (currently) be used in | 117 // There are two type representations, using different allocation: |
| 95 // a concurrent compilation context. | 118 // |
| 119 // - class Type (zone-allocated, for compiler and concurrent compilation) | |
| 120 // - class HeapType (heap-allocated, for persistent types) | |
| 121 // | |
| 122 // Both provide the same API, and the Convert method can be used to interconvert | |
| 123 // them. | |
| 96 | 124 |
| 97 | 125 |
| 98 #define BITSET_TYPE_LIST(V) \ | 126 #define RAW_REPRESENTATION_BITSET_TYPE_LIST(V) /* internal */ \ |
| 99 V(None, 0) \ | 127 V(RUntaggedInt8, 1 << 29) \ |
| 100 V(Null, 1 << 0) \ | 128 V(RUntaggedInt16, 1 << 28) \ |
| 101 V(Undefined, 1 << 1) \ | 129 V(RUntaggedInt32, 1 << 27) \ |
| 102 V(Boolean, 1 << 2) \ | 130 V(RUntaggedFloat32, 1 << 26) \ |
| 103 V(Smi, 1 << 3) \ | 131 V(RUntaggedFloat64, 1 << 25) \ |
| 104 V(OtherSigned32, 1 << 4) \ | 132 V(RUntaggedPtr, 1 << 24) \ |
| 105 V(Unsigned32, 1 << 5) \ | 133 V(RTaggedInt, 1 << 23) \ |
| 106 V(Double, 1 << 6) \ | 134 V(RTaggedPtr, 1 << 22) \ |
| 107 V(Symbol, 1 << 7) \ | |
| 108 V(InternalizedString, 1 << 8) \ | |
| 109 V(OtherString, 1 << 9) \ | |
| 110 V(Undetectable, 1 << 10) \ | |
| 111 V(Array, 1 << 11) \ | |
| 112 V(Function, 1 << 12) \ | |
| 113 V(RegExp, 1 << 13) \ | |
| 114 V(OtherObject, 1 << 14) \ | |
| 115 V(Proxy, 1 << 15) \ | |
| 116 V(Internal, 1 << 16) \ | |
| 117 \ | 135 \ |
| 118 V(Oddball, kBoolean | kNull | kUndefined) \ | 136 V(RUntaggedInt, kRUntaggedInt8 | kRUntaggedInt16 | kRUntaggedInt32) \ |
| 119 V(Signed32, kSmi | kOtherSigned32) \ | 137 V(RUntaggedFloat, kRUntaggedFloat32 | kRUntaggedFloat64) \ |
| 120 V(Number, kSigned32 | kUnsigned32 | kDouble) \ | 138 V(RUntaggedNumber, kRUntaggedInt | kRUntaggedFloat) \ |
| 121 V(String, kInternalizedString | kOtherString) \ | 139 V(RUntagged, kRUntaggedNumber | kRUntaggedPtr) \ |
| 122 V(UniqueName, kSymbol | kInternalizedString) \ | 140 V(RTagged, kRTaggedInt | kRTaggedPtr) |
| 123 V(Name, kSymbol | kString) \ | 141 |
| 124 V(NumberOrString, kNumber | kString) \ | 142 #define SEMANTIC_BITSET_TYPE_LIST(V) \ |
| 125 V(Object, kUndetectable | kArray | kFunction | \ | 143 V(None, 0) \ |
| 126 kRegExp | kOtherObject) \ | 144 V(Null, 1 << 0 | kRTaggedPtr | kRUntaggedPtr) \ |
| 127 V(Receiver, kObject | kProxy) \ | 145 V(Undefined, 1 << 1 | kRTaggedPtr | kRUntaggedPtr) \ |
| 128 V(Allocated, kDouble | kName | kReceiver) \ | 146 V(Boolean, 1 << 2 | kRTaggedPtr | kRUntaggedPtr) \ |
| 129 V(Any, kOddball | kNumber | kAllocated | kInternal) \ | 147 V(SignedSmall, 1 << 3 | kRTagged | kRUntaggedNumber) \ |
| 130 V(NonNumber, kAny - kNumber) \ | 148 V(OtherSigned32, 1 << 4 | kRTagged | kRUntaggedNumber) \ |
| 131 V(Detectable, kAllocated - kUndetectable) | 149 V(Unsigned32, 1 << 5 | kRTagged | kRUntaggedNumber) \ |
| 150 V(Float, 1 << 6 | kRTagged | kRUntaggedNumber) \ | |
| 151 V(Symbol, 1 << 7 | kRTaggedPtr | kRUntaggedPtr) \ | |
| 152 V(InternalizedString, 1 << 8 | kRTaggedPtr | kRUntaggedPtr) \ | |
| 153 V(OtherString, 1 << 9 | kRTaggedPtr | kRUntaggedPtr) \ | |
| 154 V(Undetectable, 1 << 10 | kRTaggedPtr | kRUntaggedPtr) \ | |
| 155 V(Array, 1 << 11 | kRTaggedPtr | kRUntaggedPtr) \ | |
| 156 V(Function, 1 << 12 | kRTaggedPtr | kRUntaggedPtr) \ | |
| 157 V(RegExp, 1 << 13 | kRTaggedPtr | kRUntaggedPtr) \ | |
| 158 V(OtherObject, 1 << 14 | kRTaggedPtr | kRUntaggedPtr) \ | |
| 159 V(Proxy, 1 << 15 | kRTaggedPtr | kRUntaggedPtr) \ | |
| 160 V(Internal, 1 << 16 | kRTagged | kRUntagged) \ | |
| 161 \ | |
| 162 V(Oddball, kBoolean | kNull | kUndefined) \ | |
| 163 V(Signed32, kSignedSmall | kOtherSigned32) \ | |
| 164 V(Number, kSigned32 | kUnsigned32 | kFloat) \ | |
| 165 V(String, kInternalizedString | kOtherString) \ | |
| 166 V(UniqueName, kSymbol | kInternalizedString) \ | |
| 167 V(Name, kSymbol | kString) \ | |
| 168 V(NumberOrString, kNumber | kString) \ | |
| 169 V(DetectableObject, kArray | kFunction | kRegExp | kOtherObject) \ | |
| 170 V(Object, kDetectableObject | kUndetectable) \ | |
| 171 V(Receiver, kObject | kProxy) \ | |
| 172 V(Allocated, kReceiver | kFloat | kName) \ | |
|
Michael Starzinger
2014/03/04 11:59:58
Why kFloat here?
rossberg
2014/03/04 13:53:11
Good question. I removed this thing entirely, sinc
| |
| 173 V(DetectableReceiver, kDetectableObject | kProxy) \ | |
| 174 V(Detectable, kDetectableReceiver | kFloat | kName) \ | |
|
Michael Starzinger
2014/03/04 11:59:58
Why kFloat here?
rossberg
2014/03/04 13:53:11
Changed to Number.
| |
| 175 V(NonNumber, kOddball | kAllocated | kInternal) \ | |
|
Michael Starzinger
2014/03/04 11:59:58
This way kNonNumber contains kFloat, this seems wr
rossberg
2014/03/04 13:53:11
Done.
| |
| 176 V(Any, kNumber | kNonNumber) | |
| 177 | |
| 178 #define MASK_BITSET_TYPE_LIST(V) \ | |
| 179 V(Representation, kRTagged | kRUntagged) \ | |
| 180 V(Semantic, kAny & ~kRepresentation) | |
| 181 | |
| 182 #define REPRESENTATION_BITSET_TYPE_LIST(V) \ | |
| 183 V(UntaggedInt8, kSemantic | kRUntaggedInt8) \ | |
| 184 V(UntaggedInt16, kSemantic | kRUntaggedInt16) \ | |
| 185 V(UntaggedInt32, kSemantic | kRUntaggedInt32) \ | |
| 186 V(UntaggedFloat32, kSemantic | kRUntaggedFloat32) \ | |
| 187 V(UntaggedFloat64, kSemantic | kRUntaggedFloat64) \ | |
| 188 V(UntaggedPtr, kSemantic | kRUntaggedPtr) \ | |
| 189 V(TaggedInt, kSemantic | kRTaggedInt) \ | |
| 190 V(TaggedPtr, kSemantic | kRTaggedPtr) \ | |
| 191 \ | |
| 192 V(UntaggedInt, kSemantic | kRUntaggedInt) \ | |
| 193 V(UntaggedFloat, kSemantic | kRUntaggedFloat) \ | |
| 194 V(UntaggedNumber, kSemantic | kRUntaggedNumber) \ | |
| 195 V(Untagged, kSemantic | kRUntagged) \ | |
| 196 V(Tagged, kSemantic | kRTagged) | |
| 197 | |
| 198 #define BITSET_TYPE_LIST(V) \ | |
| 199 SEMANTIC_BITSET_TYPE_LIST(V) \ | |
| 200 MASK_BITSET_TYPE_LIST(V) \ | |
| 201 REPRESENTATION_BITSET_TYPE_LIST(V) | |
| 132 | 202 |
| 133 | 203 |
| 134 // struct Config { | 204 // struct Config { |
| 135 // typedef Base; | 205 // typedef Base; |
| 136 // typedef Unioned; | 206 // typedef Unioned; |
| 137 // typedef Region; | 207 // typedef Region; |
| 138 // template<class> struct Handle { typedef type; } // No template typedefs... | 208 // template<class> struct Handle { typedef type; } // No template typedefs... |
| 139 // static Handle<Type>::type handle(Type* type); // !is_bitset(type) | 209 // static Handle<Type>::type handle(Type* type); // !is_bitset(type) |
| 140 // static bool is_bitset(Type*); | 210 // static bool is_bitset(Type*); |
| 141 // static bool is_class(Type*); | 211 // static bool is_class(Type*); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 TypeImpl* t = static_cast<TypeImpl*>(object); | 311 TypeImpl* t = static_cast<TypeImpl*>(object); |
| 242 ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion()); | 312 ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion()); |
| 243 return t; | 313 return t; |
| 244 } | 314 } |
| 245 | 315 |
| 246 template<class OtherTypeImpl> | 316 template<class OtherTypeImpl> |
| 247 static TypeHandle Convert( | 317 static TypeHandle Convert( |
| 248 typename OtherTypeImpl::TypeHandle type, Region* region); | 318 typename OtherTypeImpl::TypeHandle type, Region* region); |
| 249 | 319 |
| 250 #ifdef OBJECT_PRINT | 320 #ifdef OBJECT_PRINT |
| 251 void TypePrint(); | 321 enum PrintDim { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM }; |
|
Michael Starzinger
2014/03/04 11:59:58
nit: Can we write out "PrintDimension" at least fo
rossberg
2014/03/04 13:53:11
Done.
| |
| 252 void TypePrint(FILE* out); | 322 void TypePrint(PrintDim = BOTH_DIMS); |
| 323 void TypePrint(FILE* out, PrintDim = BOTH_DIMS); | |
| 253 #endif | 324 #endif |
| 254 | 325 |
| 255 private: | 326 private: |
| 256 template<class> friend class Iterator; | 327 template<class> friend class Iterator; |
| 257 template<class> friend class TypeImpl; | 328 template<class> friend class TypeImpl; |
| 258 | 329 |
| 259 // A union is a fixed array containing types. Invariants: | 330 // A union is a fixed array containing types. Invariants: |
| 260 // - its length is at least 2 | 331 // - its length is at least 2 |
| 261 // - at most one field is a bitset, and it must go into index 0 | 332 // - at most one field is a bitset, and it must go into index 0 |
| 262 // - no field is a union | 333 // - no field is a union |
| 263 typedef typename Config::Unioned Unioned; | 334 typedef typename Config::Unioned Unioned; |
| 264 typedef typename Config::template Handle<Unioned>::type UnionedHandle; | 335 typedef typename Config::template Handle<Unioned>::type UnionedHandle; |
| 265 | 336 |
| 266 enum { | 337 enum { |
| 267 #define DECLARE_TYPE(type, value) k##type = (value), | 338 #define DECLARE_TYPE(type, value) k##type = (value), |
| 339 RAW_REPRESENTATION_BITSET_TYPE_LIST(DECLARE_TYPE) | |
| 268 BITSET_TYPE_LIST(DECLARE_TYPE) | 340 BITSET_TYPE_LIST(DECLARE_TYPE) |
| 269 #undef DECLARE_TYPE | 341 #undef DECLARE_TYPE |
| 270 kUnusedEOL = 0 | 342 kUnusedEOL = 0 |
| 271 }; | 343 }; |
| 272 | 344 |
| 273 bool IsNone() { return this == None(); } | 345 bool IsNone() { return this == None(); } |
| 274 bool IsAny() { return this == Any(); } | 346 bool IsAny() { return this == Any(); } |
| 275 bool IsBitset() { return Config::is_bitset(this); } | 347 bool IsBitset() { return Config::is_bitset(this); } |
| 276 bool IsUnion() { return Config::is_union(this); } | 348 bool IsUnion() { return Config::is_union(this); } |
| 277 int AsBitset() { return Config::as_bitset(this); } | 349 int AsBitset() { return Config::as_bitset(this); } |
| 278 UnionedHandle AsUnion() { return Config::as_union(this); } | 350 UnionedHandle AsUnion() { return Config::as_union(this); } |
| 279 | 351 |
| 280 static int UnionLength(UnionedHandle unioned) { | 352 static int UnionLength(UnionedHandle unioned) { |
| 281 return Config::union_length(unioned); | 353 return Config::union_length(unioned); |
| 282 } | 354 } |
| 283 static TypeHandle UnionGet(UnionedHandle unioned, int i) { | 355 static TypeHandle UnionGet(UnionedHandle unioned, int i) { |
| 284 return Config::union_get(unioned, i); | 356 return Config::union_get(unioned, i); |
| 285 } | 357 } |
| 286 | 358 |
| 287 bool SlowIs(TypeImpl* that); | 359 bool SlowIs(TypeImpl* that); |
| 288 | 360 |
| 361 static bool IsInhabited(int bitset) { | |
| 362 return (bitset & kRepresentation) && (bitset & kSemantic); | |
| 363 } | |
| 364 | |
| 289 int LubBitset(); // least upper bound that's a bitset | 365 int LubBitset(); // least upper bound that's a bitset |
| 290 int GlbBitset(); // greatest lower bound that's a bitset | 366 int GlbBitset(); // greatest lower bound that's a bitset |
| 291 | 367 |
| 292 static int LubBitset(i::Object* value); | 368 static int LubBitset(i::Object* value); |
| 293 static int LubBitset(i::Map* map); | 369 static int LubBitset(i::Map* map); |
| 294 | 370 |
| 295 bool InUnion(UnionedHandle unioned, int current_size); | 371 bool InUnion(UnionedHandle unioned, int current_size); |
| 296 static int ExtendUnion( | 372 static int ExtendUnion( |
| 297 UnionedHandle unioned, TypeHandle t, int current_size); | 373 UnionedHandle unioned, TypeHandle t, int current_size); |
| 298 static int ExtendIntersection( | 374 static int ExtendIntersection( |
| 299 UnionedHandle unioned, TypeHandle t, TypeHandle other, int current_size); | 375 UnionedHandle unioned, TypeHandle t, TypeHandle other, int current_size); |
| 300 | 376 |
| 301 #ifdef OBJECT_PRINT | 377 #ifdef OBJECT_PRINT |
| 302 static const char* bitset_name(int bitset); | 378 static const char* bitset_name(int bitset); |
| 379 static void BitsetTypePrint(FILE* out, int bitset); | |
| 303 #endif | 380 #endif |
| 304 }; | 381 }; |
| 305 | 382 |
| 306 | 383 |
| 307 // Zone-allocated types are either (odd) integers to represent bitsets, or | 384 // Zone-allocated types are either (odd) integers to represent bitsets, or |
| 308 // (even) pointers to zone lists for everything else. The first slot of every | 385 // (even) pointers to zone lists for everything else. The first slot of every |
| 309 // list is an explicit tag value to distinguish representation. | 386 // list is an explicit tag value to distinguish representation. |
| 310 struct ZoneTypeConfig { | 387 struct ZoneTypeConfig { |
| 311 private: | 388 private: |
| 312 typedef i::ZoneList<void*> Tagged; | 389 typedef i::ZoneList<void*> Tagged; |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 565 return that.lower->Is(this->lower) && this->upper->Is(that.upper); | 642 return that.lower->Is(this->lower) && this->upper->Is(that.upper); |
| 566 } | 643 } |
| 567 }; | 644 }; |
| 568 | 645 |
| 569 typedef BoundsImpl<ZoneTypeConfig> Bounds; | 646 typedef BoundsImpl<ZoneTypeConfig> Bounds; |
| 570 | 647 |
| 571 | 648 |
| 572 } } // namespace v8::internal | 649 } } // namespace v8::internal |
| 573 | 650 |
| 574 #endif // V8_TYPES_H_ | 651 #endif // V8_TYPES_H_ |
| OLD | NEW |