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

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

Issue 11628011: Inline ByteArrayBase.length in the flow graph optimizer. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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_optimizer.h ('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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 956 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 length_offset, 967 length_offset,
968 Type::ZoneHandle(Type::SmiType()), 968 Type::ZoneHandle(Type::SmiType()),
969 is_immutable); 969 is_immutable);
970 load->set_result_cid(kSmiCid); 970 load->set_result_cid(kSmiCid);
971 load->set_recognized_kind(kind); 971 load->set_recognized_kind(kind);
972 call->ReplaceWith(load, current_iterator()); 972 call->ReplaceWith(load, current_iterator());
973 RemovePushArguments(call); 973 RemovePushArguments(call);
974 } 974 }
975 975
976 976
977 void FlowGraphOptimizer::InlineGArrayCapacityGetter(InstanceCallInstr* call) { 977 void FlowGraphOptimizer::InlineGrowableArrayCapacityGetter(
978 InstanceCallInstr* call) {
978 // Check receiver class. 979 // Check receiver class.
979 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); 980 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
980 981
981 // TODO(srdjan): type of load should be GrowableObjectArrayType. 982 // TODO(srdjan): type of load should be GrowableObjectArrayType.
982 LoadFieldInstr* data_load = new LoadFieldInstr( 983 LoadFieldInstr* data_load = new LoadFieldInstr(
983 call->ArgumentAt(0)->value(), 984 call->ArgumentAt(0)->value(),
984 Array::data_offset(), 985 Array::data_offset(),
985 Type::ZoneHandle(Type::DynamicType())); 986 Type::ZoneHandle(Type::DynamicType()));
986 data_load->set_result_cid(kArrayCid); 987 data_load->set_result_cid(kArrayCid);
987 InsertBefore(call, data_load, NULL, Definition::kValue); 988 InsertBefore(call, data_load, NULL, Definition::kValue);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 1034
1034 StrictCompareInstr* compare = 1035 StrictCompareInstr* compare =
1035 new StrictCompareInstr(Token::kEQ_STRICT, 1036 new StrictCompareInstr(Token::kEQ_STRICT,
1036 new Value(load), 1037 new Value(load),
1037 new Value(zero)); 1038 new Value(zero));
1038 call->ReplaceWith(compare, current_iterator()); 1039 call->ReplaceWith(compare, current_iterator());
1039 RemovePushArguments(call); 1040 RemovePushArguments(call);
1040 } 1041 }
1041 1042
1042 1043
1044 intptr_t OffsetForLengthGetter(MethodRecognizer::Kind kind) {
srdjan 2012/12/18 21:45:57 static ?
Florian Schneider 2012/12/19 09:51:29 Done.
1045 switch (kind) {
1046 case MethodRecognizer::kObjectArrayLength:
1047 case MethodRecognizer::kImmutableArrayLength:
1048 return Array::length_offset();
1049 case MethodRecognizer::kByteArrayBaseLength:
1050 return ByteArray::length_offset();
1051 case MethodRecognizer::kGrowableArrayLength:
1052 return GrowableObjectArray::length_offset();
1053 default:
1054 UNREACHABLE();
1055 return 0;
1056 }
1057 }
1058
1059
1043 // Only unique implicit instance getters can be currently handled. 1060 // Only unique implicit instance getters can be currently handled.
1044 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) { 1061 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) {
1045 ASSERT(call->HasICData()); 1062 ASSERT(call->HasICData());
1046 const ICData& ic_data = *call->ic_data(); 1063 const ICData& ic_data = *call->ic_data();
1047 if (ic_data.NumberOfChecks() == 0) { 1064 if (ic_data.NumberOfChecks() == 0) {
1048 // No type feedback collected. 1065 // No type feedback collected.
1049 return false; 1066 return false;
1050 } 1067 }
1051 Function& target = Function::Handle(ic_data.GetTargetAt(0)); 1068 Function& target = Function::Handle(ic_data.GetTargetAt(0));
1052 if (target.kind() == RawFunction::kImplicitGetter) { 1069 if (target.kind() == RawFunction::kImplicitGetter) {
1053 if (!ic_data.HasOneTarget()) { 1070 if (!ic_data.HasOneTarget()) {
1054 // TODO(srdjan): Implement for mutiple targets. 1071 // TODO(srdjan): Implement for mutiple targets.
1055 return false; 1072 return false;
1056 } 1073 }
1057 InlineImplicitInstanceGetter(call); 1074 InlineImplicitInstanceGetter(call);
1058 return true; 1075 return true;
1059 } 1076 }
1060 1077
1061 // Not an implicit getter. 1078 // Not an implicit getter.
1062 MethodRecognizer::Kind recognized_kind = 1079 MethodRecognizer::Kind recognized_kind =
1063 MethodRecognizer::RecognizeKind(target); 1080 MethodRecognizer::RecognizeKind(target);
1064 1081
1065 // VM objects length getter. 1082 // VM objects length getter.
1066 if ((recognized_kind == MethodRecognizer::kObjectArrayLength) || 1083 switch (recognized_kind) {
1067 (recognized_kind == MethodRecognizer::kImmutableArrayLength) || 1084 case MethodRecognizer::kObjectArrayLength:
1068 (recognized_kind == MethodRecognizer::kGrowableArrayLength)) { 1085 case MethodRecognizer::kImmutableArrayLength:
1069 if (!ic_data.HasOneTarget()) { 1086 case MethodRecognizer::kByteArrayBaseLength:
1070 // TODO(srdjan): Implement for mutiple targets. 1087 case MethodRecognizer::kGrowableArrayLength: {
1071 return false; 1088 if (!ic_data.HasOneTarget()) {
1089 // TODO(srdjan): Implement for mutiple targets.
1090 return false;
1091 }
1092 const bool is_immutable =
1093 (recognized_kind != MethodRecognizer::kGrowableArrayLength);
1094 InlineArrayLengthGetter(call,
1095 OffsetForLengthGetter(recognized_kind),
1096 is_immutable,
1097 recognized_kind);
1098 return true;
1072 } 1099 }
1073 switch (recognized_kind) { 1100 case MethodRecognizer::kGrowableArrayCapacity:
1074 case MethodRecognizer::kObjectArrayLength: 1101 InlineGrowableArrayCapacityGetter(call);
1075 case MethodRecognizer::kImmutableArrayLength: 1102 return true;
1076 InlineArrayLengthGetter(call, 1103
srdjan 2012/12/18 21:45:57 I would remove empty lines between the case's.
Florian Schneider 2012/12/19 09:51:29 Done.
1077 Array::length_offset(), 1104 case MethodRecognizer::kStringBaseLength:
1078 true, 1105 if (!ic_data.HasOneTarget()) {
1079 recognized_kind); 1106 // Target is not only StringBase_get_length.
1080 break; 1107 return false;
1081 case MethodRecognizer::kGrowableArrayLength: 1108 }
1082 InlineArrayLengthGetter(call, 1109 InlineStringLengthGetter(call);
1083 GrowableObjectArray::length_offset(), 1110 return true;
1084 false, 1111
1085 recognized_kind); 1112 case MethodRecognizer::kStringBaseIsEmpty:
1086 break; 1113 if (!ic_data.HasOneTarget()) {
1087 default: 1114 // Target is not only StringBase_get_isEmpty.
1088 UNREACHABLE(); 1115 return false;
1089 } 1116 }
1090 return true; 1117 InlineStringIsEmptyGetter(call);
1118 return true;
1119 default:
1120 ASSERT(recognized_kind == MethodRecognizer::kUnknown);
1091 } 1121 }
1092
1093 if (recognized_kind == MethodRecognizer::kGrowableArrayCapacity) {
1094 InlineGArrayCapacityGetter(call);
1095 return true;
1096 }
1097
1098 if (recognized_kind == MethodRecognizer::kStringBaseLength) {
1099 if (!ic_data.HasOneTarget()) {
1100 // Target is not only StringBase_get_length.
1101 return false;
1102 }
1103 InlineStringLengthGetter(call);
1104 return true;
1105 }
1106
1107 if (recognized_kind == MethodRecognizer::kStringBaseIsEmpty) {
1108 if (!ic_data.HasOneTarget()) {
1109 // Target is not only StringBase_get_isEmpty.
1110 return false;
1111 }
1112 InlineStringIsEmptyGetter(call);
1113 return true;
1114 }
1115
1116 return false; 1122 return false;
1117 } 1123 }
1118 1124
1119 1125
1120 StringCharCodeAtInstr* FlowGraphOptimizer::BuildStringCharCodeAt( 1126 StringCharCodeAtInstr* FlowGraphOptimizer::BuildStringCharCodeAt(
1121 InstanceCallInstr* call, 1127 InstanceCallInstr* call,
1122 intptr_t cid) { 1128 intptr_t cid) {
1123 Value* str = call->ArgumentAt(0)->value(); 1129 Value* str = call->ArgumentAt(0)->value();
1124 Value* index = call->ArgumentAt(1)->value(); 1130 Value* index = call->ArgumentAt(1)->value();
1125 AddCheckClass(call, str->Copy()); 1131 AddCheckClass(call, str->Copy());
(...skipping 3143 matching lines...) Expand 10 before | Expand all | Expand 10 after
4269 4275
4270 if (FLAG_trace_constant_propagation) { 4276 if (FLAG_trace_constant_propagation) {
4271 OS::Print("\n==== After constant propagation ====\n"); 4277 OS::Print("\n==== After constant propagation ====\n");
4272 FlowGraphPrinter printer(*graph_); 4278 FlowGraphPrinter printer(*graph_);
4273 printer.PrintBlocks(); 4279 printer.PrintBlocks();
4274 } 4280 }
4275 } 4281 }
4276 4282
4277 4283
4278 } // namespace dart 4284 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698