| OLD | NEW |
| 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 "src/types.h" | 5 #include "src/types.h" |
| 6 | 6 |
| 7 #include "src/string-stream.h" | 7 #include "src/string-stream.h" |
| 8 #include "src/types-inl.h" | 8 #include "src/types-inl.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 DisallowHeapAllocation no_allocation; | 255 DisallowHeapAllocation no_allocation; |
| 256 | 256 |
| 257 // Fast path for bitsets. | 257 // Fast path for bitsets. |
| 258 if (this->IsNone()) return true; | 258 if (this->IsNone()) return true; |
| 259 if (that->IsBitset()) { | 259 if (that->IsBitset()) { |
| 260 return (BitsetType::Lub(this) | that->AsBitset()) == that->AsBitset(); | 260 return (BitsetType::Lub(this) | that->AsBitset()) == that->AsBitset(); |
| 261 } | 261 } |
| 262 if (this->IsBitset() && SEMANTIC(this->AsBitset()) == BitsetType::kNone) { | 262 if (this->IsBitset() && SEMANTIC(this->AsBitset()) == BitsetType::kNone) { |
| 263 // Bitsets only have non-bitset supertypes along the representation axis. | 263 // Bitsets only have non-bitset supertypes along the representation axis. |
| 264 int that_bitset = that->BitsetGlb(); | 264 int that_bitset = that->BitsetGlb(); |
| 265 return (this->AsBitset() | that_bitset) == that_bitset; | 265 return (BitsetType::Is(this->AsBitset(), that_bitset)); |
| 266 } | 266 } |
| 267 | 267 |
| 268 if (that->IsClass()) { | 268 if (that->IsClass()) { |
| 269 return this->IsClass() | 269 return this->IsClass() |
| 270 && *this->AsClass()->Map() == *that->AsClass()->Map() | 270 && *this->AsClass()->Map() == *that->AsClass()->Map() |
| 271 && ((Config::is_class(that) && Config::is_class(this)) || | 271 && ((Config::is_class(that) && Config::is_class(this)) || |
| 272 BitsetType::New(this->BitsetLub())->Is( | 272 BitsetType::New(this->BitsetLub())->Is( |
| 273 BitsetType::New(that->BitsetLub()))); | 273 BitsetType::New(that->BitsetLub()))); |
| 274 } | 274 } |
| 275 if (that->IsConstant()) { | 275 if (that->IsConstant()) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 306 if (this->IsUnion()) { | 306 if (this->IsUnion()) { |
| 307 UnionHandle unioned = handle(this->AsUnion()); | 307 UnionHandle unioned = handle(this->AsUnion()); |
| 308 for (int i = 0; i < unioned->Length(); ++i) { | 308 for (int i = 0; i < unioned->Length(); ++i) { |
| 309 if (!unioned->Get(i)->Is(that)) return false; | 309 if (!unioned->Get(i)->Is(that)) return false; |
| 310 } | 310 } |
| 311 return true; | 311 return true; |
| 312 } | 312 } |
| 313 | 313 |
| 314 // T <= (T1 \/ ... \/ Tn) <=> (T <= T1) \/ ... \/ (T <= Tn) | 314 // T <= (T1 \/ ... \/ Tn) <=> (T <= T1) \/ ... \/ (T <= Tn) |
| 315 // (iff T is not a union) | 315 // (iff T is not a union) |
| 316 ASSERT(!this->IsUnion()); | 316 ASSERT(!this->IsUnion() && that->IsUnion()); |
| 317 if (that->IsUnion()) { | 317 UnionHandle unioned = handle(that->AsUnion()); |
| 318 UnionHandle unioned = handle(that->AsUnion()); | 318 for (int i = 0; i < unioned->Length(); ++i) { |
| 319 for (int i = 0; i < unioned->Length(); ++i) { | 319 if (this->Is(unioned->Get(i))) return true; |
| 320 if (this->Is(unioned->Get(i))) return true; | 320 if (this->IsBitset()) break; // Fast fail, only first field is a bitset. |
| 321 if (this->IsBitset()) break; // Fast fail, only first field is a bitset. | |
| 322 } | |
| 323 return false; | |
| 324 } | 321 } |
| 325 | |
| 326 return false; | 322 return false; |
| 327 } | 323 } |
| 328 | 324 |
| 329 | 325 |
| 330 template<class Config> | 326 template<class Config> |
| 331 bool TypeImpl<Config>::NowIs(TypeImpl* that) { | 327 bool TypeImpl<Config>::NowIs(TypeImpl* that) { |
| 332 DisallowHeapAllocation no_allocation; | 328 DisallowHeapAllocation no_allocation; |
| 333 | 329 |
| 334 // TODO(rossberg): this is incorrect for | 330 // TODO(rossberg): this is incorrect for |
| 335 // Union(Constant(V), T)->NowIs(Class(M)) | 331 // Union(Constant(V), T)->NowIs(Class(M)) |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn) | 371 // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn) |
| 376 if (that->IsUnion()) { | 372 if (that->IsUnion()) { |
| 377 UnionHandle unioned = handle(that->AsUnion()); | 373 UnionHandle unioned = handle(that->AsUnion()); |
| 378 for (int i = 0; i < unioned->Length(); ++i) { | 374 for (int i = 0; i < unioned->Length(); ++i) { |
| 379 if (this->Maybe(unioned->Get(i))) return true; | 375 if (this->Maybe(unioned->Get(i))) return true; |
| 380 } | 376 } |
| 381 return false; | 377 return false; |
| 382 } | 378 } |
| 383 | 379 |
| 384 ASSERT(!this->IsUnion() && !that->IsUnion()); | 380 ASSERT(!this->IsUnion() && !that->IsUnion()); |
| 385 if (this->IsBitset()) { | 381 if (this->IsBitset() || that->IsBitset()) { |
| 386 return BitsetType::IsInhabited(this->AsBitset() & that->BitsetLub()); | 382 return BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub()); |
| 387 } | |
| 388 if (that->IsBitset()) { | |
| 389 return BitsetType::IsInhabited(this->BitsetLub() & that->AsBitset()); | |
| 390 } | 383 } |
| 391 if (this->IsClass()) { | 384 if (this->IsClass()) { |
| 392 return that->IsClass() | 385 return that->IsClass() |
| 393 && *this->AsClass()->Map() == *that->AsClass()->Map(); | 386 && *this->AsClass()->Map() == *that->AsClass()->Map(); |
| 394 } | 387 } |
| 395 if (this->IsConstant()) { | 388 if (this->IsConstant()) { |
| 396 return that->IsConstant() | 389 return that->IsConstant() |
| 397 && *this->AsConstant()->Value() == *that->AsConstant()->Value(); | 390 && *this->AsConstant()->Value() == *that->AsConstant()->Value(); |
| 398 } | 391 } |
| 399 if (this->IsContext()) { | 392 if (this->IsContext()) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 } | 427 } |
| 435 } | 428 } |
| 436 return true; | 429 return true; |
| 437 } | 430 } |
| 438 | 431 |
| 439 | 432 |
| 440 // ----------------------------------------------------------------------------- | 433 // ----------------------------------------------------------------------------- |
| 441 // Union and intersection | 434 // Union and intersection |
| 442 | 435 |
| 443 template<class Config> | 436 template<class Config> |
| 444 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Narrow( | 437 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Rebound( |
| 445 int bitset, Region* region) { | 438 int bitset, Region* region) { |
| 446 TypeHandle bound = BitsetType::New(bitset, region); | 439 TypeHandle bound = BitsetType::New(bitset, region); |
| 447 if (this->IsClass()) { | 440 if (this->IsClass()) { |
| 448 return ClassType::New(this->AsClass()->Map(), bound, region); | 441 return ClassType::New(this->AsClass()->Map(), bound, region); |
| 449 } else if (this->IsConstant()) { | 442 } else if (this->IsConstant()) { |
| 450 return ConstantType::New(this->AsConstant()->Value(), bound, region); | 443 return ConstantType::New(this->AsConstant()->Value(), bound, region); |
| 451 } else if (this->IsContext()) { | 444 } else if (this->IsContext()) { |
| 452 return ContextType::New(this->AsContext()->Outer(), bound, region); | 445 return ContextType::New(this->AsContext()->Outer(), bound, region); |
| 453 } else if (this->IsArray()) { | 446 } else if (this->IsArray()) { |
| 454 return ArrayType::New(this->AsArray()->Element(), bound, region); | 447 return ArrayType::New(this->AsArray()->Element(), bound, region); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 int i = type->IndexInUnion(new_bound, result, old_size); | 541 int i = type->IndexInUnion(new_bound, result, old_size); |
| 549 if (i == -1) { | 542 if (i == -1) { |
| 550 i = size++; | 543 i = size++; |
| 551 } else if (result->Get(i)->IsBitset()) { | 544 } else if (result->Get(i)->IsBitset()) { |
| 552 return size; // Already fully subsumed. | 545 return size; // Already fully subsumed. |
| 553 } else { | 546 } else { |
| 554 int type_i_bound = result->Get(i)->BitsetLub(); | 547 int type_i_bound = result->Get(i)->BitsetLub(); |
| 555 new_bound |= type_i_bound; | 548 new_bound |= type_i_bound; |
| 556 if (new_bound == type_i_bound) return size; | 549 if (new_bound == type_i_bound) return size; |
| 557 } | 550 } |
| 558 if (new_bound != old_bound) type = type->Narrow(new_bound, region); | 551 if (new_bound != old_bound) type = type->Rebound(new_bound, region); |
| 559 result->Set(i, type); | 552 result->Set(i, type); |
| 560 } | 553 } |
| 561 } | 554 } |
| 562 return size; | 555 return size; |
| 563 } | 556 } |
| 564 | 557 |
| 565 | 558 |
| 566 // If bitset is subsumed by another entry in the result, remove it. | 559 // If bitset is subsumed by another entry in the result, remove it. |
| 567 // (Only bitsets with empty semantic axis can be subtypes of non-bitsets.) | 560 // (Only bitsets with empty semantic axis can be subtypes of non-bitsets.) |
| 568 template<class Config> | 561 template<class Config> |
| 569 int TypeImpl<Config>::NormalizeUnion(UnionHandle result, int size, int bitset) { | 562 int TypeImpl<Config>::NormalizeUnion(UnionHandle result, int size, int bitset) { |
| 570 if (bitset != BitsetType::kNone && SEMANTIC(bitset) == BitsetType::kNone) { | 563 if (bitset != BitsetType::kNone && SEMANTIC(bitset) == BitsetType::kNone) { |
| 571 for (int i = 1; i < size; ++i) { | 564 for (int i = 1; i < size; ++i) { |
| 572 int glb = result->Get(i)->BitsetGlb(); | 565 int glb = result->Get(i)->BitsetGlb(); |
| 573 if ((bitset | glb) == glb) { | 566 if (BitsetType::Is(bitset, glb)) { |
| 574 for (int j = 1; j < size; ++j) { | 567 for (int j = 1; j < size; ++j) { |
| 575 result->Set(j - 1, result->Get(j)); | 568 result->Set(j - 1, result->Get(j)); |
| 576 } | 569 } |
| 577 --size; | 570 --size; |
| 578 break; | 571 break; |
| 579 } | 572 } |
| 580 } | 573 } |
| 581 } | 574 } |
| 582 return size; | 575 return size; |
| 583 } | 576 } |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 968 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; | 961 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; |
| 969 | 962 |
| 970 template TypeImpl<ZoneTypeConfig>::TypeHandle | 963 template TypeImpl<ZoneTypeConfig>::TypeHandle |
| 971 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( | 964 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( |
| 972 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); | 965 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); |
| 973 template TypeImpl<HeapTypeConfig>::TypeHandle | 966 template TypeImpl<HeapTypeConfig>::TypeHandle |
| 974 TypeImpl<HeapTypeConfig>::Convert<Type>( | 967 TypeImpl<HeapTypeConfig>::Convert<Type>( |
| 975 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); | 968 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); |
| 976 | 969 |
| 977 } } // namespace v8::internal | 970 } } // namespace v8::internal |
| OLD | NEW |