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

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

Issue 11360033: Inline native String.charCodeAt in optimized code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: fixed a bug in indexed ops and added more tests Created 8 years, 1 month 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) 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 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 Value** index) { 463 Value** index) {
464 *array = call->ArgumentAt(0)->value(); 464 *array = call->ArgumentAt(0)->value();
465 *index = call->ArgumentAt(1)->value(); 465 *index = call->ArgumentAt(1)->value();
466 // Insert class check and index smi checks and attach a copy of the 466 // Insert class check and index smi checks and attach a copy of the
467 // original environment because the operation can still deoptimize. 467 // original environment because the operation can still deoptimize.
468 AddCheckClass(call, (*array)->Copy()); 468 AddCheckClass(call, (*array)->Copy());
469 InsertBefore(call, 469 InsertBefore(call,
470 new CheckSmiInstr((*index)->Copy(), call->deopt_id()), 470 new CheckSmiInstr((*index)->Copy(), call->deopt_id()),
471 call->env(), 471 call->env(),
472 Definition::kEffect); 472 Definition::kEffect);
473 // If both index and array are constants, then the bound check always 473 // If both index and array are constants, then do a compile-time check.
474 // succeeded. 474 // TODO(srdjan): Remove once constant propagation handles bounds checks.
475 // TODO(srdjan): Remove once constant propagation lands. 475 bool skip_check = false;
476 if (!((*array)->BindsToConstant() && (*index)->BindsToConstant())) { 476 if ((*array)->BindsToConstant() && (*index)->BindsToConstant()) {
477 ConstantInstr* array_def = (*array)->definition()->AsConstant();
478 const ImmutableArray& constant_array =
479 ImmutableArray::Cast(array_def->value());
480 ConstantInstr* index_def = (*index)->definition()->AsConstant();
481 intptr_t constant_index = Smi::Cast(index_def->value()).Value();
482 skip_check = (constant_index < constant_array.Length());
483 }
srdjan 2012/11/01 20:32:18 I get a crash with following code. Can you please
Florian Schneider 2012/11/01 22:58:56 Good point. I added the test and fixed the non-smi
484 if (!skip_check) {
477 // Insert array bounds check. 485 // Insert array bounds check.
478 InsertBefore(call, 486 InsertBefore(call,
479 new CheckArrayBoundInstr((*array)->Copy(), 487 new CheckArrayBoundInstr((*array)->Copy(),
480 (*index)->Copy(), 488 (*index)->Copy(),
481 class_id, 489 class_id,
482 call), 490 call),
483 call->env(), 491 call->env(),
484 Definition::kEffect); 492 Definition::kEffect);
485 } 493 }
486 if (class_id == kGrowableObjectArrayCid) { 494 if (class_id == kGrowableObjectArrayCid) {
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 const ICData& ic_data = *call->ic_data(); 1097 const ICData& ic_data = *call->ic_data();
1090 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) { 1098 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) {
1091 // No type feedback collected or multiple targets found. 1099 // No type feedback collected or multiple targets found.
1092 return false; 1100 return false;
1093 } 1101 }
1094 Function& target = Function::Handle(); 1102 Function& target = Function::Handle();
1095 GrowableArray<intptr_t> class_ids; 1103 GrowableArray<intptr_t> class_ids;
1096 ic_data.GetCheckAt(0, &class_ids, &target); 1104 ic_data.GetCheckAt(0, &class_ids, &target);
1097 MethodRecognizer::Kind recognized_kind = 1105 MethodRecognizer::Kind recognized_kind =
1098 MethodRecognizer::RecognizeKind(target); 1106 MethodRecognizer::RecognizeKind(target);
1107 if ((recognized_kind == MethodRecognizer::kStringBaseCharCodeAt) &&
1108 (ic_data.NumberOfChecks() == 1) &&
1109 ((class_ids[0] == kOneByteStringCid) ||
1110 (class_ids[0] == kTwoByteStringCid))) {
1111 Value* str= call->ArgumentAt(0)->value();
1112 Value* index = call->ArgumentAt(1)->value();
1113 AddCheckClass(call, str->Copy());
1114 InsertBefore(call,
1115 new CheckSmiInstr(index->Copy(), call->deopt_id()),
1116 call->env(),
1117 Definition::kEffect);
1118 // If both index and string are constants, then do a compile-time check.
1119 // TODO(srdjan): Remove once constant propagation handles bounds checks.
1120 bool skip_check = false;
1121 if (str->BindsToConstant() && index->BindsToConstant()) {
1122 ConstantInstr* string_def = str->definition()->AsConstant();
1123 const String& constant_string =
1124 String::Cast(string_def->value());
1125 ConstantInstr* index_def = index->definition()->AsConstant();
1126 intptr_t constant_index = Smi::Cast(index_def->value()).Value();
1127 skip_check = (constant_index < constant_string.Length());
1128 }
1129 if (!skip_check) {
1130 // Insert bounds check.
1131 InsertBefore(call,
1132 new CheckArrayBoundInstr(str->Copy(),
1133 index->Copy(),
1134 class_ids[0],
1135 call),
1136 call->env(),
1137 Definition::kEffect);
1138 }
1139 StringCharCodeAtInstr* instr =
1140 new StringCharCodeAtInstr(str, index, class_ids[0]);
1141 call->ReplaceWith(instr, current_iterator());
1142 RemovePushArguments(call);
1143 return true;
1144 }
1099 1145
1100 if ((recognized_kind == MethodRecognizer::kIntegerToDouble) && 1146 if ((recognized_kind == MethodRecognizer::kIntegerToDouble) &&
1101 (class_ids[0] == kSmiCid)) { 1147 (class_ids[0] == kSmiCid)) {
1102 SmiToDoubleInstr* s2d_instr = new SmiToDoubleInstr(call); 1148 SmiToDoubleInstr* s2d_instr = new SmiToDoubleInstr(call);
1103 call->ReplaceWith(s2d_instr, current_iterator()); 1149 call->ReplaceWith(s2d_instr, current_iterator());
1104 // Pushed arguments are not removed because SmiToDouble is implemented 1150 // Pushed arguments are not removed because SmiToDouble is implemented
1105 // as a call. 1151 // as a call.
1106 return true; 1152 return true;
1107 } 1153 }
1108 1154
(...skipping 2114 matching lines...) Expand 10 before | Expand all | Expand 10 after
3223 SetValue(instr, non_constant_); 3269 SetValue(instr, non_constant_);
3224 } 3270 }
3225 } 3271 }
3226 3272
3227 3273
3228 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) { 3274 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) {
3229 SetValue(instr, non_constant_); 3275 SetValue(instr, non_constant_);
3230 } 3276 }
3231 3277
3232 3278
3279 void ConstantPropagator::VisitStringCharCodeAt(StringCharCodeAtInstr* instr) {
3280 SetValue(instr, non_constant_);
3281 }
3282
3283
3233 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) { 3284 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) {
3234 SetValue(instr, non_constant_); 3285 SetValue(instr, non_constant_);
3235 } 3286 }
3236 3287
3237 3288
3238 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { 3289 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) {
3239 SetValue(instr, instr->value()->definition()->constant_value()); 3290 SetValue(instr, instr->value()->definition()->constant_value());
3240 } 3291 }
3241 3292
3242 3293
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
3655 3706
3656 if (FLAG_trace_constant_propagation) { 3707 if (FLAG_trace_constant_propagation) {
3657 OS::Print("\n==== After constant propagation ====\n"); 3708 OS::Print("\n==== After constant propagation ====\n");
3658 FlowGraphPrinter printer(*graph_); 3709 FlowGraphPrinter printer(*graph_);
3659 printer.PrintBlocks(); 3710 printer.PrintBlocks();
3660 } 3711 }
3661 } 3712 }
3662 3713
3663 3714
3664 } // namespace dart 3715 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698