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 #ifndef RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
6 #define RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/ast.h" | 9 #include "vm/ast.h" |
10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
(...skipping 2794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2805 virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 2805 virtual intptr_t ArgumentCount() const { return arguments_->length(); } |
2806 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { | 2806 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { |
2807 return (*arguments_)[index]; | 2807 return (*arguments_)[index]; |
2808 } | 2808 } |
2809 const Array& argument_names() const { return argument_names_; } | 2809 const Array& argument_names() const { return argument_names_; } |
2810 intptr_t checked_argument_count() const { return checked_argument_count_; } | 2810 intptr_t checked_argument_count() const { return checked_argument_count_; } |
2811 | 2811 |
2812 bool has_unique_selector() const { return has_unique_selector_; } | 2812 bool has_unique_selector() const { return has_unique_selector_; } |
2813 void set_has_unique_selector(bool b) { has_unique_selector_ = b; } | 2813 void set_has_unique_selector(bool b) { has_unique_selector_ = b; } |
2814 | 2814 |
| 2815 virtual intptr_t CallCount() const { |
| 2816 return ic_data() == NULL ? 0 : ic_data()->AggregateCount(); |
| 2817 } |
| 2818 |
2815 virtual bool ComputeCanDeoptimize() const { return true; } | 2819 virtual bool ComputeCanDeoptimize() const { return true; } |
2816 | 2820 |
2817 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 2821 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
2818 | 2822 |
2819 virtual bool CanBecomeDeoptimizationTarget() const { | 2823 virtual bool CanBecomeDeoptimizationTarget() const { |
2820 // Instance calls that are specialized by the optimizer need a | 2824 // Instance calls that are specialized by the optimizer need a |
2821 // deoptimization descriptor before the call. | 2825 // deoptimization descriptor before the call. |
2822 return true; | 2826 return true; |
2823 } | 2827 } |
2824 | 2828 |
(...skipping 18 matching lines...) Expand all Loading... |
2843 bool has_unique_selector_; | 2847 bool has_unique_selector_; |
2844 | 2848 |
2845 DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr); | 2849 DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr); |
2846 }; | 2850 }; |
2847 | 2851 |
2848 | 2852 |
2849 class PolymorphicInstanceCallInstr : public TemplateDefinition<0, Throws> { | 2853 class PolymorphicInstanceCallInstr : public TemplateDefinition<0, Throws> { |
2850 public: | 2854 public: |
2851 PolymorphicInstanceCallInstr(InstanceCallInstr* instance_call, | 2855 PolymorphicInstanceCallInstr(InstanceCallInstr* instance_call, |
2852 const CallTargets& targets, | 2856 const CallTargets& targets, |
2853 bool with_checks, | |
2854 bool complete) | 2857 bool complete) |
2855 : TemplateDefinition(instance_call->deopt_id()), | 2858 : TemplateDefinition(instance_call->deopt_id()), |
2856 instance_call_(instance_call), | 2859 instance_call_(instance_call), |
2857 targets_(targets), | 2860 targets_(targets), |
2858 with_checks_(with_checks), | |
2859 complete_(complete) { | 2861 complete_(complete) { |
2860 ASSERT(instance_call_ != NULL); | 2862 ASSERT(instance_call_ != NULL); |
2861 ASSERT(targets.length() != 0); | 2863 ASSERT(targets.length() != 0); |
2862 total_call_count_ = CallCount(); | 2864 total_call_count_ = CallCount(); |
2863 } | 2865 } |
2864 | 2866 |
2865 InstanceCallInstr* instance_call() const { return instance_call_; } | 2867 InstanceCallInstr* instance_call() const { return instance_call_; } |
2866 bool with_checks() const { return with_checks_; } | |
2867 void set_with_checks(bool b) { with_checks_ = b; } | |
2868 bool complete() const { return complete_; } | 2868 bool complete() const { return complete_; } |
2869 virtual TokenPosition token_pos() const { | 2869 virtual TokenPosition token_pos() const { |
2870 return instance_call_->token_pos(); | 2870 return instance_call_->token_pos(); |
2871 } | 2871 } |
2872 | 2872 |
2873 virtual CompileType ComputeType() const; | 2873 virtual CompileType ComputeType() const; |
2874 | 2874 |
2875 virtual intptr_t ArgumentCount() const { | 2875 virtual intptr_t ArgumentCount() const { |
2876 return instance_call()->ArgumentCount(); | 2876 return instance_call()->ArgumentCount(); |
2877 } | 2877 } |
2878 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { | 2878 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { |
2879 return instance_call()->PushArgumentAt(index); | 2879 return instance_call()->PushArgumentAt(index); |
2880 } | 2880 } |
| 2881 const Array& argument_names() const { |
| 2882 return instance_call()->argument_names(); |
| 2883 } |
2881 | 2884 |
2882 bool HasOnlyDispatcherOrImplicitAccessorTargets() const; | 2885 bool HasOnlyDispatcherOrImplicitAccessorTargets() const; |
2883 | 2886 |
2884 const CallTargets& targets() const { return targets_; } | 2887 const CallTargets& targets() const { return targets_; } |
2885 intptr_t NumberOfChecks() const { return targets_.length(); } | 2888 intptr_t NumberOfChecks() const { return targets_.length(); } |
2886 | 2889 |
2887 bool IsSureToCallSingleRecognizedTarget() const; | 2890 bool IsSureToCallSingleRecognizedTarget() const; |
2888 | 2891 |
2889 virtual intptr_t CallCount() const; | 2892 virtual intptr_t CallCount() const; |
2890 | 2893 |
(...skipping 16 matching lines...) Expand all Loading... |
2907 | 2910 |
2908 virtual Definition* Canonicalize(FlowGraph* graph); | 2911 virtual Definition* Canonicalize(FlowGraph* graph); |
2909 | 2912 |
2910 static RawType* ComputeRuntimeType(const CallTargets& targets); | 2913 static RawType* ComputeRuntimeType(const CallTargets& targets); |
2911 | 2914 |
2912 PRINT_OPERANDS_TO_SUPPORT | 2915 PRINT_OPERANDS_TO_SUPPORT |
2913 | 2916 |
2914 private: | 2917 private: |
2915 InstanceCallInstr* instance_call_; | 2918 InstanceCallInstr* instance_call_; |
2916 const CallTargets& targets_; | 2919 const CallTargets& targets_; |
2917 bool with_checks_; | |
2918 const bool complete_; | 2920 const bool complete_; |
2919 intptr_t total_call_count_; | 2921 intptr_t total_call_count_; |
2920 | 2922 |
2921 friend class PolymorphicInliner; | 2923 friend class PolymorphicInliner; |
2922 | 2924 |
2923 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); | 2925 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); |
2924 }; | 2926 }; |
2925 | 2927 |
2926 | 2928 |
2927 class StrictCompareInstr : public TemplateComparison<2, NoThrow, Pure> { | 2929 class StrictCompareInstr : public TemplateComparison<2, NoThrow, Pure> { |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3220 | 3222 |
3221 class StaticCallInstr : public TemplateDefinition<0, Throws> { | 3223 class StaticCallInstr : public TemplateDefinition<0, Throws> { |
3222 public: | 3224 public: |
3223 StaticCallInstr(TokenPosition token_pos, | 3225 StaticCallInstr(TokenPosition token_pos, |
3224 const Function& function, | 3226 const Function& function, |
3225 const Array& argument_names, | 3227 const Array& argument_names, |
3226 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 3228 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
3227 const ZoneGrowableArray<const ICData*>& ic_data_array) | 3229 const ZoneGrowableArray<const ICData*>& ic_data_array) |
3228 : TemplateDefinition(Thread::Current()->GetNextDeoptId()), | 3230 : TemplateDefinition(Thread::Current()->GetNextDeoptId()), |
3229 ic_data_(NULL), | 3231 ic_data_(NULL), |
| 3232 call_count_(0), |
3230 token_pos_(token_pos), | 3233 token_pos_(token_pos), |
3231 function_(function), | 3234 function_(function), |
3232 argument_names_(argument_names), | 3235 argument_names_(argument_names), |
3233 arguments_(arguments), | 3236 arguments_(arguments), |
3234 result_cid_(kDynamicCid), | 3237 result_cid_(kDynamicCid), |
3235 is_known_list_constructor_(false), | 3238 is_known_list_constructor_(false), |
3236 identity_(AliasIdentity::Unknown()) { | 3239 identity_(AliasIdentity::Unknown()) { |
3237 ic_data_ = GetICData(ic_data_array); | 3240 ic_data_ = GetICData(ic_data_array); |
3238 ASSERT(function.IsZoneHandle()); | 3241 ASSERT(function.IsZoneHandle()); |
3239 ASSERT(!function.IsNull()); | 3242 ASSERT(!function.IsNull()); |
3240 ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap()); | 3243 ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap()); |
3241 } | 3244 } |
3242 | 3245 |
3243 StaticCallInstr(TokenPosition token_pos, | 3246 StaticCallInstr(TokenPosition token_pos, |
3244 const Function& function, | 3247 const Function& function, |
3245 const Array& argument_names, | 3248 const Array& argument_names, |
3246 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 3249 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
3247 intptr_t deopt_id) | 3250 intptr_t deopt_id, |
| 3251 intptr_t call_count) |
3248 : TemplateDefinition(deopt_id), | 3252 : TemplateDefinition(deopt_id), |
3249 ic_data_(NULL), | 3253 ic_data_(NULL), |
| 3254 call_count_(call_count), |
3250 token_pos_(token_pos), | 3255 token_pos_(token_pos), |
3251 function_(function), | 3256 function_(function), |
3252 argument_names_(argument_names), | 3257 argument_names_(argument_names), |
3253 arguments_(arguments), | 3258 arguments_(arguments), |
3254 result_cid_(kDynamicCid), | 3259 result_cid_(kDynamicCid), |
3255 is_known_list_constructor_(false), | 3260 is_known_list_constructor_(false), |
3256 identity_(AliasIdentity::Unknown()) { | 3261 identity_(AliasIdentity::Unknown()) { |
3257 ASSERT(function.IsZoneHandle()); | 3262 ASSERT(function.IsZoneHandle()); |
3258 ASSERT(!function.IsNull()); | 3263 ASSERT(!function.IsNull()); |
3259 ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap()); | 3264 ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap()); |
3260 } | 3265 } |
3261 | 3266 |
| 3267 // Generate a replacement call instruction for an instance call which |
| 3268 // has been found to have only one target. |
| 3269 template <class C> |
| 3270 static StaticCallInstr* FromCall(Zone* zone, |
| 3271 const C* call, |
| 3272 const Function& target) { |
| 3273 ZoneGrowableArray<PushArgumentInstr*>* args = |
| 3274 new (zone) ZoneGrowableArray<PushArgumentInstr*>(call->ArgumentCount()); |
| 3275 for (intptr_t i = 0; i < call->ArgumentCount(); i++) { |
| 3276 args->Add(call->PushArgumentAt(i)); |
| 3277 } |
| 3278 return new (zone) |
| 3279 StaticCallInstr(call->token_pos(), target, call->argument_names(), args, |
| 3280 call->deopt_id(), call->CallCount()); |
| 3281 } |
| 3282 |
3262 // ICData for static calls carries call count. | 3283 // ICData for static calls carries call count. |
3263 const ICData* ic_data() const { return ic_data_; } | 3284 const ICData* ic_data() const { return ic_data_; } |
3264 bool HasICData() const { return (ic_data() != NULL) && !ic_data()->IsNull(); } | 3285 bool HasICData() const { return (ic_data() != NULL) && !ic_data()->IsNull(); } |
3265 | 3286 |
3266 void set_ic_data(const ICData* value) { ic_data_ = value; } | 3287 void set_ic_data(const ICData* value) { ic_data_ = value; } |
3267 | 3288 |
3268 DECLARE_INSTRUCTION(StaticCall) | 3289 DECLARE_INSTRUCTION(StaticCall) |
3269 virtual CompileType ComputeType() const; | 3290 virtual CompileType ComputeType() const; |
3270 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 3291 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
3271 | 3292 |
3272 // Accessors forwarded to the AST node. | 3293 // Accessors forwarded to the AST node. |
3273 const Function& function() const { return function_; } | 3294 const Function& function() const { return function_; } |
3274 const Array& argument_names() const { return argument_names_; } | 3295 const Array& argument_names() const { return argument_names_; } |
3275 virtual TokenPosition token_pos() const { return token_pos_; } | 3296 virtual TokenPosition token_pos() const { return token_pos_; } |
3276 | 3297 |
3277 virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 3298 virtual intptr_t ArgumentCount() const { return arguments_->length(); } |
3278 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { | 3299 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { |
3279 return (*arguments_)[index]; | 3300 return (*arguments_)[index]; |
3280 } | 3301 } |
3281 | 3302 |
3282 virtual intptr_t CallCount() const { | 3303 virtual intptr_t CallCount() const { |
3283 return ic_data() == NULL ? 0 : ic_data()->AggregateCount(); | 3304 return ic_data() == NULL ? call_count_ : ic_data()->AggregateCount(); |
3284 } | 3305 } |
3285 | 3306 |
3286 virtual bool ComputeCanDeoptimize() const { return true; } | 3307 virtual bool ComputeCanDeoptimize() const { return true; } |
3287 | 3308 |
3288 virtual bool CanBecomeDeoptimizationTarget() const { | 3309 virtual bool CanBecomeDeoptimizationTarget() const { |
3289 // Static calls that are specialized by the optimizer (e.g. sqrt) need a | 3310 // Static calls that are specialized by the optimizer (e.g. sqrt) need a |
3290 // deoptimization descriptor before the call. | 3311 // deoptimization descriptor before the call. |
3291 return true; | 3312 return true; |
3292 } | 3313 } |
3293 | 3314 |
3294 virtual EffectSet Effects() const { return EffectSet::All(); } | 3315 virtual EffectSet Effects() const { return EffectSet::All(); } |
3295 | 3316 |
3296 void set_result_cid(intptr_t value) { result_cid_ = value; } | 3317 void set_result_cid(intptr_t value) { result_cid_ = value; } |
3297 | 3318 |
3298 bool is_known_list_constructor() const { return is_known_list_constructor_; } | 3319 bool is_known_list_constructor() const { return is_known_list_constructor_; } |
3299 void set_is_known_list_constructor(bool value) { | 3320 void set_is_known_list_constructor(bool value) { |
3300 is_known_list_constructor_ = value; | 3321 is_known_list_constructor_ = value; |
3301 } | 3322 } |
3302 | 3323 |
3303 bool IsRecognizedFactory() const { return is_known_list_constructor(); } | 3324 bool IsRecognizedFactory() const { return is_known_list_constructor(); } |
3304 | 3325 |
3305 virtual AliasIdentity Identity() const { return identity_; } | 3326 virtual AliasIdentity Identity() const { return identity_; } |
3306 virtual void SetIdentity(AliasIdentity identity) { identity_ = identity; } | 3327 virtual void SetIdentity(AliasIdentity identity) { identity_ = identity; } |
3307 | 3328 |
3308 PRINT_OPERANDS_TO_SUPPORT | 3329 PRINT_OPERANDS_TO_SUPPORT |
3309 | 3330 |
3310 private: | 3331 private: |
3311 const ICData* ic_data_; | 3332 const ICData* ic_data_; |
| 3333 const intptr_t call_count_; |
3312 const TokenPosition token_pos_; | 3334 const TokenPosition token_pos_; |
3313 const Function& function_; | 3335 const Function& function_; |
3314 const Array& argument_names_; | 3336 const Array& argument_names_; |
3315 ZoneGrowableArray<PushArgumentInstr*>* arguments_; | 3337 ZoneGrowableArray<PushArgumentInstr*>* arguments_; |
3316 intptr_t result_cid_; // For some library functions we know the result. | 3338 intptr_t result_cid_; // For some library functions we know the result. |
3317 | 3339 |
3318 // 'True' for recognized list constructors. | 3340 // 'True' for recognized list constructors. |
3319 bool is_known_list_constructor_; | 3341 bool is_known_list_constructor_; |
3320 | 3342 |
3321 AliasIdentity identity_; | 3343 AliasIdentity identity_; |
(...skipping 4792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8114 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ | 8136 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ |
8115 UNIMPLEMENTED(); \ | 8137 UNIMPLEMENTED(); \ |
8116 return NULL; \ | 8138 return NULL; \ |
8117 } \ | 8139 } \ |
8118 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } | 8140 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } |
8119 | 8141 |
8120 | 8142 |
8121 } // namespace dart | 8143 } // namespace dart |
8122 | 8144 |
8123 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 8145 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |