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 |