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 |