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

Side by Side Diff: src/types.cc

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