OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/bootstrap.h" | 8 #include "vm/bootstrap.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/constant_propagator.h" | 10 #include "vm/constant_propagator.h" |
(...skipping 2927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2938 | 2938 |
2939 Array& args_desc_array = Array::Handle(zone, ic_data.arguments_descriptor()); | 2939 Array& args_desc_array = Array::Handle(zone, ic_data.arguments_descriptor()); |
2940 ArgumentsDescriptor args_desc(args_desc_array); | 2940 ArgumentsDescriptor args_desc(args_desc_array); |
2941 String& name = String::Handle(zone, ic_data.target_name()); | 2941 String& name = String::Handle(zone, ic_data.target_name()); |
2942 | 2942 |
2943 Function& fn = Function::Handle(zone); | 2943 Function& fn = Function::Handle(zone); |
2944 | 2944 |
2945 intptr_t length = targets.length(); | 2945 intptr_t length = targets.length(); |
2946 | 2946 |
2947 // Spread class-ids to preceding classes where a lookup yields the same | 2947 // Spread class-ids to preceding classes where a lookup yields the same |
2948 // method. | 2948 // method. A polymorphic target is not really the same method since its |
| 2949 // behaviour depends on the receiver class-id, so we don't spread the |
| 2950 // class-ids in that case. |
2949 for (int idx = 0; idx < length; idx++) { | 2951 for (int idx = 0; idx < length; idx++) { |
2950 int lower_limit_cid = (idx == 0) ? -1 : targets[idx - 1].cid_end; | 2952 int lower_limit_cid = (idx == 0) ? -1 : targets[idx - 1].cid_end; |
2951 const Function& target = *targets.TargetAt(idx)->target; | 2953 const Function& target = *targets.TargetAt(idx)->target; |
| 2954 if (MethodRecognizer::PolymorphicTarget(target)) continue; |
2952 for (int i = targets[idx].cid_start - 1; i > lower_limit_cid; i--) { | 2955 for (int i = targets[idx].cid_start - 1; i > lower_limit_cid; i--) { |
2953 if (FlowGraphCompiler::LookupMethodFor(i, name, args_desc, &fn) && | 2956 if (FlowGraphCompiler::LookupMethodFor(i, name, args_desc, &fn) && |
2954 fn.raw() == target.raw()) { | 2957 fn.raw() == target.raw()) { |
2955 targets[idx].cid_start = i; | 2958 targets[idx].cid_start = i; |
2956 } else { | 2959 } else { |
2957 break; | 2960 break; |
2958 } | 2961 } |
2959 } | 2962 } |
2960 } | 2963 } |
2961 // Spread class-ids to following classes where a lookup yields the same | 2964 // Spread class-ids to following classes where a lookup yields the same |
2962 // method. | 2965 // method. |
2963 for (int idx = 0; idx < length; idx++) { | 2966 for (int idx = 0; idx < length; idx++) { |
2964 int upper_limit_cid = | 2967 int upper_limit_cid = |
2965 (idx == length - 1) ? 1000000000 : targets[idx + 1].cid_start; | 2968 (idx == length - 1) ? 1000000000 : targets[idx + 1].cid_start; |
2966 const Function& target = *targets.TargetAt(idx)->target; | 2969 const Function& target = *targets.TargetAt(idx)->target; |
| 2970 if (MethodRecognizer::PolymorphicTarget(target)) continue; |
2967 for (int i = targets[idx].cid_end + 1; i < upper_limit_cid; i++) { | 2971 for (int i = targets[idx].cid_end + 1; i < upper_limit_cid; i++) { |
2968 if (FlowGraphCompiler::LookupMethodFor(i, name, args_desc, &fn) && | 2972 if (FlowGraphCompiler::LookupMethodFor(i, name, args_desc, &fn) && |
2969 fn.raw() == target.raw()) { | 2973 fn.raw() == target.raw()) { |
2970 targets[idx].cid_end = i; | 2974 targets[idx].cid_end = i; |
2971 } else { | 2975 } else { |
2972 break; | 2976 break; |
2973 } | 2977 } |
2974 } | 2978 } |
2975 } | 2979 } |
2976 targets.MergeIntoRanges(); | 2980 targets.MergeIntoRanges(); |
2977 return &targets; | 2981 return &targets; |
2978 } | 2982 } |
2979 | 2983 |
2980 | 2984 |
2981 void CallTargets::MergeIntoRanges() { | 2985 void CallTargets::MergeIntoRanges() { |
2982 // Merge adjacent class id ranges. | 2986 // Merge adjacent class id ranges. |
2983 int dest = 0; | 2987 int dest = 0; |
| 2988 // We merge entries that dispatch to the same target, but polymorphic targets |
| 2989 // are not really the same target since they depend on the class-id, so we |
| 2990 // don't merge them. |
2984 for (int src = 1; src < length(); src++) { | 2991 for (int src = 1; src < length(); src++) { |
| 2992 const Function& target = *TargetAt(dest)->target; |
2985 if (TargetAt(dest)->cid_end + 1 >= TargetAt(src)->cid_start && | 2993 if (TargetAt(dest)->cid_end + 1 >= TargetAt(src)->cid_start && |
2986 TargetAt(dest)->target->raw() == TargetAt(src)->target->raw()) { | 2994 target.raw() == TargetAt(src)->target->raw() && |
| 2995 !MethodRecognizer::PolymorphicTarget(target)) { |
2987 TargetAt(dest)->cid_end = TargetAt(src)->cid_end; | 2996 TargetAt(dest)->cid_end = TargetAt(src)->cid_end; |
2988 TargetAt(dest)->count += TargetAt(src)->count; | 2997 TargetAt(dest)->count += TargetAt(src)->count; |
2989 } else { | 2998 } else { |
2990 dest++; | 2999 dest++; |
2991 if (src != dest) { | 3000 if (src != dest) { |
2992 // Use cid_ranges_ instead of TargetAt when updating the pointer. | 3001 // Use cid_ranges_ instead of TargetAt when updating the pointer. |
2993 cid_ranges_[dest] = TargetAt(src); | 3002 cid_ranges_[dest] = TargetAt(src); |
2994 } | 3003 } |
2995 } | 3004 } |
2996 } | 3005 } |
(...skipping 1362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4359 "native function '%s' (%" Pd " arguments) cannot be found", | 4368 "native function '%s' (%" Pd " arguments) cannot be found", |
4360 native_name().ToCString(), function().NumParameters()); | 4369 native_name().ToCString(), function().NumParameters()); |
4361 } | 4370 } |
4362 set_is_auto_scope(auto_setup_scope); | 4371 set_is_auto_scope(auto_setup_scope); |
4363 set_native_c_function(native_function); | 4372 set_native_c_function(native_function); |
4364 } | 4373 } |
4365 | 4374 |
4366 #undef __ | 4375 #undef __ |
4367 | 4376 |
4368 } // namespace dart | 4377 } // namespace dart |
OLD | NEW |