Chromium Code Reviews| Index: runtime/vm/intermediate_language.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language.cc (revision 29032) |
| +++ runtime/vm/intermediate_language.cc (working copy) |
| @@ -20,6 +20,8 @@ |
| #include "vm/stub_code.h" |
| #include "vm/symbols.h" |
| +#include "vm/il_printer.h" |
| + |
| namespace dart { |
| DEFINE_FLAG(int, max_equality_polymorphic_checks, 32, |
| @@ -2697,6 +2699,59 @@ |
| } |
| +// Replace StringInterpolateInstr with a constant string if all inputs are |
| +// constant. Leave the CreateArrayInstr and StoreIndexedInstr in the |
| +// stream in case deoptimization occurs. |
| +Definition* StringInterpolateInstr::Canonicalize(FlowGraph* flow_graph) { |
| + // The following graph structure is generated by the graph builder: |
| + // v2 <- CreateArray(v0) |
| + // StoreIndexed(v2, v3, v4) -- v3:constant index, v4: value. |
| + // .. |
| + // v8 <- StringInterpolate(v2) |
| + CreateArrayInstr* create_array = value()->definition()->AsCreateArray(); |
| + ASSERT(create_array != NULL); |
| + // Check if the string interpolation has only constant inputs. |
| + GrowableArray<ConstantInstr*> constants(create_array->num_elements()); |
| + for (intptr_t i = 0; i < create_array->num_elements(); i++) { |
| + constants.Add(NULL); |
| + } |
| + for (Value::Iterator it(create_array->input_use_list()); |
| + !it.Done(); |
| + it.Advance()) { |
| + Instruction* curr = it.Current()->instruction(); |
| + if (curr != this) { |
| + StoreIndexedInstr* store = curr->AsStoreIndexed(); |
| + ASSERT(store != NULL); |
| + if (store->value()->definition()->IsConstant()) { |
| + ASSERT(store->index()->BindsToConstant()); |
| + constants[Smi::Cast(store->index()->BoundConstant()).Value()] = |
| + store->value()->definition()->AsConstant(); |
| + } else { |
| + return this; |
| + } |
| + } |
| + } |
| + // Interpolate string at compile time. |
| + const Array& array_argument = |
| + Array::Handle(Array::New(create_array->num_elements())); |
| + for (intptr_t i = 0; i < constants.length(); i++) { |
| + array_argument.SetAt(i, constants[i]->value()); |
| + } |
| + // Build argument array to pass to the interpolation function. |
| + const Array& interpolate_arg = Array::Handle(Array::New(1)); |
| + interpolate_arg.SetAt(0, array_argument); |
| + // Call interpolation function. |
| + String& concatenated = String::ZoneHandle(); |
| + concatenated ^= |
| + DartEntry::InvokeFunction(CallFunction(), interpolate_arg); |
| + if (concatenated.IsUnhandledException()) { |
| + return this; |
|
Florian Schneider
2013/10/23 17:32:39
Please make sure that the case of an exception is
srdjan
2013/10/23 20:39:02
Changed the code to allow only numbers, strings, b
|
| + } |
| + concatenated = Symbols::New(concatenated); |
| + return flow_graph->GetConstant(concatenated); |
| +} |
| + |
| + |
| InvokeMathCFunctionInstr::InvokeMathCFunctionInstr( |
| ZoneGrowableArray<Value*>* inputs, |
| intptr_t original_deopt_id, |