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

Side by Side Diff: runtime/vm/code_generator.cc

Issue 10317026: Inline type checks for complex uninstantiated types, e.g., List<T>. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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 | « no previous file | runtime/vm/code_generator_ia32.h » ('j') | runtime/vm/code_generator_ia32.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/code_generator.h" 5 #include "vm/code_generator.h"
6 6
7 #include "vm/code_patcher.h" 7 #include "vm/code_patcher.h"
8 #include "vm/compiler.h" 8 #include "vm/compiler.h"
9 #include "vm/dart_api_impl.h" 9 #include "vm/dart_api_impl.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 cloned_ctx.SetAt(i, Instance::Handle(ctx.At(i))); 372 cloned_ctx.SetAt(i, Instance::Handle(ctx.At(i)));
373 } 373 }
374 arguments.SetReturn(cloned_ctx); 374 arguments.SetReturn(cloned_ctx);
375 } 375 }
376 376
377 377
378 // Helper routine for tracing a type check. 378 // Helper routine for tracing a type check.
379 static void PrintTypeCheck(const char* message, 379 static void PrintTypeCheck(const char* message,
380 const Instance& instance, 380 const Instance& instance,
381 const AbstractType&type, 381 const AbstractType&type,
382 const AbstractTypeArguments& type_instantiator, 382 const AbstractTypeArguments& instantiator_targs,
regis 2012/05/04 21:53:39 "targs" sounds like "targets". I have always tried
srdjan 2012/05/04 23:01:58 Using instantiator_type_arguments.
383 const Bool& result) { 383 const Bool& result) {
384 DartFrameIterator iterator;
385 StackFrame* caller_frame = iterator.NextFrame();
386 ASSERT(caller_frame != NULL);
387
384 const Type& instance_type = Type::Handle(instance.GetType()); 388 const Type& instance_type = Type::Handle(instance.GetType());
385 ASSERT(instance_type.IsInstantiated()); 389 ASSERT(instance_type.IsInstantiated());
386 if (type.IsInstantiated()) { 390 if (type.IsInstantiated()) {
387 OS::Print("%s: '%s' %s '%s'.\n", 391 OS::Print("%s: '%s' %s '%s' (pc: 0x%x).\n",
388 message, 392 message,
389 String::Handle(instance_type.Name()).ToCString(), 393 String::Handle(instance_type.Name()).ToCString(),
390 (result.raw() == Bool::True()) ? "is" : "is !", 394 (result.raw() == Bool::True()) ? "is" : "is !",
391 String::Handle(type.Name()).ToCString()); 395 String::Handle(type.Name()).ToCString(),
396 caller_frame->pc());
392 } else { 397 } else {
393 // Instantiate type before printing. 398 // Instantiate type before printing.
394 const AbstractType& instantiated_type = 399 const AbstractType& instantiated_type =
395 AbstractType::Handle(type.InstantiateFrom(type_instantiator)); 400 AbstractType::Handle(type.InstantiateFrom(instantiator_targs));
396 OS::Print("%s: '%s' %s '%s' instantiated from '%s'.\n", 401 OS::Print("%s: '%s' %s '%s' instantiated from '%s' (pc: 0x%x).\n",
397 message, 402 message,
398 String::Handle(instance_type.Name()).ToCString(), 403 String::Handle(instance_type.Name()).ToCString(),
399 (result.raw() == Bool::True()) ? "is" : "is !", 404 (result.raw() == Bool::True()) ? "is" : "is !",
400 String::Handle(instantiated_type.Name()).ToCString(), 405 String::Handle(instantiated_type.Name()).ToCString(),
401 String::Handle(type.Name()).ToCString()); 406 String::Handle(type.Name()).ToCString(),
407 caller_frame->pc());
402 } 408 }
403 DartFrameIterator iterator;
404 StackFrame* caller_frame = iterator.NextFrame();
405 ASSERT(caller_frame != NULL);
406 const Function& function = Function::Handle( 409 const Function& function = Function::Handle(
407 caller_frame->LookupDartFunction()); 410 caller_frame->LookupDartFunction());
408 OS::Print(" -> Function %s\n", function.ToFullyQualifiedCString()); 411 OS::Print(" -> Function %s\n", function.ToFullyQualifiedCString());
409 } 412 }
410 413
411 414
412 // Converts InstantiatedTypeArguments to TypeArguments and stores it 415 // Converts InstantiatedTypeArguments to TypeArguments and stores it
413 // into the instance. The assembly code can handle only type arguments of 416 // into the instance. The assembly code can handle only type arguments of
414 // class TypeArguments. Because of the overhead, do it only when needed. 417 // class TypeArguments. Because of the overhead, do it only when needed.
415 static void OptimizeTypeArguments(const Instance& instance) { 418 // Return false if the optimization was aborted.
419 // Set type_arguments_replaced to true if they have changed.
420 static bool OptimizeTypeArguments(const Instance& instance,
421 bool* type_arguments_replaced) {
422 *type_arguments_replaced = false;
416 const Class& type_class = Class::ZoneHandle(instance.clazz()); 423 const Class& type_class = Class::ZoneHandle(instance.clazz());
417 if (type_class.HasTypeArguments()) { 424 if (!type_class.HasTypeArguments()) {
418 const AbstractTypeArguments& type_arguments = 425 return true;
419 AbstractTypeArguments::Handle(instance.GetTypeArguments()); 426 }
420 if (!type_arguments.IsNull() && 427 const AbstractTypeArguments& type_arguments =
421 type_arguments.IsInstantiatedTypeArguments()) { 428 AbstractTypeArguments::Handle(instance.GetTypeArguments());
422 TypeArguments& new_type_arguments = 429 if (type_arguments.IsNull()) {
423 TypeArguments::Handle(TypeArguments::New(type_arguments.Length())); 430 return true;
424 for (int i = 0; i < type_arguments.Length(); i++) { 431 }
425 const AbstractType& type_at = 432 if (type_arguments.IsInstantiatedTypeArguments()) {
426 AbstractType::Handle(type_arguments.TypeAt(i)); 433 TypeArguments& new_type_arguments =
regis 2012/05/04 21:53:39 I think you can simply call new_type_arguments = t
srdjan 2012/05/04 23:01:58 Thanks, very nice!
427 if (type_at.IsInstantiatedType()) { 434 TypeArguments::Handle(TypeArguments::New(type_arguments.Length()));
428 // TODO(srdjan): cannot canonicalize TypeArguments that contain 435 for (int i = 0; i < type_arguments.Length(); i++) {
429 // InstantiatedType. 436 const AbstractType& type_at =
430 return; 437 AbstractType::Handle(type_arguments.TypeAt(i));
431 } else if (!type_at.IsType()) { 438 if (type_at.IsInstantiatedType()) {
432 // type_at cannot be TypeParameter at runtime. 439 // TODO(srdjan): cannot canonicalize TypeArguments that contain
433 UNREACHABLE(); 440 // InstantiatedType.
434 } 441 return false;
435 new_type_arguments.SetTypeAt(i, type_at); 442 } else if (!type_at.IsType()) {
443 // type_at cannot be TypeParameter at runtime.
444 UNREACHABLE();
436 } 445 }
437 new_type_arguments ^= new_type_arguments.Canonicalize(); 446 new_type_arguments.SetTypeAt(i, type_at);
438 instance.SetTypeArguments(new_type_arguments);
439 } 447 }
448 new_type_arguments ^= new_type_arguments.Canonicalize();
449 instance.SetTypeArguments(new_type_arguments);
450 *type_arguments_replaced = true;
451 } else if (!type_arguments.IsCanonical()) {
452 AbstractTypeArguments& new_type_arguments =
453 AbstractTypeArguments::Handle();
454 new_type_arguments ^= type_arguments.Canonicalize();
455 instance.SetTypeArguments(new_type_arguments);
456 *type_arguments_replaced = true;
440 } 457 }
458 ASSERT(AbstractTypeArguments::Handle(
459 instance.GetTypeArguments()).IsTypeArguments());
460 return true;
441 } 461 }
442 462
443 463
444 // This updates the type test cache, an array containing 4-value elements 464 // This updates the type test cache, an array containing 4-value elements
445 // (instance class, instance type arguments, instantiator type arguments and 465 // (instance class, instance type arguments, instantiator type arguments and
446 // test_result). It can be applied to classes with type arguments in which 466 // test_result). It can be applied to classes with type arguments in which
447 // case it contains just the result of the class subtype test, not including 467 // case it contains just the result of the class subtype test, not including
448 // the evaluation of type arguments. 468 // the evaluation of type arguments.
449 // This operation is currently very slow (lookup of code is not efficient yet). 469 // This operation is currently very slow (lookup of code is not efficient yet).
450 static void UpdateTypeTestCache(intptr_t node_id, 470 // 'instantiator' can be null, in which case inst_targ
451 const Instance& instance, 471 static void UpdateTypeTestCache(
452 const AbstractType& type, 472 intptr_t node_id,
453 const AbstractTypeArguments& type_instantiator, 473 const Instance& instance,
454 const Bool& result, 474 const AbstractType& type,
455 const SubtypeTestCache& new_cache) { 475 const Instance& instantiator,
476 const AbstractTypeArguments& instantiator_type_arguments,
477 const Bool& result,
478 const SubtypeTestCache& new_cache) {
456 // Since the test is expensive, don't do it unless necessary. 479 // Since the test is expensive, don't do it unless necessary.
457 // The list of disallowed cases will decrease as they are implemented in 480 // The list of disallowed cases will decrease as they are implemented in
458 // inlined assembly. 481 // inlined assembly.
459 if (new_cache.IsNull()) return; 482 if (new_cache.IsNull()) return;
483 // Instantiator type arguments may be canonicalized later.
484 AbstractTypeArguments& instantiator_targs =
regis 2012/05/04 21:53:39 instantiator_type_arguments?
srdjan 2012/05/04 23:01:58 Done.
485 AbstractTypeArguments::Handle(instantiator_type_arguments.raw());
460 AbstractTypeArguments& instance_type_arguments = 486 AbstractTypeArguments& instance_type_arguments =
461 AbstractTypeArguments::Handle(); 487 AbstractTypeArguments::Handle();
462 const Class& instance_class = Class::Handle(instance.clazz()); 488 const Class& instance_class = Class::Handle(instance.clazz());
463 AbstractTypeArguments& original_instance_type_arguments = 489
464 AbstractTypeArguments::Handle(); 490 // Canonicalize type arguments.
491 bool type_arguments_replaced = false;
465 if (instance_class.HasTypeArguments()) { 492 if (instance_class.HasTypeArguments()) {
466 // Canonicalize type arguments. 493 // Canonicalize type arguments.
467 original_instance_type_arguments = instance.GetTypeArguments(); 494 if (!OptimizeTypeArguments(instance, &type_arguments_replaced)) {
468 OptimizeTypeArguments(instance); 495 if (FLAG_trace_type_checks) {
496 PrintTypeCheck("WARNING: Cannot canonicalize instance type arguments",
497 instance, type, instantiator_targs, result);
498 }
499 return;
500 }
469 instance_type_arguments = instance.GetTypeArguments(); 501 instance_type_arguments = instance.GetTypeArguments();
470 } 502 }
503 if (!instantiator.IsNull()) {
504 bool replaced = false;
505 if (!OptimizeTypeArguments(instantiator, &replaced)) {
506 if (FLAG_trace_type_checks) {
507 PrintTypeCheck("WARNING: Cannot canonicalize instantiator "
508 "type arguments",
509 instance, type, instantiator_targs, result);
510 }
511 return;
512 }
513 if (replaced) {
514 type_arguments_replaced = true;
515 }
516 instantiator_targs ^= instantiator.GetTypeArguments();
517 }
471 518
472 Class& last_instance_class = Class::Handle(); 519 Class& last_instance_class = Class::Handle();
473 AbstractTypeArguments& last_instance_type_arguments = 520 AbstractTypeArguments& last_instance_type_arguments =
474 AbstractTypeArguments::Handle(); 521 AbstractTypeArguments::Handle();
475 AbstractTypeArguments& last_instantiator_type_arguments = 522 AbstractTypeArguments& last_instantiator_type_arguments =
476 AbstractTypeArguments::Handle(); 523 AbstractTypeArguments::Handle();
477 Bool& last_result = Bool::Handle(); 524 Bool& last_result = Bool::Handle();
478 intptr_t len = new_cache.NumberOfChecks(); 525 intptr_t len = new_cache.NumberOfChecks();
479 for (intptr_t i = 0; i < len; ++i) { 526 for (intptr_t i = 0; i < len; ++i) {
480 new_cache.GetCheck( 527 new_cache.GetCheck(
481 i, 528 i,
482 &last_instance_class, 529 &last_instance_class,
483 &last_instance_type_arguments, 530 &last_instance_type_arguments,
484 &last_instantiator_type_arguments, 531 &last_instantiator_type_arguments,
485 &last_result); 532 &last_result);
486 if ((last_instance_class.raw() == instance_class.raw()) && 533 if ((last_instance_class.raw() == instance_class.raw()) &&
487 (last_instance_type_arguments.raw() == 534 (last_instance_type_arguments.raw() == instance_type_arguments.raw()) &&
488 instance_type_arguments.raw())) { 535 (last_instantiator_type_arguments.raw() == instantiator_targs.raw())) {
489 if (FLAG_trace_type_checks) { 536 if (FLAG_trace_type_checks) {
490 if (original_instance_type_arguments.raw() == 537 OS::Print("%d ", i);
491 instance_type_arguments.raw()) { 538 PrintTypeCheck("WARNING duplicate cache entry", instance, type,
492 PrintTypeCheck("WARNING duplicate cache entry", instance, type, 539 instantiator_targs, result);
493 type_instantiator, result);
494 }
495 } 540 }
496 // A duplicate entry found, likely because the instance type arguments 541 // Can occur if we have canonicalized arguments.
497 // were not cacnonicalized before. 542 ASSERT(type_arguments_replaced);
498 return; 543 return;
499 } 544 }
500 } 545 }
501 new_cache.AddCheck(instance_class, 546 new_cache.AddCheck(instance_class,
502 instance_type_arguments, 547 instance_type_arguments,
503 AbstractTypeArguments::Handle(), 548 instantiator_targs,
504 result); 549 result);
505 if (FLAG_trace_type_checks) { 550 if (FLAG_trace_type_checks) {
506 OS::Print(" Updated test cache 0x%x ix:%d:\n" 551 OS::Print(" Updated test cache 0x%x ix:%d:\n"
507 " [0x%x %s, 0x%x %s]\n" 552 " [0x%x %s, 0x%x %s]\n"
508 " [0x%x %s] %s\n", 553 " [0x%x %s, 0x%x %s] %s\n",
509 new_cache.raw(), 554 new_cache.raw(),
510 len, 555 len,
511 instance_class.raw(), 556 instance_class.raw(),
512 instance_class.ToCString(), 557 instance_class.ToCString(),
513 instance_type_arguments.raw(), 558 instance_type_arguments.raw(),
514 instance_type_arguments.ToCString(), 559 instance_type_arguments.ToCString(),
515 type.type_class(), 560 type.type_class(),
516 Class::Handle(type.type_class()).ToCString(), 561 Class::Handle(type.type_class()).ToCString(),
562 instantiator_targs.raw(),
563 instantiator_targs.ToCString(),
517 result.ToCString()); 564 result.ToCString());
518 } 565 }
519 } 566 }
520 567
521 568
522 // Check that the given instance is an instance of the given type. 569 // Check that the given instance is an instance of the given type.
523 // Tested instance may not be null, because the null test is inlined. 570 // Tested instance may not be null, because the null test is inlined.
524 // Arg0: index of the token of the instanceof test (source location). 571 // Arg0: index of the token of the instanceof test (source location).
525 // Arg1: node id of the instanceof node. 572 // Arg1: node id of the instanceof node.
526 // Arg2: instance being checked. 573 // Arg2: instance being checked.
527 // Arg3: type. 574 // Arg3: type.
528 // Arg4: type arguments of the instantiator of the type. 575 // Arg4: instantiator (or null).
529 // Arg5: SubtypeTestCache. 576 // Arg5: type arguments of the instantiator of the type.
577 // Arg6: SubtypeTestCache.
530 // Return value: true or false, or may throw a type error in checked mode. 578 // Return value: true or false, or may throw a type error in checked mode.
531 DEFINE_RUNTIME_ENTRY(Instanceof, 6) { 579 DEFINE_RUNTIME_ENTRY(Instanceof, 7) {
532 ASSERT(arguments.Count() == kInstanceofRuntimeEntry.argument_count()); 580 ASSERT(arguments.Count() == kInstanceofRuntimeEntry.argument_count());
533 // TODO(regis): Get the token index from the PcDesc (via DartFrame). 581 // TODO(regis): Get the token index from the PcDesc (via DartFrame).
534 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); 582 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value();
535 intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value(); 583 intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value();
536 const Instance& instance = Instance::CheckedHandle(arguments.At(2)); 584 const Instance& instance = Instance::CheckedHandle(arguments.At(2));
537 const AbstractType& type = AbstractType::CheckedHandle(arguments.At(3)); 585 const AbstractType& type = AbstractType::CheckedHandle(arguments.At(3));
538 const AbstractTypeArguments& type_instantiator = 586 const Instance& instantiator = Instance::CheckedHandle(arguments.At(4));
539 AbstractTypeArguments::CheckedHandle(arguments.At(4)); 587 const AbstractTypeArguments& instantiator_targs =
regis 2012/05/04 21:53:39 instantiator_type_arguments?
srdjan 2012/05/04 23:01:58 Done.
588 AbstractTypeArguments::CheckedHandle(arguments.At(5));
540 const SubtypeTestCache& cache = 589 const SubtypeTestCache& cache =
541 SubtypeTestCache::CheckedHandle(arguments.At(5)); 590 SubtypeTestCache::CheckedHandle(arguments.At(6));
542 ASSERT(type.IsFinalized()); 591 ASSERT(type.IsFinalized());
543 Error& malformed_error = Error::Handle(); 592 Error& malformed_error = Error::Handle();
544 const Bool& result = Bool::Handle( 593 const Bool& result = Bool::Handle(
545 instance.IsInstanceOf(type, type_instantiator, &malformed_error) ? 594 instance.IsInstanceOf(type, instantiator_targs, &malformed_error) ?
546 Bool::True() : Bool::False()); 595 Bool::True() : Bool::False());
547 if (FLAG_trace_type_checks) { 596 if (FLAG_trace_type_checks) {
548 PrintTypeCheck("InstanceOf", instance, type, type_instantiator, result); 597 PrintTypeCheck("InstanceOf", instance, type, instantiator_targs, result);
549 } 598 }
550 if (!result.value() && !malformed_error.IsNull()) { 599 if (!result.value() && !malformed_error.IsNull()) {
551 // Throw a dynamic type error only if the instanceof test fails. 600 // Throw a dynamic type error only if the instanceof test fails.
552 String& malformed_error_message = String::Handle( 601 String& malformed_error_message = String::Handle(
553 String::New(malformed_error.ToErrorCString())); 602 String::New(malformed_error.ToErrorCString()));
554 const String& no_name = String::Handle(String::NewSymbol("")); 603 const String& no_name = String::Handle(String::NewSymbol(""));
555 Exceptions::CreateAndThrowTypeError( 604 Exceptions::CreateAndThrowTypeError(
556 location, no_name, no_name, no_name, malformed_error_message); 605 location, no_name, no_name, no_name, malformed_error_message);
557 UNREACHABLE(); 606 UNREACHABLE();
558 } 607 }
559 UpdateTypeTestCache( 608 UpdateTypeTestCache(
560 node_id, instance, type, type_instantiator, result, cache); 609 node_id, instance, type, instantiator, instantiator_targs, result, cache);
561 arguments.SetReturn(result); 610 arguments.SetReturn(result);
562 } 611 }
563 612
564 613
565 // For error reporting simplify type name, e.g, all integer types (Smi, Mint, 614 // For error reporting simplify type name, e.g, all integer types (Smi, Mint,
566 // Bigint) a re reported as 'int'. 615 // Bigint) a re reported as 'int'.
567 static RawString* GetSimpleTypeName(const Instance& value) { 616 static RawString* GetSimpleTypeName(const Instance& value) {
568 if (value.IsInteger()) { 617 if (value.IsInteger()) {
569 return String::NewSymbol("int"); 618 return String::NewSymbol("int");
570 } else { 619 } else {
571 return Type::Handle(value.GetType()).Name(); 620 return Type::Handle(value.GetType()).Name();
572 } 621 }
573 } 622 }
574 623
575 624
576 // Check that the type of the given instance is a subtype of the given type and 625 // Check that the type of the given instance is a subtype of the given type and
577 // can therefore be assigned. 626 // can therefore be assigned.
578 // Arg0: index of the token of the assignment (source location). 627 // Arg0: index of the token of the assignment (source location).
579 // Arg1: node-id of the assignemnt. 628 // Arg1: node-id of the assignment.
580 // Arg2: instance being assigned. 629 // Arg2: instance being assigned.
581 // Arg3: type being assigned to. 630 // Arg3: type being assigned to.
582 // Arg4: type arguments of the instantiator of the type being assigned to. 631 // Arg4: instantiator (or null).
583 // Arg5: name of variable being assigned to. 632 // Arg5: type arguments of the instantiator of the type being assigned to.
584 // Arg6: SubtypeTestCache. 633 // Arg6: name of variable being assigned to.
634 // Arg7: SubtypeTestCache.
585 // Return value: instance if a subtype, otherwise throw a TypeError. 635 // Return value: instance if a subtype, otherwise throw a TypeError.
586 DEFINE_RUNTIME_ENTRY(TypeCheck, 7) { 636 DEFINE_RUNTIME_ENTRY(TypeCheck, 8) {
587 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count()); 637 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count());
588 // TODO(regis): Get the token index from the PcDesc (via DartFrame). 638 // TODO(regis): Get the token index from the PcDesc (via DartFrame).
589 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); 639 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value();
590 intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value(); 640 intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value();
591 const Instance& src_instance = Instance::CheckedHandle(arguments.At(2)); 641 const Instance& src_instance = Instance::CheckedHandle(arguments.At(2));
592 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(3)); 642 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(3));
593 const AbstractTypeArguments& dst_type_instantiator = 643 const Instance& dst_instantiator = Instance::CheckedHandle(arguments.At(4));
594 AbstractTypeArguments::CheckedHandle(arguments.At(4)); 644 const AbstractTypeArguments& dst_instantiator_targs =
regis 2012/05/04 21:53:39 instantiator_type_arguments? You can drop dst_
srdjan 2012/05/04 23:01:58 Done.
595 const String& dst_name = String::CheckedHandle(arguments.At(5)); 645 AbstractTypeArguments::CheckedHandle(arguments.At(5));
646 const String& dst_name = String::CheckedHandle(arguments.At(6));
596 const SubtypeTestCache& cache = 647 const SubtypeTestCache& cache =
597 SubtypeTestCache::CheckedHandle(arguments.At(6)); 648 SubtypeTestCache::CheckedHandle(arguments.At(7));
598 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. 649 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment.
599 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. 650 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator.
600 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. 651 ASSERT(!src_instance.IsNull()); // Already checked in inlined code.
601 652
602 Error& malformed_error = Error::Handle(); 653 Error& malformed_error = Error::Handle();
603 const bool is_instance_of = src_instance.IsInstanceOf( 654 const bool is_instance_of = src_instance.IsInstanceOf(
604 dst_type, dst_type_instantiator, &malformed_error); 655 dst_type, dst_instantiator_targs, &malformed_error);
605 656
606 if (FLAG_trace_type_checks) { 657 if (FLAG_trace_type_checks) {
607 PrintTypeCheck("TypeCheck", src_instance, dst_type, dst_type_instantiator, 658 PrintTypeCheck("TypeCheck", src_instance, dst_type, dst_instantiator_targs,
608 Bool::Handle(is_instance_of ? Bool::True() : Bool::False())); 659 Bool::Handle(is_instance_of ? Bool::True() : Bool::False()));
609 } 660 }
610 if (!is_instance_of) { 661 if (!is_instance_of) {
611 String& src_type_name = String::Handle(GetSimpleTypeName(src_instance)); 662 String& src_type_name = String::Handle(GetSimpleTypeName(src_instance));
612 String& dst_type_name = String::Handle(); 663 String& dst_type_name = String::Handle();
613 if (!dst_type.IsInstantiated()) { 664 if (!dst_type.IsInstantiated()) {
614 // Instantiate dst_type before reporting the error. 665 // Instantiate dst_type before reporting the error.
615 const AbstractType& instantiated_dst_type = AbstractType::Handle( 666 const AbstractType& instantiated_dst_type = AbstractType::Handle(
616 dst_type.InstantiateFrom(dst_type_instantiator)); 667 dst_type.InstantiateFrom(dst_instantiator_targs));
617 dst_type_name = instantiated_dst_type.Name(); 668 dst_type_name = instantiated_dst_type.Name();
618 } else { 669 } else {
619 dst_type_name = dst_type.Name(); 670 dst_type_name = dst_type.Name();
620 } 671 }
621 String& malformed_error_message = String::Handle(); 672 String& malformed_error_message = String::Handle();
622 if (!malformed_error.IsNull()) { 673 if (!malformed_error.IsNull()) {
623 ASSERT(FLAG_enable_type_checks); 674 ASSERT(FLAG_enable_type_checks);
624 malformed_error_message = String::New(malformed_error.ToErrorCString()); 675 malformed_error_message = String::New(malformed_error.ToErrorCString());
625 } 676 }
626 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, 677 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name,
627 dst_name, malformed_error_message); 678 dst_name, malformed_error_message);
628 UNREACHABLE(); 679 UNREACHABLE();
629 } 680 }
630 UpdateTypeTestCache(node_id, src_instance, dst_type, dst_type_instantiator, 681 UpdateTypeTestCache(node_id, src_instance, dst_type,
631 Bool::ZoneHandle(Bool::True()), cache); 682 dst_instantiator, dst_instantiator_targs,
683 Bool::ZoneHandle(Bool::True()), cache);
632 arguments.SetReturn(src_instance); 684 arguments.SetReturn(src_instance);
633 } 685 }
634 686
635 687
636 // Report that the type of the given object is not bool in conditional context. 688 // Report that the type of the given object is not bool in conditional context.
637 // Arg0: index of the token of the assignment (source location). 689 // Arg0: index of the token of the assignment (source location).
638 // Arg1: bad object. 690 // Arg1: bad object.
639 // Return value: none, throws a TypeError. 691 // Return value: none, throws a TypeError.
640 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 2) { 692 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 2) {
641 ASSERT(arguments.Count() == 693 ASSERT(arguments.Count() ==
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 } 1532 }
1481 } 1533 }
1482 } 1534 }
1483 // The cache is null terminated, therefore the loop above should never 1535 // The cache is null terminated, therefore the loop above should never
1484 // terminate by itself. 1536 // terminate by itself.
1485 UNREACHABLE(); 1537 UNREACHABLE();
1486 return Code::null(); 1538 return Code::null();
1487 } 1539 }
1488 1540
1489 } // namespace dart 1541 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/code_generator_ia32.h » ('j') | runtime/vm/code_generator_ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698