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

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

Powered by Google App Engine
This is Rietveld 408576698