Chromium Code Reviews| Index: runtime/vm/flow_graph_optimizer.cc |
| =================================================================== |
| --- runtime/vm/flow_graph_optimizer.cc (revision 15197) |
| +++ runtime/vm/flow_graph_optimizer.cc (working copy) |
| @@ -1107,6 +1107,43 @@ |
| } |
| +StringCharCodeAtInstr* FlowGraphOptimizer::BuildStringCharCodeAt( |
| + InstanceCallInstr* call, |
| + intptr_t cid) { |
| + 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(); |
| + if (index_def->value().IsSmi()) { |
| + intptr_t constant_index = Smi::Cast(index_def->value()).Value(); |
| + skip_check = (constant_index < constant_string.Length()); |
| + } |
|
srdjan
2012/11/21 16:38:15
Why not just return the value instead? Is that han
Florian Schneider
2012/11/22 11:05:58
This helper builds the graph for charCodeAt, which
|
| + } |
| + if (!skip_check) { |
| + // Insert bounds check. |
| + InsertBefore(call, |
| + new CheckArrayBoundInstr(str->Copy(), |
| + index->Copy(), |
| + cid, |
| + call), |
| + call->env(), |
| + Definition::kEffect); |
| + } |
| + return new StringCharCodeAtInstr(str, index, cid); |
| +} |
| + |
| + |
| // Inline only simple, frequently called core library methods. |
| bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| ASSERT(call->HasICData()); |
| @@ -1124,42 +1161,24 @@ |
| (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(); |
| - if (index_def->value().IsSmi()) { |
| - 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]); |
| + StringCharCodeAtInstr* instr = BuildStringCharCodeAt(call, class_ids[0]); |
| call->ReplaceWith(instr, current_iterator()); |
| RemovePushArguments(call); |
| return true; |
| } |
| + if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) && |
| + (ic_data.NumberOfChecks() == 1) && |
| + (class_ids[0] == kOneByteStringCid)) { |
| + // TODO(fschneider): Handle TwoByteString. |
| + StringCharCodeAtInstr* load_char_code = |
| + BuildStringCharCodeAt(call, class_ids[0]); |
| + InsertBefore(call, load_char_code, NULL, Definition::kValue); |
| + StringFromCharCodeInstr* char_at = |
| + new StringFromCharCodeInstr(new Value(load_char_code)); |
| + call->ReplaceWith(char_at, current_iterator()); |
| + RemovePushArguments(call); |
| + return true; |
| + } |
| if ((recognized_kind == MethodRecognizer::kIntegerToDouble) && |
| (class_ids[0] == kSmiCid)) { |
| @@ -3302,6 +3321,12 @@ |
| } |
| +void ConstantPropagator::VisitStringFromCharCode( |
| + StringFromCharCodeInstr* instr) { |
| + SetValue(instr, non_constant_); |
| +} |
| + |
| + |
| void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) { |
| SetValue(instr, non_constant_); |
| } |