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 2915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2926 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); | 2926 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); |
2927 } | 2927 } |
2928 | 2928 |
2929 | 2929 |
2930 LocationSummary* InstanceCallInstr::MakeLocationSummary(Zone* zone, | 2930 LocationSummary* InstanceCallInstr::MakeLocationSummary(Zone* zone, |
2931 bool optimizing) const { | 2931 bool optimizing) const { |
2932 return MakeCallSummary(zone); | 2932 return MakeCallSummary(zone); |
2933 } | 2933 } |
2934 | 2934 |
2935 | 2935 |
2936 static uword TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) { | 2936 static RawCode* TwoArgsSmiOpInlineCacheCode(Token::Kind kind) { |
2937 if (!FLAG_two_args_smi_icd) { | 2937 if (!FLAG_two_args_smi_icd) { |
2938 return 0; | 2938 return 0; |
2939 } | 2939 } |
2940 StubCode* stub_code = Isolate::Current()->stub_code(); | 2940 StubCode* stub_code = Isolate::Current()->stub_code(); |
2941 switch (kind) { | 2941 switch (kind) { |
2942 case Token::kADD: return stub_code->SmiAddInlineCacheEntryPoint(); | 2942 case Token::kADD: return stub_code->SmiAddInlineCacheCode(); |
2943 case Token::kSUB: return stub_code->SmiSubInlineCacheEntryPoint(); | 2943 case Token::kSUB: return stub_code->SmiSubInlineCacheCode(); |
2944 case Token::kEQ: return stub_code->SmiEqualInlineCacheEntryPoint(); | 2944 case Token::kEQ: return stub_code->SmiEqualInlineCacheCode(); |
2945 default: return 0; | 2945 default: return Code::null(); |
2946 } | 2946 } |
2947 } | 2947 } |
2948 | 2948 |
2949 | 2949 |
2950 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2950 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2951 Zone* zone = compiler->zone(); | 2951 Zone* zone = compiler->zone(); |
2952 const ICData* call_ic_data = NULL; | 2952 const ICData* call_ic_data = NULL; |
2953 if (!FLAG_propagate_ic_data || !compiler->is_optimizing() || | 2953 if (!FLAG_propagate_ic_data || !compiler->is_optimizing() || |
2954 (ic_data() == NULL)) { | 2954 (ic_data() == NULL)) { |
2955 const Array& arguments_descriptor = | 2955 const Array& arguments_descriptor = |
(...skipping 20 matching lines...) Expand all Loading... |
2976 compiler->GenerateInstanceCall(deopt_id(), | 2976 compiler->GenerateInstanceCall(deopt_id(), |
2977 token_pos(), | 2977 token_pos(), |
2978 ArgumentCount(), | 2978 ArgumentCount(), |
2979 locs(), | 2979 locs(), |
2980 *call_ic_data); | 2980 *call_ic_data); |
2981 } | 2981 } |
2982 } else { | 2982 } else { |
2983 // Unoptimized code. | 2983 // Unoptimized code. |
2984 ASSERT(!HasICData()); | 2984 ASSERT(!HasICData()); |
2985 bool is_smi_two_args_op = false; | 2985 bool is_smi_two_args_op = false; |
2986 const uword label_address = TwoArgsSmiOpInlineCacheEntry(token_kind()); | 2986 Code& stub = Code::Handle(TwoArgsSmiOpInlineCacheCode(token_kind())); |
2987 if (label_address != 0) { | 2987 if (stub.raw() != Code::null()) { |
2988 // We have a dedicated inline cache stub for this operation, add an | 2988 // We have a dedicated inline cache stub for this operation, add an |
2989 // an initial Smi/Smi check with count 0. | 2989 // an initial Smi/Smi check with count 0. |
2990 ASSERT(call_ic_data->NumArgsTested() == 2); | 2990 ASSERT(call_ic_data->NumArgsTested() == 2); |
2991 const String& name = String::Handle(zone, call_ic_data->target_name()); | 2991 const String& name = String::Handle(zone, call_ic_data->target_name()); |
2992 const Class& smi_class = Class::Handle(zone, Smi::Class()); | 2992 const Class& smi_class = Class::Handle(zone, Smi::Class()); |
2993 const Function& smi_op_target = | 2993 const Function& smi_op_target = |
2994 Function::Handle(Resolver::ResolveDynamicAnyArgs(smi_class, name)); | 2994 Function::Handle(Resolver::ResolveDynamicAnyArgs(smi_class, name)); |
2995 if (call_ic_data->NumberOfChecks() == 0) { | 2995 if (call_ic_data->NumberOfChecks() == 0) { |
2996 GrowableArray<intptr_t> class_ids(2); | 2996 GrowableArray<intptr_t> class_ids(2); |
2997 class_ids.Add(kSmiCid); | 2997 class_ids.Add(kSmiCid); |
2998 class_ids.Add(kSmiCid); | 2998 class_ids.Add(kSmiCid); |
2999 call_ic_data->AddCheck(class_ids, smi_op_target); | 2999 call_ic_data->AddCheck(class_ids, smi_op_target); |
3000 // 'AddCheck' sets the initial count to 1. | 3000 // 'AddCheck' sets the initial count to 1. |
3001 call_ic_data->SetCountAt(0, 0); | 3001 call_ic_data->SetCountAt(0, 0); |
3002 is_smi_two_args_op = true; | 3002 is_smi_two_args_op = true; |
3003 } else if (call_ic_data->NumberOfChecks() == 1) { | 3003 } else if (call_ic_data->NumberOfChecks() == 1) { |
3004 GrowableArray<intptr_t> class_ids(2); | 3004 GrowableArray<intptr_t> class_ids(2); |
3005 Function& target = Function::Handle(zone); | 3005 Function& target = Function::Handle(zone); |
3006 call_ic_data->GetCheckAt(0, &class_ids, &target); | 3006 call_ic_data->GetCheckAt(0, &class_ids, &target); |
3007 if ((target.raw() == smi_op_target.raw()) && | 3007 if ((target.raw() == smi_op_target.raw()) && |
3008 (class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) { | 3008 (class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) { |
3009 is_smi_two_args_op = true; | 3009 is_smi_two_args_op = true; |
3010 } | 3010 } |
3011 } | 3011 } |
3012 } | 3012 } |
3013 if (is_smi_two_args_op) { | 3013 if (is_smi_two_args_op) { |
3014 ASSERT(ArgumentCount() == 2); | 3014 ASSERT(ArgumentCount() == 2); |
3015 ExternalLabel target_label(label_address); | 3015 compiler->EmitInstanceCall(stub, *call_ic_data, ArgumentCount(), |
3016 compiler->EmitInstanceCall(&target_label, *call_ic_data, ArgumentCount(), | |
3017 deopt_id(), token_pos(), locs()); | 3016 deopt_id(), token_pos(), locs()); |
3018 } else if (FLAG_ic_range_profiling && | 3017 } else if (FLAG_ic_range_profiling && |
3019 (Token::IsBinaryArithmeticOperator(token_kind()) || | 3018 (Token::IsBinaryArithmeticOperator(token_kind()) || |
3020 Token::IsUnaryArithmeticOperator(token_kind()))) { | 3019 Token::IsUnaryArithmeticOperator(token_kind()))) { |
3021 ASSERT(Token::IsUnaryArithmeticOperator(token_kind()) == | 3020 ASSERT(Token::IsUnaryArithmeticOperator(token_kind()) == |
3022 (ArgumentCount() == 1)); | 3021 (ArgumentCount() == 1)); |
3023 ASSERT(Token::IsBinaryArithmeticOperator(token_kind()) == | 3022 ASSERT(Token::IsBinaryArithmeticOperator(token_kind()) == |
3024 (ArgumentCount() == 2)); | 3023 (ArgumentCount() == 2)); |
3025 StubCode* stub_code = compiler->isolate()->stub_code(); | 3024 StubCode* stub_code = compiler->isolate()->stub_code(); |
3026 ExternalLabel target_label((ArgumentCount() == 1) ? | 3025 stub = ((ArgumentCount() == 1) ? |
3027 stub_code->UnaryRangeCollectingInlineCacheEntryPoint() : | 3026 stub_code->UnaryRangeCollectingInlineCacheCode() : |
3028 stub_code->BinaryRangeCollectingInlineCacheEntryPoint()); | 3027 stub_code->BinaryRangeCollectingInlineCacheCode()); |
3029 compiler->EmitInstanceCall(&target_label, *call_ic_data, ArgumentCount(), | 3028 compiler->EmitInstanceCall(stub, *call_ic_data, ArgumentCount(), |
3030 deopt_id(), token_pos(), locs()); | 3029 deopt_id(), token_pos(), locs()); |
3031 } else { | 3030 } else { |
3032 compiler->GenerateInstanceCall(deopt_id(), | 3031 compiler->GenerateInstanceCall(deopt_id(), |
3033 token_pos(), | 3032 token_pos(), |
3034 ArgumentCount(), | 3033 ArgumentCount(), |
3035 locs(), | 3034 locs(), |
3036 *call_ic_data); | 3035 *call_ic_data); |
3037 } | 3036 } |
3038 } | 3037 } |
3039 } | 3038 } |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3636 case Token::kTRUNCDIV: return 0; | 3635 case Token::kTRUNCDIV: return 0; |
3637 case Token::kMOD: return 1; | 3636 case Token::kMOD: return 1; |
3638 default: UNIMPLEMENTED(); return -1; | 3637 default: UNIMPLEMENTED(); return -1; |
3639 } | 3638 } |
3640 } | 3639 } |
3641 | 3640 |
3642 | 3641 |
3643 #undef __ | 3642 #undef __ |
3644 | 3643 |
3645 } // namespace dart | 3644 } // namespace dart |
OLD | NEW |