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 #if !defined(DART_PRECOMPILED_RUNTIME) | 4 #if !defined(DART_PRECOMPILED_RUNTIME) |
5 #include "vm/flow_graph_inliner.h" | 5 #include "vm/flow_graph_inliner.h" |
6 | 6 |
7 #include "vm/aot_optimizer.h" | 7 #include "vm/aot_optimizer.h" |
8 #include "vm/precompiler.h" | 8 #include "vm/precompiler.h" |
9 #include "vm/block_scheduler.h" | 9 #include "vm/block_scheduler.h" |
10 #include "vm/branch_optimizer.h" | 10 #include "vm/branch_optimizer.h" |
(...skipping 2251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2262 } else if (RawObject::IsExternalTypedDataClassId(array_cid)) { | 2262 } else if (RawObject::IsExternalTypedDataClassId(array_cid)) { |
2263 LoadUntaggedInstr* elements = new (Z) LoadUntaggedInstr( | 2263 LoadUntaggedInstr* elements = new (Z) LoadUntaggedInstr( |
2264 new (Z) Value(*array), ExternalTypedData::data_offset()); | 2264 new (Z) Value(*array), ExternalTypedData::data_offset()); |
2265 *cursor = flow_graph->AppendTo(*cursor, elements, NULL, FlowGraph::kValue); | 2265 *cursor = flow_graph->AppendTo(*cursor, elements, NULL, FlowGraph::kValue); |
2266 *array = elements; | 2266 *array = elements; |
2267 } | 2267 } |
2268 return array_cid; | 2268 return array_cid; |
2269 } | 2269 } |
2270 | 2270 |
2271 | 2271 |
2272 static Instruction* GetCheckClass(FlowGraph* flow_graph, | |
2273 Definition* to_check, | |
2274 const ICData& unary_checks, | |
2275 intptr_t deopt_id, | |
2276 TokenPosition token_pos) { | |
2277 if ((unary_checks.NumberOfUsedChecks() == 1) && | |
2278 unary_checks.HasReceiverClassId(kSmiCid)) { | |
2279 return new (Z) CheckSmiInstr(new (Z) Value(to_check), deopt_id, token_pos); | |
2280 } | |
2281 return new (Z) CheckClassInstr(new (Z) Value(to_check), deopt_id, | |
2282 unary_checks, token_pos); | |
2283 } | |
2284 | |
2285 | |
2286 static bool InlineGetIndexed(FlowGraph* flow_graph, | 2272 static bool InlineGetIndexed(FlowGraph* flow_graph, |
2287 MethodRecognizer::Kind kind, | 2273 MethodRecognizer::Kind kind, |
2288 Instruction* call, | 2274 Instruction* call, |
2289 Definition* receiver, | 2275 Definition* receiver, |
2290 TargetEntryInstr** entry, | 2276 TargetEntryInstr** entry, |
2291 Definition** last) { | 2277 Definition** last) { |
2292 intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind); | 2278 intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind); |
2293 | 2279 |
2294 Definition* array = receiver; | 2280 Definition* array = receiver; |
2295 Definition* index = call->ArgumentAt(1); | 2281 Definition* index = call->ArgumentAt(1); |
(...skipping 30 matching lines...) Expand all Loading... | |
2326 return true; | 2312 return true; |
2327 } | 2313 } |
2328 | 2314 |
2329 | 2315 |
2330 static bool InlineSetIndexed(FlowGraph* flow_graph, | 2316 static bool InlineSetIndexed(FlowGraph* flow_graph, |
2331 MethodRecognizer::Kind kind, | 2317 MethodRecognizer::Kind kind, |
2332 const Function& target, | 2318 const Function& target, |
2333 Instruction* call, | 2319 Instruction* call, |
2334 Definition* receiver, | 2320 Definition* receiver, |
2335 TokenPosition token_pos, | 2321 TokenPosition token_pos, |
2336 const ICData& value_check, | 2322 const CallTargets* value_check, |
2337 TargetEntryInstr** entry, | 2323 TargetEntryInstr** entry, |
2338 Definition** last) { | 2324 Definition** last) { |
2339 intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind); | 2325 intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind); |
2340 | 2326 |
2341 Definition* array = receiver; | 2327 Definition* array = receiver; |
2342 Definition* index = call->ArgumentAt(1); | 2328 Definition* index = call->ArgumentAt(1); |
2343 Definition* stored_value = call->ArgumentAt(2); | 2329 Definition* stored_value = call->ArgumentAt(2); |
2344 | 2330 |
2345 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 2331 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
2346 call->GetBlock()->try_index()); | 2332 call->GetBlock()->try_index()); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2421 StoreBarrierType needs_store_barrier = | 2407 StoreBarrierType needs_store_barrier = |
2422 (RawObject::IsTypedDataClassId(array_cid) || | 2408 (RawObject::IsTypedDataClassId(array_cid) || |
2423 RawObject::IsTypedDataViewClassId(array_cid) || | 2409 RawObject::IsTypedDataViewClassId(array_cid) || |
2424 RawObject::IsExternalTypedDataClassId(array_cid)) | 2410 RawObject::IsExternalTypedDataClassId(array_cid)) |
2425 ? kNoStoreBarrier | 2411 ? kNoStoreBarrier |
2426 : kEmitStoreBarrier; | 2412 : kEmitStoreBarrier; |
2427 | 2413 |
2428 // No need to class check stores to Int32 and Uint32 arrays because | 2414 // No need to class check stores to Int32 and Uint32 arrays because |
2429 // we insert unboxing instructions below which include a class check. | 2415 // we insert unboxing instructions below which include a class check. |
2430 if ((array_cid != kTypedDataUint32ArrayCid) && | 2416 if ((array_cid != kTypedDataUint32ArrayCid) && |
2431 (array_cid != kTypedDataInt32ArrayCid) && !value_check.IsNull()) { | 2417 (array_cid != kTypedDataInt32ArrayCid) && value_check != NULL) { |
2432 // No store barrier needed because checked value is a smi, an unboxed mint, | 2418 // No store barrier needed because checked value is a smi, an unboxed mint, |
2433 // an unboxed double, an unboxed Float32x4, or unboxed Int32x4. | 2419 // an unboxed double, an unboxed Float32x4, or unboxed Int32x4. |
2434 needs_store_barrier = kNoStoreBarrier; | 2420 needs_store_barrier = kNoStoreBarrier; |
2435 Instruction* check = GetCheckClass(flow_graph, stored_value, value_check, | 2421 Instruction* check = flow_graph->GetCheckClass( |
2436 call->deopt_id(), call->token_pos()); | 2422 stored_value, *value_check, call->deopt_id(), call->token_pos()); |
2437 cursor = | 2423 cursor = |
2438 flow_graph->AppendTo(cursor, check, call->env(), FlowGraph::kEffect); | 2424 flow_graph->AppendTo(cursor, check, call->env(), FlowGraph::kEffect); |
2439 } | 2425 } |
2440 | 2426 |
2441 if (array_cid == kTypedDataFloat32ArrayCid) { | 2427 if (array_cid == kTypedDataFloat32ArrayCid) { |
2442 stored_value = new (Z) | 2428 stored_value = new (Z) |
2443 DoubleToFloatInstr(new (Z) Value(stored_value), call->deopt_id()); | 2429 DoubleToFloatInstr(new (Z) Value(stored_value), call->deopt_id()); |
2444 cursor = | 2430 cursor = |
2445 flow_graph->AppendTo(cursor, stored_value, NULL, FlowGraph::kValue); | 2431 flow_graph->AppendTo(cursor, stored_value, NULL, FlowGraph::kValue); |
2446 } else if (array_cid == kTypedDataInt32ArrayCid) { | 2432 } else if (array_cid == kTypedDataInt32ArrayCid) { |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2689 // Extract the instance call so we can use the function_name in the stored | 2675 // Extract the instance call so we can use the function_name in the stored |
2690 // value check ICData. | 2676 // value check ICData. |
2691 InstanceCallInstr* i_call = NULL; | 2677 InstanceCallInstr* i_call = NULL; |
2692 if (call->IsPolymorphicInstanceCall()) { | 2678 if (call->IsPolymorphicInstanceCall()) { |
2693 i_call = call->AsPolymorphicInstanceCall()->instance_call(); | 2679 i_call = call->AsPolymorphicInstanceCall()->instance_call(); |
2694 } else { | 2680 } else { |
2695 ASSERT(call->IsInstanceCall()); | 2681 ASSERT(call->IsInstanceCall()); |
2696 i_call = call->AsInstanceCall(); | 2682 i_call = call->AsInstanceCall(); |
2697 } | 2683 } |
2698 ASSERT(i_call != NULL); | 2684 ASSERT(i_call != NULL); |
2699 ICData& value_check = ICData::ZoneHandle(Z); | 2685 CallTargets* value_check = NULL; |
2700 switch (view_cid) { | 2686 switch (view_cid) { |
2701 case kTypedDataInt8ArrayCid: | 2687 case kTypedDataInt8ArrayCid: |
2702 case kTypedDataUint8ArrayCid: | 2688 case kTypedDataUint8ArrayCid: |
2703 case kTypedDataUint8ClampedArrayCid: | 2689 case kTypedDataUint8ClampedArrayCid: |
2704 case kExternalTypedDataUint8ArrayCid: | 2690 case kExternalTypedDataUint8ArrayCid: |
2705 case kExternalTypedDataUint8ClampedArrayCid: | 2691 case kExternalTypedDataUint8ClampedArrayCid: |
2706 case kTypedDataInt16ArrayCid: | 2692 case kTypedDataInt16ArrayCid: |
2707 case kTypedDataUint16ArrayCid: { | 2693 case kTypedDataUint16ArrayCid: { |
2708 // Check that value is always smi. | 2694 // Check that value is always smi. |
2709 value_check = ICData::New(flow_graph->function(), i_call->function_name(), | 2695 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.
| |
2710 Object::empty_array(), // Dummy args. descr. | 2696 value_check->Add(CidRangeTarget(kSmiCid, kSmiCid, NULL, /* count = */ 1)); |
2711 Thread::kNoDeoptId, 1, false); | |
2712 value_check.AddReceiverCheck(kSmiCid, target); | |
2713 break; | 2697 break; |
2714 } | 2698 } |
2715 case kTypedDataInt32ArrayCid: | 2699 case kTypedDataInt32ArrayCid: |
2716 case kTypedDataUint32ArrayCid: | 2700 case kTypedDataUint32ArrayCid: |
2717 // On 64-bit platforms assume that stored value is always a smi. | 2701 // On 64-bit platforms assume that stored value is always a smi. |
2718 if (kSmiBits >= 32) { | 2702 if (kSmiBits >= 32) { |
2719 value_check = | 2703 value_check = new (Z) CallTargets(); |
2720 ICData::New(flow_graph->function(), i_call->function_name(), | 2704 value_check->Add( |
2721 Object::empty_array(), // Dummy args. descr. | 2705 CidRangeTarget(kSmiCid, kSmiCid, NULL, /* count = */ 1)); |
2722 Thread::kNoDeoptId, 1, false); | |
2723 value_check.AddReceiverCheck(kSmiCid, target); | |
2724 } | 2706 } |
2725 break; | 2707 break; |
2726 case kTypedDataFloat32ArrayCid: | 2708 case kTypedDataFloat32ArrayCid: |
2727 case kTypedDataFloat64ArrayCid: { | 2709 case kTypedDataFloat64ArrayCid: { |
2728 // Check that value is always double. | 2710 // Check that value is always double. |
2729 value_check = ICData::New(flow_graph->function(), i_call->function_name(), | 2711 value_check = new (Z) CallTargets(); |
2730 Object::empty_array(), // Dummy args. descr. | 2712 value_check->Add( |
2731 Thread::kNoDeoptId, 1, false); | 2713 CidRangeTarget(kDoubleCid, kDoubleCid, NULL, /* count = */ 1)); |
2732 value_check.AddReceiverCheck(kDoubleCid, target); | |
2733 break; | 2714 break; |
2734 } | 2715 } |
2735 case kTypedDataInt32x4ArrayCid: { | 2716 case kTypedDataInt32x4ArrayCid: { |
2736 // Check that value is always Int32x4. | 2717 // Check that value is always Int32x4. |
2737 value_check = ICData::New(flow_graph->function(), i_call->function_name(), | 2718 value_check = new (Z) CallTargets(); |
2738 Object::empty_array(), // Dummy args. descr. | 2719 value_check->Add( |
2739 Thread::kNoDeoptId, 1, false); | 2720 CidRangeTarget(kInt32x4Cid, kInt32x4Cid, NULL, /* count = */ 1)); |
2740 value_check.AddReceiverCheck(kInt32x4Cid, target); | |
2741 break; | 2721 break; |
2742 } | 2722 } |
2743 case kTypedDataFloat32x4ArrayCid: { | 2723 case kTypedDataFloat32x4ArrayCid: { |
2744 // Check that value is always Float32x4. | 2724 // Check that value is always Float32x4. |
2745 value_check = ICData::New(flow_graph->function(), i_call->function_name(), | 2725 value_check = new (Z) CallTargets(); |
2746 Object::empty_array(), // Dummy args. descr. | 2726 value_check->Add( |
2747 Thread::kNoDeoptId, 1, false); | 2727 CidRangeTarget(kFloat32x4Cid, kFloat32x4Cid, NULL, /* count = */ 1)); |
2748 value_check.AddReceiverCheck(kFloat32x4Cid, target); | |
2749 break; | 2728 break; |
2750 } | 2729 } |
2751 default: | 2730 default: |
2752 // Array cids are already checked in the caller. | 2731 // Array cids are already checked in the caller. |
2753 UNREACHABLE(); | 2732 UNREACHABLE(); |
2754 } | 2733 } |
2755 | 2734 |
2756 Definition* stored_value = call->ArgumentAt(2); | 2735 Definition* stored_value = call->ArgumentAt(2); |
2757 if (!value_check.IsNull()) { | 2736 if (value_check != NULL) { |
2758 Instruction* check = GetCheckClass(flow_graph, stored_value, value_check, | 2737 Instruction* check = flow_graph->GetCheckClass( |
2759 call->deopt_id(), call->token_pos()); | 2738 stored_value, *value_check, call->deopt_id(), call->token_pos()); |
2760 cursor = | 2739 cursor = |
2761 flow_graph->AppendTo(cursor, check, call->env(), FlowGraph::kEffect); | 2740 flow_graph->AppendTo(cursor, check, call->env(), FlowGraph::kEffect); |
2762 } | 2741 } |
2763 | 2742 |
2764 if (view_cid == kTypedDataFloat32ArrayCid) { | 2743 if (view_cid == kTypedDataFloat32ArrayCid) { |
2765 stored_value = new (Z) | 2744 stored_value = new (Z) |
2766 DoubleToFloatInstr(new (Z) Value(stored_value), call->deopt_id()); | 2745 DoubleToFloatInstr(new (Z) Value(stored_value), call->deopt_id()); |
2767 cursor = | 2746 cursor = |
2768 flow_graph->AppendTo(cursor, stored_value, NULL, FlowGraph::kValue); | 2747 flow_graph->AppendTo(cursor, stored_value, NULL, FlowGraph::kValue); |
2769 } else if (view_cid == kTypedDataInt32ArrayCid) { | 2748 } else if (view_cid == kTypedDataInt32ArrayCid) { |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2909 const intptr_t receiver_cid = class_ids[0]; | 2888 const intptr_t receiver_cid = class_ids[0]; |
2910 | 2889 |
2911 TargetEntryInstr* entry; | 2890 TargetEntryInstr* entry; |
2912 Definition* last; | 2891 Definition* last; |
2913 if (FlowGraphInliner::TryInlineRecognizedMethod( | 2892 if (FlowGraphInliner::TryInlineRecognizedMethod( |
2914 flow_graph, receiver_cid, target, call, call->ArgumentAt(0), | 2893 flow_graph, receiver_cid, target, call, call->ArgumentAt(0), |
2915 call->token_pos(), *call->ic_data(), &entry, &last)) { | 2894 call->token_pos(), *call->ic_data(), &entry, &last)) { |
2916 // Insert receiver class check if needed. | 2895 // Insert receiver class check if needed. |
2917 if (MethodRecognizer::PolymorphicTarget(target) || | 2896 if (MethodRecognizer::PolymorphicTarget(target) || |
2918 flow_graph->InstanceCallNeedsClassCheck(call, target.kind())) { | 2897 flow_graph->InstanceCallNeedsClassCheck(call, target.kind())) { |
2919 Instruction* check = GetCheckClass( | 2898 Instruction* check = flow_graph->GetCheckClass( |
2920 flow_graph, call->ArgumentAt(0), | 2899 call->ArgumentAt(0), *CallTargets::Create(Z, *call->ic_data(), 0), |
2921 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()), | |
2922 call->deopt_id(), call->token_pos()); | 2900 call->deopt_id(), call->token_pos()); |
2923 flow_graph->InsertBefore(call, check, call->env(), FlowGraph::kEffect); | 2901 flow_graph->InsertBefore(call, check, call->env(), FlowGraph::kEffect); |
2924 } | 2902 } |
2925 | 2903 |
2926 // Remove the original push arguments. | 2904 // Remove the original push arguments. |
2927 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | 2905 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
2928 PushArgumentInstr* push = call->PushArgumentAt(i); | 2906 PushArgumentInstr* push = call->PushArgumentAt(i); |
2929 push->ReplaceUsesWith(push->value()->definition()); | 2907 push->ReplaceUsesWith(push->value()->definition()); |
2930 push->RemoveFromGraph(); | 2908 push->RemoveFromGraph(); |
2931 } | 2909 } |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3398 | 3376 |
3399 bool FlowGraphInliner::TryInlineRecognizedMethod(FlowGraph* flow_graph, | 3377 bool FlowGraphInliner::TryInlineRecognizedMethod(FlowGraph* flow_graph, |
3400 intptr_t receiver_cid, | 3378 intptr_t receiver_cid, |
3401 const Function& target, | 3379 const Function& target, |
3402 Definition* call, | 3380 Definition* call, |
3403 Definition* receiver, | 3381 Definition* receiver, |
3404 TokenPosition token_pos, | 3382 TokenPosition token_pos, |
3405 const ICData& ic_data, | 3383 const ICData& ic_data, |
3406 TargetEntryInstr** entry, | 3384 TargetEntryInstr** entry, |
3407 Definition** last) { | 3385 Definition** last) { |
3408 ICData& value_check = ICData::ZoneHandle(Z); | |
3409 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(target); | 3386 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(target); |
3410 switch (kind) { | 3387 switch (kind) { |
3411 // Recognized [] operators. | 3388 // Recognized [] operators. |
3412 case MethodRecognizer::kImmutableArrayGetIndexed: | 3389 case MethodRecognizer::kImmutableArrayGetIndexed: |
3413 case MethodRecognizer::kObjectArrayGetIndexed: | 3390 case MethodRecognizer::kObjectArrayGetIndexed: |
3414 case MethodRecognizer::kGrowableArrayGetIndexed: | 3391 case MethodRecognizer::kGrowableArrayGetIndexed: |
3415 case MethodRecognizer::kInt8ArrayGetIndexed: | 3392 case MethodRecognizer::kInt8ArrayGetIndexed: |
3416 case MethodRecognizer::kUint8ArrayGetIndexed: | 3393 case MethodRecognizer::kUint8ArrayGetIndexed: |
3417 case MethodRecognizer::kUint8ClampedArrayGetIndexed: | 3394 case MethodRecognizer::kUint8ClampedArrayGetIndexed: |
3418 case MethodRecognizer::kExternalUint8ArrayGetIndexed: | 3395 case MethodRecognizer::kExternalUint8ArrayGetIndexed: |
(...skipping 20 matching lines...) Expand all Loading... | |
3439 | 3416 |
3440 case MethodRecognizer::kInt64ArrayGetIndexed: | 3417 case MethodRecognizer::kInt64ArrayGetIndexed: |
3441 if (!ShouldInlineInt64ArrayOps()) { | 3418 if (!ShouldInlineInt64ArrayOps()) { |
3442 return false; | 3419 return false; |
3443 } | 3420 } |
3444 return InlineGetIndexed(flow_graph, kind, call, receiver, entry, last); | 3421 return InlineGetIndexed(flow_graph, kind, call, receiver, entry, last); |
3445 // Recognized []= operators. | 3422 // Recognized []= operators. |
3446 case MethodRecognizer::kObjectArraySetIndexed: | 3423 case MethodRecognizer::kObjectArraySetIndexed: |
3447 case MethodRecognizer::kGrowableArraySetIndexed: | 3424 case MethodRecognizer::kGrowableArraySetIndexed: |
3448 return InlineSetIndexed(flow_graph, kind, target, call, receiver, | 3425 return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
3449 token_pos, value_check, entry, last); | 3426 token_pos, /* value_check = */ NULL, entry, last); |
3450 case MethodRecognizer::kInt8ArraySetIndexed: | 3427 case MethodRecognizer::kInt8ArraySetIndexed: |
3451 case MethodRecognizer::kUint8ArraySetIndexed: | 3428 case MethodRecognizer::kUint8ArraySetIndexed: |
3452 case MethodRecognizer::kUint8ClampedArraySetIndexed: | 3429 case MethodRecognizer::kUint8ClampedArraySetIndexed: |
3453 case MethodRecognizer::kExternalUint8ArraySetIndexed: | 3430 case MethodRecognizer::kExternalUint8ArraySetIndexed: |
3454 case MethodRecognizer::kExternalUint8ClampedArraySetIndexed: | 3431 case MethodRecognizer::kExternalUint8ClampedArraySetIndexed: |
3455 case MethodRecognizer::kInt16ArraySetIndexed: | 3432 case MethodRecognizer::kInt16ArraySetIndexed: |
3456 case MethodRecognizer::kUint16ArraySetIndexed: | 3433 case MethodRecognizer::kUint16ArraySetIndexed: { |
3457 // Optimistically assume Smi. | 3434 // Optimistically assume Smi. |
3458 if (ic_data.HasDeoptReason(ICData::kDeoptCheckSmi)) { | 3435 if (ic_data.HasDeoptReason(ICData::kDeoptCheckSmi)) { |
3459 // Optimistic assumption failed at least once. | 3436 // Optimistic assumption failed at least once. |
3460 return false; | 3437 return false; |
3461 } | 3438 } |
3462 value_check = ic_data.AsUnaryClassChecksForCid(kSmiCid, target); | 3439 CallTargets* value_check = new (Z) CallTargets(); |
3440 value_check->Add(CidRangeTarget(kSmiCid, kSmiCid, NULL, /* count = */ 1)); | |
3463 return InlineSetIndexed(flow_graph, kind, target, call, receiver, | 3441 return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
3464 token_pos, value_check, entry, last); | 3442 token_pos, value_check, entry, last); |
3443 } | |
3465 case MethodRecognizer::kInt32ArraySetIndexed: | 3444 case MethodRecognizer::kInt32ArraySetIndexed: |
3466 case MethodRecognizer::kUint32ArraySetIndexed: { | 3445 case MethodRecognizer::kUint32ArraySetIndexed: { |
3467 // Value check not needed for Int32 and Uint32 arrays because they | 3446 // Value check not needed for Int32 and Uint32 arrays because they |
3468 // implicitly contain unboxing instructions which check for right type. | 3447 // implicitly contain unboxing instructions which check for right type. |
3469 ICData& value_check = ICData::Handle(); | |
3470 return InlineSetIndexed(flow_graph, kind, target, call, receiver, | 3448 return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
3471 token_pos, value_check, entry, last); | 3449 token_pos, /* value_check = */ NULL, entry, last); |
3472 } | 3450 } |
3473 case MethodRecognizer::kInt64ArraySetIndexed: | 3451 case MethodRecognizer::kInt64ArraySetIndexed: |
3474 if (!ShouldInlineInt64ArrayOps()) { | 3452 if (!ShouldInlineInt64ArrayOps()) { |
3475 return false; | 3453 return false; |
3476 } | 3454 } |
3477 return InlineSetIndexed(flow_graph, kind, target, call, receiver, | 3455 return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
3478 token_pos, value_check, entry, last); | 3456 token_pos, /* value_check = */ NULL, entry, last); |
3479 case MethodRecognizer::kFloat32ArraySetIndexed: | 3457 case MethodRecognizer::kFloat32ArraySetIndexed: |
3480 case MethodRecognizer::kFloat64ArraySetIndexed: | 3458 case MethodRecognizer::kFloat64ArraySetIndexed: { |
3481 if (!CanUnboxDouble()) { | 3459 if (!CanUnboxDouble()) { |
3482 return false; | 3460 return false; |
3483 } | 3461 } |
3484 value_check = ic_data.AsUnaryClassChecksForCid(kDoubleCid, target); | 3462 CallTargets* value_check = new (Z) CallTargets(); |
3463 value_check->Add( | |
3464 CidRangeTarget(kDoubleCid, kDoubleCid, NULL, /* count = */ 1)); | |
3485 return InlineSetIndexed(flow_graph, kind, target, call, receiver, | 3465 return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
3486 token_pos, value_check, entry, last); | 3466 token_pos, value_check, entry, last); |
3487 case MethodRecognizer::kFloat32x4ArraySetIndexed: | 3467 } |
3468 case MethodRecognizer::kFloat32x4ArraySetIndexed: { | |
3488 if (!ShouldInlineSimd()) { | 3469 if (!ShouldInlineSimd()) { |
3489 return false; | 3470 return false; |
3490 } | 3471 } |
3491 value_check = ic_data.AsUnaryClassChecksForCid(kFloat32x4Cid, target); | 3472 CallTargets* value_check = new (Z) CallTargets(); |
3492 | 3473 value_check->Add( |
3474 CidRangeTarget(kFloat32x4Cid, kFloat32x4Cid, NULL, /* count = */ 1)); | |
3493 return InlineSetIndexed(flow_graph, kind, target, call, receiver, | 3475 return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
3494 token_pos, value_check, entry, last); | 3476 token_pos, value_check, entry, last); |
3495 case MethodRecognizer::kFloat64x2ArraySetIndexed: | 3477 } |
3478 case MethodRecognizer::kFloat64x2ArraySetIndexed: { | |
3496 if (!ShouldInlineSimd()) { | 3479 if (!ShouldInlineSimd()) { |
3497 return false; | 3480 return false; |
3498 } | 3481 } |
3499 value_check = ic_data.AsUnaryClassChecksForCid(kFloat64x2Cid, target); | 3482 CallTargets* value_check = new (Z) CallTargets(); |
3483 value_check->Add( | |
3484 CidRangeTarget(kFloat64x2Cid, kFloat64x2Cid, NULL, /* count = */ 1)); | |
3500 return InlineSetIndexed(flow_graph, kind, target, call, receiver, | 3485 return InlineSetIndexed(flow_graph, kind, target, call, receiver, |
3501 token_pos, value_check, entry, last); | 3486 token_pos, value_check, entry, last); |
3487 } | |
3502 case MethodRecognizer::kByteArrayBaseGetInt8: | 3488 case MethodRecognizer::kByteArrayBaseGetInt8: |
3503 return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid, | 3489 return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid, |
3504 kTypedDataInt8ArrayCid, entry, last); | 3490 kTypedDataInt8ArrayCid, entry, last); |
3505 case MethodRecognizer::kByteArrayBaseGetUint8: | 3491 case MethodRecognizer::kByteArrayBaseGetUint8: |
3506 return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid, | 3492 return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid, |
3507 kTypedDataUint8ArrayCid, entry, last); | 3493 kTypedDataUint8ArrayCid, entry, last); |
3508 case MethodRecognizer::kByteArrayBaseGetInt16: | 3494 case MethodRecognizer::kByteArrayBaseGetInt16: |
3509 return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid, | 3495 return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid, |
3510 kTypedDataInt16ArrayCid, entry, last); | 3496 kTypedDataInt16ArrayCid, entry, last); |
3511 case MethodRecognizer::kByteArrayBaseGetUint16: | 3497 case MethodRecognizer::kByteArrayBaseGetUint16: |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3809 } | 3795 } |
3810 | 3796 |
3811 default: | 3797 default: |
3812 return false; | 3798 return false; |
3813 } | 3799 } |
3814 } | 3800 } |
3815 | 3801 |
3816 | 3802 |
3817 } // namespace dart | 3803 } // namespace dart |
3818 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 3804 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |