| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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/object.h" | 5 #include "vm/object.h" |
| 6 | 6 |
| 7 #include "vm/hash_table.h" | 7 #include "vm/hash_table.h" |
| 8 #include "vm/isolate_reload.h" | 8 #include "vm/isolate_reload.h" |
| 9 #include "vm/log.h" | 9 #include "vm/log.h" |
| 10 #include "vm/resolver.h" | 10 #include "vm/resolver.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 Array::Handle(Array::RawCast(saved_ic_data.At(0))); | 50 Array::Handle(Array::RawCast(saved_ic_data.At(0))); |
| 51 ASSERT(!edge_counters_array.IsNull()); | 51 ASSERT(!edge_counters_array.IsNull()); |
| 52 // Fill edge counters array with zeros. | 52 // Fill edge counters array with zeros. |
| 53 const Smi& zero = Smi::Handle(Smi::New(0)); | 53 const Smi& zero = Smi::Handle(Smi::New(0)); |
| 54 for (intptr_t i = 0; i < edge_counters_array.Length(); i++) { | 54 for (intptr_t i = 0; i < edge_counters_array.Length(); i++) { |
| 55 edge_counters_array.SetAt(i, zero); | 55 edge_counters_array.SetAt(i, zero); |
| 56 } | 56 } |
| 57 } | 57 } |
| 58 | 58 |
| 59 | 59 |
| 60 void Code::ResetICDatas() const { | 60 void Code::ResetICDatas(Zone* zone) const { |
| 61 // Iterate over the Code's object pool and reset all ICDatas. | 61 // Iterate over the Code's object pool and reset all ICDatas. |
| 62 #ifdef TARGET_ARCH_IA32 | 62 #ifdef TARGET_ARCH_IA32 |
| 63 // IA32 does not have an object pool, but, we can iterate over all | 63 // IA32 does not have an object pool, but, we can iterate over all |
| 64 // embedded objects by using the variable length data section. | 64 // embedded objects by using the variable length data section. |
| 65 if (!is_alive()) { | 65 if (!is_alive()) { |
| 66 return; | 66 return; |
| 67 } | 67 } |
| 68 const Instructions& instrs = Instructions::Handle(instructions()); | 68 const Instructions& instrs = Instructions::Handle(zone, instructions()); |
| 69 ASSERT(!instrs.IsNull()); | 69 ASSERT(!instrs.IsNull()); |
| 70 uword base_address = instrs.EntryPoint(); | 70 uword base_address = instrs.EntryPoint(); |
| 71 Object& object = Object::Handle(); | 71 Object& object = Object::Handle(zone); |
| 72 intptr_t offsets_length = pointer_offsets_length(); | 72 intptr_t offsets_length = pointer_offsets_length(); |
| 73 const int32_t* offsets = raw_ptr()->data(); | 73 const int32_t* offsets = raw_ptr()->data(); |
| 74 for (intptr_t i = 0; i < offsets_length; i++) { | 74 for (intptr_t i = 0; i < offsets_length; i++) { |
| 75 int32_t offset = offsets[i]; | 75 int32_t offset = offsets[i]; |
| 76 RawObject** object_ptr = | 76 RawObject** object_ptr = |
| 77 reinterpret_cast<RawObject**>(base_address + offset); | 77 reinterpret_cast<RawObject**>(base_address + offset); |
| 78 RawObject* raw_object = *object_ptr; | 78 RawObject* raw_object = *object_ptr; |
| 79 if (!raw_object->IsHeapObject()) { | 79 if (!raw_object->IsHeapObject()) { |
| 80 continue; | 80 continue; |
| 81 } | 81 } |
| 82 object = raw_object; | 82 object = raw_object; |
| 83 if (object.IsICData()) { | 83 if (object.IsICData()) { |
| 84 ICData::Cast(object).Reset(); | 84 ICData::Cast(object).Reset(); |
| 85 } | 85 } |
| 86 } | 86 } |
| 87 #else | 87 #else |
| 88 const ObjectPool& pool = ObjectPool::Handle(object_pool()); | 88 const ObjectPool& pool = ObjectPool::Handle(zone, object_pool()); |
| 89 Object& object = Object::Handle(); | 89 Object& object = Object::Handle(zone); |
| 90 ASSERT(!pool.IsNull()); | 90 ASSERT(!pool.IsNull()); |
| 91 for (intptr_t i = 0; i < pool.Length(); i++) { | 91 for (intptr_t i = 0; i < pool.Length(); i++) { |
| 92 ObjectPool::EntryType entry_type = pool.InfoAt(i); | 92 ObjectPool::EntryType entry_type = pool.InfoAt(i); |
| 93 if (entry_type != ObjectPool::kTaggedObject) { | 93 if (entry_type != ObjectPool::kTaggedObject) { |
| 94 continue; | 94 continue; |
| 95 } | 95 } |
| 96 object = pool.ObjectAt(i); | 96 object = pool.ObjectAt(i); |
| 97 if (object.IsICData()) { | 97 if (object.IsICData()) { |
| 98 ICData::Cast(object).Reset(); | 98 ICData::Cast(object).Reset(zone); |
| 99 } | 99 } |
| 100 } | 100 } |
| 101 #endif | 101 #endif |
| 102 } | 102 } |
| 103 | 103 |
| 104 | 104 |
| 105 void Class::CopyStaticFieldValues(const Class& old_cls) const { | 105 void Class::CopyStaticFieldValues(const Class& old_cls) const { |
| 106 // We only update values for non-enum classes. | 106 // We only update values for non-enum classes. |
| 107 const bool update_values = !is_enum_class(); | 107 const bool update_values = !is_enum_class(); |
| 108 | 108 |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 *this, replacement, prefix_name)); | 672 *this, replacement, prefix_name)); |
| 673 return; | 673 return; |
| 674 } | 674 } |
| 675 } | 675 } |
| 676 } | 676 } |
| 677 | 677 |
| 678 | 678 |
| 679 static const Function* static_call_target = NULL; | 679 static const Function* static_call_target = NULL; |
| 680 | 680 |
| 681 | 681 |
| 682 void ICData::Reset() const { | 682 void ICData::Reset(Zone* zone) const { |
| 683 if (is_static_call()) { | 683 if (is_static_call()) { |
| 684 const Function& old_target = Function::Handle(GetTargetAt(0)); | 684 const Function& old_target = Function::Handle(zone, GetTargetAt(0)); |
| 685 if (old_target.IsNull()) { | 685 if (old_target.IsNull()) { |
| 686 FATAL("old_target is NULL.\n"); | 686 FATAL("old_target is NULL.\n"); |
| 687 } | 687 } |
| 688 static_call_target = &old_target; | 688 static_call_target = &old_target; |
| 689 | 689 |
| 690 const String& selector = String::Handle(old_target.name()); | 690 const String& selector = String::Handle(zone, old_target.name()); |
| 691 Function& new_target = Function::Handle(); | 691 Function& new_target = Function::Handle(zone); |
| 692 if (!old_target.is_static()) { | 692 if (!old_target.is_static()) { |
| 693 if (old_target.kind() == RawFunction::kConstructor) { | 693 if (old_target.kind() == RawFunction::kConstructor) { |
| 694 return; // Super constructor call. | 694 return; // Super constructor call. |
| 695 } | 695 } |
| 696 Function& caller = Function::Handle(); | 696 Function& caller = Function::Handle(zone); |
| 697 caller ^= Owner(); | 697 caller ^= Owner(); |
| 698 ASSERT(!caller.is_static()); | 698 ASSERT(!caller.is_static()); |
| 699 Class& cls = Class::Handle(caller.Owner()); | 699 Class& cls = Class::Handle(zone, caller.Owner()); |
| 700 if (cls.raw() == old_target.Owner()) { | 700 if (cls.raw() == old_target.Owner()) { |
| 701 // Dispatcher. | 701 // Dispatcher. |
| 702 if (caller.IsImplicitClosureFunction()) { | 702 if (caller.IsImplicitClosureFunction()) { |
| 703 return; // Tear-off. | 703 return; // Tear-off. |
| 704 } | 704 } |
| 705 if (caller.kind() == RawFunction::kNoSuchMethodDispatcher) { | 705 if (caller.kind() == RawFunction::kNoSuchMethodDispatcher) { |
| 706 // TODO(rmacnak): noSuchMethod might have been redefined. | 706 // TODO(rmacnak): noSuchMethod might have been redefined. |
| 707 return; | 707 return; |
| 708 } | 708 } |
| 709 const Function& caller_parent = | 709 const Function& caller_parent = |
| 710 Function::Handle(caller.parent_function()); | 710 Function::Handle(zone, caller.parent_function()); |
| 711 if (!caller_parent.IsNull()) { | 711 if (!caller_parent.IsNull()) { |
| 712 if (caller_parent.kind() == RawFunction::kInvokeFieldDispatcher) { | 712 if (caller_parent.kind() == RawFunction::kInvokeFieldDispatcher) { |
| 713 return; // Call-through-getter. | 713 return; // Call-through-getter. |
| 714 } | 714 } |
| 715 } | 715 } |
| 716 FATAL2("Unexpected dispatcher-like call site: %s from %s\n", | 716 FATAL2("Unexpected dispatcher-like call site: %s from %s\n", |
| 717 selector.ToCString(), caller.ToQualifiedCString()); | 717 selector.ToCString(), caller.ToQualifiedCString()); |
| 718 } | 718 } |
| 719 // Super call. | 719 // Super call. |
| 720 cls = cls.SuperClass(); | 720 cls = cls.SuperClass(); |
| 721 while (!cls.IsNull()) { | 721 while (!cls.IsNull()) { |
| 722 // TODO(rmacnak): Should use Resolver::ResolveDynamicAnyArgs to handle | 722 // TODO(rmacnak): Should use Resolver::ResolveDynamicAnyArgs to handle |
| 723 // method-extractors and call-through-getters, but we're in a no | 723 // method-extractors and call-through-getters, but we're in a no |
| 724 // safepoint scope here. | 724 // safepoint scope here. |
| 725 new_target = cls.LookupDynamicFunction(selector); | 725 new_target = cls.LookupDynamicFunction(selector); |
| 726 if (!new_target.IsNull()) { | 726 if (!new_target.IsNull()) { |
| 727 break; | 727 break; |
| 728 } | 728 } |
| 729 cls = cls.SuperClass(); | 729 cls = cls.SuperClass(); |
| 730 } | 730 } |
| 731 } else { | 731 } else { |
| 732 // This can be incorrect if the call site was an unqualified invocation. | 732 // This can be incorrect if the call site was an unqualified invocation. |
| 733 const Class& cls = Class::Handle(old_target.Owner()); | 733 const Class& cls = Class::Handle(zone, old_target.Owner()); |
| 734 new_target = cls.LookupStaticFunction(selector); | 734 new_target = cls.LookupStaticFunction(selector); |
| 735 } | 735 } |
| 736 | 736 |
| 737 const Array& args_desc_array = Array::Handle(arguments_descriptor()); | 737 const Array& args_desc_array = Array::Handle(zone, arguments_descriptor()); |
| 738 ArgumentsDescriptor args_desc(args_desc_array); | 738 ArgumentsDescriptor args_desc(args_desc_array); |
| 739 if (new_target.IsNull() || | 739 if (new_target.IsNull() || |
| 740 !new_target.AreValidArguments(args_desc, NULL)) { | 740 !new_target.AreValidArguments(args_desc, NULL)) { |
| 741 // TODO(rmacnak): Patch to a NSME stub. | 741 // TODO(rmacnak): Patch to a NSME stub. |
| 742 VTIR_Print("Cannot rebind static call to %s from %s\n", | 742 VTIR_Print("Cannot rebind static call to %s from %s\n", |
| 743 old_target.ToCString(), | 743 old_target.ToCString(), |
| 744 Object::Handle(Owner()).ToCString()); | 744 Object::Handle(zone, Owner()).ToCString()); |
| 745 return; | 745 return; |
| 746 } | 746 } |
| 747 ClearAndSetStaticTarget(new_target); | 747 ClearAndSetStaticTarget(new_target); |
| 748 } else { | 748 } else { |
| 749 ClearWithSentinel(); | 749 intptr_t num_args = NumArgsTested(); |
| 750 if (num_args == 2) { |
| 751 ClearWithSentinel(); |
| 752 } else { |
| 753 const Array& data_array = |
| 754 Array::Handle(zone, CachedEmptyICDataArray(num_args)); |
| 755 set_ic_data_array(data_array); |
| 756 } |
| 750 } | 757 } |
| 751 } | 758 } |
| 752 | 759 |
| 753 #endif // !PRODUCT | 760 #endif // !PRODUCT |
| 754 | 761 |
| 755 } // namespace dart. | 762 } // namespace dart. |
| OLD | NEW |