Chromium Code Reviews| 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 |