Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 552303005: Fix StoreIndexedInstr input representation requirements for Int32/Uint32 arrays. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix typo Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698