| 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 "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 { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 } else if (type->IsClass()) { | 141 } else if (type->IsClass()) { |
| 142 int bitset = Config::lub_bitset(type); | 142 int bitset = Config::lub_bitset(type); |
| 143 return bitset ? bitset : Lub(*type->AsClass()->Map()); | 143 return bitset ? bitset : Lub(*type->AsClass()->Map()); |
| 144 } else if (type->IsConstant()) { | 144 } else if (type->IsConstant()) { |
| 145 int bitset = Config::lub_bitset(type); | 145 int bitset = Config::lub_bitset(type); |
| 146 return bitset ? bitset : Lub(*type->AsConstant()->Value()); | 146 return bitset ? bitset : Lub(*type->AsConstant()->Value()); |
| 147 } else if (type->IsArray()) { | 147 } else if (type->IsArray()) { |
| 148 return kArray; | 148 return kArray; |
| 149 } else if (type->IsFunction()) { | 149 } else if (type->IsFunction()) { |
| 150 return kFunction; | 150 return kFunction; |
| 151 } else if (type->IsContext()) { |
| 152 return kInternal & kTaggedPtr; |
| 151 } else { | 153 } else { |
| 152 UNREACHABLE(); | 154 UNREACHABLE(); |
| 153 return kNone; | 155 return kNone; |
| 154 } | 156 } |
| 155 } | 157 } |
| 156 | 158 |
| 157 | 159 |
| 158 template<class Config> | 160 template<class Config> |
| 159 int TypeImpl<Config>::BitsetType::Lub(i::Object* value) { | 161 int TypeImpl<Config>::BitsetType::Lub(i::Object* value) { |
| 160 DisallowHeapAllocation no_allocation; | 162 DisallowHeapAllocation no_allocation; |
| 161 if (value->IsSmi()) return kSignedSmall & kTaggedInt; | 163 if (value->IsNumber()) { |
| 162 i::Map* map = i::HeapObject::cast(value)->map(); | 164 return Lub(value->Number()) & (value->IsSmi() ? kTaggedInt : kTaggedPtr); |
| 163 if (map->instance_type() == HEAP_NUMBER_TYPE) { | |
| 164 int32_t i; | |
| 165 uint32_t u; | |
| 166 return kTaggedPtr & ( | |
| 167 value->ToInt32(&i) ? (Smi::IsValid(i) ? kSignedSmall : kOtherSigned32) : | |
| 168 value->ToUint32(&u) ? kUnsigned32 : kFloat); | |
| 169 } | 165 } |
| 170 return Lub(map); | 166 return Lub(i::HeapObject::cast(value)->map()); |
| 171 } | 167 } |
| 172 | 168 |
| 173 | 169 |
| 170 template<class Config> |
| 171 int TypeImpl<Config>::BitsetType::Lub(double value) { |
| 172 DisallowHeapAllocation no_allocation; |
| 173 if (i::IsMinusZero(value)) return kMinusZero; |
| 174 if (std::isnan(value)) return kNaN; |
| 175 if (IsUint32Double(value)) return Lub(FastD2UI(value)); |
| 176 if (IsInt32Double(value)) return Lub(FastD2I(value)); |
| 177 return kOtherNumber; |
| 178 } |
| 179 |
| 180 |
| 181 template<class Config> |
| 182 int TypeImpl<Config>::BitsetType::Lub(int32_t value) { |
| 183 if (value >= 0x40000000) { |
| 184 return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall; |
| 185 } |
| 186 if (value >= 0) return kUnsignedSmall; |
| 187 if (value >= -0x40000000) return kOtherSignedSmall; |
| 188 return i::SmiValuesAre31Bits() ? kOtherSigned32 : kOtherSignedSmall; |
| 189 } |
| 190 |
| 191 |
| 192 template<class Config> |
| 193 int TypeImpl<Config>::BitsetType::Lub(uint32_t value) { |
| 194 DisallowHeapAllocation no_allocation; |
| 195 if (value >= 0x80000000u) return kOtherUnsigned32; |
| 196 if (value >= 0x40000000u) { |
| 197 return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall; |
| 198 } |
| 199 return kUnsignedSmall; |
| 200 } |
| 201 |
| 202 |
| 174 template<class Config> | 203 template<class Config> |
| 175 int TypeImpl<Config>::BitsetType::Lub(i::Map* map) { | 204 int TypeImpl<Config>::BitsetType::Lub(i::Map* map) { |
| 176 DisallowHeapAllocation no_allocation; | 205 DisallowHeapAllocation no_allocation; |
| 177 switch (map->instance_type()) { | 206 switch (map->instance_type()) { |
| 178 case STRING_TYPE: | 207 case STRING_TYPE: |
| 179 case ASCII_STRING_TYPE: | 208 case ASCII_STRING_TYPE: |
| 180 case CONS_STRING_TYPE: | 209 case CONS_STRING_TYPE: |
| 181 case CONS_ASCII_STRING_TYPE: | 210 case CONS_ASCII_STRING_TYPE: |
| 182 case SLICED_STRING_TYPE: | 211 case SLICED_STRING_TYPE: |
| 183 case SLICED_ASCII_STRING_TYPE: | 212 case SLICED_ASCII_STRING_TYPE: |
| (...skipping 20 matching lines...) Expand all Loading... |
| 204 if (map == heap->the_hole_map()) return kAny; // TODO(rossberg): kNone? | 233 if (map == heap->the_hole_map()) return kAny; // TODO(rossberg): kNone? |
| 205 if (map == heap->null_map()) return kNull; | 234 if (map == heap->null_map()) return kNull; |
| 206 if (map == heap->boolean_map()) return kBoolean; | 235 if (map == heap->boolean_map()) return kBoolean; |
| 207 ASSERT(map == heap->uninitialized_map() || | 236 ASSERT(map == heap->uninitialized_map() || |
| 208 map == heap->no_interceptor_result_sentinel_map() || | 237 map == heap->no_interceptor_result_sentinel_map() || |
| 209 map == heap->termination_exception_map() || | 238 map == heap->termination_exception_map() || |
| 210 map == heap->arguments_marker_map()); | 239 map == heap->arguments_marker_map()); |
| 211 return kInternal & kTaggedPtr; | 240 return kInternal & kTaggedPtr; |
| 212 } | 241 } |
| 213 case HEAP_NUMBER_TYPE: | 242 case HEAP_NUMBER_TYPE: |
| 214 return kFloat & kTaggedPtr; | 243 return kNumber & kTaggedPtr; |
| 215 case JS_VALUE_TYPE: | 244 case JS_VALUE_TYPE: |
| 216 case JS_DATE_TYPE: | 245 case JS_DATE_TYPE: |
| 217 case JS_OBJECT_TYPE: | 246 case JS_OBJECT_TYPE: |
| 218 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: | 247 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: |
| 219 case JS_GENERATOR_OBJECT_TYPE: | 248 case JS_GENERATOR_OBJECT_TYPE: |
| 220 case JS_MODULE_TYPE: | 249 case JS_MODULE_TYPE: |
| 221 case JS_GLOBAL_OBJECT_TYPE: | 250 case JS_GLOBAL_OBJECT_TYPE: |
| 222 case JS_BUILTINS_OBJECT_TYPE: | 251 case JS_BUILTINS_OBJECT_TYPE: |
| 223 case JS_GLOBAL_PROXY_TYPE: | 252 case JS_GLOBAL_PROXY_TYPE: |
| 224 case JS_ARRAY_BUFFER_TYPE: | 253 case JS_ARRAY_BUFFER_TYPE: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 247 // We treat it as a kind of type variable whose upper bound is Any. | 276 // We treat it as a kind of type variable whose upper bound is Any. |
| 248 // TODO(rossberg): for caching of CompareNilIC stubs to work correctly, | 277 // TODO(rossberg): for caching of CompareNilIC stubs to work correctly, |
| 249 // we must exclude Undetectable here. This makes no sense, really, | 278 // we must exclude Undetectable here. This makes no sense, really, |
| 250 // because it means that the template isn't actually parametric. | 279 // because it means that the template isn't actually parametric. |
| 251 // Also, it doesn't apply elsewhere. 8-( | 280 // Also, it doesn't apply elsewhere. 8-( |
| 252 // We ought to find a cleaner solution for compiling stubs parameterised | 281 // We ought to find a cleaner solution for compiling stubs parameterised |
| 253 // over type or class variables, esp ones with bounds... | 282 // over type or class variables, esp ones with bounds... |
| 254 return kDetectable; | 283 return kDetectable; |
| 255 case DECLARED_ACCESSOR_INFO_TYPE: | 284 case DECLARED_ACCESSOR_INFO_TYPE: |
| 256 case EXECUTABLE_ACCESSOR_INFO_TYPE: | 285 case EXECUTABLE_ACCESSOR_INFO_TYPE: |
| 286 case SHARED_FUNCTION_INFO_TYPE: |
| 257 case ACCESSOR_PAIR_TYPE: | 287 case ACCESSOR_PAIR_TYPE: |
| 258 case FIXED_ARRAY_TYPE: | 288 case FIXED_ARRAY_TYPE: |
| 259 case FOREIGN_TYPE: | 289 case FOREIGN_TYPE: |
| 260 return kInternal & kTaggedPtr; | 290 return kInternal & kTaggedPtr; |
| 261 default: | 291 default: |
| 262 UNREACHABLE(); | 292 UNREACHABLE(); |
| 263 return kNone; | 293 return kNone; |
| 264 } | 294 } |
| 265 } | 295 } |
| 266 | 296 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 289 } | 319 } |
| 290 | 320 |
| 291 if (that->IsClass()) { | 321 if (that->IsClass()) { |
| 292 return this->IsClass() | 322 return this->IsClass() |
| 293 && *this->AsClass()->Map() == *that->AsClass()->Map(); | 323 && *this->AsClass()->Map() == *that->AsClass()->Map(); |
| 294 } | 324 } |
| 295 if (that->IsConstant()) { | 325 if (that->IsConstant()) { |
| 296 return this->IsConstant() | 326 return this->IsConstant() |
| 297 && *this->AsConstant()->Value() == *that->AsConstant()->Value(); | 327 && *this->AsConstant()->Value() == *that->AsConstant()->Value(); |
| 298 } | 328 } |
| 329 if (that->IsContext()) { |
| 330 return this->IsContext() |
| 331 && this->AsContext()->Outer()->Equals(that->AsContext()->Outer()); |
| 332 } |
| 299 if (that->IsArray()) { | 333 if (that->IsArray()) { |
| 300 return this->IsArray() | 334 return this->IsArray() |
| 301 && this->AsArray()->Element()->Equals(that->AsArray()->Element()); | 335 && this->AsArray()->Element()->Equals(that->AsArray()->Element()); |
| 302 } | 336 } |
| 303 if (that->IsFunction()) { | 337 if (that->IsFunction()) { |
| 304 // We currently do not allow for any variance here, in order to keep | 338 // We currently do not allow for any variance here, in order to keep |
| 305 // Union and Intersect operations simple. | 339 // Union and Intersect operations simple. |
| 306 if (!this->IsFunction()) return false; | 340 if (!this->IsFunction()) return false; |
| 307 FunctionType* this_fun = this->AsFunction(); | 341 FunctionType* this_fun = this->AsFunction(); |
| 308 FunctionType* that_fun = that->AsFunction(); | 342 FunctionType* that_fun = that->AsFunction(); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 return BitsetType::IsInhabited(this->BitsetLub() & that->AsBitset()); | 438 return BitsetType::IsInhabited(this->BitsetLub() & that->AsBitset()); |
| 405 } | 439 } |
| 406 if (this->IsClass()) { | 440 if (this->IsClass()) { |
| 407 return that->IsClass() | 441 return that->IsClass() |
| 408 && *this->AsClass()->Map() == *that->AsClass()->Map(); | 442 && *this->AsClass()->Map() == *that->AsClass()->Map(); |
| 409 } | 443 } |
| 410 if (this->IsConstant()) { | 444 if (this->IsConstant()) { |
| 411 return that->IsConstant() | 445 return that->IsConstant() |
| 412 && *this->AsConstant()->Value() == *that->AsConstant()->Value(); | 446 && *this->AsConstant()->Value() == *that->AsConstant()->Value(); |
| 413 } | 447 } |
| 448 if (this->IsContext()) { |
| 449 return this->Equals(that); |
| 450 } |
| 414 if (this->IsArray()) { | 451 if (this->IsArray()) { |
| 415 // There is no variance! | 452 // There is no variance! |
| 416 return this->Equals(that); | 453 return this->Equals(that); |
| 417 } | 454 } |
| 418 if (this->IsFunction()) { | 455 if (this->IsFunction()) { |
| 419 // There is no variance! | 456 // There is no variance! |
| 420 return this->Equals(that); | 457 return this->Equals(that); |
| 421 } | 458 } |
| 422 | 459 |
| 423 return false; | 460 return false; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 for (int i = 0; i < unioned->Length(); ++i) { | 493 for (int i = 0; i < unioned->Length(); ++i) { |
| 457 TypeHandle type = unioned->Get(i); | 494 TypeHandle type = unioned->Get(i); |
| 458 ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0)))); | 495 ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0)))); |
| 459 if (!type->IsBitset() && !type->InUnion(result, old_size)) { | 496 if (!type->IsBitset() && !type->InUnion(result, old_size)) { |
| 460 result->Set(current_size++, type); | 497 result->Set(current_size++, type); |
| 461 } | 498 } |
| 462 } | 499 } |
| 463 } else if (!type->IsBitset()) { | 500 } else if (!type->IsBitset()) { |
| 464 // For all structural types, subtyping implies equivalence. | 501 // For all structural types, subtyping implies equivalence. |
| 465 ASSERT(type->IsClass() || type->IsConstant() || | 502 ASSERT(type->IsClass() || type->IsConstant() || |
| 466 type->IsArray() || type->IsFunction()); | 503 type->IsArray() || type->IsFunction() || |
| 504 type->IsContext()); |
| 467 if (!type->InUnion(result, old_size)) { | 505 if (!type->InUnion(result, old_size)) { |
| 468 result->Set(current_size++, type); | 506 result->Set(current_size++, type); |
| 469 } | 507 } |
| 470 } | 508 } |
| 471 return current_size; | 509 return current_size; |
| 472 } | 510 } |
| 473 | 511 |
| 474 | 512 |
| 475 // Union is O(1) on simple bit unions, but O(n*m) on structured unions. | 513 // Union is O(1) on simple bit unions, but O(n*m) on structured unions. |
| 476 template<class Config> | 514 template<class Config> |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 TypeHandle type = unioned->Get(i); | 570 TypeHandle type = unioned->Get(i); |
| 533 ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0)))); | 571 ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0)))); |
| 534 if (!type->IsBitset() && type->Is(other) && | 572 if (!type->IsBitset() && type->Is(other) && |
| 535 !type->InUnion(result, old_size)) { | 573 !type->InUnion(result, old_size)) { |
| 536 result->Set(current_size++, type); | 574 result->Set(current_size++, type); |
| 537 } | 575 } |
| 538 } | 576 } |
| 539 } else if (!type->IsBitset()) { | 577 } else if (!type->IsBitset()) { |
| 540 // For all structural types, subtyping implies equivalence. | 578 // For all structural types, subtyping implies equivalence. |
| 541 ASSERT(type->IsClass() || type->IsConstant() || | 579 ASSERT(type->IsClass() || type->IsConstant() || |
| 542 type->IsArray() || type->IsFunction()); | 580 type->IsArray() || type->IsFunction() || type->IsContext()); |
| 543 if (type->Is(other) && !type->InUnion(result, old_size)) { | 581 if (type->Is(other) && !type->InUnion(result, old_size)) { |
| 544 result->Set(current_size++, type); | 582 result->Set(current_size++, type); |
| 545 } | 583 } |
| 546 } | 584 } |
| 547 return current_size; | 585 return current_size; |
| 548 } | 586 } |
| 549 | 587 |
| 550 | 588 |
| 551 // Intersection is O(1) on simple bit unions, but O(n*m) on structured unions. | 589 // Intersection is O(1) on simple bit unions, but O(n*m) on structured unions. |
| 552 template<class Config> | 590 template<class Config> |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 template<class Config> | 639 template<class Config> |
| 602 template<class OtherType> | 640 template<class OtherType> |
| 603 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert( | 641 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert( |
| 604 typename OtherType::TypeHandle type, Region* region) { | 642 typename OtherType::TypeHandle type, Region* region) { |
| 605 if (type->IsBitset()) { | 643 if (type->IsBitset()) { |
| 606 return BitsetType::New(type->AsBitset(), region); | 644 return BitsetType::New(type->AsBitset(), region); |
| 607 } else if (type->IsClass()) { | 645 } else if (type->IsClass()) { |
| 608 return ClassType::New(type->AsClass()->Map(), region); | 646 return ClassType::New(type->AsClass()->Map(), region); |
| 609 } else if (type->IsConstant()) { | 647 } else if (type->IsConstant()) { |
| 610 return ConstantType::New(type->AsConstant()->Value(), region); | 648 return ConstantType::New(type->AsConstant()->Value(), region); |
| 649 } else if (type->IsContext()) { |
| 650 TypeHandle outer = Convert<OtherType>(type->AsContext()->Outer(), region); |
| 651 return ContextType::New(outer, region); |
| 611 } else if (type->IsUnion()) { | 652 } else if (type->IsUnion()) { |
| 612 int length = type->AsUnion()->Length(); | 653 int length = type->AsUnion()->Length(); |
| 613 UnionHandle unioned = UnionType::New(length, region); | 654 UnionHandle unioned = UnionType::New(length, region); |
| 614 for (int i = 0; i < length; ++i) { | 655 for (int i = 0; i < length; ++i) { |
| 615 unioned->Set(i, Convert<OtherType>(type->AsUnion()->Get(i), region)); | 656 unioned->Set(i, Convert<OtherType>(type->AsUnion()->Get(i), region)); |
| 616 } | 657 } |
| 617 return unioned; | 658 return unioned; |
| 618 } else if (type->IsArray()) { | 659 } else if (type->IsArray()) { |
| 619 return ArrayType::New( | 660 return ArrayType::New( |
| 620 Convert<OtherType>(type->AsArray()->Element(), region), region); | 661 Convert<OtherType>(type->AsArray()->Element(), region), region); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 640 DisallowHeapAllocation no_allocation; | 681 DisallowHeapAllocation no_allocation; |
| 641 if (type->Is(Type::None())) return Representation::None(); | 682 if (type->Is(Type::None())) return Representation::None(); |
| 642 if (type->Is(Type::SignedSmall())) return Representation::Smi(); | 683 if (type->Is(Type::SignedSmall())) return Representation::Smi(); |
| 643 if (type->Is(Type::Signed32())) return Representation::Integer32(); | 684 if (type->Is(Type::Signed32())) return Representation::Integer32(); |
| 644 if (type->Is(Type::Number())) return Representation::Double(); | 685 if (type->Is(Type::Number())) return Representation::Double(); |
| 645 return Representation::Tagged(); | 686 return Representation::Tagged(); |
| 646 } | 687 } |
| 647 | 688 |
| 648 | 689 |
| 649 template<class Config> | 690 template<class Config> |
| 650 void TypeImpl<Config>::TypePrint(PrintDimension dim) { | |
| 651 TypePrint(stdout, dim); | |
| 652 PrintF(stdout, "\n"); | |
| 653 Flush(stdout); | |
| 654 } | |
| 655 | |
| 656 | |
| 657 template<class Config> | |
| 658 const char* TypeImpl<Config>::BitsetType::Name(int bitset) { | 691 const char* TypeImpl<Config>::BitsetType::Name(int bitset) { |
| 659 switch (bitset) { | 692 switch (bitset) { |
| 660 case kAny & kRepresentation: return "Any"; | 693 case REPRESENTATION(kAny): return "Any"; |
| 661 #define PRINT_COMPOSED_TYPE(type, value) \ | 694 #define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \ |
| 662 case k##type & kRepresentation: return #type; | 695 case REPRESENTATION(k##type): return #type; |
| 663 REPRESENTATION_BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE) | 696 REPRESENTATION_BITSET_TYPE_LIST(RETURN_NAMED_REPRESENTATION_TYPE) |
| 664 #undef PRINT_COMPOSED_TYPE | 697 #undef RETURN_NAMED_REPRESENTATION_TYPE |
| 665 | 698 |
| 666 #define PRINT_COMPOSED_TYPE(type, value) \ | 699 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ |
| 667 case k##type & kSemantic: return #type; | 700 case SEMANTIC(k##type): return #type; |
| 668 SEMANTIC_BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE) | 701 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) |
| 669 #undef PRINT_COMPOSED_TYPE | 702 #undef RETURN_NAMED_SEMANTIC_TYPE |
| 670 | 703 |
| 671 default: | 704 default: |
| 672 return NULL; | 705 return NULL; |
| 673 } | 706 } |
| 674 } | 707 } |
| 675 | 708 |
| 676 | 709 |
| 677 template<class Config> | 710 template<class Config> |
| 678 void TypeImpl<Config>::BitsetType::BitsetTypePrint(FILE* out, int bitset) { | 711 void TypeImpl<Config>::BitsetType::PrintTo(StringStream* stream, int bitset) { |
| 679 DisallowHeapAllocation no_allocation; | 712 DisallowHeapAllocation no_allocation; |
| 680 const char* name = Name(bitset); | 713 const char* name = Name(bitset); |
| 681 if (name != NULL) { | 714 if (name != NULL) { |
| 682 PrintF(out, "%s", name); | 715 stream->Add("%s", name); |
| 683 } else { | 716 } else { |
| 684 static const int named_bitsets[] = { | 717 static const int named_bitsets[] = { |
| 685 #define BITSET_CONSTANT(type, value) k##type & kRepresentation, | 718 #define BITSET_CONSTANT(type, value) REPRESENTATION(k##type), |
| 686 REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT) | 719 REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT) |
| 687 #undef BITSET_CONSTANT | 720 #undef BITSET_CONSTANT |
| 688 | 721 |
| 689 #define BITSET_CONSTANT(type, value) k##type & kSemantic, | 722 #define BITSET_CONSTANT(type, value) SEMANTIC(k##type), |
| 690 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) | 723 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) |
| 691 #undef BITSET_CONSTANT | 724 #undef BITSET_CONSTANT |
| 692 }; | 725 }; |
| 693 | 726 |
| 694 bool is_first = true; | 727 bool is_first = true; |
| 695 PrintF(out, "("); | 728 stream->Add("("); |
| 696 for (int i(ARRAY_SIZE(named_bitsets) - 1); bitset != 0 && i >= 0; --i) { | 729 for (int i(ARRAY_SIZE(named_bitsets) - 1); bitset != 0 && i >= 0; --i) { |
| 697 int subset = named_bitsets[i]; | 730 int subset = named_bitsets[i]; |
| 698 if ((bitset & subset) == subset) { | 731 if ((bitset & subset) == subset) { |
| 699 if (!is_first) PrintF(out, " | "); | 732 if (!is_first) stream->Add(" | "); |
| 700 is_first = false; | 733 is_first = false; |
| 701 PrintF(out, "%s", Name(subset)); | 734 stream->Add("%s", Name(subset)); |
| 702 bitset -= subset; | 735 bitset -= subset; |
| 703 } | 736 } |
| 704 } | 737 } |
| 705 ASSERT(bitset == 0); | 738 ASSERT(bitset == 0); |
| 706 PrintF(out, ")"); | 739 stream->Add(")"); |
| 740 } |
| 741 } |
| 742 |
| 743 |
| 744 template<class Config> |
| 745 void TypeImpl<Config>::PrintTo(StringStream* stream, PrintDimension dim) { |
| 746 DisallowHeapAllocation no_allocation; |
| 747 if (this->IsBitset()) { |
| 748 int bitset = this->AsBitset(); |
| 749 switch (dim) { |
| 750 case BOTH_DIMS: |
| 751 BitsetType::PrintTo(stream, SEMANTIC(bitset)); |
| 752 stream->Add("/"); |
| 753 BitsetType::PrintTo(stream, REPRESENTATION(bitset)); |
| 754 break; |
| 755 case SEMANTIC_DIM: |
| 756 BitsetType::PrintTo(stream, SEMANTIC(bitset)); |
| 757 break; |
| 758 case REPRESENTATION_DIM: |
| 759 BitsetType::PrintTo(stream, REPRESENTATION(bitset)); |
| 760 break; |
| 761 } |
| 762 } else if (this->IsConstant()) { |
| 763 stream->Add("Constant(%p : ", |
| 764 static_cast<void*>(*this->AsConstant()->Value())); |
| 765 BitsetType::New(BitsetType::Lub(this))->PrintTo(stream, dim); |
| 766 stream->Add(")"); |
| 767 } else if (this->IsClass()) { |
| 768 stream->Add("Class(%p < ", static_cast<void*>(*this->AsClass()->Map())); |
| 769 BitsetType::New(BitsetType::Lub(this))->PrintTo(stream, dim); |
| 770 stream->Add(")"); |
| 771 } else if (this->IsContext()) { |
| 772 stream->Add("Context("); |
| 773 this->AsContext()->Outer()->PrintTo(stream, dim); |
| 774 stream->Add(")"); |
| 775 } else if (this->IsUnion()) { |
| 776 stream->Add("("); |
| 777 UnionHandle unioned = handle(this->AsUnion()); |
| 778 for (int i = 0; i < unioned->Length(); ++i) { |
| 779 TypeHandle type_i = unioned->Get(i); |
| 780 if (i > 0) stream->Add(" | "); |
| 781 type_i->PrintTo(stream, dim); |
| 782 } |
| 783 stream->Add(")"); |
| 784 } else if (this->IsArray()) { |
| 785 stream->Add("["); |
| 786 AsArray()->Element()->PrintTo(stream, dim); |
| 787 stream->Add("]"); |
| 788 } else if (this->IsFunction()) { |
| 789 if (!this->AsFunction()->Receiver()->IsAny()) { |
| 790 this->AsFunction()->Receiver()->PrintTo(stream, dim); |
| 791 stream->Add("."); |
| 792 } |
| 793 stream->Add("("); |
| 794 for (int i = 0; i < this->AsFunction()->Arity(); ++i) { |
| 795 if (i > 0) stream->Add(", "); |
| 796 this->AsFunction()->Parameter(i)->PrintTo(stream, dim); |
| 797 } |
| 798 stream->Add(")->"); |
| 799 this->AsFunction()->Result()->PrintTo(stream, dim); |
| 800 } else { |
| 801 UNREACHABLE(); |
| 707 } | 802 } |
| 708 } | 803 } |
| 709 | 804 |
| 710 | 805 |
| 711 template<class Config> | 806 template<class Config> |
| 712 void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) { | 807 void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) { |
| 713 DisallowHeapAllocation no_allocation; | 808 HeapStringAllocator allocator; |
| 714 if (this->IsBitset()) { | 809 StringStream stream(&allocator); |
| 715 int bitset = this->AsBitset(); | 810 PrintTo(&stream, dim); |
| 716 switch (dim) { | 811 stream.OutputToFile(out); |
| 717 case BOTH_DIMS: | 812 } |
| 718 BitsetType::BitsetTypePrint(out, bitset & BitsetType::kSemantic); | 813 |
| 719 PrintF(out, "/"); | 814 |
| 720 BitsetType::BitsetTypePrint(out, bitset & BitsetType::kRepresentation); | 815 template<class Config> |
| 721 break; | 816 void TypeImpl<Config>::TypePrint(PrintDimension dim) { |
| 722 case SEMANTIC_DIM: | 817 TypePrint(stdout, dim); |
| 723 BitsetType::BitsetTypePrint(out, bitset & BitsetType::kSemantic); | 818 PrintF(stdout, "\n"); |
| 724 break; | 819 Flush(stdout); |
| 725 case REPRESENTATION_DIM: | |
| 726 BitsetType::BitsetTypePrint(out, bitset & BitsetType::kRepresentation); | |
| 727 break; | |
| 728 } | |
| 729 } else if (this->IsConstant()) { | |
| 730 PrintF(out, "Constant(%p : ", | |
| 731 static_cast<void*>(*this->AsConstant()->Value())); | |
| 732 BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim); | |
| 733 PrintF(out, ")"); | |
| 734 } else if (this->IsClass()) { | |
| 735 PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass()->Map())); | |
| 736 BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim); | |
| 737 PrintF(out, ")"); | |
| 738 } else if (this->IsUnion()) { | |
| 739 PrintF(out, "("); | |
| 740 UnionHandle unioned = handle(this->AsUnion()); | |
| 741 for (int i = 0; i < unioned->Length(); ++i) { | |
| 742 TypeHandle type_i = unioned->Get(i); | |
| 743 if (i > 0) PrintF(out, " | "); | |
| 744 type_i->TypePrint(out, dim); | |
| 745 } | |
| 746 PrintF(out, ")"); | |
| 747 } else if (this->IsArray()) { | |
| 748 PrintF(out, "["); | |
| 749 AsArray()->Element()->TypePrint(out, dim); | |
| 750 PrintF(out, "]"); | |
| 751 } else if (this->IsFunction()) { | |
| 752 if (!this->AsFunction()->Receiver()->IsAny()) { | |
| 753 this->AsFunction()->Receiver()->TypePrint(out, dim); | |
| 754 PrintF(out, "."); | |
| 755 } | |
| 756 PrintF(out, "("); | |
| 757 for (int i = 0; i < this->AsFunction()->Arity(); ++i) { | |
| 758 if (i > 0) PrintF(out, ", "); | |
| 759 this->AsFunction()->Parameter(i)->TypePrint(out, dim); | |
| 760 } | |
| 761 PrintF(out, ")->"); | |
| 762 this->AsFunction()->Result()->TypePrint(out, dim); | |
| 763 } else { | |
| 764 UNREACHABLE(); | |
| 765 } | |
| 766 } | 820 } |
| 767 | 821 |
| 768 | 822 |
| 769 template class TypeImpl<ZoneTypeConfig>; | 823 template class TypeImpl<ZoneTypeConfig>; |
| 770 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>; | 824 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>; |
| 771 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>; | 825 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>; |
| 772 | 826 |
| 773 template class TypeImpl<HeapTypeConfig>; | 827 template class TypeImpl<HeapTypeConfig>; |
| 774 template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>; | 828 template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>; |
| 775 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; | 829 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; |
| 776 | 830 |
| 777 template TypeImpl<ZoneTypeConfig>::TypeHandle | 831 template TypeImpl<ZoneTypeConfig>::TypeHandle |
| 778 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( | 832 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( |
| 779 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); | 833 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); |
| 780 template TypeImpl<HeapTypeConfig>::TypeHandle | 834 template TypeImpl<HeapTypeConfig>::TypeHandle |
| 781 TypeImpl<HeapTypeConfig>::Convert<Type>( | 835 TypeImpl<HeapTypeConfig>::Convert<Type>( |
| 782 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); | 836 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); |
| 783 | 837 |
| 784 } } // namespace v8::internal | 838 } } // namespace v8::internal |
| OLD | NEW |