Chromium Code Reviews| Index: runtime/vm/intermediate_language_dbc.cc |
| diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc |
| index 3838de2cbf23169b146711bf97fbfdd8a6d999b3..3dc2aa7823685445aacc81d7ef26a8d7d666cd6b 100644 |
| --- a/runtime/vm/intermediate_language_dbc.cc |
| +++ b/runtime/vm/intermediate_language_dbc.cc |
| @@ -242,18 +242,17 @@ EMIT_NATIVE_CODE(PolymorphicInstanceCall, |
| const Array& arguments_descriptor = Array::Handle(ArgumentsDescriptor::New( |
| instance_call()->ArgumentCount(), instance_call()->argument_names())); |
| const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor); |
| - const CallTargets& ic_data = targets(); |
| // Push the target onto the stack. |
| if (with_checks()) { |
| - const intptr_t length = ic_data.length(); |
| + const intptr_t length = targets_.length(); |
| if (!Utils::IsUint(8, length)) { |
| Unsupported(compiler); |
| UNREACHABLE(); |
| } |
| bool using_ranges = false; |
| for (intptr_t i = 0; i < length; i++) { |
| - if (ic_data[i].cid_start != ic_data[i].cid_end) { |
| + if (targets_[i].cid_start != targets_[i].cid_end) { |
| using_ranges = true; |
| break; |
| } |
| @@ -266,9 +265,9 @@ EMIT_NATIVE_CODE(PolymorphicInstanceCall, |
| __ PushPolymorphicInstanceCall(instance_call()->ArgumentCount(), length); |
| } |
| for (intptr_t i = 0; i < length; i++) { |
| - const Function& target = *ic_data[i].target; |
| - intptr_t cid_start = ic_data[i].cid_start; |
| - intptr_t cid_end = ic_data[i].cid_end; |
| + const Function& target = *targets_.TargetAt(i)->target; |
| + intptr_t cid_start = targets_[i].cid_start; |
| + intptr_t cid_end = targets_[i].cid_end; |
| __ Nop(compiler->ToEmbeddableCid(cid_start, this)); |
| if (using_ranges) { |
| @@ -1499,55 +1498,56 @@ EMIT_NATIVE_CODE(CheckClassId, 1) { |
| EMIT_NATIVE_CODE(CheckClass, 1) { |
| const Register value = locs()->in(0).reg(); |
| if (IsNullCheck()) { |
| - ASSERT(DeoptIfNull() || DeoptIfNotNull()); |
| - if (DeoptIfNull()) { |
| + ASSERT(IsDeoptIfNull() || IsDeoptIfNotNull()); |
| + if (IsDeoptIfNull()) { |
| __ IfEqNull(value); |
| } else { |
| __ IfNeNull(value); |
| } |
| } else { |
| - ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || |
| - (unary_checks().NumberOfChecks() > 1)); |
| - const intptr_t may_be_smi = |
| - (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) ? 1 : 0; |
| - bool is_dense_switch = false; |
| + ASSERT(!cids_.IsMonomorphic() || !cids_.HasClassId(kSmiCid)); |
| + const intptr_t may_be_smi = cids_.HasClassId(kSmiCid) ? 1 : 0; |
| + bool is_bit_test = false; |
| intptr_t cid_mask = 0; |
| - if (IsDenseSwitch()) { |
| - ASSERT(cids_[0] < cids_[cids_.length() - 1]); |
| + if (IsBitTest()) { |
| cid_mask = ComputeCidMask(); |
| - is_dense_switch = Smi::IsValid(cid_mask); |
| + is_bit_test = Smi::IsValid(cid_mask); |
| } |
| - if (is_dense_switch) { |
| - const intptr_t low_cid = cids_[0]; |
| - __ CheckDenseSwitch(value, may_be_smi); |
| - __ Nop(compiler->ToEmbeddableCid(low_cid, this)); |
| + if (is_bit_test) { |
| + intptr_t min = cids_.ComputeLowestCid(); |
| + __ CheckBitTest(value, may_be_smi); |
| + __ Nop(compiler->ToEmbeddableCid(min, this)); |
| __ Nop(__ AddConstant(Smi::Handle(Smi::New(cid_mask)))); |
| } else { |
| - GrowableArray<CidRangeTarget> sorted_ic_data; |
| - FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, |
| - /* drop_smi = */ true); |
| - const intptr_t sorted_length = sorted_ic_data.length(); |
| - |
| bool using_ranges = false; |
| - for (intptr_t i = 0; i < sorted_length; i++) { |
| - if (sorted_ic_data[i].cid_start != sorted_ic_data[i].cid_end) { |
| + int smi_adjustment = 0; |
| + int length = cids_.length(); |
| + for (intptr_t i = 0; i < length; i++) { |
| + if (cids_[i].cid_start != cids_[i].cid_end) { |
| using_ranges = true; |
| - break; |
| + } else if (cids_[i].cid_start == kSmiCid) { |
| + ASSERT(cids_[i].cid_end == kSmiCid); |
|
Vyacheslav Egorov (Google)
2017/05/09 21:07:27
it is not completely clear to me why we can assume
erikcorry
2017/05/10 08:47:43
Comment added: // We are in the else clause.
|
| + ASSERT(smi_adjustment == 0); |
| + smi_adjustment = 1; |
| } |
| } |
| - if (!Utils::IsUint(8, sorted_length)) { |
| + if (!Utils::IsUint(8, length)) { |
| Unsupported(compiler); |
| UNREACHABLE(); |
| } |
| if (using_ranges) { |
| - __ CheckCidsByRange(value, may_be_smi, sorted_length * 2); |
| + __ CheckCidsByRange(value, may_be_smi, (length - smi_adjustment) * 2); |
| } else { |
| - __ CheckCids(value, may_be_smi, sorted_length); |
| + __ CheckCids(value, may_be_smi, length - smi_adjustment); |
| } |
| - for (intptr_t i = 0; i < sorted_length; i++) { |
| - intptr_t cid_start = sorted_ic_data[i].cid_start; |
| - intptr_t cid_end = sorted_ic_data[i].cid_end; |
| + for (intptr_t i = 0; i < length; i++) { |
| + intptr_t cid_start = cids_[i].cid_start; |
| + intptr_t cid_end = cids_[i].cid_end; |
| + if (cid_start == kSmiCid && cid_end == kSmiCid) { |
| + ASSERT(smi_adjustment == 1); |
| + continue; |
| + } |
| __ Nop(compiler->ToEmbeddableCid(cid_start, this)); |
| if (using_ranges) { |
| __ Nop(compiler->ToEmbeddableCid(1 + cid_end - cid_start, this)); |