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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 kSignedSmall & kTaggedInt; |
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 return kTaggedPtr & ( |
Michael Starzinger
2014/03/04 11:59:58
High-level comment: This assumes HeapNumber object
rossberg
2014/03/04 13:53:11
Good point. As discussed off-line, I think we shou
| |
159 if (value->ToUint32(&u)) return kUnsigned32; | 159 value->ToInt32(&i) ? (Smi::IsValid(i) ? kSignedSmall : kOtherSigned32) : |
160 return kDouble; | 160 value->ToUint32(&u) ? kUnsigned32 : kFloat); |
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 if (value->IsUninitialized()) return kNone; |
168 UNREACHABLE(); | 168 UNREACHABLE(); |
169 } | 169 } |
170 return LubBitset(map); | 170 return LubBitset(map); |
(...skipping 24 matching lines...) Expand all Loading... | |
195 case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE: | 195 case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE: |
196 case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE: | 196 case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE: |
197 case SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE: | 197 case SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE: |
198 case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE: | 198 case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE: |
199 return kString; | 199 return kString; |
200 case SYMBOL_TYPE: | 200 case SYMBOL_TYPE: |
201 return kSymbol; | 201 return kSymbol; |
202 case ODDBALL_TYPE: | 202 case ODDBALL_TYPE: |
203 return kOddball; | 203 return kOddball; |
204 case HEAP_NUMBER_TYPE: | 204 case HEAP_NUMBER_TYPE: |
205 return kDouble; | 205 return kFloat & kTaggedPtr; |
206 case JS_VALUE_TYPE: | 206 case JS_VALUE_TYPE: |
207 case JS_DATE_TYPE: | 207 case JS_DATE_TYPE: |
208 case JS_OBJECT_TYPE: | 208 case JS_OBJECT_TYPE: |
209 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: | 209 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: |
210 case JS_GENERATOR_OBJECT_TYPE: | 210 case JS_GENERATOR_OBJECT_TYPE: |
211 case JS_MODULE_TYPE: | 211 case JS_MODULE_TYPE: |
212 case JS_GLOBAL_OBJECT_TYPE: | 212 case JS_GLOBAL_OBJECT_TYPE: |
213 case JS_BUILTINS_OBJECT_TYPE: | 213 case JS_BUILTINS_OBJECT_TYPE: |
214 case JS_GLOBAL_PROXY_TYPE: | 214 case JS_GLOBAL_PROXY_TYPE: |
215 case JS_ARRAY_BUFFER_TYPE: | 215 case JS_ARRAY_BUFFER_TYPE: |
(...skipping 22 matching lines...) Expand all Loading... | |
238 // we must exclude Undetectable here. This makes no sense, really, | 238 // we must exclude Undetectable here. This makes no sense, really, |
239 // because it means that the template isn't actually parametric. | 239 // because it means that the template isn't actually parametric. |
240 // Also, it doesn't apply elsewhere. 8-( | 240 // Also, it doesn't apply elsewhere. 8-( |
241 // We ought to find a cleaner solution for compiling stubs parameterised | 241 // We ought to find a cleaner solution for compiling stubs parameterised |
242 // over type or class variables, esp ones with bounds... | 242 // over type or class variables, esp ones with bounds... |
243 return kDetectable; | 243 return kDetectable; |
244 case DECLARED_ACCESSOR_INFO_TYPE: | 244 case DECLARED_ACCESSOR_INFO_TYPE: |
245 case EXECUTABLE_ACCESSOR_INFO_TYPE: | 245 case EXECUTABLE_ACCESSOR_INFO_TYPE: |
246 case ACCESSOR_PAIR_TYPE: | 246 case ACCESSOR_PAIR_TYPE: |
247 case FIXED_ARRAY_TYPE: | 247 case FIXED_ARRAY_TYPE: |
248 return kInternal; | 248 return kInternal & kTaggedPtr; |
249 default: | 249 default: |
250 UNREACHABLE(); | 250 UNREACHABLE(); |
251 return kNone; | 251 return kNone; |
252 } | 252 } |
253 } | 253 } |
254 | 254 |
255 | 255 |
256 // Get the largest bitset subsumed by this type. | 256 // Get the largest bitset subsumed by this type. |
257 template<class Config> | 257 template<class Config> |
258 int TypeImpl<Config>::GlbBitset() { | 258 int TypeImpl<Config>::GlbBitset() { |
259 if (this->IsBitset()) { | 259 if (this->IsBitset()) { |
260 return this->AsBitset(); | 260 return this->AsBitset(); |
261 } else if (this->IsUnion()) { | 261 } else if (this->IsUnion()) { |
262 // All but the first are non-bitsets and thus would yield kNone anyway. | 262 // All but the first are non-bitsets and thus would yield kNone anyway. |
263 return Config::union_get(this->AsUnion(), 0)->GlbBitset(); | 263 return Config::union_get(this->AsUnion(), 0)->GlbBitset(); |
264 } else { | 264 } else { |
265 return kNone; | 265 return kNone; |
266 } | 266 } |
267 } | 267 } |
268 | 268 |
269 | 269 |
270 // Most precise _current_ type of a value (usually its class). | 270 // Most precise _current_ type of a value (usually its class). |
271 template<class Config> | 271 template<class Config> |
272 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::OfCurrently( | 272 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::OfCurrently( |
273 i::Handle<i::Object> value, Region* region) { | 273 i::Handle<i::Object> value, Region* region) { |
274 if (value->IsSmi()) return Smi(region); | 274 if (value->IsSmi()) return SignedSmall(region); |
Michael Starzinger
2014/03/04 11:59:58
Shouldn't this be tagged?
rossberg
2014/03/04 13:53:11
Good catch.
| |
275 i::Map* map = i::HeapObject::cast(*value)->map(); | 275 i::Map* map = i::HeapObject::cast(*value)->map(); |
276 if (map->instance_type() == HEAP_NUMBER_TYPE || | 276 if (map->instance_type() == HEAP_NUMBER_TYPE || |
277 map->instance_type() == ODDBALL_TYPE) { | 277 map->instance_type() == ODDBALL_TYPE) { |
278 return Of(value, region); | 278 return Of(value, region); |
279 } | 279 } |
280 return Class(i::handle(map), region); | 280 return Class(i::handle(map), region); |
281 } | 281 } |
282 | 282 |
283 | 283 |
284 // Check this <= that. | 284 // Check this <= that. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
331 this->AsConstant()->IsHeapObject() && | 331 this->AsConstant()->IsHeapObject() && |
332 i::HeapObject::cast(*this->AsConstant())->map() == *that->AsClass()); | 332 i::HeapObject::cast(*this->AsConstant())->map() == *that->AsClass()); |
333 } | 333 } |
334 | 334 |
335 | 335 |
336 // Check this overlaps that. | 336 // Check this overlaps that. |
337 template<class Config> | 337 template<class Config> |
338 bool TypeImpl<Config>::Maybe(TypeImpl* that) { | 338 bool TypeImpl<Config>::Maybe(TypeImpl* that) { |
339 // Fast path for bitsets. | 339 // Fast path for bitsets. |
340 if (this->IsBitset()) { | 340 if (this->IsBitset()) { |
341 return (this->AsBitset() & that->LubBitset()) != 0; | 341 return IsInhabited(this->AsBitset() & that->LubBitset()); |
342 } | 342 } |
343 if (that->IsBitset()) { | 343 if (that->IsBitset()) { |
344 return (this->LubBitset() & that->AsBitset()) != 0; | 344 return IsInhabited(this->LubBitset() & that->AsBitset()); |
345 } | 345 } |
346 | 346 |
347 // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T) | 347 // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T) |
348 if (this->IsUnion()) { | 348 if (this->IsUnion()) { |
349 UnionedHandle unioned = this->AsUnion(); | 349 UnionedHandle unioned = this->AsUnion(); |
350 for (int i = 0; i < Config::union_length(unioned); ++i) { | 350 for (int i = 0; i < Config::union_length(unioned); ++i) { |
351 TypeHandle this_i = Config::union_get(unioned, i); | 351 TypeHandle this_i = Config::union_get(unioned, i); |
352 if (this_i->Maybe(that)) return true; | 352 if (this_i->Maybe(that)) return true; |
353 } | 353 } |
354 return false; | 354 return false; |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
561 Convert<OtherType>(OtherType::UnionGet(unioned, i), region)); | 561 Convert<OtherType>(OtherType::UnionGet(unioned, i), region)); |
562 } | 562 } |
563 return Config::from_union(new_unioned); | 563 return Config::from_union(new_unioned); |
564 } | 564 } |
565 } | 565 } |
566 | 566 |
567 | 567 |
568 // TODO(rossberg): this does not belong here. | 568 // TODO(rossberg): this does not belong here. |
569 Representation Representation::FromType(Type* type) { | 569 Representation Representation::FromType(Type* type) { |
570 if (type->Is(Type::None())) return Representation::None(); | 570 if (type->Is(Type::None())) return Representation::None(); |
571 if (type->Is(Type::Smi())) return Representation::Smi(); | 571 if (type->Is(Type::SignedSmall())) return Representation::Smi(); |
572 if (type->Is(Type::Signed32())) return Representation::Integer32(); | 572 if (type->Is(Type::Signed32())) return Representation::Integer32(); |
573 if (type->Is(Type::Number())) return Representation::Double(); | 573 if (type->Is(Type::Number())) return Representation::Double(); |
574 return Representation::Tagged(); | 574 return Representation::Tagged(); |
575 } | 575 } |
576 | 576 |
577 | 577 |
578 #ifdef OBJECT_PRINT | 578 #ifdef OBJECT_PRINT |
579 template<class Config> | 579 template<class Config> |
580 void TypeImpl<Config>::TypePrint() { | 580 void TypeImpl<Config>::TypePrint(PrintDim dim) { |
581 TypePrint(stdout); | 581 TypePrint(stdout, dim); |
582 PrintF(stdout, "\n"); | 582 PrintF(stdout, "\n"); |
583 Flush(stdout); | 583 Flush(stdout); |
584 } | 584 } |
585 | 585 |
586 | 586 |
587 template<class Config> | 587 template<class Config> |
588 const char* TypeImpl<Config>::bitset_name(int bitset) { | 588 const char* TypeImpl<Config>::bitset_name(int bitset) { |
589 switch (bitset) { | 589 switch (bitset) { |
590 #define PRINT_COMPOSED_TYPE(type, value) case k##type: return #type; | 590 #define PRINT_COMPOSED_TYPE(type, value) \ |
591 BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE) | 591 case k##type & kSemantic: return #type; |
592 SEMANTIC_BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE) | |
592 #undef PRINT_COMPOSED_TYPE | 593 #undef PRINT_COMPOSED_TYPE |
594 | |
595 #define PRINT_COMPOSED_TYPE(type, value) \ | |
596 case k##type & kRepresentation: return #type; | |
597 REPRESENTATION_BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE) | |
598 #undef PRINT_COMPOSED_TYPE | |
599 | |
593 default: | 600 default: |
594 return NULL; | 601 return NULL; |
595 } | 602 } |
596 } | 603 } |
597 | 604 |
598 | 605 |
599 template<class Config> | 606 template<class Config> |
600 void TypeImpl<Config>::TypePrint(FILE* out) { | 607 void TypeImpl<Config>::BitsetTypePrint(FILE* out, int bitset) { |
608 const char* name = bitset_name(bitset); | |
609 if (name != NULL) { | |
610 PrintF(out, "%s", name); | |
611 } else { | |
612 static const int named_bitsets[] = { | |
613 #define BITSET_CONSTANT(type, value) k##type & kSemantic, | |
614 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) | |
615 #undef BITSET_CONSTANT | |
616 | |
617 #define BITSET_CONSTANT(type, value) k##type & kRepresentation, | |
618 REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT) | |
619 #undef BITSET_CONSTANT | |
620 }; | |
621 | |
622 bool is_first = true; | |
623 PrintF(out, "("); | |
624 for (int i(ARRAY_SIZE(named_bitsets) - 1); bitset != 0 && i >= 0; --i) { | |
625 int subset = named_bitsets[i]; | |
626 if ((bitset & subset) == subset) { | |
627 if (!is_first) PrintF(out, " | "); | |
628 is_first = false; | |
629 PrintF(out, "%s", bitset_name(subset)); | |
630 bitset -= subset; | |
631 } | |
632 } | |
633 ASSERT(bitset == 0); | |
634 PrintF(out, ")"); | |
635 } | |
636 } | |
637 | |
638 | |
639 template<class Config> | |
640 void TypeImpl<Config>::TypePrint(FILE* out, PrintDim dim) { | |
601 if (this->IsBitset()) { | 641 if (this->IsBitset()) { |
602 int bitset = this->AsBitset(); | 642 int bitset = this->AsBitset(); |
603 const char* name = bitset_name(bitset); | 643 switch (dim) { |
604 if (name != NULL) { | 644 case BOTH_DIMS: |
605 PrintF(out, "%s", name); | 645 BitsetTypePrint(out, bitset & kSemantic); |
606 } else { | 646 PrintF("/"); |
607 bool is_first = true; | 647 BitsetTypePrint(out, bitset & kRepresentation); |
608 PrintF(out, "("); | 648 break; |
609 for (int mask = 1; mask != 0; mask = mask << 1) { | 649 case SEMANTIC_DIM: |
610 if ((bitset & mask) != 0) { | 650 BitsetTypePrint(out, bitset & kSemantic); |
611 if (!is_first) PrintF(out, " | "); | 651 break; |
612 is_first = false; | 652 case REPRESENTATION_DIM: |
613 PrintF(out, "%s", bitset_name(mask)); | 653 BitsetTypePrint(out, bitset & kRepresentation); |
614 } | 654 break; |
615 } | |
616 PrintF(out, ")"); | |
617 } | 655 } |
618 } else if (this->IsConstant()) { | 656 } else if (this->IsConstant()) { |
619 PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant())); | 657 PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant())); |
620 Config::from_bitset(this->LubBitset())->TypePrint(out); | 658 Config::from_bitset(this->LubBitset())->TypePrint(out); |
621 PrintF(")"); | 659 PrintF(")"); |
622 } else if (this->IsClass()) { | 660 } else if (this->IsClass()) { |
623 PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass())); | 661 PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass())); |
624 Config::from_bitset(this->LubBitset())->TypePrint(out); | 662 Config::from_bitset(this->LubBitset())->TypePrint(out); |
625 PrintF(")"); | 663 PrintF(")"); |
626 } else if (this->IsUnion()) { | 664 } else if (this->IsUnion()) { |
(...skipping 20 matching lines...) Expand all Loading... | |
647 | 685 |
648 template TypeImpl<ZoneTypeConfig>::TypeHandle | 686 template TypeImpl<ZoneTypeConfig>::TypeHandle |
649 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( | 687 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( |
650 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); | 688 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); |
651 template TypeImpl<HeapTypeConfig>::TypeHandle | 689 template TypeImpl<HeapTypeConfig>::TypeHandle |
652 TypeImpl<HeapTypeConfig>::Convert<Type>( | 690 TypeImpl<HeapTypeConfig>::Convert<Type>( |
653 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); | 691 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); |
654 | 692 |
655 | 693 |
656 } } // namespace v8::internal | 694 } } // namespace v8::internal |
OLD | NEW |