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

Side by Side Diff: src/types.cc

Issue 142813003: A64: Synchronize with r15358. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 months 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') | src/typing.h » ('j') | 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 for (int i = 0; i < unioned->length(); ++i) { 118 for (int i = 0; i < unioned->length(); ++i) {
119 bitset |= union_get(unioned, i)->LubBitset(); 119 bitset |= union_get(unioned, i)->LubBitset();
120 } 120 }
121 return bitset; 121 return bitset;
122 } else { 122 } else {
123 Map* map = NULL; 123 Map* map = NULL;
124 if (this->is_class()) { 124 if (this->is_class()) {
125 map = *this->as_class(); 125 map = *this->as_class();
126 } else { 126 } else {
127 Handle<v8::internal::Object> value = this->as_constant(); 127 Handle<v8::internal::Object> value = this->as_constant();
128 if (value->IsSmi()) return kInteger31; 128 if (value->IsSmi()) return kSmi;
129 map = HeapObject::cast(*value)->map(); 129 map = HeapObject::cast(*value)->map();
130 if (map->instance_type() == ODDBALL_TYPE) { 130 if (map->instance_type() == ODDBALL_TYPE) {
131 if (value->IsUndefined()) return kUndefined; 131 if (value->IsUndefined()) return kUndefined;
132 if (value->IsNull()) return kNull; 132 if (value->IsNull()) return kNull;
133 if (value->IsTrue() || value->IsFalse()) return kBoolean; 133 if (value->IsTrue() || value->IsFalse()) return kBoolean;
134 } 134 }
135 } 135 }
136 switch (map->instance_type()) { 136 switch (map->instance_type()) {
137 case STRING_TYPE: 137 case STRING_TYPE:
138 case ASCII_STRING_TYPE: 138 case ASCII_STRING_TYPE:
(...skipping 28 matching lines...) Expand all
167 case JS_DATE_TYPE: 167 case JS_DATE_TYPE:
168 case JS_OBJECT_TYPE: 168 case JS_OBJECT_TYPE:
169 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 169 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
170 case JS_GENERATOR_OBJECT_TYPE: 170 case JS_GENERATOR_OBJECT_TYPE:
171 case JS_MODULE_TYPE: 171 case JS_MODULE_TYPE:
172 case JS_GLOBAL_OBJECT_TYPE: 172 case JS_GLOBAL_OBJECT_TYPE:
173 case JS_BUILTINS_OBJECT_TYPE: 173 case JS_BUILTINS_OBJECT_TYPE:
174 case JS_GLOBAL_PROXY_TYPE: 174 case JS_GLOBAL_PROXY_TYPE:
175 case JS_ARRAY_BUFFER_TYPE: 175 case JS_ARRAY_BUFFER_TYPE:
176 case JS_TYPED_ARRAY_TYPE: 176 case JS_TYPED_ARRAY_TYPE:
177 case JS_DATA_VIEW_TYPE:
178 case JS_SET_TYPE:
179 case JS_MAP_TYPE:
177 case JS_WEAK_MAP_TYPE: 180 case JS_WEAK_MAP_TYPE:
178 case JS_REGEXP_TYPE:
179 if (map->is_undetectable()) return kUndetectable; 181 if (map->is_undetectable()) return kUndetectable;
180 return kOtherObject; 182 return kOtherObject;
181 case JS_ARRAY_TYPE: 183 case JS_ARRAY_TYPE:
182 return kArray; 184 return kArray;
183 case JS_FUNCTION_TYPE: 185 case JS_FUNCTION_TYPE:
184 return kFunction; 186 return kFunction;
187 case JS_REGEXP_TYPE:
188 return kRegExp;
185 case JS_PROXY_TYPE: 189 case JS_PROXY_TYPE:
186 case JS_FUNCTION_PROXY_TYPE: 190 case JS_FUNCTION_PROXY_TYPE:
187 return kProxy; 191 return kProxy;
188 case MAP_TYPE: 192 case MAP_TYPE:
189 // When compiling stub templates, the meta map is used as a place holder 193 // When compiling stub templates, the meta map is used as a place holder
190 // for the actual map with which the template is later instantiated. 194 // for the actual map with which the template is later instantiated.
191 // We treat it as a kind of type variable whose upper bound is Any. 195 // We treat it as a kind of type variable whose upper bound is Any.
192 // TODO(rossberg): for caching of CompareNilIC stubs to work correctly, 196 // TODO(rossberg): for caching of CompareNilIC stubs to work correctly,
193 // we must exclude Undetectable here. This makes no sense, really, 197 // we must exclude Undetectable here. This makes no sense, really,
194 // because it means that the template isn't actually parametric. 198 // because it means that the template isn't actually parametric.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 Handle<Unioned> unioned = this->as_union(); 240 Handle<Unioned> unioned = this->as_union();
237 for (int i = 0; i < unioned->length(); ++i) { 241 for (int i = 0; i < unioned->length(); ++i) {
238 Handle<Type> this_i = union_get(unioned, i); 242 Handle<Type> this_i = union_get(unioned, i);
239 if (!this_i->Is(that)) return false; 243 if (!this_i->Is(that)) return false;
240 } 244 }
241 return true; 245 return true;
242 } 246 }
243 247
244 // T <= (T1 \/ ... \/ Tn) <=> (T <= T1) \/ ... \/ (T <= Tn) 248 // T <= (T1 \/ ... \/ Tn) <=> (T <= T1) \/ ... \/ (T <= Tn)
245 // (iff T is not a union) 249 // (iff T is not a union)
250 ASSERT(!this->is_union());
246 if (that->is_union()) { 251 if (that->is_union()) {
247 Handle<Unioned> unioned = that->as_union(); 252 Handle<Unioned> unioned = that->as_union();
248 for (int i = 0; i < unioned->length(); ++i) { 253 for (int i = 0; i < unioned->length(); ++i) {
249 Handle<Type> that_i = union_get(unioned, i); 254 Handle<Type> that_i = union_get(unioned, i);
250 if (this->Is(that_i)) return true; 255 if (this->Is(that_i)) return true;
251 if (this->is_bitset()) break; // Fast fail, no other field is a bitset. 256 if (this->is_bitset()) break; // Fast fail, no other field is a bitset.
252 } 257 }
253 return false; 258 return false;
254 } 259 }
255 260
256 return false; 261 return false;
257 } 262 }
258 263
259 264
260 // Check this overlaps that. 265 // Check this overlaps that.
261 bool Type::Maybe(Type* that) { 266 bool Type::Maybe(Type* that) {
262 // Fast path for bitsets. 267 // Fast path for bitsets.
263 if (this->is_bitset()) { 268 if (this->is_bitset()) {
264 return (this->as_bitset() & that->LubBitset()) != 0; 269 return (this->as_bitset() & that->LubBitset()) != 0;
265 } 270 }
266 if (that->is_bitset()) { 271 if (that->is_bitset()) {
267 return (this->LubBitset() & that->as_bitset()) != 0; 272 return (this->LubBitset() & that->as_bitset()) != 0;
268 } 273 }
269 274
270 if (this->is_class()) {
271 return that->is_class() && *this->as_class() == *that->as_class();
272 }
273 if (this->is_constant()) {
274 return that->is_constant() && *this->as_constant() == *that->as_constant();
275 }
276
277 // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T) 275 // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T)
278 if (this->is_union()) { 276 if (this->is_union()) {
279 Handle<Unioned> unioned = this->as_union(); 277 Handle<Unioned> unioned = this->as_union();
280 for (int i = 0; i < unioned->length(); ++i) { 278 for (int i = 0; i < unioned->length(); ++i) {
281 Handle<Type> this_i = union_get(unioned, i); 279 Handle<Type> this_i = union_get(unioned, i);
282 if (this_i->Maybe(that)) return true; 280 if (this_i->Maybe(that)) return true;
283 } 281 }
284 return false; 282 return false;
285 } 283 }
286 284
287 // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn) 285 // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn)
288 if (that->is_union()) { 286 if (that->is_union()) {
289 Handle<Unioned> unioned = that->as_union(); 287 Handle<Unioned> unioned = that->as_union();
290 for (int i = 0; i < unioned->length(); ++i) { 288 for (int i = 0; i < unioned->length(); ++i) {
291 Handle<Type> that_i = union_get(unioned, i); 289 Handle<Type> that_i = union_get(unioned, i);
292 if (this->Maybe(that_i)) return true; 290 if (this->Maybe(that_i)) return true;
293 } 291 }
294 return false; 292 return false;
295 } 293 }
296 294
295 ASSERT(!that->is_union());
296 if (this->is_class()) {
297 return that->is_class() && *this->as_class() == *that->as_class();
298 }
299 if (this->is_constant()) {
300 return that->is_constant() && *this->as_constant() == *that->as_constant();
301 }
302
297 return false; 303 return false;
298 } 304 }
299 305
300 306
301 bool Type::InUnion(Handle<Unioned> unioned, int current_size) { 307 bool Type::InUnion(Handle<Unioned> unioned, int current_size) {
302 ASSERT(!this->is_union()); 308 ASSERT(!this->is_union());
303 for (int i = 0; i < current_size; ++i) { 309 for (int i = 0; i < current_size; ++i) {
304 Handle<Type> type = union_get(unioned, i); 310 Handle<Type> type = union_get(unioned, i);
305 if (type->is_bitset() ? this->Is(type) : this == *type) return true; 311 if (this->Is(type)) return true;
306 } 312 }
307 return false; 313 return false;
308 } 314 }
309 315
310 // Get non-bitsets from this which are not subsumed by that, store at unioned, 316 // Get non-bitsets from this which are not subsumed by union, store at unioned,
311 // starting at index. Returns updated index. 317 // starting at index. Returns updated index.
312 int Type::ExtendUnion(Handle<Unioned> result, int current_size) { 318 int Type::ExtendUnion(Handle<Unioned> result, int current_size) {
313 int old_size = current_size; 319 int old_size = current_size;
314 if (this->is_class() || this->is_constant()) { 320 if (this->is_class() || this->is_constant()) {
315 if (!this->InUnion(result, old_size)) result->set(current_size++, this); 321 if (!this->InUnion(result, old_size)) result->set(current_size++, this);
316 } else if (this->is_union()) { 322 } else if (this->is_union()) {
317 Handle<Unioned> unioned = this->as_union(); 323 Handle<Unioned> unioned = this->as_union();
318 for (int i = 0; i < unioned->length(); ++i) { 324 for (int i = 0; i < unioned->length(); ++i) {
319 Handle<Type> type = union_get(unioned, i); 325 Handle<Type> type = union_get(unioned, i);
320 ASSERT(i == 0 || !(type->is_bitset() || type->Is(union_get(unioned, 0)))); 326 ASSERT(i == 0 || !(type->is_bitset() || type->Is(union_get(unioned, 0))));
321 if (type->is_bitset()) continue; 327 if (type->is_bitset()) continue;
322 if (!type->InUnion(result, old_size)) result->set(current_size++, *type); 328 if (!type->InUnion(result, old_size)) result->set(current_size++, *type);
323 } 329 }
324 } 330 }
325 return current_size; 331 return current_size;
326 } 332 }
327 333
328 334
329 // Union is O(1) on simple bit unions, but O(n*m) on structured unions. 335 // Union is O(1) on simple bit unions, but O(n*m) on structured unions.
330 // TODO(rossberg): Should we use object sets somehow? Is it worth it? 336 // TODO(rossberg): Should we use object sets somehow? Is it worth it?
331 Type* Type::Union(Handle<Type> type1, Handle<Type> type2) { 337 Type* Type::Union(Handle<Type> type1, Handle<Type> type2) {
332 // Fast case: bit sets. 338 // Fast case: bit sets.
333 if (type1->is_bitset() && type2->is_bitset()) { 339 if (type1->is_bitset() && type2->is_bitset()) {
334 return from_bitset(type1->as_bitset() | type2->as_bitset()); 340 return from_bitset(type1->as_bitset() | type2->as_bitset());
335 } 341 }
336 342
343 // Fast case: top or bottom types.
344 if (type1->SameValue(Type::Any())) return *type1;
345 if (type2->SameValue(Type::Any())) return *type2;
346 if (type1->SameValue(Type::None())) return *type2;
347 if (type2->SameValue(Type::None())) return *type1;
348
337 // Semi-fast case: Unioned objects are neither involved nor produced. 349 // Semi-fast case: Unioned objects are neither involved nor produced.
338 if (!(type1->is_union() || type2->is_union())) { 350 if (!(type1->is_union() || type2->is_union())) {
339 if (type1->Is(type2)) return *type2; 351 if (type1->Is(type2)) return *type2;
340 if (type2->Is(type1)) return *type1; 352 if (type2->Is(type1)) return *type1;
341 } 353 }
342 354
343 // Slow case: may need to produce a Unioned object. 355 // Slow case: may need to produce a Unioned object.
344 Isolate* isolate = NULL; 356 Isolate* isolate = NULL;
345 int size = type1->is_bitset() || type2->is_bitset() ? 1 : 0; 357 int size = type1->is_bitset() || type2->is_bitset() ? 1 : 0;
346 if (!type1->is_bitset()) { 358 if (!type1->is_bitset()) {
(...skipping 20 matching lines...) Expand all
367 return from_handle(unioned); 379 return from_handle(unioned);
368 } 380 }
369 381
370 // There was an overlap. Copy to smaller union. 382 // There was an overlap. Copy to smaller union.
371 Handle<Unioned> result = isolate->factory()->NewFixedArray(size); 383 Handle<Unioned> result = isolate->factory()->NewFixedArray(size);
372 for (int i = 0; i < size; ++i) result->set(i, unioned->get(i)); 384 for (int i = 0; i < size; ++i) result->set(i, unioned->get(i));
373 return from_handle(result); 385 return from_handle(result);
374 } 386 }
375 387
376 388
389 // Get non-bitsets from this which are also in that, store at unioned,
390 // starting at index. Returns updated index.
391 int Type::ExtendIntersection(
392 Handle<Unioned> result, Handle<Type> that, int current_size) {
393 int old_size = current_size;
394 if (this->is_class() || this->is_constant()) {
395 if (this->Is(that) && !this->InUnion(result, old_size))
396 result->set(current_size++, this);
397 } else if (this->is_union()) {
398 Handle<Unioned> unioned = this->as_union();
399 for (int i = 0; i < unioned->length(); ++i) {
400 Handle<Type> type = union_get(unioned, i);
401 ASSERT(i == 0 || !(type->is_bitset() || type->Is(union_get(unioned, 0))));
402 if (type->is_bitset()) continue;
403 if (type->Is(that) && !type->InUnion(result, old_size))
404 result->set(current_size++, *type);
405 }
406 }
407 return current_size;
408 }
409
410
411 // Intersection is O(1) on simple bit unions, but O(n*m) on structured unions.
412 // TODO(rossberg): Should we use object sets somehow? Is it worth it?
413 Type* Type::Intersect(Handle<Type> type1, Handle<Type> type2) {
414 // Fast case: bit sets.
415 if (type1->is_bitset() && type2->is_bitset()) {
416 return from_bitset(type1->as_bitset() & type2->as_bitset());
417 }
418
419 // Fast case: top or bottom types.
420 if (type1->SameValue(Type::None())) return *type1;
421 if (type2->SameValue(Type::None())) return *type2;
422 if (type1->SameValue(Type::Any())) return *type2;
423 if (type2->SameValue(Type::Any())) return *type1;
424
425 // Semi-fast case: Unioned objects are neither involved nor produced.
426 if (!(type1->is_union() || type2->is_union())) {
427 if (type1->Is(type2)) return *type1;
428 if (type2->Is(type1)) return *type2;
429 }
430
431 // Slow case: may need to produce a Unioned object.
432 Isolate* isolate = NULL;
433 int size = 0;
434 if (!type1->is_bitset()) {
435 isolate = HeapObject::cast(*type1)->GetIsolate();
436 size = (type1->is_union() ? type1->as_union()->length() : 2);
437 }
438 if (!type2->is_bitset()) {
439 isolate = HeapObject::cast(*type2)->GetIsolate();
440 int size2 = (type2->is_union() ? type2->as_union()->length() : 2);
441 size = (size == 0 ? size2 : Min(size, size2));
442 }
443 ASSERT(isolate != NULL);
444 ASSERT(size >= 2);
445 Handle<Unioned> unioned = isolate->factory()->NewFixedArray(size);
446 size = 0;
447
448 int bitset = type1->GlbBitset() & type2->GlbBitset();
449 if (bitset != kNone) unioned->set(size++, from_bitset(bitset));
450 size = type1->ExtendIntersection(unioned, type2, size);
451 size = type2->ExtendIntersection(unioned, type1, size);
452
453 if (size == 0) {
454 return None();
455 } else if (size == 1) {
456 return *union_get(unioned, 0);
457 } else if (size == unioned->length()) {
458 return from_handle(unioned);
459 }
460
461 // There were dropped cases. Copy to smaller union.
462 Handle<Unioned> result = isolate->factory()->NewFixedArray(size);
463 for (int i = 0; i < size; ++i) result->set(i, unioned->get(i));
464 return from_handle(result);
465 }
466
467
377 Type* Type::Optional(Handle<Type> type) { 468 Type* Type::Optional(Handle<Type> type) {
378 return type->is_bitset() 469 return type->is_bitset()
379 ? from_bitset(type->as_bitset() | kUndefined) 470 ? from_bitset(type->as_bitset() | kUndefined)
380 : Union(type, Undefined()->handle_via_isolate_of(*type)); 471 : Union(type, Undefined()->handle_via_isolate_of(*type));
381 } 472 }
382 473
383 } } // namespace v8::internal 474 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/types.h ('k') | src/typing.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698