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 | 4 |
| 5 #include "vm/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1357 } | 1357 } |
| 1358 | 1358 |
| 1359 if (array_cid == kTypedDataFloat32ArrayCid) { | 1359 if (array_cid == kTypedDataFloat32ArrayCid) { |
| 1360 stored_value = | 1360 stored_value = |
| 1361 new(I) DoubleToFloatInstr( | 1361 new(I) DoubleToFloatInstr( |
| 1362 new(I) Value(stored_value), call->deopt_id()); | 1362 new(I) Value(stored_value), call->deopt_id()); |
| 1363 cursor = flow_graph()->AppendTo(cursor, | 1363 cursor = flow_graph()->AppendTo(cursor, |
| 1364 stored_value, | 1364 stored_value, |
| 1365 NULL, | 1365 NULL, |
| 1366 FlowGraph::kValue); | 1366 FlowGraph::kValue); |
| 1367 } else if (array_cid == kTypedDataInt32ArrayCid) { | |
| 1368 stored_value = new(I) UnboxInt32Instr( | |
| 1369 new(I) Value(stored_value), | |
| 1370 call->deopt_id()); | |
| 1371 stored_value->AsUnboxIntN()->mark_truncating(); | |
| 1372 cursor = flow_graph()->AppendTo(cursor, | |
| 1373 stored_value, | |
| 1374 call->env(), | |
| 1375 FlowGraph::kValue); | |
| 1376 } else if (array_cid == kTypedDataUint32ArrayCid) { | |
| 1377 stored_value = new(I) UnboxUint32Instr( | |
| 1378 new(I) Value(stored_value), | |
| 1379 call->deopt_id()); | |
| 1380 ASSERT(stored_value->AsUnboxIntN()->is_truncating()); | |
| 1381 cursor = flow_graph()->AppendTo(cursor, | |
| 1382 stored_value, | |
| 1383 call->env(), | |
| 1384 FlowGraph::kValue); | |
| 1367 } | 1385 } |
| 1368 | 1386 |
| 1387 | |
|
Florian Schneider
2014/09/11 09:38:53
Remove extra \n.
Vyacheslav Egorov (Google)
2014/09/11 11:49:17
Done.
| |
| 1369 const intptr_t index_scale = Instance::ElementSizeFor(array_cid); | 1388 const intptr_t index_scale = Instance::ElementSizeFor(array_cid); |
| 1370 *last = new(I) StoreIndexedInstr(new(I) Value(array), | 1389 *last = new(I) StoreIndexedInstr(new(I) Value(array), |
| 1371 new(I) Value(index), | 1390 new(I) Value(index), |
| 1372 new(I) Value(stored_value), | 1391 new(I) Value(stored_value), |
| 1373 needs_store_barrier, | 1392 needs_store_barrier, |
| 1374 index_scale, | 1393 index_scale, |
| 1375 array_cid, | 1394 array_cid, |
| 1376 call->deopt_id(), | 1395 call->deopt_id(), |
| 1377 call->token_pos()); | 1396 call->token_pos()); |
| 1378 flow_graph()->AppendTo(cursor, | 1397 flow_graph()->AppendTo(cursor, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1439 case MethodRecognizer::kInt16ArraySetIndexed: | 1458 case MethodRecognizer::kInt16ArraySetIndexed: |
| 1440 case MethodRecognizer::kUint16ArraySetIndexed: | 1459 case MethodRecognizer::kUint16ArraySetIndexed: |
| 1441 if (!ArgIsAlways(kSmiCid, ic_data, 2)) { | 1460 if (!ArgIsAlways(kSmiCid, ic_data, 2)) { |
| 1442 return false; | 1461 return false; |
| 1443 } | 1462 } |
| 1444 value_check = ic_data.AsUnaryClassChecksForArgNr(2); | 1463 value_check = ic_data.AsUnaryClassChecksForArgNr(2); |
| 1445 return InlineSetIndexed(kind, target, call, receiver, token_pos, | 1464 return InlineSetIndexed(kind, target, call, receiver, token_pos, |
| 1446 &ic_data, value_check, entry, last); | 1465 &ic_data, value_check, entry, last); |
| 1447 case MethodRecognizer::kInt32ArraySetIndexed: | 1466 case MethodRecognizer::kInt32ArraySetIndexed: |
| 1448 case MethodRecognizer::kUint32ArraySetIndexed: | 1467 case MethodRecognizer::kUint32ArraySetIndexed: |
| 1449 if (!CanUnboxInt32()) { | |
| 1450 return false; | |
| 1451 } | |
| 1452 // Check that value is always smi or mint, if the platform has unboxed | 1468 // Check that value is always smi or mint, if the platform has unboxed |
| 1453 // mints (ia32 with at least SSE 4.1). | 1469 // mints (ia32 with at least SSE 4.1). |
|
Florian Schneider
2014/09/11 09:38:53
This comment is now out of date.
Vyacheslav Egorov (Google)
2014/09/11 11:49:17
Done.
| |
| 1454 value_check = ic_data.AsUnaryClassChecksForArgNr(2); | 1470 value_check = ic_data.AsUnaryClassChecksForArgNr(2); |
| 1455 if (FlowGraphCompiler::SupportsUnboxedMints()) { | 1471 if (!HasOnlySmiOrMint(value_check)) { |
| 1456 if (!HasOnlySmiOrMint(value_check)) { | |
| 1457 return false; | |
| 1458 } | |
| 1459 } else if (!HasOnlyOneSmi(value_check)) { | |
| 1460 return false; | 1472 return false; |
| 1461 } | 1473 } |
| 1462 return InlineSetIndexed(kind, target, call, receiver, token_pos, | 1474 return InlineSetIndexed(kind, target, call, receiver, token_pos, |
| 1463 &ic_data, value_check, entry, last); | 1475 &ic_data, value_check, entry, last); |
| 1464 case MethodRecognizer::kFloat32ArraySetIndexed: | 1476 case MethodRecognizer::kFloat32ArraySetIndexed: |
| 1465 case MethodRecognizer::kFloat64ArraySetIndexed: | 1477 case MethodRecognizer::kFloat64ArraySetIndexed: |
| 1466 if (!CanUnboxDouble()) { | 1478 if (!CanUnboxDouble()) { |
| 1467 return false; | 1479 return false; |
| 1468 } | 1480 } |
| 1469 // Check that value is always double. | 1481 // Check that value is always double. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1563 ic_data, entry, last); | 1575 ic_data, entry, last); |
| 1564 case MethodRecognizer::kByteArrayBaseSetInt16: | 1576 case MethodRecognizer::kByteArrayBaseSetInt16: |
| 1565 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, | 1577 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, |
| 1566 kTypedDataInt16ArrayCid, | 1578 kTypedDataInt16ArrayCid, |
| 1567 ic_data, entry, last); | 1579 ic_data, entry, last); |
| 1568 case MethodRecognizer::kByteArrayBaseSetUint16: | 1580 case MethodRecognizer::kByteArrayBaseSetUint16: |
| 1569 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, | 1581 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, |
| 1570 kTypedDataUint16ArrayCid, | 1582 kTypedDataUint16ArrayCid, |
| 1571 ic_data, entry, last); | 1583 ic_data, entry, last); |
| 1572 case MethodRecognizer::kByteArrayBaseSetInt32: | 1584 case MethodRecognizer::kByteArrayBaseSetInt32: |
| 1573 if (!CanUnboxInt32()) { | |
| 1574 return false; | |
| 1575 } | |
| 1576 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, | 1585 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, |
| 1577 kTypedDataInt32ArrayCid, | 1586 kTypedDataInt32ArrayCid, |
| 1578 ic_data, entry, last); | 1587 ic_data, entry, last); |
| 1579 case MethodRecognizer::kByteArrayBaseSetUint32: | 1588 case MethodRecognizer::kByteArrayBaseSetUint32: |
| 1580 if (!CanUnboxInt32()) { | |
| 1581 return false; | |
| 1582 } | |
| 1583 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, | 1589 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, |
| 1584 kTypedDataUint32ArrayCid, | 1590 kTypedDataUint32ArrayCid, |
| 1585 ic_data, entry, last); | 1591 ic_data, entry, last); |
| 1586 case MethodRecognizer::kByteArrayBaseSetFloat32: | 1592 case MethodRecognizer::kByteArrayBaseSetFloat32: |
| 1587 if (!CanUnboxDouble()) { | 1593 if (!CanUnboxDouble()) { |
| 1588 return false; | 1594 return false; |
| 1589 } | 1595 } |
| 1590 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, | 1596 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, |
| 1591 kTypedDataFloat32ArrayCid, | 1597 kTypedDataFloat32ArrayCid, |
| 1592 ic_data, entry, last); | 1598 ic_data, entry, last); |
| (...skipping 2122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3715 Object::empty_array(), // Dummy args. descr. | 3721 Object::empty_array(), // Dummy args. descr. |
| 3716 Isolate::kNoDeoptId, | 3722 Isolate::kNoDeoptId, |
| 3717 1); | 3723 1); |
| 3718 value_check.AddReceiverCheck(kSmiCid, target); | 3724 value_check.AddReceiverCheck(kSmiCid, target); |
| 3719 break; | 3725 break; |
| 3720 } | 3726 } |
| 3721 case kTypedDataInt32ArrayCid: | 3727 case kTypedDataInt32ArrayCid: |
| 3722 case kTypedDataUint32ArrayCid: | 3728 case kTypedDataUint32ArrayCid: |
| 3723 // Prevent excessive deoptimization, assume full 32 bits used, and therefore | 3729 // Prevent excessive deoptimization, assume full 32 bits used, and therefore |
| 3724 // generate Mint on 32-bit architectures. | 3730 // generate Mint on 32-bit architectures. |
| 3725 if (kSmiBits >= 32) { | 3731 if (kSmiBits >= 32) { |
| 3726 value_check = ICData::New(flow_graph_->parsed_function().function(), | 3732 value_check = ICData::New(flow_graph_->parsed_function().function(), |
| 3727 i_call->function_name(), | 3733 i_call->function_name(), |
| 3728 Object::empty_array(), // Dummy args. descr. | 3734 Object::empty_array(), // Dummy args. descr. |
| 3729 Isolate::kNoDeoptId, | 3735 Isolate::kNoDeoptId, |
| 3730 1); | 3736 1); |
| 3731 value_check.AddReceiverCheck(kSmiCid, target); | 3737 value_check.AddReceiverCheck(kSmiCid, target); |
| 3732 } | 3738 } |
| 3733 break; | 3739 break; |
| 3734 case kTypedDataFloat32ArrayCid: | 3740 case kTypedDataFloat32ArrayCid: |
| 3735 case kTypedDataFloat64ArrayCid: { | 3741 case kTypedDataFloat64ArrayCid: { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3773 call); | 3779 call); |
| 3774 } | 3780 } |
| 3775 | 3781 |
| 3776 if (view_cid == kTypedDataFloat32ArrayCid) { | 3782 if (view_cid == kTypedDataFloat32ArrayCid) { |
| 3777 stored_value = new(I) DoubleToFloatInstr( | 3783 stored_value = new(I) DoubleToFloatInstr( |
| 3778 new(I) Value(stored_value), call->deopt_id()); | 3784 new(I) Value(stored_value), call->deopt_id()); |
| 3779 cursor = flow_graph()->AppendTo(cursor, | 3785 cursor = flow_graph()->AppendTo(cursor, |
| 3780 stored_value, | 3786 stored_value, |
| 3781 NULL, | 3787 NULL, |
| 3782 FlowGraph::kValue); | 3788 FlowGraph::kValue); |
| 3789 } else if (view_cid == kTypedDataInt32ArrayCid) { | |
| 3790 stored_value = new(I) UnboxInt32Instr( | |
| 3791 new(I) Value(stored_value), | |
| 3792 call->deopt_id()); | |
| 3793 stored_value->AsUnboxIntN()->mark_truncating(); | |
| 3794 cursor = flow_graph()->AppendTo(cursor, | |
| 3795 stored_value, | |
| 3796 call->env(), | |
| 3797 FlowGraph::kValue); | |
| 3798 } else if (view_cid == kTypedDataUint32ArrayCid) { | |
| 3799 stored_value = new(I) UnboxUint32Instr( | |
| 3800 new(I) Value(stored_value), | |
| 3801 call->deopt_id()); | |
| 3802 ASSERT(stored_value->AsUnboxIntN()->is_truncating()); | |
| 3803 cursor = flow_graph()->AppendTo(cursor, | |
| 3804 stored_value, | |
| 3805 call->env(), | |
| 3806 FlowGraph::kValue); | |
| 3783 } | 3807 } |
| 3784 | 3808 |
| 3785 StoreBarrierType needs_store_barrier = kNoStoreBarrier; | 3809 StoreBarrierType needs_store_barrier = kNoStoreBarrier; |
| 3786 *last = new(I) StoreIndexedInstr(new(I) Value(array), | 3810 *last = new(I) StoreIndexedInstr(new(I) Value(array), |
| 3787 new(I) Value(index), | 3811 new(I) Value(index), |
| 3788 new(I) Value(stored_value), | 3812 new(I) Value(stored_value), |
| 3789 needs_store_barrier, | 3813 needs_store_barrier, |
| 3790 1, // Index scale | 3814 1, // Index scale |
| 3791 view_cid, | 3815 view_cid, |
| 3792 call->deopt_id(), | 3816 call->deopt_id(), |
| (...skipping 4483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8276 SetValue(instr, non_constant_); | 8300 SetValue(instr, non_constant_); |
| 8277 break; | 8301 break; |
| 8278 } | 8302 } |
| 8279 result = result.CheckAndCanonicalize(NULL); | 8303 result = result.CheckAndCanonicalize(NULL); |
| 8280 ASSERT(!result.IsNull()); | 8304 ASSERT(!result.IsNull()); |
| 8281 SetValue(instr, result); | 8305 SetValue(instr, result); |
| 8282 break; | 8306 break; |
| 8283 } | 8307 } |
| 8284 case Token::kSHL: | 8308 case Token::kSHL: |
| 8285 case Token::kSHR: | 8309 case Token::kSHR: |
| 8286 if (left.IsSmi() && right.IsSmi()) { | 8310 if (left.IsSmi() && |
| 8311 right.IsSmi() && | |
| 8312 (Smi::Cast(right).Value() >= 0)) { | |
| 8287 Instance& result = Integer::ZoneHandle(I, | 8313 Instance& result = Integer::ZoneHandle(I, |
| 8288 Smi::Cast(left_int).ShiftOp(op_kind, Smi::Cast(right_int))); | 8314 Smi::Cast(left_int).ShiftOp(op_kind, Smi::Cast(right_int))); |
| 8289 if (result.IsNull()) { | |
| 8290 // TODO(regis): A bigint operation is required. Invoke dart? | |
| 8291 // Punt for now. | |
| 8292 SetValue(instr, non_constant_); | |
| 8293 break; | |
| 8294 } | |
| 8295 result = result.CheckAndCanonicalize(NULL); | 8315 result = result.CheckAndCanonicalize(NULL); |
| 8296 ASSERT(!result.IsNull()); | 8316 ASSERT(!result.IsNull()); |
| 8297 SetValue(instr, result); | 8317 SetValue(instr, result); |
| 8298 } else { | 8318 } else { |
| 8299 SetValue(instr, non_constant_); | 8319 SetValue(instr, non_constant_); |
| 8300 } | 8320 } |
| 8301 break; | 8321 break; |
| 8302 case Token::kBIT_AND: | 8322 case Token::kBIT_AND: |
| 8303 case Token::kBIT_OR: | 8323 case Token::kBIT_OR: |
| 8304 case Token::kBIT_XOR: { | 8324 case Token::kBIT_XOR: { |
| (...skipping 1770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10075 | 10095 |
| 10076 // Insert materializations at environment uses. | 10096 // Insert materializations at environment uses. |
| 10077 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 10097 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
| 10078 CreateMaterializationAt( | 10098 CreateMaterializationAt( |
| 10079 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); | 10099 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); |
| 10080 } | 10100 } |
| 10081 } | 10101 } |
| 10082 | 10102 |
| 10083 | 10103 |
| 10084 } // namespace dart | 10104 } // namespace dart |
| OLD | NEW |