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

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

Powered by Google App Engine
This is Rietveld 408576698