Chromium Code Reviews| Index: runtime/vm/flow_graph_inliner.cc |
| diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc |
| index 95e634b1a1815002f21702aa1889bdf8a54acbf0..5be550b3fc7c2e5e8d9f6071dfbc0185c9b41fb9 100644 |
| --- a/runtime/vm/flow_graph_inliner.cc |
| +++ b/runtime/vm/flow_graph_inliner.cc |
| @@ -2269,20 +2269,6 @@ static intptr_t PrepareInlineIndexedOp(FlowGraph* flow_graph, |
| } |
| -static Instruction* GetCheckClass(FlowGraph* flow_graph, |
| - Definition* to_check, |
| - const ICData& unary_checks, |
| - intptr_t deopt_id, |
| - TokenPosition token_pos) { |
| - if ((unary_checks.NumberOfUsedChecks() == 1) && |
| - unary_checks.HasReceiverClassId(kSmiCid)) { |
| - return new (Z) CheckSmiInstr(new (Z) Value(to_check), deopt_id, token_pos); |
| - } |
| - return new (Z) CheckClassInstr(new (Z) Value(to_check), deopt_id, |
| - unary_checks, token_pos); |
| -} |
| - |
| - |
| static bool InlineGetIndexed(FlowGraph* flow_graph, |
| MethodRecognizer::Kind kind, |
| Instruction* call, |
| @@ -2333,7 +2319,7 @@ static bool InlineSetIndexed(FlowGraph* flow_graph, |
| Instruction* call, |
| Definition* receiver, |
| TokenPosition token_pos, |
| - const ICData& value_check, |
| + const CallTargets* value_check, |
| TargetEntryInstr** entry, |
| Definition** last) { |
| intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind); |
| @@ -2428,12 +2414,12 @@ static bool InlineSetIndexed(FlowGraph* flow_graph, |
| // No need to class check stores to Int32 and Uint32 arrays because |
| // we insert unboxing instructions below which include a class check. |
| if ((array_cid != kTypedDataUint32ArrayCid) && |
| - (array_cid != kTypedDataInt32ArrayCid) && !value_check.IsNull()) { |
| + (array_cid != kTypedDataInt32ArrayCid) && value_check != NULL) { |
| // No store barrier needed because checked value is a smi, an unboxed mint, |
| // an unboxed double, an unboxed Float32x4, or unboxed Int32x4. |
| needs_store_barrier = kNoStoreBarrier; |
| - Instruction* check = GetCheckClass(flow_graph, stored_value, value_check, |
| - call->deopt_id(), call->token_pos()); |
| + Instruction* check = flow_graph->GetCheckClass( |
| + stored_value, *value_check, call->deopt_id(), call->token_pos()); |
| cursor = |
| flow_graph->AppendTo(cursor, check, call->env(), FlowGraph::kEffect); |
| } |
| @@ -2696,7 +2682,7 @@ static bool InlineByteArrayBaseStore(FlowGraph* flow_graph, |
| i_call = call->AsInstanceCall(); |
| } |
| ASSERT(i_call != NULL); |
| - ICData& value_check = ICData::ZoneHandle(Z); |
| + CallTargets* value_check = NULL; |
| switch (view_cid) { |
| case kTypedDataInt8ArrayCid: |
| case kTypedDataUint8ArrayCid: |
| @@ -2706,46 +2692,39 @@ static bool InlineByteArrayBaseStore(FlowGraph* flow_graph, |
| case kTypedDataInt16ArrayCid: |
| case kTypedDataUint16ArrayCid: { |
| // Check that value is always smi. |
| - value_check = ICData::New(flow_graph->function(), i_call->function_name(), |
| - Object::empty_array(), // Dummy args. descr. |
| - Thread::kNoDeoptId, 1, false); |
| - value_check.AddReceiverCheck(kSmiCid, target); |
| + value_check = new (Z) CallTargets(); |
|
Vyacheslav Egorov (Google)
2017/05/01 12:21:24
Maybe make a helper CallTargets::CreateMonomorphic
erikcorry
2017/05/05 15:15:51
Done.
|
| + value_check->Add(CidRangeTarget(kSmiCid, kSmiCid, NULL, /* count = */ 1)); |
| break; |
| } |
| case kTypedDataInt32ArrayCid: |
| case kTypedDataUint32ArrayCid: |
| // On 64-bit platforms assume that stored value is always a smi. |
| if (kSmiBits >= 32) { |
| - value_check = |
| - ICData::New(flow_graph->function(), i_call->function_name(), |
| - Object::empty_array(), // Dummy args. descr. |
| - Thread::kNoDeoptId, 1, false); |
| - value_check.AddReceiverCheck(kSmiCid, target); |
| + value_check = new (Z) CallTargets(); |
| + value_check->Add( |
| + CidRangeTarget(kSmiCid, kSmiCid, NULL, /* count = */ 1)); |
| } |
| break; |
| case kTypedDataFloat32ArrayCid: |
| case kTypedDataFloat64ArrayCid: { |
| // Check that value is always double. |
| - value_check = ICData::New(flow_graph->function(), i_call->function_name(), |
| - Object::empty_array(), // Dummy args. descr. |
| - Thread::kNoDeoptId, 1, false); |
| - value_check.AddReceiverCheck(kDoubleCid, target); |
| + value_check = new (Z) CallTargets(); |
| + value_check->Add( |
| + CidRangeTarget(kDoubleCid, kDoubleCid, NULL, /* count = */ 1)); |
| break; |
| } |
| case kTypedDataInt32x4ArrayCid: { |
| // Check that value is always Int32x4. |
| - value_check = ICData::New(flow_graph->function(), i_call->function_name(), |
| - Object::empty_array(), // Dummy args. descr. |
| - Thread::kNoDeoptId, 1, false); |
| - value_check.AddReceiverCheck(kInt32x4Cid, target); |
| + value_check = new (Z) CallTargets(); |
| + value_check->Add( |
| + CidRangeTarget(kInt32x4Cid, kInt32x4Cid, NULL, /* count = */ 1)); |
| break; |
| } |
| case kTypedDataFloat32x4ArrayCid: { |
| // Check that value is always Float32x4. |
| - value_check = ICData::New(flow_graph->function(), i_call->function_name(), |
| - Object::empty_array(), // Dummy args. descr. |
| - Thread::kNoDeoptId, 1, false); |
| - value_check.AddReceiverCheck(kFloat32x4Cid, target); |
| + value_check = new (Z) CallTargets(); |
| + value_check->Add( |
| + CidRangeTarget(kFloat32x4Cid, kFloat32x4Cid, NULL, /* count = */ 1)); |
| break; |
| } |
| default: |
| @@ -2754,9 +2733,9 @@ static bool InlineByteArrayBaseStore(FlowGraph* flow_graph, |
| } |
| Definition* stored_value = call->ArgumentAt(2); |
| - if (!value_check.IsNull()) { |
| - Instruction* check = GetCheckClass(flow_graph, stored_value, value_check, |
| - call->deopt_id(), call->token_pos()); |
| + if (value_check != NULL) { |
| + Instruction* check = flow_graph->GetCheckClass( |
| + stored_value, *value_check, call->deopt_id(), call->token_pos()); |
| cursor = |
| flow_graph->AppendTo(cursor, check, call->env(), FlowGraph::kEffect); |
| } |
| @@ -2916,9 +2895,8 @@ bool FlowGraphInliner::TryReplaceInstanceCallWithInline( |
| // Insert receiver class check if needed. |
| if (MethodRecognizer::PolymorphicTarget(target) || |
| flow_graph->InstanceCallNeedsClassCheck(call, target.kind())) { |
| - Instruction* check = GetCheckClass( |
| - flow_graph, call->ArgumentAt(0), |
| - ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()), |
| + Instruction* check = flow_graph->GetCheckClass( |
| + call->ArgumentAt(0), *CallTargets::Create(Z, *call->ic_data(), 0), |
| call->deopt_id(), call->token_pos()); |
| flow_graph->InsertBefore(call, check, call->env(), FlowGraph::kEffect); |
| } |
| @@ -3405,7 +3383,6 @@ bool FlowGraphInliner::TryInlineRecognizedMethod(FlowGraph* flow_graph, |
| const ICData& ic_data, |
| TargetEntryInstr** entry, |
| Definition** last) { |
| - ICData& value_check = ICData::ZoneHandle(Z); |
| MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(target); |
| switch (kind) { |
| // Recognized [] operators. |
| @@ -3446,59 +3423,68 @@ bool FlowGraphInliner::TryInlineRecognizedMethod(FlowGraph* flow_graph, |
| case MethodRecognizer::kObjectArraySetIndexed: |
| case MethodRecognizer::kGrowableArraySetIndexed: |
| return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
| - token_pos, value_check, entry, last); |
| + token_pos, /* value_check = */ NULL, entry, last); |
| case MethodRecognizer::kInt8ArraySetIndexed: |
| case MethodRecognizer::kUint8ArraySetIndexed: |
| case MethodRecognizer::kUint8ClampedArraySetIndexed: |
| case MethodRecognizer::kExternalUint8ArraySetIndexed: |
| case MethodRecognizer::kExternalUint8ClampedArraySetIndexed: |
| case MethodRecognizer::kInt16ArraySetIndexed: |
| - case MethodRecognizer::kUint16ArraySetIndexed: |
| + case MethodRecognizer::kUint16ArraySetIndexed: { |
| // Optimistically assume Smi. |
| if (ic_data.HasDeoptReason(ICData::kDeoptCheckSmi)) { |
| // Optimistic assumption failed at least once. |
| return false; |
| } |
| - value_check = ic_data.AsUnaryClassChecksForCid(kSmiCid, target); |
| + CallTargets* value_check = new (Z) CallTargets(); |
| + value_check->Add(CidRangeTarget(kSmiCid, kSmiCid, NULL, /* count = */ 1)); |
| return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
| token_pos, value_check, entry, last); |
| + } |
| case MethodRecognizer::kInt32ArraySetIndexed: |
| case MethodRecognizer::kUint32ArraySetIndexed: { |
| // Value check not needed for Int32 and Uint32 arrays because they |
| // implicitly contain unboxing instructions which check for right type. |
| - ICData& value_check = ICData::Handle(); |
| return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
| - token_pos, value_check, entry, last); |
| + token_pos, /* value_check = */ NULL, entry, last); |
| } |
| case MethodRecognizer::kInt64ArraySetIndexed: |
| if (!ShouldInlineInt64ArrayOps()) { |
| return false; |
| } |
| return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
| - token_pos, value_check, entry, last); |
| + token_pos, /* value_check = */ NULL, entry, last); |
| case MethodRecognizer::kFloat32ArraySetIndexed: |
| - case MethodRecognizer::kFloat64ArraySetIndexed: |
| + case MethodRecognizer::kFloat64ArraySetIndexed: { |
| if (!CanUnboxDouble()) { |
| return false; |
| } |
| - value_check = ic_data.AsUnaryClassChecksForCid(kDoubleCid, target); |
| + CallTargets* value_check = new (Z) CallTargets(); |
| + value_check->Add( |
| + CidRangeTarget(kDoubleCid, kDoubleCid, NULL, /* count = */ 1)); |
| return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
| token_pos, value_check, entry, last); |
| - case MethodRecognizer::kFloat32x4ArraySetIndexed: |
| + } |
| + case MethodRecognizer::kFloat32x4ArraySetIndexed: { |
| if (!ShouldInlineSimd()) { |
| return false; |
| } |
| - value_check = ic_data.AsUnaryClassChecksForCid(kFloat32x4Cid, target); |
| - |
| + CallTargets* value_check = new (Z) CallTargets(); |
| + value_check->Add( |
| + CidRangeTarget(kFloat32x4Cid, kFloat32x4Cid, NULL, /* count = */ 1)); |
| return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
| token_pos, value_check, entry, last); |
| - case MethodRecognizer::kFloat64x2ArraySetIndexed: |
| + } |
| + case MethodRecognizer::kFloat64x2ArraySetIndexed: { |
| if (!ShouldInlineSimd()) { |
| return false; |
| } |
| - value_check = ic_data.AsUnaryClassChecksForCid(kFloat64x2Cid, target); |
| + CallTargets* value_check = new (Z) CallTargets(); |
| + value_check->Add( |
| + CidRangeTarget(kFloat64x2Cid, kFloat64x2Cid, NULL, /* count = */ 1)); |
| return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
| token_pos, value_check, entry, last); |
| + } |
| case MethodRecognizer::kByteArrayBaseGetInt8: |
| return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid, |
| kTypedDataInt8ArrayCid, entry, last); |