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/constant_propagator.h" | 8 #include "vm/constant_propagator.h" |
9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 2927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2938 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); | 2938 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); |
2939 } | 2939 } |
2940 | 2940 |
2941 | 2941 |
2942 LocationSummary* InstanceCallInstr::MakeLocationSummary(Zone* zone, | 2942 LocationSummary* InstanceCallInstr::MakeLocationSummary(Zone* zone, |
2943 bool optimizing) const { | 2943 bool optimizing) const { |
2944 return MakeCallSummary(zone); | 2944 return MakeCallSummary(zone); |
2945 } | 2945 } |
2946 | 2946 |
2947 | 2947 |
2948 static uword TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) { | 2948 static const StubEntry* TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) { |
2949 if (!FLAG_two_args_smi_icd) { | 2949 if (!FLAG_two_args_smi_icd) { |
2950 return 0; | 2950 return 0; |
2951 } | 2951 } |
2952 switch (kind) { | 2952 switch (kind) { |
2953 case Token::kADD: return StubCode::SmiAddInlineCacheEntryPoint(); | 2953 case Token::kADD: return StubCode::SmiAddInlineCache_entry(); |
2954 case Token::kSUB: return StubCode::SmiSubInlineCacheEntryPoint(); | 2954 case Token::kSUB: return StubCode::SmiSubInlineCache_entry(); |
2955 case Token::kEQ: return StubCode::SmiEqualInlineCacheEntryPoint(); | 2955 case Token::kEQ: return StubCode::SmiEqualInlineCache_entry(); |
2956 default: return 0; | 2956 default: return NULL; |
2957 } | 2957 } |
2958 } | 2958 } |
2959 | 2959 |
2960 | 2960 |
2961 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2961 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2962 Zone* zone = compiler->zone(); | 2962 Zone* zone = compiler->zone(); |
2963 const ICData* call_ic_data = NULL; | 2963 const ICData* call_ic_data = NULL; |
2964 if (!FLAG_propagate_ic_data || !compiler->is_optimizing() || | 2964 if (!FLAG_propagate_ic_data || !compiler->is_optimizing() || |
2965 (ic_data() == NULL)) { | 2965 (ic_data() == NULL)) { |
2966 const Array& arguments_descriptor = | 2966 const Array& arguments_descriptor = |
(...skipping 20 matching lines...) Expand all Loading... |
2987 compiler->GenerateInstanceCall(deopt_id(), | 2987 compiler->GenerateInstanceCall(deopt_id(), |
2988 token_pos(), | 2988 token_pos(), |
2989 ArgumentCount(), | 2989 ArgumentCount(), |
2990 locs(), | 2990 locs(), |
2991 *call_ic_data); | 2991 *call_ic_data); |
2992 } | 2992 } |
2993 } else { | 2993 } else { |
2994 // Unoptimized code. | 2994 // Unoptimized code. |
2995 ASSERT(!HasICData()); | 2995 ASSERT(!HasICData()); |
2996 bool is_smi_two_args_op = false; | 2996 bool is_smi_two_args_op = false; |
2997 const uword label_address = TwoArgsSmiOpInlineCacheEntry(token_kind()); | 2997 const StubEntry* stub_entry = TwoArgsSmiOpInlineCacheEntry(token_kind()); |
2998 if (label_address != 0) { | 2998 if (stub_entry != NULL) { |
2999 // We have a dedicated inline cache stub for this operation, add an | 2999 // We have a dedicated inline cache stub for this operation, add an |
3000 // an initial Smi/Smi check with count 0. | 3000 // an initial Smi/Smi check with count 0. |
3001 ASSERT(call_ic_data->NumArgsTested() == 2); | 3001 ASSERT(call_ic_data->NumArgsTested() == 2); |
3002 const String& name = String::Handle(zone, call_ic_data->target_name()); | 3002 const String& name = String::Handle(zone, call_ic_data->target_name()); |
3003 const Class& smi_class = Class::Handle(zone, Smi::Class()); | 3003 const Class& smi_class = Class::Handle(zone, Smi::Class()); |
3004 const Function& smi_op_target = | 3004 const Function& smi_op_target = |
3005 Function::Handle(Resolver::ResolveDynamicAnyArgs(smi_class, name)); | 3005 Function::Handle(Resolver::ResolveDynamicAnyArgs(smi_class, name)); |
3006 if (call_ic_data->NumberOfChecks() == 0) { | 3006 if (call_ic_data->NumberOfChecks() == 0) { |
3007 GrowableArray<intptr_t> class_ids(2); | 3007 GrowableArray<intptr_t> class_ids(2); |
3008 class_ids.Add(kSmiCid); | 3008 class_ids.Add(kSmiCid); |
3009 class_ids.Add(kSmiCid); | 3009 class_ids.Add(kSmiCid); |
3010 call_ic_data->AddCheck(class_ids, smi_op_target); | 3010 call_ic_data->AddCheck(class_ids, smi_op_target); |
3011 // 'AddCheck' sets the initial count to 1. | 3011 // 'AddCheck' sets the initial count to 1. |
3012 call_ic_data->SetCountAt(0, 0); | 3012 call_ic_data->SetCountAt(0, 0); |
3013 is_smi_two_args_op = true; | 3013 is_smi_two_args_op = true; |
3014 } else if (call_ic_data->NumberOfChecks() == 1) { | 3014 } else if (call_ic_data->NumberOfChecks() == 1) { |
3015 GrowableArray<intptr_t> class_ids(2); | 3015 GrowableArray<intptr_t> class_ids(2); |
3016 Function& target = Function::Handle(zone); | 3016 Function& target = Function::Handle(zone); |
3017 call_ic_data->GetCheckAt(0, &class_ids, &target); | 3017 call_ic_data->GetCheckAt(0, &class_ids, &target); |
3018 if ((target.raw() == smi_op_target.raw()) && | 3018 if ((target.raw() == smi_op_target.raw()) && |
3019 (class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) { | 3019 (class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) { |
3020 is_smi_two_args_op = true; | 3020 is_smi_two_args_op = true; |
3021 } | 3021 } |
3022 } | 3022 } |
3023 } | 3023 } |
3024 if (is_smi_two_args_op) { | 3024 if (is_smi_two_args_op) { |
3025 ASSERT(ArgumentCount() == 2); | 3025 ASSERT(ArgumentCount() == 2); |
3026 ExternalLabel target_label(label_address); | 3026 compiler->EmitInstanceCall(*stub_entry, *call_ic_data, ArgumentCount(), |
3027 compiler->EmitInstanceCall(&target_label, *call_ic_data, ArgumentCount(), | |
3028 deopt_id(), token_pos(), locs()); | 3027 deopt_id(), token_pos(), locs()); |
3029 } else if (FLAG_ic_range_profiling && | 3028 } else if (FLAG_ic_range_profiling && |
3030 (Token::IsBinaryArithmeticOperator(token_kind()) || | 3029 (Token::IsBinaryArithmeticOperator(token_kind()) || |
3031 Token::IsUnaryArithmeticOperator(token_kind()))) { | 3030 Token::IsUnaryArithmeticOperator(token_kind()))) { |
3032 ASSERT(Token::IsUnaryArithmeticOperator(token_kind()) == | 3031 ASSERT(Token::IsUnaryArithmeticOperator(token_kind()) == |
3033 (ArgumentCount() == 1)); | 3032 (ArgumentCount() == 1)); |
3034 ASSERT(Token::IsBinaryArithmeticOperator(token_kind()) == | 3033 ASSERT(Token::IsBinaryArithmeticOperator(token_kind()) == |
3035 (ArgumentCount() == 2)); | 3034 (ArgumentCount() == 2)); |
3036 ExternalLabel target_label((ArgumentCount() == 1) ? | 3035 const StubEntry* stub_entry = (ArgumentCount() == 1) |
3037 StubCode::UnaryRangeCollectingInlineCacheEntryPoint() : | 3036 ? StubCode::UnaryRangeCollectingInlineCache_entry() |
3038 StubCode::BinaryRangeCollectingInlineCacheEntryPoint()); | 3037 : StubCode::BinaryRangeCollectingInlineCache_entry(); |
3039 compiler->EmitInstanceCall(&target_label, *call_ic_data, ArgumentCount(), | 3038 compiler->EmitInstanceCall(*stub_entry, *call_ic_data, ArgumentCount(), |
3040 deopt_id(), token_pos(), locs()); | 3039 deopt_id(), token_pos(), locs()); |
3041 } else { | 3040 } else { |
3042 compiler->GenerateInstanceCall(deopt_id(), | 3041 compiler->GenerateInstanceCall(deopt_id(), |
3043 token_pos(), | 3042 token_pos(), |
3044 ArgumentCount(), | 3043 ArgumentCount(), |
3045 locs(), | 3044 locs(), |
3046 *call_ic_data); | 3045 *call_ic_data); |
3047 } | 3046 } |
3048 } | 3047 } |
3049 } | 3048 } |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3646 case Token::kTRUNCDIV: return 0; | 3645 case Token::kTRUNCDIV: return 0; |
3647 case Token::kMOD: return 1; | 3646 case Token::kMOD: return 1; |
3648 default: UNIMPLEMENTED(); return -1; | 3647 default: UNIMPLEMENTED(); return -1; |
3649 } | 3648 } |
3650 } | 3649 } |
3651 | 3650 |
3652 | 3651 |
3653 #undef __ | 3652 #undef __ |
3654 | 3653 |
3655 } // namespace dart | 3654 } // namespace dart |
OLD | NEW |