| OLD | NEW |
| 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 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 // class TypeArguments. Because of the overhead, do it only when needed. | 418 // class TypeArguments. Because of the overhead, do it only when needed. |
| 419 // Return false if the optimization was aborted. | 419 // Return false if the optimization was aborted. |
| 420 // Set type_arguments_replaced to true if they have changed. | 420 // Set type_arguments_replaced to true if they have changed. |
| 421 static bool OptimizeTypeArguments(const Instance& instance, | 421 static bool OptimizeTypeArguments(const Instance& instance, |
| 422 bool* type_arguments_replaced) { | 422 bool* type_arguments_replaced) { |
| 423 *type_arguments_replaced = false; | 423 *type_arguments_replaced = false; |
| 424 const Class& type_class = Class::ZoneHandle(instance.clazz()); | 424 const Class& type_class = Class::ZoneHandle(instance.clazz()); |
| 425 if (!type_class.HasTypeArguments()) { | 425 if (!type_class.HasTypeArguments()) { |
| 426 return true; | 426 return true; |
| 427 } | 427 } |
| 428 const AbstractTypeArguments& type_arguments = | 428 AbstractTypeArguments& type_arguments = |
| 429 AbstractTypeArguments::Handle(instance.GetTypeArguments()); | 429 AbstractTypeArguments::Handle(instance.GetTypeArguments()); |
| 430 if (type_arguments.IsNull()) { | 430 if (type_arguments.IsNull()) { |
| 431 return true; | 431 return true; |
| 432 } | 432 } |
| 433 if (type_arguments.IsInstantiatedTypeArguments()) { | 433 if (type_arguments.IsInstantiatedTypeArguments()) { |
| 434 do { |
| 435 InstantiatedTypeArguments& instantiated_type_arguments = |
| 436 InstantiatedTypeArguments::Handle(); |
| 437 instantiated_type_arguments ^= type_arguments.raw(); |
| 438 const AbstractTypeArguments& uninstantiated = |
| 439 AbstractTypeArguments::Handle( |
| 440 instantiated_type_arguments.uninstantiated_type_arguments()); |
| 441 const AbstractTypeArguments& instantiator = |
| 442 AbstractTypeArguments::Handle( |
| 443 instantiated_type_arguments.instantiator_type_arguments()); |
| 444 type_arguments = uninstantiated.InstantiateFrom(instantiator); |
| 445 } while (type_arguments.IsInstantiatedTypeArguments()); |
| 434 TypeArguments& new_type_arguments = TypeArguments::Handle(); | 446 TypeArguments& new_type_arguments = TypeArguments::Handle(); |
| 435 InstantiatedTypeArguments& instantiated_type_arguments = | 447 new_type_arguments ^= type_arguments.raw(); |
| 436 InstantiatedTypeArguments::Handle(); | |
| 437 instantiated_type_arguments ^= type_arguments.raw(); | |
| 438 const AbstractTypeArguments& uninstantiated = | |
| 439 AbstractTypeArguments::Handle( | |
| 440 instantiated_type_arguments.uninstantiated_type_arguments()); | |
| 441 const AbstractTypeArguments& instantiator = | |
| 442 AbstractTypeArguments::Handle( | |
| 443 instantiated_type_arguments.instantiator_type_arguments()); | |
| 444 AbstractTypeArguments& temp = AbstractTypeArguments::Handle(); | |
| 445 temp = uninstantiated.InstantiateFrom(instantiator); | |
| 446 if (!temp.IsTypeArguments()) { | |
| 447 // TODO(srdjan): Figure out why it does not want to convert to | |
| 448 // TypeArguments. | |
| 449 return false; | |
| 450 } | |
| 451 new_type_arguments ^= temp.raw(); | |
| 452 new_type_arguments ^= new_type_arguments.Canonicalize(); | 448 new_type_arguments ^= new_type_arguments.Canonicalize(); |
| 453 instance.SetTypeArguments(new_type_arguments); | 449 instance.SetTypeArguments(new_type_arguments); |
| 454 *type_arguments_replaced = true; | 450 *type_arguments_replaced = true; |
| 455 } else if (!type_arguments.IsCanonical()) { | 451 } else if (!type_arguments.IsCanonical()) { |
| 456 AbstractTypeArguments& new_type_arguments = | 452 AbstractTypeArguments& new_type_arguments = |
| 457 AbstractTypeArguments::Handle(); | 453 AbstractTypeArguments::Handle(); |
| 458 new_type_arguments ^= type_arguments.Canonicalize(); | 454 new_type_arguments ^= type_arguments.Canonicalize(); |
| 459 instance.SetTypeArguments(new_type_arguments); | 455 instance.SetTypeArguments(new_type_arguments); |
| 460 *type_arguments_replaced = true; | 456 *type_arguments_replaced = true; |
| 461 } | 457 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 &last_instance_class, | 529 &last_instance_class, |
| 534 &last_instance_type_arguments, | 530 &last_instance_type_arguments, |
| 535 &last_instantiator_type_arguments, | 531 &last_instantiator_type_arguments, |
| 536 &last_result); | 532 &last_result); |
| 537 if ((last_instance_class.raw() == instance_class.raw()) && | 533 if ((last_instance_class.raw() == instance_class.raw()) && |
| 538 (last_instance_type_arguments.raw() == instance_type_arguments.raw()) && | 534 (last_instance_type_arguments.raw() == instance_type_arguments.raw()) && |
| 539 (last_instantiator_type_arguments.raw() == | 535 (last_instantiator_type_arguments.raw() == |
| 540 instantiator_type_arguments.raw())) { | 536 instantiator_type_arguments.raw())) { |
| 541 if (FLAG_trace_type_checks) { | 537 if (FLAG_trace_type_checks) { |
| 542 OS::Print("%d ", i); | 538 OS::Print("%d ", i); |
| 543 PrintTypeCheck("WARNING duplicate cache entry", instance, type, | 539 if (type_arguments_replaced) { |
| 544 instantiator_type_arguments, result); | 540 PrintTypeCheck("Duplicate cache entry (canonical.)", instance, type, |
| 541 instantiator_type_arguments, result); |
| 542 } else { |
| 543 PrintTypeCheck("WARNING Duplicate cache entry", instance, type, |
| 544 instantiator_type_arguments, result); |
| 545 } |
| 545 } | 546 } |
| 546 // Can occur if we have canonicalized arguments. | 547 // Can occur if we have canonicalized arguments. |
| 547 // TODO(srdjan): Investigate why this assert can fail. | 548 // TODO(srdjan): Investigate why this assert can fail. |
| 548 // ASSERT(type_arguments_replaced); | 549 // ASSERT(type_arguments_replaced); |
| 549 return; | 550 return; |
| 550 } | 551 } |
| 551 } | 552 } |
| 552 new_cache.AddCheck(instance_class, | 553 new_cache.AddCheck(instance_class, |
| 553 instance_type_arguments, | 554 instance_type_arguments, |
| 554 instantiator_type_arguments, | 555 instantiator_type_arguments, |
| 555 result); | 556 result); |
| 556 if (FLAG_trace_type_checks) { | 557 if (FLAG_trace_type_checks) { |
| 558 AbstractType& test_type = AbstractType::Handle(type.raw()); |
| 559 if (!test_type.IsInstantiated()) { |
| 560 test_type = type.InstantiateFrom(instantiator_type_arguments); |
| 561 } |
| 557 OS::Print(" Updated test cache 0x%x ix:%d:\n" | 562 OS::Print(" Updated test cache 0x%x ix:%d:\n" |
| 558 " [0x%x %s, 0x%x %s]\n" | 563 " [0x%x %s, 0x%x %s]\n" |
| 559 " [0x%x %s, 0x%x %s] %s\n", | 564 " [0x%x %s, 0x%x %s] %s\n", |
| 560 new_cache.raw(), | 565 new_cache.raw(), |
| 561 len, | 566 len, |
| 562 instance_class.raw(), | 567 instance_class.raw(), |
| 563 instance_class.ToCString(), | 568 instance_class.ToCString(), |
| 564 instance_type_arguments.raw(), | 569 instance_type_arguments.raw(), |
| 565 instance_type_arguments.ToCString(), | 570 instance_type_arguments.ToCString(), |
| 566 type.type_class(), | 571 test_type.type_class(), |
| 567 Class::Handle(type.type_class()).ToCString(), | 572 Class::Handle(test_type.type_class()).ToCString(), |
| 568 instantiator_type_arguments.raw(), | 573 instantiator_type_arguments.raw(), |
| 569 instantiator_type_arguments.ToCString(), | 574 instantiator_type_arguments.ToCString(), |
| 570 result.ToCString()); | 575 result.ToCString()); |
| 571 } | 576 } |
| 572 } | 577 } |
| 573 | 578 |
| 574 | 579 |
| 575 // Check that the given instance is an instance of the given type. | 580 // Check that the given instance is an instance of the given type. |
| 576 // Tested instance may not be null, because the null test is inlined. | 581 // Tested instance may not be null, because the null test is inlined. |
| 577 // Arg0: index of the token of the instanceof test (source location). | 582 // Arg0: index of the token of the instanceof test (source location). |
| (...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1542 } | 1547 } |
| 1543 } | 1548 } |
| 1544 } | 1549 } |
| 1545 // The cache is null terminated, therefore the loop above should never | 1550 // The cache is null terminated, therefore the loop above should never |
| 1546 // terminate by itself. | 1551 // terminate by itself. |
| 1547 UNREACHABLE(); | 1552 UNREACHABLE(); |
| 1548 return Code::null(); | 1553 return Code::null(); |
| 1549 } | 1554 } |
| 1550 | 1555 |
| 1551 } // namespace dart | 1556 } // namespace dart |
| OLD | NEW |