Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/types.cc

Issue 228263005: Implement structural function and array types (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Eps Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/types.h ('K') | « src/types.h ('k') | src/types-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "types.h" 5 #include "types.h"
6 6
7 #include "string-stream.h" 7 #include "string-stream.h"
8 #include "types-inl.h" 8 #include "types-inl.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 12
13 template<class Config> 13 template<class Config>
14 int TypeImpl<Config>::NumClasses() { 14 int TypeImpl<Config>::NumClasses() {
15 if (this->IsClass()) { 15 if (this->IsClass()) {
16 return 1; 16 return 1;
17 } else if (this->IsUnion()) { 17 } else if (this->IsUnion()) {
18 StructHandle unioned = this->AsUnion(); 18 UnionHandle unioned = handle(this->AsUnion());
19 int result = 0; 19 int result = 0;
20 for (int i = 0; i < Config::struct_length(unioned); ++i) { 20 for (int i = 0; i < unioned->Length(); ++i) {
21 if (Config::struct_get(unioned, i)->IsClass()) ++result; 21 if (unioned->Get(i)->IsClass()) ++result;
22 } 22 }
23 return result; 23 return result;
24 } else { 24 } else {
25 return 0; 25 return 0;
26 } 26 }
27 } 27 }
28 28
29 29
30 template<class Config> 30 template<class Config>
31 int TypeImpl<Config>::NumConstants() { 31 int TypeImpl<Config>::NumConstants() {
32 if (this->IsConstant()) { 32 if (this->IsConstant()) {
33 return 1; 33 return 1;
34 } else if (this->IsUnion()) { 34 } else if (this->IsUnion()) {
35 StructHandle unioned = this->AsUnion(); 35 UnionHandle unioned = handle(this->AsUnion());
36 int result = 0; 36 int result = 0;
37 for (int i = 0; i < Config::struct_length(unioned); ++i) { 37 for (int i = 0; i < unioned->Length(); ++i) {
38 if (Config::struct_get(unioned, i)->IsConstant()) ++result; 38 if (unioned->Get(i)->IsConstant()) ++result;
39 } 39 }
40 return result; 40 return result;
41 } else { 41 } else {
42 return 0; 42 return 0;
43 } 43 }
44 } 44 }
45 45
46 46
47 template<class Config> template<class T> 47 template<class Config> template<class T>
48 typename TypeImpl<Config>::TypeHandle 48 typename TypeImpl<Config>::TypeHandle
49 TypeImpl<Config>::Iterator<T>::get_type() { 49 TypeImpl<Config>::Iterator<T>::get_type() {
50 ASSERT(!Done()); 50 ASSERT(!Done());
51 return type_->IsUnion() 51 return type_->IsUnion() ? type_->AsUnion()->Get(index_) : type_;
52 ? Config::struct_get(type_->AsUnion(), index_) : type_;
53 } 52 }
54 53
55 54
56 // C++ cannot specialise nested templates, so we have to go through this 55 // C++ cannot specialise nested templates, so we have to go through this
57 // contortion with an auxiliary template to simulate it. 56 // contortion with an auxiliary template to simulate it.
58 template<class Config, class T> 57 template<class Config, class T>
59 struct TypeImplIteratorAux { 58 struct TypeImplIteratorAux {
60 static bool matches(typename TypeImpl<Config>::TypeHandle type); 59 static bool matches(typename TypeImpl<Config>::TypeHandle type);
61 static i::Handle<T> current(typename TypeImpl<Config>::TypeHandle type); 60 static i::Handle<T> current(typename TypeImpl<Config>::TypeHandle type);
62 }; 61 };
63 62
64 template<class Config> 63 template<class Config>
65 struct TypeImplIteratorAux<Config, i::Map> { 64 struct TypeImplIteratorAux<Config, i::Map> {
66 static bool matches(typename TypeImpl<Config>::TypeHandle type) { 65 static bool matches(typename TypeImpl<Config>::TypeHandle type) {
67 return type->IsClass(); 66 return type->IsClass();
68 } 67 }
69 static i::Handle<i::Map> current(typename TypeImpl<Config>::TypeHandle type) { 68 static i::Handle<i::Map> current(typename TypeImpl<Config>::TypeHandle type) {
70 return type->AsClass(); 69 return type->AsClass()->Map();
71 } 70 }
72 }; 71 };
73 72
74 template<class Config> 73 template<class Config>
75 struct TypeImplIteratorAux<Config, i::Object> { 74 struct TypeImplIteratorAux<Config, i::Object> {
76 static bool matches(typename TypeImpl<Config>::TypeHandle type) { 75 static bool matches(typename TypeImpl<Config>::TypeHandle type) {
77 return type->IsConstant(); 76 return type->IsConstant();
78 } 77 }
79 static i::Handle<i::Object> current( 78 static i::Handle<i::Object> current(
80 typename TypeImpl<Config>::TypeHandle type) { 79 typename TypeImpl<Config>::TypeHandle type) {
81 return type->AsConstant(); 80 return type->AsConstant()->Value();
82 } 81 }
83 }; 82 };
84 83
85 template<class Config> template<class T> 84 template<class Config> template<class T>
86 bool TypeImpl<Config>::Iterator<T>::matches(TypeHandle type) { 85 bool TypeImpl<Config>::Iterator<T>::matches(TypeHandle type) {
87 return TypeImplIteratorAux<Config, T>::matches(type); 86 return TypeImplIteratorAux<Config, T>::matches(type);
88 } 87 }
89 88
90 template<class Config> template<class T> 89 template<class Config> template<class T>
91 i::Handle<T> TypeImpl<Config>::Iterator<T>::Current() { 90 i::Handle<T> TypeImpl<Config>::Iterator<T>::Current() {
92 return TypeImplIteratorAux<Config, T>::current(get_type()); 91 return TypeImplIteratorAux<Config, T>::current(get_type());
93 } 92 }
94 93
95 94
96 template<class Config> template<class T> 95 template<class Config> template<class T>
97 void TypeImpl<Config>::Iterator<T>::Advance() { 96 void TypeImpl<Config>::Iterator<T>::Advance() {
98 ++index_; 97 ++index_;
99 if (type_->IsUnion()) { 98 if (type_->IsUnion()) {
100 StructHandle unioned = type_->AsUnion(); 99 UnionHandle unioned = handle(type_->AsUnion());
101 for (; index_ < Config::struct_length(unioned); ++index_) { 100 for (; index_ < unioned->Length(); ++index_) {
102 if (matches(Config::struct_get(unioned, index_))) return; 101 if (matches(unioned->Get(index_))) return;
103 } 102 }
104 } else if (index_ == 0 && matches(type_)) { 103 } else if (index_ == 0 && matches(type_)) {
105 return; 104 return;
106 } 105 }
107 index_ = -1; 106 index_ = -1;
108 } 107 }
109 108
110 109
110 // Get the largest bitset subsumed by this type.
111 template<class Config>
112 int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
113 if (type->IsBitset()) {
114 return type->AsBitset();
115 } else if (type->IsUnion()) {
116 // All but the first are non-bitsets and thus would yield kNone anyway.
117 return type->AsUnion()->Get(0)->BitsetGlb();
118 } else {
119 return kNone;
120 }
121 }
122
123
111 // Get the smallest bitset subsuming this type. 124 // Get the smallest bitset subsuming this type.
112 template<class Config> 125 template<class Config>
113 int TypeImpl<Config>::LubBitset() { 126 int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
114 if (this->IsBitset()) { 127 if (type->IsBitset()) {
115 return this->AsBitset(); 128 return type->AsBitset();
116 } else if (this->IsUnion()) { 129 } else if (type->IsUnion()) {
117 StructHandle unioned = this->AsUnion(); 130 UnionHandle unioned = handle(type->AsUnion());
118 int bitset = kNone; 131 int bitset = kNone;
119 for (int i = 0; i < Config::struct_length(unioned); ++i) { 132 for (int i = 0; i < unioned->Length(); ++i) {
120 bitset |= Config::struct_get(unioned, i)->LubBitset(); 133 bitset |= unioned->Get(i)->BitsetLub();
121 } 134 }
122 return bitset; 135 return bitset;
123 } else if (this->IsClass()) { 136 } else if (type->IsClass()) {
124 int bitset = Config::lub_bitset(this); 137 int bitset = Config::lub_bitset(type);
125 return bitset ? bitset : LubBitset(*this->AsClass()); 138 return bitset ? bitset : Lub(*type->AsClass()->Map());
139 } else if (type->IsConstant()) {
140 int bitset = Config::lub_bitset(type);
141 return bitset ? bitset : Lub(*type->AsConstant()->Value());
142 } else if (type->IsArray()) {
143 return kArray;
144 } else if (type->IsFunction()) {
145 return kFunction;
126 } else { 146 } else {
127 int bitset = Config::lub_bitset(this); 147 UNREACHABLE();
128 return bitset ? bitset : LubBitset(*this->AsConstant()); 148 return kNone;
129 } 149 }
130 } 150 }
131 151
132 152
133 template<class Config> 153 template<class Config>
134 int TypeImpl<Config>::LubBitset(i::Object* value) { 154 int TypeImpl<Config>::BitsetType::Lub(i::Object* value) {
135 if (value->IsSmi()) return kSignedSmall & kTaggedInt; 155 if (value->IsSmi()) return kSignedSmall & kTaggedInt;
136 i::Map* map = i::HeapObject::cast(value)->map(); 156 i::Map* map = i::HeapObject::cast(value)->map();
137 if (map->instance_type() == HEAP_NUMBER_TYPE) { 157 if (map->instance_type() == HEAP_NUMBER_TYPE) {
138 int32_t i; 158 int32_t i;
139 uint32_t u; 159 uint32_t u;
140 return kTaggedPtr & ( 160 return kTaggedPtr & (
141 value->ToInt32(&i) ? (Smi::IsValid(i) ? kSignedSmall : kOtherSigned32) : 161 value->ToInt32(&i) ? (Smi::IsValid(i) ? kSignedSmall : kOtherSigned32) :
142 value->ToUint32(&u) ? kUnsigned32 : kFloat); 162 value->ToUint32(&u) ? kUnsigned32 : kFloat);
143 } 163 }
144 return LubBitset(map); 164 return Lub(map);
145 } 165 }
146 166
147 167
148 template<class Config> 168 template<class Config>
149 int TypeImpl<Config>::LubBitset(i::Map* map) { 169 int TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
150 switch (map->instance_type()) { 170 switch (map->instance_type()) {
151 case STRING_TYPE: 171 case STRING_TYPE:
152 case ASCII_STRING_TYPE: 172 case ASCII_STRING_TYPE:
153 case CONS_STRING_TYPE: 173 case CONS_STRING_TYPE:
154 case CONS_ASCII_STRING_TYPE: 174 case CONS_ASCII_STRING_TYPE:
155 case SLICED_STRING_TYPE: 175 case SLICED_STRING_TYPE:
156 case SLICED_ASCII_STRING_TYPE: 176 case SLICED_ASCII_STRING_TYPE:
157 case EXTERNAL_STRING_TYPE: 177 case EXTERNAL_STRING_TYPE:
158 case EXTERNAL_ASCII_STRING_TYPE: 178 case EXTERNAL_ASCII_STRING_TYPE:
159 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: 179 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 case ACCESSOR_PAIR_TYPE: 248 case ACCESSOR_PAIR_TYPE:
229 case FIXED_ARRAY_TYPE: 249 case FIXED_ARRAY_TYPE:
230 return kInternal & kTaggedPtr; 250 return kInternal & kTaggedPtr;
231 default: 251 default:
232 UNREACHABLE(); 252 UNREACHABLE();
233 return kNone; 253 return kNone;
234 } 254 }
235 } 255 }
236 256
237 257
238 // Get the largest bitset subsumed by this type.
239 template<class Config>
240 int TypeImpl<Config>::GlbBitset() {
241 if (this->IsBitset()) {
242 return this->AsBitset();
243 } else if (this->IsUnion()) {
244 // All but the first are non-bitsets and thus would yield kNone anyway.
245 return Config::struct_get(this->AsUnion(), 0)->GlbBitset();
246 } else {
247 return kNone;
248 }
249 }
250
251
252 // Most precise _current_ type of a value (usually its class). 258 // Most precise _current_ type of a value (usually its class).
253 template<class Config> 259 template<class Config>
254 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NowOf( 260 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NowOf(
255 i::Object* value, Region* region) { 261 i::Object* value, Region* region) {
256 if (value->IsSmi() || 262 if (value->IsSmi() ||
257 i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) { 263 i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) {
258 return Of(value, region); 264 return Of(value, region);
259 } 265 }
260 return Class(i::handle(i::HeapObject::cast(value)->map()), region); 266 return Class(i::handle(i::HeapObject::cast(value)->map()), region);
261 } 267 }
262 268
263 269
264 // Check this <= that. 270 // Check this <= that.
265 template<class Config> 271 template<class Config>
266 bool TypeImpl<Config>::SlowIs(TypeImpl* that) { 272 bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
267 // Fast path for bitsets. 273 // Fast path for bitsets.
268 if (this->IsNone()) return true; 274 if (this->IsNone()) return true;
269 if (that->IsBitset()) { 275 if (that->IsBitset()) {
270 return (this->LubBitset() | that->AsBitset()) == that->AsBitset(); 276 return (BitsetType::Lub(this) | that->AsBitset()) == that->AsBitset();
271 } 277 }
272 278
273 if (that->IsClass()) { 279 if (that->IsClass()) {
274 return this->IsClass() && *this->AsClass() == *that->AsClass(); 280 return this->IsClass()
281 && *this->AsClass()->Map() == *that->AsClass()->Map();
275 } 282 }
276 if (that->IsConstant()) { 283 if (that->IsConstant()) {
277 return this->IsConstant() && *this->AsConstant() == *that->AsConstant(); 284 return this->IsConstant()
285 && *this->AsConstant()->Value() == *that->AsConstant()->Value();
286 }
287 if (that->IsArray()) {
288 return this->IsArray()
289 && this->AsArray()->Element()->Equals(that->AsArray()->Element());
290 }
291 if (that->IsFunction()) {
292 // We currently do not allow for any variance here, in order to keep
293 // Union and Intersect operations simple.
294 if (!this->IsFunction()) return false;
295 FunctionType* this_fun = this->AsFunction();
296 FunctionType* that_fun = that->AsFunction();
297 if (this_fun->Arity() != that_fun->Arity() ||
298 !this_fun->Result()->Equals(that_fun->Result()) ||
299 !that_fun->Receiver()->Equals(this_fun->Receiver())) {
300 return false;
301 }
302 for (int i = 0; i < this_fun->Arity(); ++i) {
303 if (!that_fun->Parameter(i)->Equals(this_fun->Parameter(i))) return false;
304 }
305 return true;
278 } 306 }
279 307
280 // (T1 \/ ... \/ Tn) <= T <=> (T1 <= T) /\ ... /\ (Tn <= T) 308 // (T1 \/ ... \/ Tn) <= T <=> (T1 <= T) /\ ... /\ (Tn <= T)
281 if (this->IsUnion()) { 309 if (this->IsUnion()) {
282 StructHandle unioned = this->AsUnion(); 310 UnionHandle unioned = handle(this->AsUnion());
283 for (int i = 0; i < Config::struct_length(unioned); ++i) { 311 for (int i = 0; i < unioned->Length(); ++i) {
284 TypeHandle this_i = Config::struct_get(unioned, i); 312 if (!unioned->Get(i)->Is(that)) return false;
285 if (!this_i->Is(that)) return false;
286 } 313 }
287 return true; 314 return true;
288 } 315 }
289 316
290 // T <= (T1 \/ ... \/ Tn) <=> (T <= T1) \/ ... \/ (T <= Tn) 317 // T <= (T1 \/ ... \/ Tn) <=> (T <= T1) \/ ... \/ (T <= Tn)
291 // (iff T is not a union) 318 // (iff T is not a union)
292 ASSERT(!this->IsUnion()); 319 ASSERT(!this->IsUnion());
293 if (that->IsUnion()) { 320 if (that->IsUnion()) {
294 StructHandle unioned = that->AsUnion(); 321 UnionHandle unioned = handle(that->AsUnion());
295 for (int i = 0; i < Config::struct_length(unioned); ++i) { 322 for (int i = 0; i < unioned->Length(); ++i) {
296 TypeHandle that_i = Config::struct_get(unioned, i); 323 if (this->Is(unioned->Get(i))) return true;
297 if (this->Is(that_i)) return true;
298 if (this->IsBitset()) break; // Fast fail, only first field is a bitset. 324 if (this->IsBitset()) break; // Fast fail, only first field is a bitset.
299 } 325 }
300 return false; 326 return false;
301 } 327 }
302 328
303 return false; 329 return false;
304 } 330 }
305 331
306 332
307 template<class Config> 333 template<class Config>
308 bool TypeImpl<Config>::NowIs(TypeImpl* that) { 334 bool TypeImpl<Config>::NowIs(TypeImpl* that) {
309 return this->Is(that) || 335 return this->Is(that) ||
310 (this->IsConstant() && that->IsClass() && 336 (this->IsConstant() && that->IsClass() &&
311 this->AsConstant()->IsHeapObject() && 337 this->AsConstant()->Value()->IsHeapObject() &&
312 i::HeapObject::cast(*this->AsConstant())->map() == *that->AsClass()); 338 i::HeapObject::cast(*this->AsConstant()->Value())->map() ==
339 *that->AsClass()->Map());
313 } 340 }
314 341
315 342
316 // Check this overlaps that. 343 // Check this overlaps that.
317 template<class Config> 344 template<class Config>
318 bool TypeImpl<Config>::Maybe(TypeImpl* that) { 345 bool TypeImpl<Config>::Maybe(TypeImpl* that) {
319 // Fast path for bitsets. 346 // Fast path for bitsets.
320 if (this->IsBitset()) { 347 if (this->IsBitset()) {
321 return IsInhabited(this->AsBitset() & that->LubBitset()); 348 return BitsetType::IsInhabited(this->AsBitset() & BitsetType::Lub(that));
322 } 349 }
323 if (that->IsBitset()) { 350 if (that->IsBitset()) {
324 return IsInhabited(this->LubBitset() & that->AsBitset()); 351 return BitsetType::IsInhabited(BitsetType::Lub(this) & that->AsBitset());
325 } 352 }
326 353
327 // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T) 354 // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T)
328 if (this->IsUnion()) { 355 if (this->IsUnion()) {
329 StructHandle unioned = this->AsUnion(); 356 UnionHandle unioned = handle(this->AsUnion());
330 for (int i = 0; i < Config::struct_length(unioned); ++i) { 357 for (int i = 0; i < unioned->Length(); ++i) {
331 TypeHandle this_i = Config::struct_get(unioned, i); 358 if (unioned->Get(i)->Maybe(that)) return true;
332 if (this_i->Maybe(that)) return true;
333 } 359 }
334 return false; 360 return false;
335 } 361 }
336 362
337 // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn) 363 // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn)
338 if (that->IsUnion()) { 364 if (that->IsUnion()) {
339 StructHandle unioned = that->AsUnion(); 365 UnionHandle unioned = handle(that->AsUnion());
340 for (int i = 0; i < Config::struct_length(unioned); ++i) { 366 for (int i = 0; i < unioned->Length(); ++i) {
341 TypeHandle that_i = Config::struct_get(unioned, i); 367 if (this->Maybe(unioned->Get(i))) return true;
342 if (this->Maybe(that_i)) return true;
343 } 368 }
344 return false; 369 return false;
345 } 370 }
346 371
347 ASSERT(!this->IsUnion() && !that->IsUnion()); 372 ASSERT(!this->IsUnion() && !that->IsUnion());
348 if (this->IsClass()) { 373 if (this->IsClass()) {
349 return that->IsClass() && *this->AsClass() == *that->AsClass(); 374 return that->IsClass()
375 && *this->AsClass()->Map() == *that->AsClass()->Map();
350 } 376 }
351 if (this->IsConstant()) { 377 if (this->IsConstant()) {
352 return that->IsConstant() && *this->AsConstant() == *that->AsConstant(); 378 return that->IsConstant()
379 && *this->AsConstant()->Value() == *that->AsConstant()->Value();
380 }
381 if (this->IsArray()) {
382 return that->IsArray()
383 && this->AsArray()->Element()->Maybe(that->AsArray()->Element());
384 }
385 if (this->IsFunction()) {
386 if (!this->IsFunction()) return false;
387 FunctionType* this_fun = this->AsFunction();
388 FunctionType* that_fun = that->AsFunction();
389 if (!this_fun->Result()->Maybe(that_fun->Result()) ||
390 !that_fun->Receiver()->Maybe(this_fun->Receiver())) {
391 return false;
392 }
393 int min_arity = Min(this_fun->Arity(), that_fun->Arity());
394 for (int i = 0; i < min_arity; ++i) {
395 if (!that_fun->Parameter(i)->Maybe(this_fun->Parameter(i))) return false;
396 }
397 return true;
353 } 398 }
354 399
355 return false; 400 return false;
356 } 401 }
357 402
358 403
359 template<class Config> 404 template<class Config>
360 bool TypeImpl<Config>::Contains(i::Object* value) { 405 bool TypeImpl<Config>::Contains(i::Object* value) {
361 if (this->IsConstant()) { 406 if (this->IsConstant()) {
362 return *this->AsConstant() == value; 407 return *this->AsConstant()->Value() == value;
363 } 408 }
364 return Config::from_bitset(LubBitset(value))->Is(this); 409 return BitsetType::New(BitsetType::Lub(value))->Is(this);
365 } 410 }
366 411
367 412
368 template<class Config> 413 template<class Config>
369 bool TypeImpl<Config>::NowContains(i::Object* value) { 414 bool TypeImpl<Config>::NowContains(i::Object* value) {
370 return this->Contains(value) || 415 return this->Contains(value) ||
371 (this->IsClass() && value->IsHeapObject() && 416 (this->IsClass() && value->IsHeapObject() &&
372 *this->AsClass() == i::HeapObject::cast(value)->map()); 417 *this->AsClass()->Map() == i::HeapObject::cast(value)->map());
373 } 418 }
374 419
375 420
376 template<class Config> 421 template<class Config>
377 bool TypeImpl<Config>::InUnion(StructHandle unioned, int current_size) { 422 bool TypeImpl<Config>::InUnion(UnionHandle unioned, int current_size) {
378 ASSERT(!this->IsUnion()); 423 ASSERT(!this->IsUnion());
379 for (int i = 0; i < current_size; ++i) { 424 for (int i = 0; i < current_size; ++i) {
380 TypeHandle type = Config::struct_get(unioned, i); 425 if (this->Is(unioned->Get(i))) return true;
381 if (this->Is(type)) return true;
382 } 426 }
383 return false; 427 return false;
384 } 428 }
385 429
386 430
387 // Get non-bitsets from this which are not subsumed by union, store at result, 431 // Get non-bitsets from this which are not subsumed by union, store at result,
388 // starting at index. Returns updated index. 432 // starting at index. Returns updated index.
389 template<class Config> 433 template<class Config>
390 int TypeImpl<Config>::ExtendUnion( 434 int TypeImpl<Config>::ExtendUnion(
391 StructHandle result, TypeHandle type, int current_size) { 435 UnionHandle result, TypeHandle type, int current_size) {
392 int old_size = current_size; 436 int old_size = current_size;
393 if (type->IsClass() || type->IsConstant()) { 437 if (type->IsUnion()) {
438 UnionHandle unioned = handle(type->AsUnion());
439 for (int i = 0; i < unioned->Length(); ++i) {
440 TypeHandle type = unioned->Get(i);
441 ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0))));
442 if (!type->IsBitset() && !type->InUnion(result, old_size)) {
443 result->Set(current_size++, type);
444 }
445 }
446 } else if (!type->IsBitset()) {
447 // For all structural types, subtyping implies equivalence.
448 ASSERT(type->IsClass() || type->IsConstant() ||
449 type->IsArray() || type->IsFunction());
394 if (!type->InUnion(result, old_size)) { 450 if (!type->InUnion(result, old_size)) {
395 Config::struct_set(result, current_size++, type); 451 result->Set(current_size++, type);
396 }
397 } else if (type->IsUnion()) {
398 StructHandle unioned = type->AsUnion();
399 for (int i = 0; i < Config::struct_length(unioned); ++i) {
400 TypeHandle type = Config::struct_get(unioned, i);
401 ASSERT(i == 0 ||
402 !(type->IsBitset() || type->Is(Config::struct_get(unioned, 0))));
403 if (!type->IsBitset() && !type->InUnion(result, old_size)) {
404 Config::struct_set(result, current_size++, type);
405 }
406 } 452 }
407 } 453 }
408 return current_size; 454 return current_size;
409 } 455 }
410 456
411 457
412 // Union is O(1) on simple bit unions, but O(n*m) on structured unions. 458 // Union is O(1) on simple bit unions, but O(n*m) on structured unions.
413 template<class Config> 459 template<class Config>
414 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( 460 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
415 TypeHandle type1, TypeHandle type2, Region* region) { 461 TypeHandle type1, TypeHandle type2, Region* region) {
416 // Fast case: bit sets. 462 // Fast case: bit sets.
417 if (type1->IsBitset() && type2->IsBitset()) { 463 if (type1->IsBitset() && type2->IsBitset()) {
418 return Config::from_bitset(type1->AsBitset() | type2->AsBitset(), region); 464 return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region);
419 } 465 }
420 466
421 // Fast case: top or bottom types. 467 // Fast case: top or bottom types.
422 if (type1->IsAny() || type2->IsNone()) return type1; 468 if (type1->IsAny() || type2->IsNone()) return type1;
423 if (type2->IsAny() || type1->IsNone()) return type2; 469 if (type2->IsAny() || type1->IsNone()) return type2;
424 470
425 // Semi-fast case: Unioned objects are neither involved nor produced. 471 // Semi-fast case: Unioned objects are neither involved nor produced.
426 if (!(type1->IsUnion() || type2->IsUnion())) { 472 if (!(type1->IsUnion() || type2->IsUnion())) {
427 if (type1->Is(type2)) return type2; 473 if (type1->Is(type2)) return type2;
428 if (type2->Is(type1)) return type1; 474 if (type2->Is(type1)) return type1;
429 } 475 }
430 476
431 // Slow case: may need to produce a Unioned object. 477 // Slow case: may need to produce a Unioned object.
432 int size = 0; 478 int size = 0;
433 if (!type1->IsBitset()) { 479 if (!type1->IsBitset()) {
434 size += (type1->IsUnion() ? Config::struct_length(type1->AsUnion()) : 1); 480 size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1);
435 } 481 }
436 if (!type2->IsBitset()) { 482 if (!type2->IsBitset()) {
437 size += (type2->IsUnion() ? Config::struct_length(type2->AsUnion()) : 1); 483 size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1);
438 } 484 }
439 int bitset = type1->GlbBitset() | type2->GlbBitset(); 485 int bitset = type1->BitsetGlb() | type2->BitsetGlb();
440 if (IsInhabited(bitset)) ++size; 486 if (BitsetType::IsInhabited(bitset)) ++size;
441 ASSERT(size >= 1); 487 ASSERT(size >= 1);
442 StructHandle unioned = Config::struct_create(kUnionTag, size, region);
443 488
489 UnionHandle unioned = UnionType::New(size, region);
444 size = 0; 490 size = 0;
445 if (IsInhabited(bitset)) { 491 if (BitsetType::IsInhabited(bitset)) {
446 Config::struct_set(unioned, size++, Config::from_bitset(bitset, region)); 492 unioned->Set(size++, BitsetType::New(bitset, region));
447 } 493 }
448 size = ExtendUnion(unioned, type1, size); 494 size = ExtendUnion(unioned, type1, size);
449 size = ExtendUnion(unioned, type2, size); 495 size = ExtendUnion(unioned, type2, size);
450 496
451 if (size == 1) { 497 if (size == 1) {
452 return Config::struct_get(unioned, 0); 498 return unioned->Get(0);
453 } else { 499 } else {
454 Config::struct_shrink(unioned, size); 500 unioned->Shrink(size);
455 return Config::from_struct(unioned); 501 return unioned;
456 } 502 }
457 } 503 }
458 504
459 505
460 // Get non-bitsets from type which are also in other, store at result, 506 // Get non-bitsets from type which are also in other, store at result,
461 // starting at index. Returns updated index. 507 // starting at index. Returns updated index.
462 template<class Config> 508 template<class Config>
463 int TypeImpl<Config>::ExtendIntersection( 509 int TypeImpl<Config>::ExtendIntersection(
464 StructHandle result, TypeHandle type, TypeHandle other, int current_size) { 510 UnionHandle result, TypeHandle type, TypeHandle other, int current_size) {
465 int old_size = current_size; 511 int old_size = current_size;
466 if (type->IsClass() || type->IsConstant()) { 512 if (type->IsUnion()) {
467 if (type->Is(other) && !type->InUnion(result, old_size)) { 513 UnionHandle unioned = handle(type->AsUnion());
468 Config::struct_set(result, current_size++, type); 514 for (int i = 0; i < unioned->Length(); ++i) {
469 } 515 TypeHandle type = unioned->Get(i);
470 } else if (type->IsUnion()) { 516 ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0))));
471 StructHandle unioned = type->AsUnion();
472 for (int i = 0; i < Config::struct_length(unioned); ++i) {
473 TypeHandle type = Config::struct_get(unioned, i);
474 ASSERT(i == 0 ||
475 !(type->IsBitset() || type->Is(Config::struct_get(unioned, 0))));
476 if (!type->IsBitset() && type->Is(other) && 517 if (!type->IsBitset() && type->Is(other) &&
477 !type->InUnion(result, old_size)) { 518 !type->InUnion(result, old_size)) {
478 Config::struct_set(result, current_size++, type); 519 result->Set(current_size++, type);
479 } 520 }
480 } 521 }
522 } else if (!type->IsBitset()) {
523 // For all structural types, subtyping implies equivalence.
524 ASSERT(type->IsClass() || type->IsConstant() ||
525 type->IsArray() || type->IsFunction());
526 if (type->Is(other) && !type->InUnion(result, old_size)) {
527 result->Set(current_size++, type);
528 }
481 } 529 }
482 return current_size; 530 return current_size;
483 } 531 }
484 532
485 533
486 // Intersection is O(1) on simple bit unions, but O(n*m) on structured unions. 534 // Intersection is O(1) on simple bit unions, but O(n*m) on structured unions.
487 // TODO(rossberg): Should we use object sets somehow? Is it worth it?
488 template<class Config> 535 template<class Config>
489 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect( 536 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
490 TypeHandle type1, TypeHandle type2, Region* region) { 537 TypeHandle type1, TypeHandle type2, Region* region) {
491 // Fast case: bit sets. 538 // Fast case: bit sets.
492 if (type1->IsBitset() && type2->IsBitset()) { 539 if (type1->IsBitset() && type2->IsBitset()) {
493 return Config::from_bitset(type1->AsBitset() & type2->AsBitset(), region); 540 return BitsetType::New(type1->AsBitset() & type2->AsBitset(), region);
494 } 541 }
495 542
496 // Fast case: top or bottom types. 543 // Fast case: top or bottom types.
497 if (type1->IsNone() || type2->IsAny()) return type1; 544 if (type1->IsNone() || type2->IsAny()) return type1;
498 if (type2->IsNone() || type1->IsAny()) return type2; 545 if (type2->IsNone() || type1->IsAny()) return type2;
499 546
500 // Semi-fast case: Unioned objects are neither involved nor produced. 547 // Semi-fast case: Unioned objects are neither involved nor produced.
501 if (!(type1->IsUnion() || type2->IsUnion())) { 548 if (!(type1->IsUnion() || type2->IsUnion())) {
502 if (type1->Is(type2)) return type1; 549 if (type1->Is(type2)) return type1;
503 if (type2->Is(type1)) return type2; 550 if (type2->Is(type1)) return type2;
504 } 551 }
505 552
506 // Slow case: may need to produce a Unioned object. 553 // Slow case: may need to produce a Unioned object.
507 int size = INT_MAX; 554 int size = INT_MAX;
508 if (!type1->IsBitset()) { 555 if (!type1->IsBitset()) {
509 size = (type1->IsUnion() ? Config::struct_length(type1->AsUnion()) : 1); 556 size = (type1->IsUnion() ? type1->AsUnion()->Length() : 1);
510 } 557 }
511 if (!type2->IsBitset()) { 558 if (!type2->IsBitset()) {
512 size = Min(size, 559 size = Min(size, type2->IsUnion() ? type2->AsUnion()->Length() : 1);
513 type2->IsUnion() ? Config::struct_length(type2->AsUnion()) : 1);
514 } 560 }
515 int bitset = type1->GlbBitset() & type2->GlbBitset(); 561 int bitset = type1->BitsetGlb() & type2->BitsetGlb();
516 if (IsInhabited(bitset)) ++size; 562 if (BitsetType::IsInhabited(bitset)) ++size;
517 ASSERT(size >= 1); 563 ASSERT(size >= 1);
518 StructHandle unioned = Config::struct_create(kUnionTag, size, region);
519 564
565 UnionHandle unioned = UnionType::New(size, region);
520 size = 0; 566 size = 0;
521 if (IsInhabited(bitset)) { 567 if (BitsetType::IsInhabited(bitset)) {
522 Config::struct_set(unioned, size++, Config::from_bitset(bitset, region)); 568 unioned->Set(size++, BitsetType::New(bitset, region));
523 } 569 }
524 size = ExtendIntersection(unioned, type1, type2, size); 570 size = ExtendIntersection(unioned, type1, type2, size);
525 size = ExtendIntersection(unioned, type2, type1, size); 571 size = ExtendIntersection(unioned, type2, type1, size);
526 572
527 if (size == 0) { 573 if (size == 0) {
528 return None(region); 574 return None(region);
529 } else if (size == 1) { 575 } else if (size == 1) {
530 return Config::struct_get(unioned, 0); 576 return unioned->Get(0);
531 } else { 577 } else {
532 Config::struct_shrink(unioned, size); 578 unioned->Shrink(size);
533 return Config::from_struct(unioned); 579 return unioned;
534 } 580 }
535 } 581 }
536 582
537 583
538 template<class Config> 584 template<class Config>
539 template<class OtherType> 585 template<class OtherType>
540 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert( 586 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert(
541 typename OtherType::TypeHandle type, Region* region) { 587 typename OtherType::TypeHandle type, Region* region) {
542 if (type->IsBitset()) { 588 if (type->IsBitset()) {
543 return Config::from_bitset(type->AsBitset(), region); 589 return BitsetType::New(type->AsBitset(), region);
544 } else if (type->IsClass()) { 590 } else if (type->IsClass()) {
545 return Config::from_class(type->AsClass(), type->LubBitset(), region); 591 return ClassType::New(type->AsClass()->Map(), region);
546 } else if (type->IsConstant()) { 592 } else if (type->IsConstant()) {
547 return Config::from_constant(type->AsConstant(), type->LubBitset(), region); 593 return ConstantType::New(type->AsConstant()->Value(), region);
594 } else if (type->IsUnion()) {
595 int length = type->AsUnion()->Length();
596 UnionHandle unioned = UnionType::New(length, region);
597 for (int i = 0; i < length; ++i) {
598 unioned->Set(i, Convert<OtherType>(type->AsUnion()->Get(i), region));
599 }
600 return unioned;
601 } else if (type->IsArray()) {
602 return ArrayType::New(
603 Convert<OtherType>(type->AsArray()->Element(), region), region);
604 } else if (type->IsFunction()) {
605 FunctionHandle function = FunctionType::New(
606 Convert<OtherType>(type->AsFunction()->Result(), region),
607 Convert<OtherType>(type->AsFunction()->Receiver(), region),
608 type->AsFunction()->Arity(), region);
609 for (int i = 0; i < function->Arity(); ++i) {
610 function->InitParameter(i,
611 Convert<OtherType>(type->AsFunction()->Parameter(i), region));
612 }
613 return function;
548 } else { 614 } else {
549 ASSERT(type->IsUnion()); 615 UNREACHABLE();
550 typename OtherType::StructHandle unioned = type->AsUnion(); 616 return None(region);
551 int length = OtherType::StructLength(unioned);
552 StructHandle new_unioned = Config::struct_create(kUnionTag, length, region);
553 for (int i = 0; i < length; ++i) {
554 Config::struct_set(new_unioned, i,
555 Convert<OtherType>(OtherType::StructGet(unioned, i), region));
556 }
557 return Config::from_struct(new_unioned);
558 } 617 }
559 } 618 }
560 619
561 620
562 // TODO(rossberg): this does not belong here. 621 // TODO(rossberg): this does not belong here.
563 Representation Representation::FromType(Type* type) { 622 Representation Representation::FromType(Type* type) {
564 if (type->Is(Type::None())) return Representation::None(); 623 if (type->Is(Type::None())) return Representation::None();
565 if (type->Is(Type::SignedSmall())) return Representation::Smi(); 624 if (type->Is(Type::SignedSmall())) return Representation::Smi();
566 if (type->Is(Type::Signed32())) return Representation::Integer32(); 625 if (type->Is(Type::Signed32())) return Representation::Integer32();
567 if (type->Is(Type::Number())) return Representation::Double(); 626 if (type->Is(Type::Number())) return Representation::Double();
568 return Representation::Tagged(); 627 return Representation::Tagged();
569 } 628 }
570 629
571 630
572 template<class Config> 631 template<class Config>
573 void TypeImpl<Config>::TypePrint(PrintDimension dim) { 632 void TypeImpl<Config>::TypePrint(PrintDimension dim) {
574 TypePrint(stdout, dim); 633 TypePrint(stdout, dim);
575 PrintF(stdout, "\n"); 634 PrintF(stdout, "\n");
576 Flush(stdout); 635 Flush(stdout);
577 } 636 }
578 637
579 638
580 template<class Config> 639 template<class Config>
581 const char* TypeImpl<Config>::bitset_name(int bitset) { 640 const char* TypeImpl<Config>::BitsetType::Name(int bitset) {
582 switch (bitset) { 641 switch (bitset) {
583 case kAny & kRepresentation: return "Any"; 642 case kAny & kRepresentation: return "Any";
584 #define PRINT_COMPOSED_TYPE(type, value) \ 643 #define PRINT_COMPOSED_TYPE(type, value) \
585 case k##type & kRepresentation: return #type; 644 case k##type & kRepresentation: return #type;
586 REPRESENTATION_BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE) 645 REPRESENTATION_BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE)
587 #undef PRINT_COMPOSED_TYPE 646 #undef PRINT_COMPOSED_TYPE
588 647
589 #define PRINT_COMPOSED_TYPE(type, value) \ 648 #define PRINT_COMPOSED_TYPE(type, value) \
590 case k##type & kSemantic: return #type; 649 case k##type & kSemantic: return #type;
591 SEMANTIC_BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE) 650 SEMANTIC_BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE)
592 #undef PRINT_COMPOSED_TYPE 651 #undef PRINT_COMPOSED_TYPE
593 652
594 default: 653 default:
595 return NULL; 654 return NULL;
596 } 655 }
597 } 656 }
598 657
599 658
600 template<class Config> 659 template<class Config>
601 void TypeImpl<Config>::BitsetTypePrint(FILE* out, int bitset) { 660 void TypeImpl<Config>::BitsetType::BitsetTypePrint(FILE* out, int bitset) {
602 const char* name = bitset_name(bitset); 661 const char* name = Name(bitset);
603 if (name != NULL) { 662 if (name != NULL) {
604 PrintF(out, "%s", name); 663 PrintF(out, "%s", name);
605 } else { 664 } else {
606 static const int named_bitsets[] = { 665 static const int named_bitsets[] = {
607 #define BITSET_CONSTANT(type, value) k##type & kRepresentation, 666 #define BITSET_CONSTANT(type, value) k##type & kRepresentation,
608 REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT) 667 REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT)
609 #undef BITSET_CONSTANT 668 #undef BITSET_CONSTANT
610 669
611 #define BITSET_CONSTANT(type, value) k##type & kSemantic, 670 #define BITSET_CONSTANT(type, value) k##type & kSemantic,
612 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) 671 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT)
613 #undef BITSET_CONSTANT 672 #undef BITSET_CONSTANT
614 }; 673 };
615 674
616 bool is_first = true; 675 bool is_first = true;
617 PrintF(out, "("); 676 PrintF(out, "(");
618 for (int i(ARRAY_SIZE(named_bitsets) - 1); bitset != 0 && i >= 0; --i) { 677 for (int i(ARRAY_SIZE(named_bitsets) - 1); bitset != 0 && i >= 0; --i) {
619 int subset = named_bitsets[i]; 678 int subset = named_bitsets[i];
620 if ((bitset & subset) == subset) { 679 if ((bitset & subset) == subset) {
621 if (!is_first) PrintF(out, " | "); 680 if (!is_first) PrintF(out, " | ");
622 is_first = false; 681 is_first = false;
623 PrintF(out, "%s", bitset_name(subset)); 682 PrintF(out, "%s", Name(subset));
624 bitset -= subset; 683 bitset -= subset;
625 } 684 }
626 } 685 }
627 ASSERT(bitset == 0); 686 ASSERT(bitset == 0);
628 PrintF(out, ")"); 687 PrintF(out, ")");
629 } 688 }
630 } 689 }
631 690
632 691
633 template<class Config> 692 template<class Config>
634 void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) { 693 void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) {
635 if (this->IsBitset()) { 694 if (this->IsBitset()) {
636 int bitset = this->AsBitset(); 695 int bitset = this->AsBitset();
637 switch (dim) { 696 switch (dim) {
638 case BOTH_DIMS: 697 case BOTH_DIMS:
639 BitsetTypePrint(out, bitset & kSemantic); 698 BitsetType::BitsetTypePrint(out, bitset & BitsetType::kSemantic);
640 PrintF(out, "/"); 699 PrintF(out, "/");
641 BitsetTypePrint(out, bitset & kRepresentation); 700 BitsetType::BitsetTypePrint(out, bitset & BitsetType::kRepresentation);
642 break; 701 break;
643 case SEMANTIC_DIM: 702 case SEMANTIC_DIM:
644 BitsetTypePrint(out, bitset & kSemantic); 703 BitsetType::BitsetTypePrint(out, bitset & BitsetType::kSemantic);
645 break; 704 break;
646 case REPRESENTATION_DIM: 705 case REPRESENTATION_DIM:
647 BitsetTypePrint(out, bitset & kRepresentation); 706 BitsetType::BitsetTypePrint(out, bitset & BitsetType::kRepresentation);
648 break; 707 break;
649 } 708 }
650 } else if (this->IsConstant()) { 709 } else if (this->IsConstant()) {
651 PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant())); 710 PrintF(out, "Constant(%p : ",
652 Config::from_bitset(this->LubBitset())->TypePrint(out, dim); 711 static_cast<void*>(*this->AsConstant()->Value()));
712 BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim);
653 PrintF(out, ")"); 713 PrintF(out, ")");
654 } else if (this->IsClass()) { 714 } else if (this->IsClass()) {
655 PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass())); 715 PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass()->Map()));
656 Config::from_bitset(this->LubBitset())->TypePrint(out, dim); 716 BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim);
657 PrintF(out, ")"); 717 PrintF(out, ")");
658 } else if (this->IsUnion()) { 718 } else if (this->IsUnion()) {
659 PrintF(out, "("); 719 PrintF(out, "(");
660 StructHandle unioned = this->AsUnion(); 720 UnionHandle unioned = handle(this->AsUnion());
661 for (int i = 0; i < Config::struct_length(unioned); ++i) { 721 for (int i = 0; i < unioned->Length(); ++i) {
662 TypeHandle type_i = Config::struct_get(unioned, i); 722 TypeHandle type_i = unioned->Get(i);
663 if (i > 0) PrintF(out, " | "); 723 if (i > 0) PrintF(out, " | ");
664 type_i->TypePrint(out, dim); 724 type_i->TypePrint(out, dim);
665 } 725 }
666 PrintF(out, ")"); 726 PrintF(out, ")");
727 } else if (this->IsArray()) {
728 PrintF(out, "[");
729 AsArray()->Element()->TypePrint(out, dim);
730 PrintF(out, "]");
731 } else if (this->IsFunction()) {
732 if (!this->AsFunction()->Receiver()->IsAny()) {
733 this->AsFunction()->Receiver()->TypePrint(out, dim);
734 PrintF(out, ".");
735 }
736 PrintF(out, "(");
737 for (int i = 0; i < this->AsFunction()->Arity(); ++i) {
738 if (i > 0) PrintF(out, ", ");
739 this->AsFunction()->Parameter(i)->TypePrint(out, dim);
740 }
741 PrintF(out, ")->");
742 this->AsFunction()->Result()->TypePrint(out, dim);
743 } else {
744 UNREACHABLE();
667 } 745 }
668 } 746 }
669 747
670 748
671 template class TypeImpl<ZoneTypeConfig>; 749 template class TypeImpl<ZoneTypeConfig>;
672 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>; 750 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>;
673 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>; 751 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>;
674 752
675 template class TypeImpl<HeapTypeConfig>; 753 template class TypeImpl<HeapTypeConfig>;
676 template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>; 754 template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>;
677 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; 755 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>;
678 756
679 template TypeImpl<ZoneTypeConfig>::TypeHandle 757 template TypeImpl<ZoneTypeConfig>::TypeHandle
680 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( 758 TypeImpl<ZoneTypeConfig>::Convert<HeapType>(
681 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); 759 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*);
682 template TypeImpl<HeapTypeConfig>::TypeHandle 760 template TypeImpl<HeapTypeConfig>::TypeHandle
683 TypeImpl<HeapTypeConfig>::Convert<Type>( 761 TypeImpl<HeapTypeConfig>::Convert<Type>(
684 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); 762 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*);
685 763
686 } } // namespace v8::internal 764 } } // namespace v8::internal
OLDNEW
« src/types.h ('K') | « src/types.h ('k') | src/types-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698