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 |