| Index: runtime/vm/flow_graph_builder.cc
|
| ===================================================================
|
| --- runtime/vm/flow_graph_builder.cc (revision 7560)
|
| +++ runtime/vm/flow_graph_builder.cc (working copy)
|
| @@ -1506,34 +1506,61 @@
|
| args->Add(new UseVal(no_instantiator));
|
| return;
|
| }
|
| - // The type arguments are uninstantiated.
|
| - // Place holder to hold uninstantiated constructor type arguments.
|
| - BindInstr* placeholder =
|
| - new BindInstr(new ConstantVal(Object::ZoneHandle()));
|
| - AddInstruction(placeholder);
|
| - Value* instantiator =
|
| - BuildInstantiatorTypeArguments(node->token_index());
|
| + // The type arguments are uninstantiated. The generated pseudo code:
|
| + // t1 = InstantiatorTypeArguments();
|
| + // t2 = ExtractConstructorTypeArguments(t1);
|
| + // t1 = ExtractConstructorInstantiator(t1, t2);
|
| + // t_n <- t2
|
| + // t_n+1 <- t1
|
| + const intptr_t context_level = owner()->context_level();
|
| + // Use expression_temp_var and node->allocated_object_var() locals to keep
|
| + // intermediate results around (t1 and t2 above).
|
| + ASSERT(owner()->parsed_function().expression_temp_var() != NULL);
|
| + const LocalVariable& t1 = *owner()->parsed_function().expression_temp_var();
|
| + const LocalVariable& t2 = node->allocated_object_var();
|
| +
|
| + Value* instantiator = BuildInstantiatorTypeArguments(node->token_index());
|
| ASSERT(instantiator->IsUse());
|
| - PickTempInstr* duplicate_instantiator =
|
| - new PickTempInstr(instantiator->AsUse()->definition()->temp_index());
|
| - AddInstruction(duplicate_instantiator);
|
| + Definition* stored_instantiator = new BindInstr(new StoreLocalComp(
|
| + t1, instantiator, context_level));
|
| + AddInstruction(stored_instantiator);
|
| + // t1: instantiator type arguments.
|
| +
|
| BindInstr* extract_type_arguments = new BindInstr(
|
| new ExtractConstructorTypeArgumentsComp(
|
| node->token_index(),
|
| owner()->try_index(),
|
| node->type_arguments(),
|
| - new UseVal(duplicate_instantiator)));
|
| + new UseVal(stored_instantiator)));
|
| AddInstruction(extract_type_arguments);
|
| - AddInstruction(new TuckTempInstr(placeholder->temp_index(),
|
| - extract_type_arguments->temp_index()));
|
| +
|
| + Instruction* stored_type_arguments = new DoInstr(new StoreLocalComp(
|
| + t2, new UseVal(extract_type_arguments), context_level));
|
| + AddInstruction(stored_type_arguments);
|
| + // t2: extracted constructor type arguments.
|
| + Definition* load_instantiator = new BindInstr(
|
| + new LoadLocalComp(t1, context_level));
|
| + AddInstruction(load_instantiator);
|
| + Definition* load_type_arguments = new BindInstr(
|
| + new LoadLocalComp(t2, context_level));
|
| + AddInstruction(load_type_arguments);
|
| +
|
| BindInstr* extract_instantiator =
|
| new BindInstr(new ExtractConstructorInstantiatorComp(
|
| node,
|
| - instantiator,
|
| - new UseVal(extract_type_arguments)));
|
| + new UseVal(load_instantiator),
|
| + new UseVal(load_type_arguments)));
|
| AddInstruction(extract_instantiator);
|
| - args->Add(new UseVal(placeholder));
|
| - args->Add(new UseVal(extract_instantiator));
|
| + AddInstruction(new DoInstr(new StoreLocalComp(
|
| + t1, new UseVal(extract_instantiator), context_level)));
|
| + // t2: extracted constructor type arguments.
|
| + // t1: extracted constructor instantiator.
|
| + Definition* load_0 = new BindInstr(new LoadLocalComp(t2, context_level));
|
| + AddInstruction(load_0);
|
| + Definition* load_1 = new BindInstr(new LoadLocalComp(t1, context_level));
|
| + AddInstruction(load_1);
|
| + args->Add(new UseVal(load_0));
|
| + args->Add(new UseVal(load_1));
|
| }
|
|
|
|
|
| @@ -1545,16 +1572,26 @@
|
|
|
| // t_n contains the allocated and initialized object.
|
| // t_n <- AllocateObject(class)
|
| - // t_n+1 <- Pick(t_n)
|
| - // t_n+2 <- ctor-arg
|
| - // t_n+3... <- constructor arguments start here
|
| - // StaticCall(constructor, t_n+1, t_n+2, ...)
|
| + // t_n <- StoreLocal(temp, t_n);
|
| + // t_n+1 <- ctor-arg
|
| + // t_n+2... <- constructor arguments start here
|
| + // StaticCall(constructor, t_n, t_n+1, ...)
|
| + // tn <- LoadLocal(temp)
|
|
|
| Definition* allocate = BuildObjectAllocation(node);
|
| - PickTempInstr* duplicate = new PickTempInstr(allocate->temp_index());
|
| - AddInstruction(duplicate);
|
| - BuildConstructorCall(node, new UseVal(duplicate));
|
| - ReturnValue(new UseVal(allocate));
|
| + StoreLocalComp* store_allocated = new StoreLocalComp(
|
| + node->allocated_object_var(),
|
| + new UseVal(allocate),
|
| + owner()->context_level());
|
| + Definition* allocated_value = new BindInstr(store_allocated);
|
| + AddInstruction(allocated_value);
|
| + BuildConstructorCall(node, new UseVal(allocated_value));
|
| + LoadLocalComp* load_allocated = new LoadLocalComp(
|
| + node->allocated_object_var(),
|
| + owner()->context_level());
|
| + allocated_value = new BindInstr(load_allocated);
|
| + AddInstruction(allocated_value);
|
| + ReturnValue(new UseVal(allocated_value));
|
| }
|
|
|
|
|
| @@ -2434,16 +2471,6 @@
|
| }
|
|
|
|
|
| -void FlowGraphPrinter::VisitPickTemp(PickTempInstr* instr) {
|
| - OS::Print(" t%d <- Pick(t%d)", instr->temp_index(), instr->source());
|
| -}
|
| -
|
| -
|
| -void FlowGraphPrinter::VisitTuckTemp(TuckTempInstr* instr) {
|
| - OS::Print(" t%d := t%d", instr->destination(), instr->source());
|
| -}
|
| -
|
| -
|
| void FlowGraphPrinter::VisitReturn(ReturnInstr* instr) {
|
| OS::Print(" return ");
|
| instr->value()->Accept(this);
|
|
|