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

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

Issue 12256037: Fix bug in optimizing string .length loads. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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 | « no previous file | tests/language/optimized_string_charcodeat_test.dart » ('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 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 Type::ZoneHandle(Type::SmiType())); 1168 Type::ZoneHandle(Type::SmiType()));
1169 length_load->set_result_cid(kSmiCid); 1169 length_load->set_result_cid(kSmiCid);
1170 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength); 1170 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength);
1171 1171
1172 call->ReplaceWith(length_load, current_iterator()); 1172 call->ReplaceWith(length_load, current_iterator());
1173 RemovePushArguments(call); 1173 RemovePushArguments(call);
1174 } 1174 }
1175 1175
1176 1176
1177 static LoadFieldInstr* BuildLoadStringLength(Value* str) { 1177 static LoadFieldInstr* BuildLoadStringLength(Value* str) {
1178 const bool is_immutable = true; // String length is immutable. 1178 // Treat length loads as mutable (i.e. affected by side effects) to avoid
1179 // hoisting them since we can't hoist the preceding class-check. This
1180 // is because of externalization of strings that affects their class-id.
1181 const bool is_immutable = false;
1179 LoadFieldInstr* load = new LoadFieldInstr( 1182 LoadFieldInstr* load = new LoadFieldInstr(
1180 str, 1183 str,
1181 String::length_offset(), 1184 String::length_offset(),
1182 Type::ZoneHandle(Type::SmiType()), 1185 Type::ZoneHandle(Type::SmiType()),
1183 is_immutable); 1186 is_immutable);
1184 load->set_result_cid(kSmiCid); 1187 load->set_result_cid(kSmiCid);
1188 load->set_recognized_kind(MethodRecognizer::kStringBaseLength);
1185 return load; 1189 return load;
1186 } 1190 }
1187 1191
1188 1192
1189 void FlowGraphOptimizer::InlineStringLengthGetter(InstanceCallInstr* call) { 1193 void FlowGraphOptimizer::InlineStringLengthGetter(InstanceCallInstr* call) {
1190 // Check receiver class. 1194 // Check receiver class.
1191 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); 1195 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
1192 1196
1193 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)->value()); 1197 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)->value());
1194 load->set_recognized_kind(MethodRecognizer::kStringBaseLength);
1195 call->ReplaceWith(load, current_iterator()); 1198 call->ReplaceWith(load, current_iterator());
1196 RemovePushArguments(call); 1199 RemovePushArguments(call);
1197 } 1200 }
1198 1201
1199 1202
1200 void FlowGraphOptimizer::InlineStringIsEmptyGetter(InstanceCallInstr* call) { 1203 void FlowGraphOptimizer::InlineStringIsEmptyGetter(InstanceCallInstr* call) {
1201 // Check receiver class. 1204 // Check receiver class.
1202 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); 1205 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
1203 1206
1204 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)->value()); 1207 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)->value());
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 const String& constant_string = 1321 const String& constant_string =
1319 String::Cast(string_def->value()); 1322 String::Cast(string_def->value());
1320 ConstantInstr* index_def = index->definition()->AsConstant(); 1323 ConstantInstr* index_def = index->definition()->AsConstant();
1321 if (index_def->value().IsSmi()) { 1324 if (index_def->value().IsSmi()) {
1322 intptr_t constant_index = Smi::Cast(index_def->value()).Value(); 1325 intptr_t constant_index = Smi::Cast(index_def->value()).Value();
1323 skip_check = (constant_index < constant_string.Length()); 1326 skip_check = (constant_index < constant_string.Length());
1324 } 1327 }
1325 } 1328 }
1326 if (!skip_check) { 1329 if (!skip_check) {
1327 // Insert bounds check. 1330 // Insert bounds check.
1328 const bool is_immutable = true; 1331 LoadFieldInstr* length = BuildLoadStringLength(str->Copy());
1329 LoadFieldInstr* length = new LoadFieldInstr(
1330 str->Copy(),
1331 CheckArrayBoundInstr::LengthOffsetFor(cid),
1332 Type::ZoneHandle(Type::SmiType()),
1333 is_immutable);
1334 length->set_result_cid(kSmiCid);
1335 length->set_recognized_kind(MethodRecognizer::kStringBaseLength);
1336 InsertBefore(call, length, NULL, Definition::kValue); 1332 InsertBefore(call, length, NULL, Definition::kValue);
1337 InsertBefore(call, 1333 InsertBefore(call,
1338 new CheckArrayBoundInstr(new Value(length), 1334 new CheckArrayBoundInstr(new Value(length),
1339 index->Copy(), 1335 index->Copy(),
1340 cid, 1336 cid,
1341 call), 1337 call),
1342 call->env(), 1338 call->env(),
1343 Definition::kEffect); 1339 Definition::kEffect);
1344 } 1340 }
1345 return new LoadIndexedInstr(str, 1341 return new LoadIndexedInstr(str,
(...skipping 2913 matching lines...) Expand 10 before | Expand all | Expand 10 after
4259 4255
4260 if (FLAG_trace_constant_propagation) { 4256 if (FLAG_trace_constant_propagation) {
4261 OS::Print("\n==== After constant propagation ====\n"); 4257 OS::Print("\n==== After constant propagation ====\n");
4262 FlowGraphPrinter printer(*graph_); 4258 FlowGraphPrinter printer(*graph_);
4263 printer.PrintBlocks(); 4259 printer.PrintBlocks();
4264 } 4260 }
4265 } 4261 }
4266 4262
4267 4263
4268 } // namespace dart 4264 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | tests/language/optimized_string_charcodeat_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698