| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 namespace v8 { | 31 namespace v8 { |
| 32 namespace internal { | 32 namespace internal { |
| 33 | 33 |
| 34 template<class Config> | 34 template<class Config> |
| 35 int TypeImpl<Config>::NumClasses() { | 35 int TypeImpl<Config>::NumClasses() { |
| 36 if (this->IsClass()) { | 36 if (this->IsClass()) { |
| 37 return 1; | 37 return 1; |
| 38 } else if (this->IsUnion()) { | 38 } else if (this->IsUnion()) { |
| 39 UnionedHandle unioned = this->AsUnion(); | 39 UnionedHandle unioned = this->AsUnion(); |
| 40 int result = 0; | 40 int result = 0; |
| 41 for (int i = 0; i < unioned->length(); ++i) { | 41 for (int i = 0; i < Config::union_length(unioned); ++i) { |
| 42 if (Config::union_get(unioned, i)->IsClass()) ++result; | 42 if (Config::union_get(unioned, i)->IsClass()) ++result; |
| 43 } | 43 } |
| 44 return result; | 44 return result; |
| 45 } else { | 45 } else { |
| 46 return 0; | 46 return 0; |
| 47 } | 47 } |
| 48 } | 48 } |
| 49 | 49 |
| 50 | 50 |
| 51 template<class Config> | 51 template<class Config> |
| 52 int TypeImpl<Config>::NumConstants() { | 52 int TypeImpl<Config>::NumConstants() { |
| 53 if (this->IsConstant()) { | 53 if (this->IsConstant()) { |
| 54 return 1; | 54 return 1; |
| 55 } else if (this->IsUnion()) { | 55 } else if (this->IsUnion()) { |
| 56 UnionedHandle unioned = this->AsUnion(); | 56 UnionedHandle unioned = this->AsUnion(); |
| 57 int result = 0; | 57 int result = 0; |
| 58 for (int i = 0; i < unioned->length(); ++i) { | 58 for (int i = 0; i < Config::union_length(unioned); ++i) { |
| 59 if (Config::union_get(unioned, i)->IsConstant()) ++result; | 59 if (Config::union_get(unioned, i)->IsConstant()) ++result; |
| 60 } | 60 } |
| 61 return result; | 61 return result; |
| 62 } else { | 62 } else { |
| 63 return 0; | 63 return 0; |
| 64 } | 64 } |
| 65 } | 65 } |
| 66 | 66 |
| 67 | 67 |
| 68 template<class Config> template<class T> | 68 template<class Config> template<class T> |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 i::Handle<T> TypeImpl<Config>::Iterator<T>::Current() { | 111 i::Handle<T> TypeImpl<Config>::Iterator<T>::Current() { |
| 112 return TypeImplIteratorAux<Config, T>::current(get_type()); | 112 return TypeImplIteratorAux<Config, T>::current(get_type()); |
| 113 } | 113 } |
| 114 | 114 |
| 115 | 115 |
| 116 template<class Config> template<class T> | 116 template<class Config> template<class T> |
| 117 void TypeImpl<Config>::Iterator<T>::Advance() { | 117 void TypeImpl<Config>::Iterator<T>::Advance() { |
| 118 ++index_; | 118 ++index_; |
| 119 if (type_->IsUnion()) { | 119 if (type_->IsUnion()) { |
| 120 UnionedHandle unioned = type_->AsUnion(); | 120 UnionedHandle unioned = type_->AsUnion(); |
| 121 for (; index_ < unioned->length(); ++index_) { | 121 for (; index_ < Config::union_length(unioned); ++index_) { |
| 122 if (matches(Config::union_get(unioned, index_))) return; | 122 if (matches(Config::union_get(unioned, index_))) return; |
| 123 } | 123 } |
| 124 } else if (index_ == 0 && matches(type_)) { | 124 } else if (index_ == 0 && matches(type_)) { |
| 125 return; | 125 return; |
| 126 } | 126 } |
| 127 index_ = -1; | 127 index_ = -1; |
| 128 } | 128 } |
| 129 | 129 |
| 130 | 130 |
| 131 // Get the smallest bitset subsuming this type. | 131 // Get the smallest bitset subsuming this type. |
| 132 template<class Config> | 132 template<class Config> |
| 133 int TypeImpl<Config>::LubBitset() { | 133 int TypeImpl<Config>::LubBitset() { |
| 134 if (this->IsBitset()) { | 134 if (this->IsBitset()) { |
| 135 return this->AsBitset(); | 135 return this->AsBitset(); |
| 136 } else if (this->IsUnion()) { | 136 } else if (this->IsUnion()) { |
| 137 UnionedHandle unioned = this->AsUnion(); | 137 UnionedHandle unioned = this->AsUnion(); |
| 138 int bitset = kNone; | 138 int bitset = kNone; |
| 139 for (int i = 0; i < unioned->length(); ++i) { | 139 for (int i = 0; i < Config::union_length(unioned); ++i) { |
| 140 bitset |= Config::union_get(unioned, i)->LubBitset(); | 140 bitset |= Config::union_get(unioned, i)->LubBitset(); |
| 141 } | 141 } |
| 142 return bitset; | 142 return bitset; |
| 143 } else if (this->IsClass()) { | 143 } else if (this->IsClass()) { |
| 144 return LubBitset(*this->AsClass()); | 144 return LubBitset(*this->AsClass()); |
| 145 } else { | 145 } else { |
| 146 return LubBitset(*this->AsConstant()); | 146 return LubBitset(*this->AsConstant()); |
| 147 } | 147 } |
| 148 } | 148 } |
| 149 | 149 |
| 150 | 150 |
| 151 template<class Config> | 151 template<class Config> |
| 152 int TypeImpl<Config>::LubBitset(i::Object* value) { | 152 int TypeImpl<Config>::LubBitset(i::Object* value) { |
| 153 if (value->IsSmi()) return kSmi; | 153 if (value->IsSmi()) return kSmi; |
| 154 i::Map* map = i::HeapObject::cast(value)->map(); | 154 i::Map* map = i::HeapObject::cast(value)->map(); |
| 155 if (map->instance_type() == HEAP_NUMBER_TYPE) { | 155 if (map->instance_type() == HEAP_NUMBER_TYPE) { |
| 156 int32_t i; | 156 int32_t i; |
| 157 uint32_t u; | 157 uint32_t u; |
| 158 if (value->ToInt32(&i)) return Smi::IsValid(i) ? kSmi : kOtherSigned32; | 158 if (value->ToInt32(&i)) return Smi::IsValid(i) ? kSmi : kOtherSigned32; |
| 159 if (value->ToUint32(&u)) return kUnsigned32; | 159 if (value->ToUint32(&u)) return kUnsigned32; |
| 160 return kDouble; | 160 return kDouble; |
| 161 } | 161 } |
| 162 if (map->instance_type() == ODDBALL_TYPE) { | 162 if (map->instance_type() == ODDBALL_TYPE) { |
| 163 if (value->IsUndefined()) return kUndefined; | 163 if (value->IsUndefined()) return kUndefined; |
| 164 if (value->IsNull()) return kNull; | 164 if (value->IsNull()) return kNull; |
| 165 if (value->IsBoolean()) return kBoolean; | 165 if (value->IsBoolean()) return kBoolean; |
| 166 if (value->IsTheHole()) return kAny; // TODO(rossberg): kNone? | 166 if (value->IsTheHole()) return kAny; // TODO(rossberg): kNone? |
| 167 if (value->IsUninitialized()) return kNone; |
| 167 UNREACHABLE(); | 168 UNREACHABLE(); |
| 168 } | 169 } |
| 169 return LubBitset(map); | 170 return LubBitset(map); |
| 170 } | 171 } |
| 171 | 172 |
| 172 | 173 |
| 173 template<class Config> | 174 template<class Config> |
| 174 int TypeImpl<Config>::LubBitset(i::Map* map) { | 175 int TypeImpl<Config>::LubBitset(i::Map* map) { |
| 175 switch (map->instance_type()) { | 176 switch (map->instance_type()) { |
| 176 case STRING_TYPE: | 177 case STRING_TYPE: |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 if (that->IsClass()) { | 293 if (that->IsClass()) { |
| 293 return this->IsClass() && *this->AsClass() == *that->AsClass(); | 294 return this->IsClass() && *this->AsClass() == *that->AsClass(); |
| 294 } | 295 } |
| 295 if (that->IsConstant()) { | 296 if (that->IsConstant()) { |
| 296 return this->IsConstant() && *this->AsConstant() == *that->AsConstant(); | 297 return this->IsConstant() && *this->AsConstant() == *that->AsConstant(); |
| 297 } | 298 } |
| 298 | 299 |
| 299 // (T1 \/ ... \/ Tn) <= T <=> (T1 <= T) /\ ... /\ (Tn <= T) | 300 // (T1 \/ ... \/ Tn) <= T <=> (T1 <= T) /\ ... /\ (Tn <= T) |
| 300 if (this->IsUnion()) { | 301 if (this->IsUnion()) { |
| 301 UnionedHandle unioned = this->AsUnion(); | 302 UnionedHandle unioned = this->AsUnion(); |
| 302 for (int i = 0; i < unioned->length(); ++i) { | 303 for (int i = 0; i < Config::union_length(unioned); ++i) { |
| 303 TypeHandle this_i = Config::union_get(unioned, i); | 304 TypeHandle this_i = Config::union_get(unioned, i); |
| 304 if (!this_i->Is(that)) return false; | 305 if (!this_i->Is(that)) return false; |
| 305 } | 306 } |
| 306 return true; | 307 return true; |
| 307 } | 308 } |
| 308 | 309 |
| 309 // T <= (T1 \/ ... \/ Tn) <=> (T <= T1) \/ ... \/ (T <= Tn) | 310 // T <= (T1 \/ ... \/ Tn) <=> (T <= T1) \/ ... \/ (T <= Tn) |
| 310 // (iff T is not a union) | 311 // (iff T is not a union) |
| 311 ASSERT(!this->IsUnion()); | 312 ASSERT(!this->IsUnion()); |
| 312 if (that->IsUnion()) { | 313 if (that->IsUnion()) { |
| 313 UnionedHandle unioned = that->AsUnion(); | 314 UnionedHandle unioned = that->AsUnion(); |
| 314 for (int i = 0; i < unioned->length(); ++i) { | 315 for (int i = 0; i < Config::union_length(unioned); ++i) { |
| 315 TypeHandle that_i = Config::union_get(unioned, i); | 316 TypeHandle that_i = Config::union_get(unioned, i); |
| 316 if (this->Is(that_i)) return true; | 317 if (this->Is(that_i)) return true; |
| 317 if (this->IsBitset()) break; // Fast fail, only first field is a bitset. | 318 if (this->IsBitset()) break; // Fast fail, only first field is a bitset. |
| 318 } | 319 } |
| 319 return false; | 320 return false; |
| 320 } | 321 } |
| 321 | 322 |
| 322 return false; | 323 return false; |
| 323 } | 324 } |
| 324 | 325 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 339 if (this->IsBitset()) { | 340 if (this->IsBitset()) { |
| 340 return (this->AsBitset() & that->LubBitset()) != 0; | 341 return (this->AsBitset() & that->LubBitset()) != 0; |
| 341 } | 342 } |
| 342 if (that->IsBitset()) { | 343 if (that->IsBitset()) { |
| 343 return (this->LubBitset() & that->AsBitset()) != 0; | 344 return (this->LubBitset() & that->AsBitset()) != 0; |
| 344 } | 345 } |
| 345 | 346 |
| 346 // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T) | 347 // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T) |
| 347 if (this->IsUnion()) { | 348 if (this->IsUnion()) { |
| 348 UnionedHandle unioned = this->AsUnion(); | 349 UnionedHandle unioned = this->AsUnion(); |
| 349 for (int i = 0; i < unioned->length(); ++i) { | 350 for (int i = 0; i < Config::union_length(unioned); ++i) { |
| 350 TypeHandle this_i = Config::union_get(unioned, i); | 351 TypeHandle this_i = Config::union_get(unioned, i); |
| 351 if (this_i->Maybe(that)) return true; | 352 if (this_i->Maybe(that)) return true; |
| 352 } | 353 } |
| 353 return false; | 354 return false; |
| 354 } | 355 } |
| 355 | 356 |
| 356 // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn) | 357 // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn) |
| 357 if (that->IsUnion()) { | 358 if (that->IsUnion()) { |
| 358 UnionedHandle unioned = that->AsUnion(); | 359 UnionedHandle unioned = that->AsUnion(); |
| 359 for (int i = 0; i < unioned->length(); ++i) { | 360 for (int i = 0; i < Config::union_length(unioned); ++i) { |
| 360 TypeHandle that_i = Config::union_get(unioned, i); | 361 TypeHandle that_i = Config::union_get(unioned, i); |
| 361 if (this->Maybe(that_i)) return true; | 362 if (this->Maybe(that_i)) return true; |
| 362 } | 363 } |
| 363 return false; | 364 return false; |
| 364 } | 365 } |
| 365 | 366 |
| 366 ASSERT(!this->IsUnion() && !that->IsUnion()); | 367 ASSERT(!this->IsUnion() && !that->IsUnion()); |
| 367 if (this->IsClass()) { | 368 if (this->IsClass()) { |
| 368 return that->IsClass() && *this->AsClass() == *that->AsClass(); | 369 return that->IsClass() && *this->AsClass() == *that->AsClass(); |
| 369 } | 370 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 382 TypeHandle type = Config::union_get(unioned, i); | 383 TypeHandle type = Config::union_get(unioned, i); |
| 383 if (this->Is(type)) return true; | 384 if (this->Is(type)) return true; |
| 384 } | 385 } |
| 385 return false; | 386 return false; |
| 386 } | 387 } |
| 387 | 388 |
| 388 | 389 |
| 389 // Get non-bitsets from this which are not subsumed by union, store at unioned, | 390 // Get non-bitsets from this which are not subsumed by union, store at unioned, |
| 390 // starting at index. Returns updated index. | 391 // starting at index. Returns updated index. |
| 391 template<class Config> | 392 template<class Config> |
| 392 int TypeImpl<Config>::ExtendUnion(UnionedHandle result, int current_size) { | 393 int TypeImpl<Config>::ExtendUnion( |
| 394 UnionedHandle result, TypeHandle type, int current_size) { |
| 393 int old_size = current_size; | 395 int old_size = current_size; |
| 394 if (this->IsClass() || this->IsConstant()) { | 396 if (type->IsClass() || type->IsConstant()) { |
| 395 if (!this->InUnion(result, old_size)) result->set(current_size++, this); | 397 if (!type->InUnion(result, old_size)) { |
| 396 } else if (this->IsUnion()) { | 398 Config::union_set(result, current_size++, type); |
| 397 UnionedHandle unioned = this->AsUnion(); | 399 } |
| 398 for (int i = 0; i < unioned->length(); ++i) { | 400 } else if (type->IsUnion()) { |
| 401 UnionedHandle unioned = type->AsUnion(); |
| 402 for (int i = 0; i < Config::union_length(unioned); ++i) { |
| 399 TypeHandle type = Config::union_get(unioned, i); | 403 TypeHandle type = Config::union_get(unioned, i); |
| 400 ASSERT(i == 0 || | 404 ASSERT(i == 0 || |
| 401 !(type->IsBitset() || type->Is(Config::union_get(unioned, 0)))); | 405 !(type->IsBitset() || type->Is(Config::union_get(unioned, 0)))); |
| 402 if (!type->IsBitset() && !type->InUnion(result, old_size)) { | 406 if (!type->IsBitset() && !type->InUnion(result, old_size)) { |
| 403 result->set(current_size++, *type); | 407 Config::union_set(result, current_size++, type); |
| 404 } | 408 } |
| 405 } | 409 } |
| 406 } | 410 } |
| 407 return current_size; | 411 return current_size; |
| 408 } | 412 } |
| 409 | 413 |
| 410 | 414 |
| 411 // Union is O(1) on simple bit unions, but O(n*m) on structured unions. | 415 // Union is O(1) on simple bit unions, but O(n*m) on structured unions. |
| 412 // TODO(rossberg): Should we use object sets somehow? Is it worth it? | 416 // TODO(rossberg): Should we use object sets somehow? Is it worth it? |
| 413 template<class Config> | 417 template<class Config> |
| (...skipping 12 matching lines...) Expand all Loading... |
| 426 | 430 |
| 427 // Semi-fast case: Unioned objects are neither involved nor produced. | 431 // Semi-fast case: Unioned objects are neither involved nor produced. |
| 428 if (!(type1->IsUnion() || type2->IsUnion())) { | 432 if (!(type1->IsUnion() || type2->IsUnion())) { |
| 429 if (type1->Is(type2)) return type2; | 433 if (type1->Is(type2)) return type2; |
| 430 if (type2->Is(type1)) return type1; | 434 if (type2->Is(type1)) return type1; |
| 431 } | 435 } |
| 432 | 436 |
| 433 // Slow case: may need to produce a Unioned object. | 437 // Slow case: may need to produce a Unioned object. |
| 434 int size = type1->IsBitset() || type2->IsBitset() ? 1 : 0; | 438 int size = type1->IsBitset() || type2->IsBitset() ? 1 : 0; |
| 435 if (!type1->IsBitset()) { | 439 if (!type1->IsBitset()) { |
| 436 size += (type1->IsUnion() ? type1->AsUnion()->length() : 1); | 440 size += (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1); |
| 437 } | 441 } |
| 438 if (!type2->IsBitset()) { | 442 if (!type2->IsBitset()) { |
| 439 size += (type2->IsUnion() ? type2->AsUnion()->length() : 1); | 443 size += (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1); |
| 440 } | 444 } |
| 441 ASSERT(size >= 2); | 445 ASSERT(size >= 2); |
| 442 UnionedHandle unioned = Config::union_create(size, region); | 446 UnionedHandle unioned = Config::union_create(size, region); |
| 443 size = 0; | 447 size = 0; |
| 444 | 448 |
| 445 int bitset = type1->GlbBitset() | type2->GlbBitset(); | 449 int bitset = type1->GlbBitset() | type2->GlbBitset(); |
| 446 if (bitset != kNone) unioned->set(size++, Config::from_bitset(bitset)); | 450 if (bitset != kNone) { |
| 447 size = type1->ExtendUnion(unioned, size); | 451 Config::union_set(unioned, size++, Config::from_bitset(bitset, region)); |
| 448 size = type2->ExtendUnion(unioned, size); | 452 } |
| 453 size = ExtendUnion(unioned, type1, size); |
| 454 size = ExtendUnion(unioned, type2, size); |
| 449 | 455 |
| 450 if (size == 1) { | 456 if (size == 1) { |
| 451 return Config::union_get(unioned, 0); | 457 return Config::union_get(unioned, 0); |
| 452 } else if (size == unioned->length()) { | 458 } else { |
| 459 Config::union_shrink(unioned, size); |
| 453 return Config::from_union(unioned); | 460 return Config::from_union(unioned); |
| 454 } | 461 } |
| 455 | |
| 456 // There was an overlap. Copy to smaller union. | |
| 457 UnionedHandle result = Config::union_create(size, region); | |
| 458 for (int i = 0; i < size; ++i) result->set(i, unioned->get(i)); | |
| 459 return Config::from_union(result); | |
| 460 } | 462 } |
| 461 | 463 |
| 462 | 464 |
| 463 // Get non-bitsets from this which are also in that, store at unioned, | 465 // Get non-bitsets from type which are also in other, store at unioned, |
| 464 // starting at index. Returns updated index. | 466 // starting at index. Returns updated index. |
| 465 template<class Config> | 467 template<class Config> |
| 466 int TypeImpl<Config>::ExtendIntersection( | 468 int TypeImpl<Config>::ExtendIntersection( |
| 467 UnionedHandle result, TypeHandle that, int current_size) { | 469 UnionedHandle result, TypeHandle type, TypeHandle other, int current_size) { |
| 468 int old_size = current_size; | 470 int old_size = current_size; |
| 469 if (this->IsClass() || this->IsConstant()) { | 471 if (type->IsClass() || type->IsConstant()) { |
| 470 if (this->Is(that) && !this->InUnion(result, old_size)) | 472 if (type->Is(other) && !type->InUnion(result, old_size)) { |
| 471 result->set(current_size++, this); | 473 Config::union_set(result, current_size++, type); |
| 472 } else if (this->IsUnion()) { | 474 } |
| 473 UnionedHandle unioned = this->AsUnion(); | 475 } else if (type->IsUnion()) { |
| 474 for (int i = 0; i < unioned->length(); ++i) { | 476 UnionedHandle unioned = type->AsUnion(); |
| 477 for (int i = 0; i < Config::union_length(unioned); ++i) { |
| 475 TypeHandle type = Config::union_get(unioned, i); | 478 TypeHandle type = Config::union_get(unioned, i); |
| 476 ASSERT(i == 0 || | 479 ASSERT(i == 0 || |
| 477 !(type->IsBitset() || type->Is(Config::union_get(unioned, 0)))); | 480 !(type->IsBitset() || type->Is(Config::union_get(unioned, 0)))); |
| 478 if (!type->IsBitset() && type->Is(that) && | 481 if (!type->IsBitset() && type->Is(other) && |
| 479 !type->InUnion(result, old_size)) { | 482 !type->InUnion(result, old_size)) { |
| 480 result->set(current_size++, *type); | 483 Config::union_set(result, current_size++, type); |
| 481 } | 484 } |
| 482 } | 485 } |
| 483 } | 486 } |
| 484 return current_size; | 487 return current_size; |
| 485 } | 488 } |
| 486 | 489 |
| 487 | 490 |
| 488 // Intersection is O(1) on simple bit unions, but O(n*m) on structured unions. | 491 // Intersection is O(1) on simple bit unions, but O(n*m) on structured unions. |
| 489 // TODO(rossberg): Should we use object sets somehow? Is it worth it? | 492 // TODO(rossberg): Should we use object sets somehow? Is it worth it? |
| 490 template<class Config> | 493 template<class Config> |
| (...skipping 12 matching lines...) Expand all Loading... |
| 503 | 506 |
| 504 // Semi-fast case: Unioned objects are neither involved nor produced. | 507 // Semi-fast case: Unioned objects are neither involved nor produced. |
| 505 if (!(type1->IsUnion() || type2->IsUnion())) { | 508 if (!(type1->IsUnion() || type2->IsUnion())) { |
| 506 if (type1->Is(type2)) return type1; | 509 if (type1->Is(type2)) return type1; |
| 507 if (type2->Is(type1)) return type2; | 510 if (type2->Is(type1)) return type2; |
| 508 } | 511 } |
| 509 | 512 |
| 510 // Slow case: may need to produce a Unioned object. | 513 // Slow case: may need to produce a Unioned object. |
| 511 int size = 0; | 514 int size = 0; |
| 512 if (!type1->IsBitset()) { | 515 if (!type1->IsBitset()) { |
| 513 size = (type1->IsUnion() ? type1->AsUnion()->length() : 2); | 516 size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 2); |
| 514 } | 517 } |
| 515 if (!type2->IsBitset()) { | 518 if (!type2->IsBitset()) { |
| 516 int size2 = (type2->IsUnion() ? type2->AsUnion()->length() : 2); | 519 int size2 = (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 2); |
| 517 size = (size == 0 ? size2 : Min(size, size2)); | 520 size = (size == 0 ? size2 : Min(size, size2)); |
| 518 } | 521 } |
| 519 ASSERT(size >= 2); | 522 ASSERT(size >= 2); |
| 520 UnionedHandle unioned = Config::union_create(size, region); | 523 UnionedHandle unioned = Config::union_create(size, region); |
| 521 size = 0; | 524 size = 0; |
| 522 | 525 |
| 523 int bitset = type1->GlbBitset() & type2->GlbBitset(); | 526 int bitset = type1->GlbBitset() & type2->GlbBitset(); |
| 524 if (bitset != kNone) unioned->set(size++, Config::from_bitset(bitset)); | 527 if (bitset != kNone) { |
| 525 size = type1->ExtendIntersection(unioned, type2, size); | 528 Config::union_set(unioned, size++, Config::from_bitset(bitset, region)); |
| 526 size = type2->ExtendIntersection(unioned, type1, size); | 529 } |
| 530 size = ExtendIntersection(unioned, type1, type2, size); |
| 531 size = ExtendIntersection(unioned, type2, type1, size); |
| 527 | 532 |
| 528 if (size == 0) { | 533 if (size == 0) { |
| 529 return None(region); | 534 return None(region); |
| 530 } else if (size == 1) { | 535 } else if (size == 1) { |
| 531 return Config::union_get(unioned, 0); | 536 return Config::union_get(unioned, 0); |
| 532 } else if (size == unioned->length()) { | 537 } else { |
| 538 Config::union_shrink(unioned, size); |
| 533 return Config::from_union(unioned); | 539 return Config::from_union(unioned); |
| 534 } | 540 } |
| 541 } |
| 535 | 542 |
| 536 // There were dropped cases. Copy to smaller union. | 543 |
| 537 UnionedHandle result = Config::union_create(size, region); | 544 template<class Config> |
| 538 for (int i = 0; i < size; ++i) result->set(i, unioned->get(i)); | 545 template<class OtherType> |
| 539 return Config::from_union(result); | 546 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert( |
| 547 typename OtherType::TypeHandle type, Region* region) { |
| 548 if (type->IsBitset()) { |
| 549 return Config::from_bitset(type->AsBitset(), region); |
| 550 } else if (type->IsClass()) { |
| 551 return Config::from_class(type->AsClass(), region); |
| 552 } else if (type->IsConstant()) { |
| 553 return Config::from_constant(type->AsConstant(), region); |
| 554 } else { |
| 555 ASSERT(type->IsUnion()); |
| 556 typename OtherType::UnionedHandle unioned = type->AsUnion(); |
| 557 int length = OtherType::UnionLength(unioned); |
| 558 UnionedHandle new_unioned = Config::union_create(length, region); |
| 559 for (int i = 0; i < length; ++i) { |
| 560 Config::union_set(new_unioned, i, |
| 561 Convert<OtherType>(OtherType::UnionGet(unioned, i), region)); |
| 562 } |
| 563 return Config::from_union(new_unioned); |
| 564 } |
| 540 } | 565 } |
| 541 | 566 |
| 542 | 567 |
| 543 // TODO(rossberg): this does not belong here. | 568 // TODO(rossberg): this does not belong here. |
| 544 Representation Representation::FromType(Handle<Type> type) { | 569 Representation Representation::FromType(Type* type) { |
| 545 if (type->Is(Type::None())) return Representation::None(); | 570 if (type->Is(Type::None())) return Representation::None(); |
| 546 if (type->Is(Type::Smi())) return Representation::Smi(); | 571 if (type->Is(Type::Smi())) return Representation::Smi(); |
| 547 if (type->Is(Type::Signed32())) return Representation::Integer32(); | 572 if (type->Is(Type::Signed32())) return Representation::Integer32(); |
| 548 if (type->Is(Type::Number())) return Representation::Double(); | 573 if (type->Is(Type::Number())) return Representation::Double(); |
| 549 return Representation::Tagged(); | 574 return Representation::Tagged(); |
| 550 } | 575 } |
| 551 | 576 |
| 552 | 577 |
| 553 #ifdef OBJECT_PRINT | 578 #ifdef OBJECT_PRINT |
| 554 template<class Config> | 579 template<class Config> |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant())); | 619 PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant())); |
| 595 Config::from_bitset(this->LubBitset())->TypePrint(out); | 620 Config::from_bitset(this->LubBitset())->TypePrint(out); |
| 596 PrintF(")"); | 621 PrintF(")"); |
| 597 } else if (this->IsClass()) { | 622 } else if (this->IsClass()) { |
| 598 PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass())); | 623 PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass())); |
| 599 Config::from_bitset(this->LubBitset())->TypePrint(out); | 624 Config::from_bitset(this->LubBitset())->TypePrint(out); |
| 600 PrintF(")"); | 625 PrintF(")"); |
| 601 } else if (this->IsUnion()) { | 626 } else if (this->IsUnion()) { |
| 602 PrintF(out, "("); | 627 PrintF(out, "("); |
| 603 UnionedHandle unioned = this->AsUnion(); | 628 UnionedHandle unioned = this->AsUnion(); |
| 604 for (int i = 0; i < unioned->length(); ++i) { | 629 for (int i = 0; i < Config::union_length(unioned); ++i) { |
| 605 TypeHandle type_i = Config::union_get(unioned, i); | 630 TypeHandle type_i = Config::union_get(unioned, i); |
| 606 if (i > 0) PrintF(out, " | "); | 631 if (i > 0) PrintF(out, " | "); |
| 607 type_i->TypePrint(out); | 632 type_i->TypePrint(out); |
| 608 } | 633 } |
| 609 PrintF(out, ")"); | 634 PrintF(out, ")"); |
| 610 } | 635 } |
| 611 } | 636 } |
| 612 #endif | 637 #endif |
| 613 | 638 |
| 614 | 639 |
| 640 template class TypeImpl<ZoneTypeConfig>; |
| 641 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>; |
| 642 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>; |
| 643 |
| 615 template class TypeImpl<HeapTypeConfig>; | 644 template class TypeImpl<HeapTypeConfig>; |
| 616 template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>; | 645 template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>; |
| 617 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; | 646 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; |
| 618 | 647 |
| 648 template TypeImpl<ZoneTypeConfig>::TypeHandle |
| 649 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( |
| 650 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); |
| 651 template TypeImpl<HeapTypeConfig>::TypeHandle |
| 652 TypeImpl<HeapTypeConfig>::Convert<Type>( |
| 653 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); |
| 654 |
| 619 | 655 |
| 620 } } // namespace v8::internal | 656 } } // namespace v8::internal |
| OLD | NEW |