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

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

Issue 12775009: Optimize TypedData operators [] and []= in the same way as ScalarList. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: ARM/MIPS build, comments, rebased Created 7 years, 9 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
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); 709 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2);
710 } 710 }
711 break; 711 break;
712 case kInt8ArrayCid: 712 case kInt8ArrayCid:
713 case kUint8ArrayCid: 713 case kUint8ArrayCid:
714 case kUint8ClampedArrayCid: 714 case kUint8ClampedArrayCid:
715 case kExternalUint8ArrayCid: 715 case kExternalUint8ArrayCid:
716 case kExternalUint8ClampedArrayCid: 716 case kExternalUint8ClampedArrayCid:
717 case kInt16ArrayCid: 717 case kInt16ArrayCid:
718 case kUint16ArrayCid: 718 case kUint16ArrayCid:
719 case kTypedDataInt8ArrayCid:
720 case kTypedDataUint8ArrayCid:
721 case kTypedDataUint8ClampedArrayCid:
722 case kExternalTypedDataUint8ArrayCid:
723 case kExternalTypedDataUint8ClampedArrayCid:
724 case kTypedDataInt16ArrayCid:
725 case kTypedDataUint16ArrayCid:
719 // Check that value is always smi. 726 // Check that value is always smi.
720 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); 727 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2);
721 if ((value_check.NumberOfChecks() != 1) || 728 if ((value_check.NumberOfChecks() != 1) ||
722 (value_check.GetReceiverClassIdAt(0) != kSmiCid)) { 729 (value_check.GetReceiverClassIdAt(0) != kSmiCid)) {
723 return false; 730 return false;
724 } 731 }
725 break; 732 break;
726 case kInt32ArrayCid: 733 case kInt32ArrayCid:
727 case kUint32ArrayCid: { 734 case kUint32ArrayCid:
735 case kTypedDataInt32ArrayCid:
736 case kTypedDataUint32ArrayCid: {
728 if (!CanUnboxInt32()) return false; 737 if (!CanUnboxInt32()) return false;
729 // Check that value is always smi or mint, if the platform has unboxed 738 // Check that value is always smi or mint, if the platform has unboxed
730 // mints (ia32 with at least SSE 4.1). 739 // mints (ia32 with at least SSE 4.1).
731 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); 740 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2);
732 for (intptr_t i = 0; i < value_check.NumberOfChecks(); i++) { 741 for (intptr_t i = 0; i < value_check.NumberOfChecks(); i++) {
733 intptr_t cid = value_check.GetReceiverClassIdAt(i); 742 intptr_t cid = value_check.GetReceiverClassIdAt(i);
734 if (FlowGraphCompiler::SupportsUnboxedMints()) { 743 if (FlowGraphCompiler::SupportsUnboxedMints()) {
735 if ((cid != kSmiCid) && (cid != kMintCid)) { 744 if ((cid != kSmiCid) && (cid != kMintCid)) {
736 return false; 745 return false;
737 } 746 }
738 } else if (cid != kSmiCid) { 747 } else if (cid != kSmiCid) {
739 return false; 748 return false;
740 } 749 }
741 } 750 }
742 break; 751 break;
743 } 752 }
744 case kFloat32ArrayCid: 753 case kFloat32ArrayCid:
745 case kFloat64ArrayCid: { 754 case kFloat64ArrayCid:
755 case kTypedDataFloat32ArrayCid:
756 case kTypedDataFloat64ArrayCid: {
746 // Check that value is always double. 757 // Check that value is always double.
747 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); 758 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2);
748 if ((value_check.NumberOfChecks() != 1) || 759 if ((value_check.NumberOfChecks() != 1) ||
749 (value_check.GetReceiverClassIdAt(0) != kDoubleCid)) { 760 (value_check.GetReceiverClassIdAt(0) != kDoubleCid)) {
750 return false; 761 return false;
751 } 762 }
752 break; 763 break;
753 } 764 }
754 default: 765 default:
755 // TODO(fschneider): Add support for other array types. 766 // TODO(fschneider): Add support for other array types.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 } 857 }
847 case kInt8ArrayCid: 858 case kInt8ArrayCid:
848 case kUint8ArrayCid: 859 case kUint8ArrayCid:
849 case kUint8ClampedArrayCid: 860 case kUint8ClampedArrayCid:
850 case kExternalUint8ArrayCid: 861 case kExternalUint8ArrayCid:
851 case kExternalUint8ClampedArrayCid: 862 case kExternalUint8ClampedArrayCid:
852 case kInt16ArrayCid: 863 case kInt16ArrayCid:
853 case kUint16ArrayCid: 864 case kUint16ArrayCid:
854 case kInt32ArrayCid: 865 case kInt32ArrayCid:
855 case kUint32ArrayCid: 866 case kUint32ArrayCid:
867 case kTypedDataInt8ArrayCid:
868 case kTypedDataUint8ArrayCid:
869 case kTypedDataUint8ClampedArrayCid:
870 case kExternalTypedDataUint8ArrayCid:
871 case kExternalTypedDataUint8ClampedArrayCid:
872 case kTypedDataInt16ArrayCid:
873 case kTypedDataUint16ArrayCid:
874 case kTypedDataInt32ArrayCid:
875 case kTypedDataUint32ArrayCid:
856 ASSERT(value_type.IsIntType()); 876 ASSERT(value_type.IsIntType());
857 // Fall through. 877 // Fall through.
858 case kFloat32ArrayCid: 878 case kFloat32ArrayCid:
859 case kFloat64ArrayCid: { 879 case kFloat64ArrayCid:
880 case kTypedDataFloat32ArrayCid:
881 case kTypedDataFloat64ArrayCid: {
860 type_args = instantiator = flow_graph_->constant_null(); 882 type_args = instantiator = flow_graph_->constant_null();
861 ASSERT((class_id != kFloat32ArrayCid && class_id != kFloat64ArrayCid) || 883 ASSERT((class_id != kFloat32ArrayCid &&
884 class_id != kFloat64ArrayCid &&
885 class_id != kTypedDataFloat32ArrayCid &&
886 class_id != kTypedDataFloat64ArrayCid) ||
862 value_type.IsDoubleType()); 887 value_type.IsDoubleType());
863 ASSERT(value_type.IsInstantiated()); 888 ASSERT(value_type.IsInstantiated());
864 break; 889 break;
865 } 890 }
866 default: 891 default:
867 // TODO(fschneider): Add support for other array types. 892 // TODO(fschneider): Add support for other array types.
868 UNREACHABLE(); 893 UNREACHABLE();
869 } 894 }
870 AssertAssignableInstr* assert_value = 895 AssertAssignableInstr* assert_value =
871 new AssertAssignableInstr(call->token_pos(), 896 new AssertAssignableInstr(call->token_pos(),
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 case kGrowableObjectArrayCid: 943 case kGrowableObjectArrayCid:
919 case kFloat32ArrayCid: 944 case kFloat32ArrayCid:
920 case kFloat64ArrayCid: 945 case kFloat64ArrayCid:
921 case kInt8ArrayCid: 946 case kInt8ArrayCid:
922 case kUint8ArrayCid: 947 case kUint8ArrayCid:
923 case kUint8ClampedArrayCid: 948 case kUint8ClampedArrayCid:
924 case kExternalUint8ArrayCid: 949 case kExternalUint8ArrayCid:
925 case kExternalUint8ClampedArrayCid: 950 case kExternalUint8ClampedArrayCid:
926 case kInt16ArrayCid: 951 case kInt16ArrayCid:
927 case kUint16ArrayCid: 952 case kUint16ArrayCid:
953 case kTypedDataFloat32ArrayCid:
954 case kTypedDataFloat64ArrayCid:
955 case kTypedDataInt8ArrayCid:
956 case kTypedDataUint8ArrayCid:
957 case kTypedDataUint8ClampedArrayCid:
958 case kExternalTypedDataUint8ArrayCid:
959 case kExternalTypedDataUint8ClampedArrayCid:
960 case kTypedDataInt16ArrayCid:
961 case kTypedDataUint16ArrayCid:
928 break; 962 break;
929 case kInt32ArrayCid: 963 case kInt32ArrayCid:
930 case kUint32ArrayCid: { 964 case kUint32ArrayCid:
965 case kTypedDataInt32ArrayCid:
966 case kTypedDataUint32ArrayCid: {
931 if (!CanUnboxInt32()) return false; 967 if (!CanUnboxInt32()) return false;
932 968
933 // Set deopt_id if we can optimistically assume that the result is Smi. 969 // Set deopt_id if we can optimistically assume that the result is Smi.
934 // Assume mixed Mint/Smi if this instruction caused deoptimization once. 970 // Assume mixed Mint/Smi if this instruction caused deoptimization once.
935 ASSERT(call->HasICData()); 971 ASSERT(call->HasICData());
936 const ICData& ic_data = *call->ic_data(); 972 const ICData& ic_data = *call->ic_data();
937 deopt_id = (ic_data.deopt_reason() == kDeoptUnknown) ? 973 deopt_id = (ic_data.deopt_reason() == kDeoptUnknown) ?
938 call->deopt_id() : Isolate::kNoDeoptId; 974 call->deopt_id() : Isolate::kNoDeoptId;
939 } 975 }
940 break; 976 break;
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 } 1356 }
1321 1357
1322 1358
1323 static intptr_t OffsetForLengthGetter(MethodRecognizer::Kind kind) { 1359 static intptr_t OffsetForLengthGetter(MethodRecognizer::Kind kind) {
1324 switch (kind) { 1360 switch (kind) {
1325 case MethodRecognizer::kObjectArrayLength: 1361 case MethodRecognizer::kObjectArrayLength:
1326 case MethodRecognizer::kImmutableArrayLength: 1362 case MethodRecognizer::kImmutableArrayLength:
1327 return Array::length_offset(); 1363 return Array::length_offset();
1328 case MethodRecognizer::kByteArrayBaseLength: 1364 case MethodRecognizer::kByteArrayBaseLength:
1329 return ByteArray::length_offset(); 1365 return ByteArray::length_offset();
1366 case MethodRecognizer::kTypedDataLength:
1367 // .length is defined in _TypedList which is the base class for internal
1368 // and external typed data.
1369 ASSERT(TypedData::length_offset() == ExternalTypedData::length_offset());
1370 return TypedData::length_offset();
1330 case MethodRecognizer::kGrowableArrayLength: 1371 case MethodRecognizer::kGrowableArrayLength:
1331 return GrowableObjectArray::length_offset(); 1372 return GrowableObjectArray::length_offset();
1332 default: 1373 default:
1333 UNREACHABLE(); 1374 UNREACHABLE();
1334 return 0; 1375 return 0;
1335 } 1376 }
1336 } 1377 }
1337 1378
1338 1379
1339 // Only unique implicit instance getters can be currently handled. 1380 // Only unique implicit instance getters can be currently handled.
(...skipping 18 matching lines...) Expand all
1358 1399
1359 // Not an implicit getter. 1400 // Not an implicit getter.
1360 MethodRecognizer::Kind recognized_kind = 1401 MethodRecognizer::Kind recognized_kind =
1361 MethodRecognizer::RecognizeKind(target); 1402 MethodRecognizer::RecognizeKind(target);
1362 1403
1363 // VM objects length getter. 1404 // VM objects length getter.
1364 switch (recognized_kind) { 1405 switch (recognized_kind) {
1365 case MethodRecognizer::kObjectArrayLength: 1406 case MethodRecognizer::kObjectArrayLength:
1366 case MethodRecognizer::kImmutableArrayLength: 1407 case MethodRecognizer::kImmutableArrayLength:
1367 case MethodRecognizer::kByteArrayBaseLength: 1408 case MethodRecognizer::kByteArrayBaseLength:
1409 case MethodRecognizer::kTypedDataLength:
1368 case MethodRecognizer::kGrowableArrayLength: { 1410 case MethodRecognizer::kGrowableArrayLength: {
1369 if (!ic_data.HasOneTarget()) { 1411 if (!ic_data.HasOneTarget()) {
1370 // TODO(srdjan): Implement for mutiple targets. 1412 // TODO(srdjan): Implement for mutiple targets.
1371 return false; 1413 return false;
1372 } 1414 }
1373 const bool is_immutable = 1415 const bool is_immutable =
1374 (recognized_kind == MethodRecognizer::kObjectArrayLength) || 1416 (recognized_kind == MethodRecognizer::kObjectArrayLength) ||
1375 (recognized_kind == MethodRecognizer::kImmutableArrayLength) || 1417 (recognized_kind == MethodRecognizer::kImmutableArrayLength) ||
1376 (recognized_kind == MethodRecognizer::kByteArrayBaseLength); 1418 (recognized_kind == MethodRecognizer::kByteArrayBaseLength) ||
1419 (recognized_kind == MethodRecognizer::kTypedDataLength);
1377 InlineArrayLengthGetter(call, 1420 InlineArrayLengthGetter(call,
1378 OffsetForLengthGetter(recognized_kind), 1421 OffsetForLengthGetter(recognized_kind),
1379 is_immutable, 1422 is_immutable,
1380 recognized_kind); 1423 recognized_kind);
1381 return true; 1424 return true;
1382 } 1425 }
1383 case MethodRecognizer::kGrowableArrayCapacity: 1426 case MethodRecognizer::kGrowableArrayCapacity:
1384 InlineGrowableArrayCapacityGetter(call); 1427 InlineGrowableArrayCapacityGetter(call);
1385 return true; 1428 return true;
1386 case MethodRecognizer::kStringBaseLength: 1429 case MethodRecognizer::kStringBaseLength:
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
1893 const ICData& unary_checks = 1936 const ICData& unary_checks =
1894 ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks()); 1937 ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks());
1895 1938
1896 if ((unary_checks.NumberOfChecks() > FLAG_max_polymorphic_checks) && 1939 if ((unary_checks.NumberOfChecks() > FLAG_max_polymorphic_checks) &&
1897 InstanceCallNeedsClassCheck(instr)) { 1940 InstanceCallNeedsClassCheck(instr)) {
1898 // Too many checks, it will be megamorphic which needs unary checks. 1941 // Too many checks, it will be megamorphic which needs unary checks.
1899 instr->set_ic_data(&unary_checks); 1942 instr->set_ic_data(&unary_checks);
1900 return; 1943 return;
1901 } 1944 }
1902 1945
1903 if ((op_kind == Token::kASSIGN_INDEX) && 1946 if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithStoreIndexed(instr)) {
1904 TryReplaceWithStoreIndexed(instr)) {
1905 return; 1947 return;
1906 } 1948 }
1907 if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) { 1949 if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) {
1908 return; 1950 return;
1909 } 1951 }
1910 if (Token::IsBinaryOperator(op_kind) && 1952 if (Token::IsBinaryOperator(op_kind) &&
1911 TryReplaceWithBinaryOp(instr, op_kind)) { 1953 TryReplaceWithBinaryOp(instr, op_kind)) {
1912 return; 1954 return;
1913 } 1955 }
1914 if (Token::IsPrefixOperator(op_kind) && 1956 if (Token::IsPrefixOperator(op_kind) &&
(...skipping 2751 matching lines...) Expand 10 before | Expand all | Expand 10 after
4666 if (changed) { 4708 if (changed) {
4667 // We may have changed the block order and the dominator tree. 4709 // We may have changed the block order and the dominator tree.
4668 flow_graph->DiscoverBlocks(); 4710 flow_graph->DiscoverBlocks();
4669 GrowableArray<BitVector*> dominance_frontier; 4711 GrowableArray<BitVector*> dominance_frontier;
4670 flow_graph->ComputeDominators(&dominance_frontier); 4712 flow_graph->ComputeDominators(&dominance_frontier);
4671 } 4713 }
4672 } 4714 }
4673 4715
4674 4716
4675 } // namespace dart 4717 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698