Chromium Code Reviews| Index: runtime/vm/flow_graph_optimizer.cc |
| =================================================================== |
| --- runtime/vm/flow_graph_optimizer.cc (revision 14406) |
| +++ runtime/vm/flow_graph_optimizer.cc (working copy) |
| @@ -470,10 +470,18 @@ |
| new CheckSmiInstr((*index)->Copy(), call->deopt_id()), |
| call->env(), |
| Definition::kEffect); |
| - // If both index and array are constants, then the bound check always |
| - // succeeded. |
| - // TODO(srdjan): Remove once constant propagation lands. |
| - if (!((*array)->BindsToConstant() && (*index)->BindsToConstant())) { |
| + // If both index and array are constants, then do a compile-time check. |
| + // TODO(srdjan): Remove once constant propagation handles bounds checks. |
| + bool skip_check = false; |
| + if ((*array)->BindsToConstant() && (*index)->BindsToConstant()) { |
| + ConstantInstr* array_def = (*array)->definition()->AsConstant(); |
| + const ImmutableArray& constant_array = |
| + ImmutableArray::Cast(array_def->value()); |
| + ConstantInstr* index_def = (*index)->definition()->AsConstant(); |
| + intptr_t constant_index = Smi::Cast(index_def->value()).Value(); |
| + skip_check = (constant_index < constant_array.Length()); |
| + } |
|
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
|
| + if (!skip_check) { |
| // Insert array bounds check. |
| InsertBefore(call, |
| new CheckArrayBoundInstr((*array)->Copy(), |
| @@ -1096,6 +1104,44 @@ |
| ic_data.GetCheckAt(0, &class_ids, &target); |
| MethodRecognizer::Kind recognized_kind = |
| MethodRecognizer::RecognizeKind(target); |
| + if ((recognized_kind == MethodRecognizer::kStringBaseCharCodeAt) && |
| + (ic_data.NumberOfChecks() == 1) && |
| + ((class_ids[0] == kOneByteStringCid) || |
| + (class_ids[0] == kTwoByteStringCid))) { |
| + Value* str= call->ArgumentAt(0)->value(); |
| + Value* index = call->ArgumentAt(1)->value(); |
| + AddCheckClass(call, str->Copy()); |
| + InsertBefore(call, |
| + new CheckSmiInstr(index->Copy(), call->deopt_id()), |
| + call->env(), |
| + Definition::kEffect); |
| + // If both index and string are constants, then do a compile-time check. |
| + // TODO(srdjan): Remove once constant propagation handles bounds checks. |
| + bool skip_check = false; |
| + if (str->BindsToConstant() && index->BindsToConstant()) { |
| + ConstantInstr* string_def = str->definition()->AsConstant(); |
| + const String& constant_string = |
| + String::Cast(string_def->value()); |
| + ConstantInstr* index_def = index->definition()->AsConstant(); |
| + intptr_t constant_index = Smi::Cast(index_def->value()).Value(); |
| + skip_check = (constant_index < constant_string.Length()); |
| + } |
| + if (!skip_check) { |
| + // Insert bounds check. |
| + InsertBefore(call, |
| + new CheckArrayBoundInstr(str->Copy(), |
| + index->Copy(), |
| + class_ids[0], |
| + call), |
| + call->env(), |
| + Definition::kEffect); |
| + } |
| + StringCharCodeAtInstr* instr = |
| + new StringCharCodeAtInstr(str, index, class_ids[0]); |
| + call->ReplaceWith(instr, current_iterator()); |
| + RemovePushArguments(call); |
| + return true; |
| + } |
| if ((recognized_kind == MethodRecognizer::kIntegerToDouble) && |
| (class_ids[0] == kSmiCid)) { |
| @@ -3230,6 +3276,11 @@ |
| } |
| +void ConstantPropagator::VisitStringCharCodeAt(StringCharCodeAtInstr* instr) { |
| + SetValue(instr, non_constant_); |
| +} |
| + |
| + |
| void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) { |
| SetValue(instr, non_constant_); |
| } |