Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: src/types.cc

Issue 73193004: Provide Type::Of and Type::CurrentOf operators (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comment Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/types.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 } 63 }
64 64
65 65
66 template<class T> 66 template<class T>
67 Handle<Type> Type::Iterator<T>::get_type() { 67 Handle<Type> Type::Iterator<T>::get_type() {
68 ASSERT(!Done()); 68 ASSERT(!Done());
69 return type_->is_union() ? union_get(type_->as_union(), index_) : type_; 69 return type_->is_union() ? union_get(type_->as_union(), index_) : type_;
70 } 70 }
71 71
72 template<> 72 template<>
73 Handle<Map> Type::Iterator<Map>::Current() { 73 Handle<i::Map> Type::Iterator<i::Map>::Current() {
74 return get_type()->as_class(); 74 return get_type()->as_class();
75 } 75 }
76 76
77 template<> 77 template<>
78 Handle<v8::internal::Object> Type::Iterator<v8::internal::Object>::Current() { 78 Handle<i::Object> Type::Iterator<i::Object>::Current() {
79 return get_type()->as_constant(); 79 return get_type()->as_constant();
80 } 80 }
81 81
82 82
83 template<> 83 template<>
84 bool Type::Iterator<Map>::matches(Handle<Type> type) { 84 bool Type::Iterator<i::Map>::matches(Handle<Type> type) {
85 return type->is_class(); 85 return type->is_class();
86 } 86 }
87 87
88 template<> 88 template<>
89 bool Type::Iterator<v8::internal::Object>::matches(Handle<Type> type) { 89 bool Type::Iterator<i::Object>::matches(Handle<Type> type) {
90 return type->is_constant(); 90 return type->is_constant();
91 } 91 }
92 92
93 93
94 template<class T> 94 template<class T>
95 void Type::Iterator<T>::Advance() { 95 void Type::Iterator<T>::Advance() {
96 ++index_; 96 ++index_;
97 if (type_->is_union()) { 97 if (type_->is_union()) {
98 Handle<Unioned> unioned = type_->as_union(); 98 Handle<Unioned> unioned = type_->as_union();
99 for (; index_ < unioned->length(); ++index_) { 99 for (; index_ < unioned->length(); ++index_) {
100 if (matches(union_get(unioned, index_))) return; 100 if (matches(union_get(unioned, index_))) return;
101 } 101 }
102 } else if (index_ == 0 && matches(type_)) { 102 } else if (index_ == 0 && matches(type_)) {
103 return; 103 return;
104 } 104 }
105 index_ = -1; 105 index_ = -1;
106 } 106 }
107 107
108 template class Type::Iterator<Map>; 108 template class Type::Iterator<i::Map>;
109 template class Type::Iterator<v8::internal::Object>; 109 template class Type::Iterator<i::Object>;
110 110
111 111
112 // Get the smallest bitset subsuming this type. 112 // Get the smallest bitset subsuming this type.
113 int Type::LubBitset() { 113 int Type::LubBitset() {
114 if (this->is_bitset()) { 114 if (this->is_bitset()) {
115 return this->as_bitset(); 115 return this->as_bitset();
116 } else if (this->is_union()) { 116 } else if (this->is_union()) {
117 Handle<Unioned> unioned = this->as_union(); 117 Handle<Unioned> unioned = this->as_union();
118 int bitset = kNone; 118 int bitset = kNone;
119 for (int i = 0; i < unioned->length(); ++i) { 119 for (int i = 0; i < unioned->length(); ++i) {
120 bitset |= union_get(unioned, i)->LubBitset(); 120 bitset |= union_get(unioned, i)->LubBitset();
121 } 121 }
122 return bitset; 122 return bitset;
123 } else if (this->is_class()) {
124 return LubBitset(*this->as_class());
123 } else { 125 } else {
124 Map* map = NULL; 126 return LubBitset(*this->as_constant());
125 if (this->is_class()) {
126 map = *this->as_class();
127 } else {
128 Handle<v8::internal::Object> value = this->as_constant();
129 if (value->IsSmi()) return kSmi;
130 map = HeapObject::cast(*value)->map();
131 if (map->instance_type() == HEAP_NUMBER_TYPE) {
132 int32_t i;
133 uint32_t u;
134 if (value->ToInt32(&i)) return Smi::IsValid(i) ? kSmi : kOtherSigned32;
135 if (value->ToUint32(&u)) return kUnsigned32;
136 return kDouble;
137 }
138 if (map->instance_type() == ODDBALL_TYPE) {
139 if (value->IsUndefined()) return kUndefined;
140 if (value->IsNull()) return kNull;
141 if (value->IsTrue() || value->IsFalse()) return kBoolean;
142 if (value->IsTheHole()) return kAny; // TODO(rossberg): kNone?
143 UNREACHABLE();
144 }
145 }
146 switch (map->instance_type()) {
147 case STRING_TYPE:
148 case ASCII_STRING_TYPE:
149 case CONS_STRING_TYPE:
150 case CONS_ASCII_STRING_TYPE:
151 case SLICED_STRING_TYPE:
152 case SLICED_ASCII_STRING_TYPE:
153 case EXTERNAL_STRING_TYPE:
154 case EXTERNAL_ASCII_STRING_TYPE:
155 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
156 case SHORT_EXTERNAL_STRING_TYPE:
157 case SHORT_EXTERNAL_ASCII_STRING_TYPE:
158 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
159 case INTERNALIZED_STRING_TYPE:
160 case ASCII_INTERNALIZED_STRING_TYPE:
161 case CONS_INTERNALIZED_STRING_TYPE:
162 case CONS_ASCII_INTERNALIZED_STRING_TYPE:
163 case EXTERNAL_INTERNALIZED_STRING_TYPE:
164 case EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
165 case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
166 case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE:
167 case SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
168 case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
169 return kString;
170 case SYMBOL_TYPE:
171 return kSymbol;
172 case ODDBALL_TYPE:
173 return kOddball;
174 case HEAP_NUMBER_TYPE:
175 return kDouble;
176 case JS_VALUE_TYPE:
177 case JS_DATE_TYPE:
178 case JS_OBJECT_TYPE:
179 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
180 case JS_GENERATOR_OBJECT_TYPE:
181 case JS_MODULE_TYPE:
182 case JS_GLOBAL_OBJECT_TYPE:
183 case JS_BUILTINS_OBJECT_TYPE:
184 case JS_GLOBAL_PROXY_TYPE:
185 case JS_ARRAY_BUFFER_TYPE:
186 case JS_TYPED_ARRAY_TYPE:
187 case JS_DATA_VIEW_TYPE:
188 case JS_SET_TYPE:
189 case JS_MAP_TYPE:
190 case JS_WEAK_MAP_TYPE:
191 case JS_WEAK_SET_TYPE:
192 if (map->is_undetectable()) return kUndetectable;
193 return kOtherObject;
194 case JS_ARRAY_TYPE:
195 return kArray;
196 case JS_FUNCTION_TYPE:
197 return kFunction;
198 case JS_REGEXP_TYPE:
199 return kRegExp;
200 case JS_PROXY_TYPE:
201 case JS_FUNCTION_PROXY_TYPE:
202 return kProxy;
203 case MAP_TYPE:
204 // When compiling stub templates, the meta map is used as a place holder
205 // for the actual map with which the template is later instantiated.
206 // We treat it as a kind of type variable whose upper bound is Any.
207 // TODO(rossberg): for caching of CompareNilIC stubs to work correctly,
208 // we must exclude Undetectable here. This makes no sense, really,
209 // because it means that the template isn't actually parametric.
210 // Also, it doesn't apply elsewhere. 8-(
211 // We ought to find a cleaner solution for compiling stubs parameterised
212 // over type or class variables, esp ones with bounds...
213 return kDetectable;
214 case DECLARED_ACCESSOR_INFO_TYPE:
215 case EXECUTABLE_ACCESSOR_INFO_TYPE:
216 case ACCESSOR_PAIR_TYPE:
217 case FIXED_ARRAY_TYPE:
218 return kInternal;
219 default:
220 UNREACHABLE();
221 return kNone;
222 }
223 } 127 }
224 } 128 }
225 129
130
131 int Type::LubBitset(i::Object* value) {
132 if (value->IsSmi()) return kSmi;
133 i::Map* map = i::HeapObject::cast(value)->map();
134 if (map->instance_type() == HEAP_NUMBER_TYPE) {
135 int32_t i;
136 uint32_t u;
137 if (value->ToInt32(&i)) return Smi::IsValid(i) ? kSmi : kOtherSigned32;
138 if (value->ToUint32(&u)) return kUnsigned32;
139 return kDouble;
140 }
141 if (map->instance_type() == ODDBALL_TYPE) {
142 if (value->IsUndefined()) return kUndefined;
143 if (value->IsNull()) return kNull;
144 if (value->IsBoolean()) return kBoolean;
145 if (value->IsTheHole()) return kAny; // TODO(rossberg): kNone?
146 UNREACHABLE();
147 }
148 return Type::LubBitset(map);
149 }
150
151
152 int Type::LubBitset(i::Map* map) {
153 switch (map->instance_type()) {
154 case STRING_TYPE:
155 case ASCII_STRING_TYPE:
156 case CONS_STRING_TYPE:
157 case CONS_ASCII_STRING_TYPE:
158 case SLICED_STRING_TYPE:
159 case SLICED_ASCII_STRING_TYPE:
160 case EXTERNAL_STRING_TYPE:
161 case EXTERNAL_ASCII_STRING_TYPE:
162 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
163 case SHORT_EXTERNAL_STRING_TYPE:
164 case SHORT_EXTERNAL_ASCII_STRING_TYPE:
165 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
166 case INTERNALIZED_STRING_TYPE:
167 case ASCII_INTERNALIZED_STRING_TYPE:
168 case CONS_INTERNALIZED_STRING_TYPE:
169 case CONS_ASCII_INTERNALIZED_STRING_TYPE:
170 case EXTERNAL_INTERNALIZED_STRING_TYPE:
171 case EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
172 case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
173 case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE:
174 case SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
175 case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
176 return kString;
177 case SYMBOL_TYPE:
178 return kSymbol;
179 case ODDBALL_TYPE:
180 return kOddball;
181 case HEAP_NUMBER_TYPE:
182 return kDouble;
183 case JS_VALUE_TYPE:
184 case JS_DATE_TYPE:
185 case JS_OBJECT_TYPE:
186 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
187 case JS_GENERATOR_OBJECT_TYPE:
188 case JS_MODULE_TYPE:
189 case JS_GLOBAL_OBJECT_TYPE:
190 case JS_BUILTINS_OBJECT_TYPE:
191 case JS_GLOBAL_PROXY_TYPE:
192 case JS_ARRAY_BUFFER_TYPE:
193 case JS_TYPED_ARRAY_TYPE:
194 case JS_DATA_VIEW_TYPE:
195 case JS_SET_TYPE:
196 case JS_MAP_TYPE:
197 case JS_WEAK_MAP_TYPE:
198 case JS_WEAK_SET_TYPE:
199 if (map->is_undetectable()) return kUndetectable;
200 return kOtherObject;
201 case JS_ARRAY_TYPE:
202 return kArray;
203 case JS_FUNCTION_TYPE:
204 return kFunction;
205 case JS_REGEXP_TYPE:
206 return kRegExp;
207 case JS_PROXY_TYPE:
208 case JS_FUNCTION_PROXY_TYPE:
209 return kProxy;
210 case MAP_TYPE:
211 // When compiling stub templates, the meta map is used as a place holder
212 // for the actual map with which the template is later instantiated.
213 // We treat it as a kind of type variable whose upper bound is Any.
214 // TODO(rossberg): for caching of CompareNilIC stubs to work correctly,
215 // we must exclude Undetectable here. This makes no sense, really,
216 // because it means that the template isn't actually parametric.
217 // Also, it doesn't apply elsewhere. 8-(
218 // We ought to find a cleaner solution for compiling stubs parameterised
219 // over type or class variables, esp ones with bounds...
220 return kDetectable;
221 case DECLARED_ACCESSOR_INFO_TYPE:
222 case EXECUTABLE_ACCESSOR_INFO_TYPE:
223 case ACCESSOR_PAIR_TYPE:
224 case FIXED_ARRAY_TYPE:
225 return kInternal;
226 default:
227 UNREACHABLE();
228 return kNone;
229 }
230 }
231
226 232
227 // Get the largest bitset subsumed by this type. 233 // Get the largest bitset subsumed by this type.
228 int Type::GlbBitset() { 234 int Type::GlbBitset() {
229 if (this->is_bitset()) { 235 if (this->is_bitset()) {
230 return this->as_bitset(); 236 return this->as_bitset();
231 } else if (this->is_union()) { 237 } else if (this->is_union()) {
232 // All but the first are non-bitsets and thus would yield kNone anyway. 238 // All but the first are non-bitsets and thus would yield kNone anyway.
233 return union_get(this->as_union(), 0)->GlbBitset(); 239 return union_get(this->as_union(), 0)->GlbBitset();
234 } else { 240 } else {
235 return kNone; 241 return kNone;
236 } 242 }
237 } 243 }
238 244
239 245
246 // Most precise _current_ type of a value (usually its class).
247 Type* Type::CurrentOf(Handle<i::Object> value) {
248 if (value->IsSmi()) return Smi();
249 i::Map* map = i::HeapObject::cast(*value)->map();
250 if (map->instance_type() == HEAP_NUMBER_TYPE ||
251 map->instance_type() == ODDBALL_TYPE) {
252 return Type::Of(value);
253 }
254 return Class(i::handle(map));
255 }
256
257
240 // Check this <= that. 258 // Check this <= that.
241 bool Type::SlowIs(Type* that) { 259 bool Type::SlowIs(Type* that) {
242 // Fast path for bitsets. 260 // Fast path for bitsets.
243 if (this->is_none()) return true; 261 if (this->is_none()) return true;
244 if (that->is_bitset()) { 262 if (that->is_bitset()) {
245 return (this->LubBitset() | that->as_bitset()) == that->as_bitset(); 263 return (this->LubBitset() | that->as_bitset()) == that->as_bitset();
246 } 264 }
247 265
248 if (that->is_class()) { 266 if (that->is_class()) {
249 return this->is_class() && *this->as_class() == *that->as_class(); 267 return this->is_class() && *this->as_class() == *that->as_class();
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 // Semi-fast case: Unioned objects are neither involved nor produced. 385 // Semi-fast case: Unioned objects are neither involved nor produced.
368 if (!(type1->is_union() || type2->is_union())) { 386 if (!(type1->is_union() || type2->is_union())) {
369 if (type1->Is(type2)) return *type2; 387 if (type1->Is(type2)) return *type2;
370 if (type2->Is(type1)) return *type1; 388 if (type2->Is(type1)) return *type1;
371 } 389 }
372 390
373 // Slow case: may need to produce a Unioned object. 391 // Slow case: may need to produce a Unioned object.
374 Isolate* isolate = NULL; 392 Isolate* isolate = NULL;
375 int size = type1->is_bitset() || type2->is_bitset() ? 1 : 0; 393 int size = type1->is_bitset() || type2->is_bitset() ? 1 : 0;
376 if (!type1->is_bitset()) { 394 if (!type1->is_bitset()) {
377 isolate = HeapObject::cast(*type1)->GetIsolate(); 395 isolate = i::HeapObject::cast(*type1)->GetIsolate();
378 size += (type1->is_union() ? type1->as_union()->length() : 1); 396 size += (type1->is_union() ? type1->as_union()->length() : 1);
379 } 397 }
380 if (!type2->is_bitset()) { 398 if (!type2->is_bitset()) {
381 isolate = HeapObject::cast(*type2)->GetIsolate(); 399 isolate = i::HeapObject::cast(*type2)->GetIsolate();
382 size += (type2->is_union() ? type2->as_union()->length() : 1); 400 size += (type2->is_union() ? type2->as_union()->length() : 1);
383 } 401 }
384 ASSERT(isolate != NULL); 402 ASSERT(isolate != NULL);
385 ASSERT(size >= 2); 403 ASSERT(size >= 2);
386 Handle<Unioned> unioned = isolate->factory()->NewFixedArray(size); 404 Handle<Unioned> unioned = isolate->factory()->NewFixedArray(size);
387 size = 0; 405 size = 0;
388 406
389 int bitset = type1->GlbBitset() | type2->GlbBitset(); 407 int bitset = type1->GlbBitset() | type2->GlbBitset();
390 if (bitset != kNone) unioned->set(size++, from_bitset(bitset)); 408 if (bitset != kNone) unioned->set(size++, from_bitset(bitset));
391 size = type1->ExtendUnion(unioned, size); 409 size = type1->ExtendUnion(unioned, size);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 // Semi-fast case: Unioned objects are neither involved nor produced. 461 // Semi-fast case: Unioned objects are neither involved nor produced.
444 if (!(type1->is_union() || type2->is_union())) { 462 if (!(type1->is_union() || type2->is_union())) {
445 if (type1->Is(type2)) return *type1; 463 if (type1->Is(type2)) return *type1;
446 if (type2->Is(type1)) return *type2; 464 if (type2->Is(type1)) return *type2;
447 } 465 }
448 466
449 // Slow case: may need to produce a Unioned object. 467 // Slow case: may need to produce a Unioned object.
450 Isolate* isolate = NULL; 468 Isolate* isolate = NULL;
451 int size = 0; 469 int size = 0;
452 if (!type1->is_bitset()) { 470 if (!type1->is_bitset()) {
453 isolate = HeapObject::cast(*type1)->GetIsolate(); 471 isolate = i::HeapObject::cast(*type1)->GetIsolate();
454 size = (type1->is_union() ? type1->as_union()->length() : 2); 472 size = (type1->is_union() ? type1->as_union()->length() : 2);
455 } 473 }
456 if (!type2->is_bitset()) { 474 if (!type2->is_bitset()) {
457 isolate = HeapObject::cast(*type2)->GetIsolate(); 475 isolate = i::HeapObject::cast(*type2)->GetIsolate();
458 int size2 = (type2->is_union() ? type2->as_union()->length() : 2); 476 int size2 = (type2->is_union() ? type2->as_union()->length() : 2);
459 size = (size == 0 ? size2 : Min(size, size2)); 477 size = (size == 0 ? size2 : Min(size, size2));
460 } 478 }
461 ASSERT(isolate != NULL); 479 ASSERT(isolate != NULL);
462 ASSERT(size >= 2); 480 ASSERT(size >= 2);
463 Handle<Unioned> unioned = isolate->factory()->NewFixedArray(size); 481 Handle<Unioned> unioned = isolate->factory()->NewFixedArray(size);
464 size = 0; 482 size = 0;
465 483
466 int bitset = type1->GlbBitset() & type2->GlbBitset(); 484 int bitset = type1->GlbBitset() & type2->GlbBitset();
467 if (bitset != kNone) unioned->set(size++, from_bitset(bitset)); 485 if (bitset != kNone) unioned->set(size++, from_bitset(bitset));
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 if (i > 0) PrintF(out, ","); 560 if (i > 0) PrintF(out, ",");
543 type_i->TypePrint(out); 561 type_i->TypePrint(out);
544 } 562 }
545 PrintF(out, "}"); 563 PrintF(out, "}");
546 } 564 }
547 } 565 }
548 #endif 566 #endif
549 567
550 568
551 } } // namespace v8::internal 569 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/types.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698