Chromium Code Reviews| Index: runtime/vm/flow_graph_builder.cc |
| diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc |
| index 8f908e576665aff542f83e8ca0c36bc5e65f8ea5..5587229a9391edb1d25f9cb4a58612122b26b09a 100644 |
| --- a/runtime/vm/flow_graph_builder.cc |
| +++ b/runtime/vm/flow_graph_builder.cc |
| @@ -40,7 +40,9 @@ FlowGraphBuilder::FlowGraphBuilder(const ParsedFunction& parsed_function) |
| context_level_(0), |
| last_used_try_index_(CatchClauseNode::kInvalidTryIndex), |
| try_index_(CatchClauseNode::kInvalidTryIndex), |
| - graph_entry_(NULL) { } |
| + graph_entry_(NULL), |
| + inlining_context_(kNotInlining), |
| + exits_(NULL) { } |
| void FlowGraphBuilder::AddCatchEntry(TargetEntryInstr* entry) { |
| @@ -339,6 +341,11 @@ void EffectGraphVisitor::Bailout(const char* reason) { |
| } |
| +void EffectGraphVisitor::InlineBailout(const char* reason) { |
| + if (owner()->InInliningContext()) owner()->Bailout(reason); |
| +} |
| + |
| + |
| // <Statement> ::= Return { value: <Expression> |
| // inlined_finally_list: <InlinedFinally>* } |
| void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { |
| @@ -347,6 +354,7 @@ void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { |
| Append(for_value); |
| for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| + InlineBailout("EffectGraphVisitor::VisitReturnNode (finally)"); |
| EffectGraphVisitor for_effect(owner(), temp_index()); |
| node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| Append(for_effect); |
| @@ -355,6 +363,7 @@ void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { |
| Value* return_value = for_value.value(); |
| if (FLAG_enable_type_checks) { |
| + InlineBailout("EffectGraphVisitor::VisitReturnNode (type check)"); |
| const Function& function = owner()->parsed_function().function(); |
| const bool is_implicit_dynamic_getter = |
| (!function.is_static() && |
| @@ -389,7 +398,9 @@ void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { |
| } |
| } |
| - AddInstruction(new ReturnInstr(node->token_pos(), return_value)); |
| + ReturnInstr* return_instr = new ReturnInstr(node->token_pos(), return_value); |
| + AddReturnExit(return_instr); |
| + AddInstruction(return_instr); |
| CloseFragment(); |
| } |
| @@ -417,6 +428,7 @@ bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, |
| Value* value, |
| const AbstractType& dst_type, |
| const String& dst_name) { |
| + InlineBailout("EffectGraphVisitor::CanSkipTypeCheck"); |
| ASSERT(!dst_type.IsNull()); |
| ASSERT(dst_type.IsFinalized()); |
| @@ -464,11 +476,13 @@ bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, |
| // type: AbstractType |
| // dst_name: String } |
| void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitAssignableNode"); |
| UNREACHABLE(); |
| } |
| void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| + InlineBailout("ValueGraphVisitor::VisitAssignableNode"); |
| ValueGraphVisitor for_value(owner(), temp_index()); |
| node->expr()->Visit(&for_value); |
| Append(for_value); |
| @@ -483,6 +497,7 @@ void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| // left: <Expression> |
| // right: <Expression> } |
| void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitBinaryOpNode"); |
| // Operators "&&" and "||" cannot be overloaded therefore do not call |
| // operator. |
| if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| @@ -528,6 +543,7 @@ void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| // Special handling for AND/OR. |
| void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| + InlineBailout("ValueGraphVisitor::VisitBinaryOpNode"); |
| // Operators "&&" and "||" cannot be overloaded therefore do not call |
| // operator. |
| if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| @@ -588,6 +604,7 @@ void EffectGraphVisitor::BuildTypecheckArguments( |
| intptr_t token_pos, |
| Value** instantiator_result, |
| Value** instantiator_type_arguments_result) { |
| + InlineBailout("EffectGraphVisitor::VisitBinaryOpNode"); |
| Value* instantiator = NULL; |
| Value* instantiator_type_arguments = NULL; |
| const Class& instantiator_class = Class::Handle( |
| @@ -615,6 +632,7 @@ void EffectGraphVisitor::BuildTypecheckArguments( |
| Value* EffectGraphVisitor::BuildNullValue() { |
| + InlineBailout("EffectGraphVisitor::BuildNullValue"); |
| return Bind(new ConstantComp(Object::ZoneHandle())); |
| } |
| @@ -625,6 +643,7 @@ AssertAssignableComp* EffectGraphVisitor::BuildAssertAssignable( |
| Value* value, |
| const AbstractType& dst_type, |
| const String& dst_name) { |
| + InlineBailout("EffectGraphVisitor::BuildAssertAssignable"); |
| // Build the type check computation. |
| Value* instantiator = NULL; |
| Value* instantiator_type_arguments = NULL; |
| @@ -650,6 +669,7 @@ Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, |
| Value* value, |
| const AbstractType& dst_type, |
| const String& dst_name) { |
| + InlineBailout("EffectGraphVisitor::BuildAssignableValue"); |
| if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { |
| return value; |
| } |
| @@ -658,6 +678,7 @@ Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, |
| void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| + InlineBailout("EffectGraphVisitor::BuildTypeTest"); |
| ASSERT(Token::IsTypeTestOperator(node->kind())); |
| EffectGraphVisitor for_left_value(owner(), temp_index()); |
| node->left()->Visit(&for_left_value); |
| @@ -666,6 +687,7 @@ void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| + InlineBailout("EffectGraphVisitor::BuildTypeCast"); |
| ASSERT(Token::IsTypeCastOperator(node->kind())); |
| const AbstractType& type = node->right()->AsTypeNode()->type(); |
| ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| @@ -682,6 +704,7 @@ void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| + InlineBailout("ValueGraphVisitor::BuildTypeTest"); |
| ASSERT(Token::IsTypeTestOperator(node->kind())); |
| const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| @@ -748,6 +771,7 @@ void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| + InlineBailout("ValueGraphVisitor::BuildTypeCast"); |
| ASSERT(Token::IsTypeCastOperator(node->kind())); |
| const AbstractType& type = node->right()->AsTypeNode()->type(); |
| ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| @@ -768,6 +792,7 @@ void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| // right: <Expression> } |
| // TODO(srdjan): Implement new equality. |
| void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitComparisonNode"); |
| if (Token::IsTypeTestOperator(node->kind())) { |
| BuildTypeTest(node); |
| return; |
| @@ -836,6 +861,7 @@ void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitUnaryOpNode"); |
| // "!" cannot be overloaded, therefore do not call operator. |
| if (node->kind() == Token::kNOT) { |
| ValueGraphVisitor for_value(owner(), temp_index()); |
| @@ -871,6 +897,7 @@ void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitConditionalExprNode"); |
| TestGraphVisitor for_test(owner(), |
| temp_index(), |
| node->condition()->token_pos()); |
| @@ -887,6 +914,7 @@ void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| + InlineBailout("ValueGraphVisitor::VisitConditionalExprNode"); |
| TestGraphVisitor for_test(owner(), |
| temp_index(), |
| node->condition()->token_pos()); |
| @@ -931,6 +959,7 @@ void EffectGraphVisitor::VisitIfNode(IfNode* node) { |
| void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitSwitchNode"); |
| EffectGraphVisitor switch_body(owner(), temp_index()); |
| node->body()->Visit(&switch_body); |
| Append(switch_body); |
| @@ -966,6 +995,7 @@ void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { |
| // Note: The specification of switch/case is under discussion and may change |
| // drastically. |
| void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitCaseNode"); |
| const intptr_t len = node->case_expressions()->length(); |
| // Create case statements instructions. |
| EffectGraphVisitor for_case_statements(owner(), temp_index()); |
| @@ -1065,6 +1095,7 @@ void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { |
| // f) loop-exit-target |
| // g) break-join (optional) |
| void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitWhileNode"); |
| TestGraphVisitor for_test(owner(), |
| temp_index(), |
| node->condition()->token_pos()); |
| @@ -1102,6 +1133,7 @@ void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { |
| // f) loop-exit-target |
| // g) break-join |
| void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitDoWhileNode"); |
| // Traverse body first in order to generate continue and break labels. |
| EffectGraphVisitor for_body(owner(), temp_index()); |
| for_body.Do( |
| @@ -1157,6 +1189,7 @@ void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { |
| // h) loop-exit-target |
| // i) break-join |
| void EffectGraphVisitor::VisitForNode(ForNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitForNode"); |
| EffectGraphVisitor for_initializer(owner(), temp_index()); |
| node->initializer()->Visit(&for_initializer); |
| Append(for_initializer); |
| @@ -1229,6 +1262,7 @@ void EffectGraphVisitor::VisitForNode(ForNode* node) { |
| void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitJumpNode"); |
| for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| EffectGraphVisitor for_effect(owner(), temp_index()); |
| node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| @@ -1283,11 +1317,13 @@ void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { |
| void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitArgumentListNode"); |
| UNREACHABLE(); |
| } |
| void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitArrayNode"); |
| // Translate the array elements and collect their values. |
| ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| new ZoneGrowableArray<PushArgumentInstr*>(node->length()); |
| @@ -1310,6 +1346,7 @@ void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitClosureNode"); |
| const Function& function = node->function(); |
| Value* receiver = NULL; |
| @@ -1359,6 +1396,7 @@ void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| void EffectGraphVisitor::TranslateArgumentList( |
| const ArgumentListNode& node, |
| ZoneGrowableArray<Value*>* values) { |
| + InlineBailout("EffectGraphVisitor::TranslateArgumentList"); |
| for (intptr_t i = 0; i < node.length(); ++i) { |
| ValueGraphVisitor for_argument(owner(), temp_index()); |
| node.NodeAt(i)->Visit(&for_argument); |
| @@ -1371,6 +1409,7 @@ void EffectGraphVisitor::TranslateArgumentList( |
| void EffectGraphVisitor::BuildPushArguments( |
| const ArgumentListNode& node, |
| ZoneGrowableArray<PushArgumentInstr*>* values) { |
| + InlineBailout("EffectGraphVisitor::BuildPushArguments"); |
| for (intptr_t i = 0; i < node.length(); ++i) { |
| ValueGraphVisitor for_argument(owner(), temp_index()); |
| node.NodeAt(i)->Visit(&for_argument); |
| @@ -1382,6 +1421,7 @@ void EffectGraphVisitor::BuildPushArguments( |
| void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitInstanceCallNode"); |
| ValueGraphVisitor for_receiver(owner(), temp_index()); |
| node->receiver()->Visit(&for_receiver); |
| Append(for_receiver); |
| @@ -1403,6 +1443,7 @@ void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| // <Expression> ::= StaticCall { function: Function |
| // arguments: <ArgumentList> } |
| void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitStaticCallNode"); |
| ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| BuildPushArguments(*node->arguments(), arguments); |
| @@ -1417,6 +1458,7 @@ void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| ClosureCallComp* EffectGraphVisitor::BuildClosureCall( |
| ClosureCallNode* node) { |
| + InlineBailout("EffectGraphVisitor::BuildClosureCall"); |
| ValueGraphVisitor for_closure(owner(), temp_index()); |
| node->closure()->Visit(&for_closure); |
| Append(for_closure); |
| @@ -1434,6 +1476,7 @@ ClosureCallComp* EffectGraphVisitor::BuildClosureCall( |
| void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitClosureCallNode"); |
| Do(BuildClosureCall(node)); |
| // Restore context from saved location. |
| BuildLoadContext(*owner()->parsed_function().expression_temp_var()); |
| @@ -1441,6 +1484,7 @@ void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| + InlineBailout("ValueGraphVisitor::VisitClosureCallNode"); |
| Value* result = Bind(BuildClosureCall(node)); |
| // Restore context from temp. |
| BuildLoadContext(*owner()->parsed_function().expression_temp_var()); |
| @@ -1449,6 +1493,7 @@ void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitCloneContextNode"); |
| Value* context = Bind(new CurrentContextComp()); |
| Value* clone = Bind(new CloneContextComp(node->token_pos(), context)); |
| ReturnComputation(new StoreContextComp(clone)); |
| @@ -1457,6 +1502,7 @@ void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| Value* EffectGraphVisitor::BuildObjectAllocation( |
| ConstructorCallNode* node) { |
| + InlineBailout("EffectGraphVisitor::BuildObjectAllocation"); |
| const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| const bool requires_type_arguments = cls.HasTypeArguments(); |
| @@ -1499,6 +1545,7 @@ Value* EffectGraphVisitor::BuildObjectAllocation( |
| void EffectGraphVisitor::BuildConstructorCall( |
| ConstructorCallNode* node, |
| PushArgumentInstr* push_alloc_value) { |
| + InlineBailout("EffectGraphVisitor::BuildConstructorCall"); |
| Value* ctor_arg = Bind( |
| new ConstantComp(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); |
| PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); |
| @@ -1517,6 +1564,7 @@ void EffectGraphVisitor::BuildConstructorCall( |
| void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitConstructorCallNode"); |
| if (node->constructor().IsFactory()) { |
| ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| new ZoneGrowableArray<PushArgumentInstr*>(); |
| @@ -1547,6 +1595,7 @@ void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| Value* EffectGraphVisitor::BuildInstantiator() { |
| + InlineBailout("EffectGraphVisitor::BuildInstantiator"); |
| const Class& instantiator_class = Class::Handle( |
| owner()->parsed_function().function().Owner()); |
| if (instantiator_class.NumTypeParameters() == 0) { |
| @@ -1573,6 +1622,7 @@ Value* EffectGraphVisitor::BuildInstantiator() { |
| // is not NULL. |
| Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| intptr_t token_pos, Value* instantiator) { |
| + InlineBailout("EffectGraphVisitor::BuildInstantiatorTypeArguments"); |
| const Class& instantiator_class = Class::Handle( |
| owner()->parsed_function().function().Owner()); |
| if (instantiator_class.NumTypeParameters() == 0) { |
| @@ -1623,6 +1673,7 @@ Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| intptr_t token_pos, |
| const AbstractTypeArguments& type_arguments) { |
| + InlineBailout("EffectGraphVisitor::BuildInstantiatedTypeArguments"); |
| if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| return Bind(new ConstantComp(type_arguments)); |
| } |
| @@ -1640,6 +1691,7 @@ void EffectGraphVisitor::BuildConstructorTypeArguments( |
| Value** type_arguments, |
| Value** instantiator, |
| ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { |
| + InlineBailout("EffectGraphVisitor::BuildConstructorTypeArguments"); |
| const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); |
| if (node->type_arguments().IsNull() || |
| @@ -1719,6 +1771,7 @@ void EffectGraphVisitor::BuildConstructorTypeArguments( |
| void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| + InlineBailout("ValueGraphVisitor::VisitConstructorCallNode"); |
| if (node->constructor().IsFactory()) { |
| EffectGraphVisitor::VisitConstructorCallNode(node); |
| return; |
| @@ -1747,6 +1800,7 @@ void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitConstructorCallNode"); |
| ValueGraphVisitor for_receiver(owner(), temp_index()); |
| node->receiver()->Visit(&for_receiver); |
| Append(for_receiver); |
| @@ -1767,6 +1821,7 @@ void EffectGraphVisitor::BuildInstanceSetterArguments( |
| InstanceSetterNode* node, |
| ZoneGrowableArray<PushArgumentInstr*>* arguments, |
| bool result_is_needed) { |
| + InlineBailout("EffectGraphVisitor::BuildInstanceSetterArguments"); |
| ValueGraphVisitor for_receiver(owner(), temp_index()); |
| node->receiver()->Visit(&for_receiver); |
| Append(for_receiver); |
| @@ -1789,6 +1844,7 @@ void EffectGraphVisitor::BuildInstanceSetterArguments( |
| void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitInstanceSetterNode"); |
| ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| new ZoneGrowableArray<PushArgumentInstr*>(2); |
| BuildInstanceSetterArguments(node, arguments, false); // Value not used. |
| @@ -1805,6 +1861,7 @@ void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| + InlineBailout("ValueGraphVisitor::VisitInstanceSetterNode"); |
| ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| new ZoneGrowableArray<PushArgumentInstr*>(2); |
| BuildInstanceSetterArguments(node, arguments, true); // Value used. |
| @@ -1822,6 +1879,7 @@ void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitStaticGetterNode"); |
| const String& getter_name = |
| String::Handle(Field::GetterName(node->field_name())); |
| ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| @@ -1851,6 +1909,7 @@ void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
| void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, |
| bool result_is_needed) { |
| + InlineBailout("EffectGraphVisitor::BuildStaticSetter"); |
| const String& setter_name = |
| String::Handle(Field::SetterName(node->field_name())); |
| // A super setter is an instance setter whose setter function is |
| @@ -1900,22 +1959,26 @@ void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, |
| void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitStaticSetterNode"); |
| BuildStaticSetter(node, false); // Result not needed. |
| } |
| void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| + InlineBailout("ValueGraphVisitor::VisitStaticSetterNode"); |
| BuildStaticSetter(node, true); // Result needed. |
| } |
| void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); |
| NativeCallComp* native_call = new NativeCallComp(node); |
| ReturnComputation(native_call); |
| } |
| void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitPrimaryNode"); |
| // PrimaryNodes are temporary during parsing. |
| UNREACHABLE(); |
| } |
| @@ -1923,6 +1986,7 @@ void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { |
| // <Expression> ::= LoadLocal { local: LocalVariable } |
| void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitLoadLocalNode"); |
| if (node->HasPseudo()) { |
| EffectGraphVisitor for_pseudo(owner(), temp_index()); |
| node->pseudo()->Visit(&for_pseudo); |
| @@ -1932,6 +1996,7 @@ void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| + InlineBailout("ValueGraphVisitor::VisitLoadLocalNode"); |
| EffectGraphVisitor::VisitLoadLocalNode(node); |
| Computation* load = BuildLoadLocal(node->local()); |
| ReturnComputation(load); |
| @@ -1941,6 +2006,7 @@ void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| // <Expression> ::= StoreLocal { local: LocalVariable |
| // value: <Expression> } |
| void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitStoreLocalNode"); |
| ValueGraphVisitor for_value(owner(), temp_index()); |
| node->value()->Visit(&for_value); |
| Append(for_value); |
| @@ -1958,6 +2024,7 @@ void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| LoadInstanceFieldNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitLoadInstanceFieldNode"); |
| ValueGraphVisitor for_instance(owner(), temp_index()); |
| node->instance()->Visit(&for_instance); |
| Append(for_instance); |
| @@ -1969,6 +2036,7 @@ void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| StoreInstanceFieldNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitStoreInstanceFieldNode"); |
| ValueGraphVisitor for_instance(owner(), temp_index()); |
| node->instance()->Visit(&for_instance); |
| Append(for_instance); |
| @@ -1993,17 +2061,20 @@ void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| // StoreInstanceFieldNode does not return result. |
| void ValueGraphVisitor::VisitStoreInstanceFieldNode( |
| StoreInstanceFieldNode* node) { |
| + InlineBailout("ValueGraphVisitor::VisitStoreInstanceFieldNode"); |
| UNIMPLEMENTED(); |
| } |
| void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitLoadStaticFieldNode"); |
| LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); |
| ReturnComputation(load); |
| } |
| void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitStoreStaticFieldNode"); |
| ValueGraphVisitor for_value(owner(), temp_index()); |
| node->value()->Visit(&for_value); |
| Append(for_value); |
| @@ -2023,6 +2094,7 @@ void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitLoadIndexedNode"); |
| ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| new ZoneGrowableArray<PushArgumentInstr*>(2); |
| ValueGraphVisitor for_array(owner(), temp_index()); |
| @@ -2051,6 +2123,7 @@ void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| Computation* EffectGraphVisitor::BuildStoreIndexedValues( |
| StoreIndexedNode* node, |
| bool result_is_needed) { |
| + InlineBailout("EffectGraphVisitor::BuildStoreIndexedValues"); |
| ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| new ZoneGrowableArray<PushArgumentInstr*>(3); |
| ValueGraphVisitor for_array(owner(), temp_index()); |
| @@ -2095,12 +2168,14 @@ Computation* EffectGraphVisitor::BuildStoreIndexedValues( |
| void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitStoreIndexedNode"); |
| ReturnComputation(BuildStoreIndexedValues(node, |
| false)); // Result not needed. |
| } |
| void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| + InlineBailout("ValueGraphVisitor::VisitStoreIndexedNode"); |
| ReturnComputation(BuildStoreIndexedValues(node, |
| true)); // Result is needed. |
| } |
| @@ -2113,6 +2188,7 @@ bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { |
| void EffectGraphVisitor::UnchainContext() { |
| + InlineBailout("EffectGraphVisitor::UnchainContext"); |
| Value* context = Bind(new CurrentContextComp()); |
| Value* parent = Bind( |
| new LoadVMFieldComp(context, |
| @@ -2131,6 +2207,7 @@ void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| (scope != NULL) ? scope->num_context_variables() : 0; |
| int previous_context_level = owner()->context_level(); |
| if (num_context_variables > 0) { |
| + InlineBailout("EffectGraphVisitor::VisitSequenceNode (captured vars)"); |
| // The loop local scope declares variables that are captured. |
| // Allocate and chain a new context. |
| // Allocate context computation (uses current CTX) |
| @@ -2189,6 +2266,7 @@ void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| if (FLAG_enable_type_checks && |
| (node == owner()->parsed_function().node_sequence())) { |
| + InlineBailout("EffectGraphVisitor::VisitSequenceNode (type check)"); |
| const Function& function = owner()->parsed_function().function(); |
| const int num_params = function.NumberOfParameters(); |
| int pos = 0; |
| @@ -2262,6 +2340,7 @@ void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitCatchClauseNode"); |
| // NOTE: The implicit variables ':saved_context', ':exception_var' |
| // and ':stacktrace_var' can never be captured variables. |
| // Restores CTX from local variable ':saved_context'. |
| @@ -2275,6 +2354,7 @@ void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
| void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitTryCatchNode"); |
| intptr_t old_try_index = owner()->try_index(); |
| intptr_t try_index = owner()->AllocateTryIndex(); |
| owner()->set_try_index(try_index); |
| @@ -2332,6 +2412,7 @@ void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { |
| + InlineBailout("EffectGraphVisitor::BuildThrowNode"); |
| ValueGraphVisitor for_exception(owner(), temp_index()); |
| node->exception()->Visit(&for_exception); |
| Append(for_exception); |
| @@ -2351,6 +2432,7 @@ void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { |
| void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitThrowNode"); |
| BuildThrowNode(node); |
| CloseFragment(); |
| } |
| @@ -2360,12 +2442,14 @@ void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| // certain expression nodes with a throw. In that case generate a literal null |
| // so that the fragment is not closed in the middle of an expression. |
| void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| + InlineBailout("ValueGraphVisitor::VisitThrowNode"); |
| BuildThrowNode(node); |
| ReturnComputation(new ConstantComp(Instance::ZoneHandle())); |
| } |
| void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
| + InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode"); |
| const intptr_t try_index = owner()->try_index(); |
| if (try_index >= 0) { |
| // We are about to generate code for an inlined finally block. Exceptions |
| @@ -2417,6 +2501,23 @@ FlowGraph* FlowGraphBuilder::BuildGraph() { |
| } |
| +FlowGraph* FlowGraphBuilder::BuildGraphForInlining(InliningContext context) { |
|
srdjan
2012/09/05 17:40:05
You may want to print the AST if you have succeede
zerny-google
2012/09/07 14:08:43
That is done in flow_graph_inliner.cc after it has
|
| + ASSERT(inlining_context_ == kNotInlining); |
| + inlining_context_ = context; |
| + exits_ = new ZoneGrowableArray<ReturnInstr*>(); |
| + TargetEntryInstr* normal_entry = new TargetEntryInstr( |
| + CatchClauseNode::kInvalidTryIndex); |
| + graph_entry_ = new GraphEntryInstr(normal_entry); |
| + EffectGraphVisitor for_effect(this, 0); |
| + parsed_function().node_sequence()->Visit(&for_effect); |
| + AppendFragment(normal_entry, for_effect); |
| + ASSERT(!for_effect.is_open()); |
| + FlowGraph* graph = new FlowGraph(*this, graph_entry_); |
| + graph->set_exits(exits_); |
| + return graph; |
| +} |
| + |
| + |
| void FlowGraphBuilder::Bailout(const char* reason) { |
| const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; |
| const char* function_name = parsed_function_.function().ToCString(); |