| Index: runtime/vm/flow_graph_builder.cc
|
| diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
|
| index 876f96cac06bb461525ad0abbe91c16b2886550d..df9ea5437d446060a1144ade21d1579995486fea 100644
|
| --- a/runtime/vm/flow_graph_builder.cc
|
| +++ b/runtime/vm/flow_graph_builder.cc
|
| @@ -66,6 +66,7 @@ void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) {
|
|
|
| Value* EffectGraphVisitor::Bind(Definition* definition) {
|
| ASSERT(is_open());
|
| + ASSERT(!owner()->InInliningContext() || !definition->CanDeoptimize());
|
| DeallocateTempIndex(definition->InputCount());
|
| definition->set_use_kind(Definition::kValue);
|
| definition->set_temp_index(AllocateTempIndex());
|
| @@ -81,6 +82,7 @@ Value* EffectGraphVisitor::Bind(Definition* definition) {
|
|
|
| void EffectGraphVisitor::Do(Definition* definition) {
|
| ASSERT(is_open());
|
| + ASSERT(!owner()->InInliningContext() || !definition->CanDeoptimize());
|
| DeallocateTempIndex(definition->InputCount());
|
| definition->set_use_kind(Definition::kEffect);
|
| if (is_empty()) {
|
| @@ -229,6 +231,7 @@ Definition* EffectGraphVisitor::BuildLoadExprTemp() {
|
| Definition* EffectGraphVisitor::BuildStoreLocal(
|
| const LocalVariable& local, Value* value, bool result_is_needed) {
|
| if (local.is_captured()) {
|
| + InlineBailout("EffectGraphVisitor::BuildStoreLocal (context)");
|
| if (result_is_needed) {
|
| value = Bind(BuildStoreExprTemp(value));
|
| }
|
| @@ -261,6 +264,7 @@ Definition* EffectGraphVisitor::BuildStoreLocal(
|
|
|
| Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) {
|
| if (local.is_captured()) {
|
| + InlineBailout("EffectGraphVisitor::BuildLoadLocal (context)");
|
| intptr_t delta =
|
| owner()->context_level() - local.owner()->context_level();
|
| ASSERT(delta >= 0);
|
| @@ -476,7 +480,6 @@ 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() &&
|
| @@ -541,7 +544,6 @@ 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());
|
|
|
| @@ -589,13 +591,11 @@ 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);
|
| @@ -610,7 +610,6 @@ 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)) {
|
| @@ -629,6 +628,7 @@ void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
|
| }
|
| return;
|
| }
|
| + InlineBailout("EffectGraphVisitor::VisitBinaryOpNode (deopt)");
|
| ValueGraphVisitor for_left_value(owner(), temp_index());
|
| node->left()->Visit(&for_left_value);
|
| Append(for_left_value);
|
| @@ -656,7 +656,6 @@ 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)) {
|
| @@ -676,6 +675,7 @@ void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
|
| node->right()->Visit(&for_right);
|
| Value* right_value = for_right.value();
|
| if (FLAG_enable_type_checks) {
|
| + InlineBailout("ValueGraphVisitor::VisitBinaryOpNode (type check)");
|
| right_value =
|
| for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(),
|
| right_value));
|
| @@ -710,7 +710,6 @@ 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(
|
| @@ -736,7 +735,6 @@ void EffectGraphVisitor::BuildTypecheckArguments(
|
|
|
|
|
| Value* EffectGraphVisitor::BuildNullValue() {
|
| - InlineBailout("EffectGraphVisitor::BuildNullValue");
|
| return Bind(new ConstantInstr(Object::ZoneHandle()));
|
| }
|
|
|
| @@ -747,7 +745,7 @@ AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable(
|
| Value* value,
|
| const AbstractType& dst_type,
|
| const String& dst_name) {
|
| - InlineBailout("EffectGraphVisitor::BuildAssertAssignable");
|
| + InlineBailout("EffectGraphVisitor::BuildAssertAssignable (deopt)");
|
| // Build the type check computation.
|
| Value* instantiator = NULL;
|
| Value* instantiator_type_arguments = NULL;
|
| @@ -773,7 +771,6 @@ 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;
|
| }
|
| @@ -782,7 +779,6 @@ 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);
|
| @@ -791,7 +787,6 @@ 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.
|
| @@ -808,7 +803,6 @@ 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());
|
| @@ -849,6 +843,7 @@ void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) {
|
| ReturnDefinition(result);
|
| return;
|
| }
|
| + InlineBailout("ValueGraphVisitor::BuildTypeTest (deopt)");
|
|
|
| ValueGraphVisitor for_left_value(owner(), temp_index());
|
| node->left()->Visit(&for_left_value);
|
| @@ -875,7 +870,6 @@ 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.
|
| @@ -896,7 +890,6 @@ 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;
|
| @@ -918,6 +911,7 @@ void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
|
| ReturnDefinition(comp);
|
| return;
|
| }
|
| + InlineBailout("EffectGraphVisitor::VisitComparisonNode (deopt)");
|
|
|
| if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) {
|
| ValueGraphVisitor for_left_value(owner(), temp_index());
|
| @@ -965,7 +959,6 @@ 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());
|
| @@ -980,6 +973,8 @@ void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
|
| ReturnDefinition(negate);
|
| return;
|
| }
|
| + InlineBailout("EffectGraphVisitor::VisitUnaryOpNode (deopt)");
|
| +
|
| ValueGraphVisitor for_value(owner(), temp_index());
|
| node->operand()->Visit(&for_value);
|
| Append(for_value);
|
| @@ -1001,7 +996,6 @@ void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
|
|
|
|
|
| void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitConditionalExprNode");
|
| TestGraphVisitor for_test(owner(),
|
| temp_index(),
|
| node->condition()->token_pos());
|
| @@ -1018,7 +1012,6 @@ void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
|
|
|
|
|
| void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
|
| - InlineBailout("ValueGraphVisitor::VisitConditionalExprNode");
|
| TestGraphVisitor for_test(owner(),
|
| temp_index(),
|
| node->condition()->token_pos());
|
| @@ -1060,7 +1053,6 @@ 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);
|
| @@ -1405,7 +1397,6 @@ void EffectGraphVisitor::VisitJumpNode(JumpNode* node) {
|
|
|
|
|
| void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitArgumentListNode");
|
| UNREACHABLE();
|
| }
|
|
|
| @@ -1421,7 +1412,6 @@ void EffectGraphVisitor::VisitArgumentDefinitionTestNode(
|
|
|
|
|
| void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitArrayNode");
|
| // Translate the array elements and collect their values.
|
| ZoneGrowableArray<PushArgumentInstr*>* arguments =
|
| new ZoneGrowableArray<PushArgumentInstr*>(node->length());
|
| @@ -1444,7 +1434,6 @@ void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
|
|
|
|
|
| void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitClosureNode");
|
| const Function& function = node->function();
|
|
|
| Value* receiver = NULL;
|
| @@ -1495,7 +1484,6 @@ 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);
|
| @@ -1508,7 +1496,6 @@ 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);
|
| @@ -1520,7 +1507,7 @@ void EffectGraphVisitor::BuildPushArguments(
|
|
|
|
|
| void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitInstanceCallNode");
|
| + InlineBailout("EffectGraphVisitor::VisitInstanceCallNode (deopt)");
|
| ValueGraphVisitor for_receiver(owner(), temp_index());
|
| node->receiver()->Visit(&for_receiver);
|
| Append(for_receiver);
|
| @@ -1542,7 +1529,7 @@ void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
|
| // <Expression> ::= StaticCall { function: Function
|
| // arguments: <ArgumentList> }
|
| void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitStaticCallNode");
|
| + InlineBailout("EffectGraphVisitor::VisitStaticCallNode (deopt)");
|
| ZoneGrowableArray<PushArgumentInstr*>* arguments =
|
| new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
|
| BuildPushArguments(*node->arguments(), arguments);
|
| @@ -1557,7 +1544,7 @@ void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
|
|
|
| ClosureCallInstr* EffectGraphVisitor::BuildClosureCall(
|
| ClosureCallNode* node) {
|
| - InlineBailout("EffectGraphVisitor::BuildClosureCall");
|
| + InlineBailout("EffectGraphVisitor::BuildClosureCall (deopt)");
|
| ValueGraphVisitor for_closure(owner(), temp_index());
|
| node->closure()->Visit(&for_closure);
|
| Append(for_closure);
|
| @@ -1575,7 +1562,6 @@ ClosureCallInstr* 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());
|
| @@ -1583,7 +1569,6 @@ 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());
|
| @@ -1592,7 +1577,7 @@ void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
|
|
|
|
|
| void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitCloneContextNode");
|
| + InlineBailout("EffectGraphVisitor::VisitCloneContextNode (deopt)");
|
| Value* context = Bind(new CurrentContextInstr());
|
| Value* clone = Bind(new CloneContextInstr(node->token_pos(), context));
|
| ReturnDefinition(new StoreContextInstr(clone));
|
| @@ -1601,7 +1586,6 @@ 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();
|
|
|
| @@ -1624,6 +1608,7 @@ Value* EffectGraphVisitor::BuildObjectAllocation(
|
| // Although the type arguments may be uninstantiated at compile time, they
|
| // may represent the identity vector and may be replaced by the instantiated
|
| // type arguments of the instantiator at run time.
|
| + InlineBailout("EffectGraphVisitor::BuildObjectAllocation (deopt)");
|
| allocate_comp = new AllocateObjectWithBoundsCheckInstr(node,
|
| type_arguments,
|
| instantiator);
|
| @@ -1644,7 +1629,7 @@ Value* EffectGraphVisitor::BuildObjectAllocation(
|
| void EffectGraphVisitor::BuildConstructorCall(
|
| ConstructorCallNode* node,
|
| PushArgumentInstr* push_alloc_value) {
|
| - InlineBailout("EffectGraphVisitor::BuildConstructorCall");
|
| + InlineBailout("EffectGraphVisitor::BuildConstructorCall (deopt)");
|
| Value* ctor_arg = Bind(
|
| new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))));
|
| PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg);
|
| @@ -1663,8 +1648,8 @@ void EffectGraphVisitor::BuildConstructorCall(
|
|
|
|
|
| void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitConstructorCallNode");
|
| if (node->constructor().IsFactory()) {
|
| + InlineBailout("EffectGraphVisitor::VisitConstructorCallNode (deopt)");
|
| ZoneGrowableArray<PushArgumentInstr*>* arguments =
|
| new ZoneGrowableArray<PushArgumentInstr*>();
|
| PushArgumentInstr* push_type_arguments = PushArgument(
|
| @@ -1694,7 +1679,6 @@ 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) {
|
| @@ -1721,7 +1705,6 @@ 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) {
|
| @@ -1762,6 +1745,7 @@ Value* EffectGraphVisitor::BuildInstantiatorTypeArguments(
|
| instantiator_class.type_arguments_instance_field_offset();
|
| ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments);
|
|
|
| + InlineBailout("EffectGraphVisitor::BuildInstantiatorTypeArguments (deopt)");
|
| return Bind(new LoadVMFieldInstr(
|
| instantiator,
|
| type_arguments_instance_field_offset,
|
| @@ -1772,10 +1756,10 @@ 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 ConstantInstr(type_arguments));
|
| }
|
| + InlineBailout("EffectGraphVisitor::BuildInstantiatedTypeArguments (deopt)");
|
| // The type arguments are uninstantiated.
|
| Value* instantiator_value =
|
| BuildInstantiatorTypeArguments(token_pos, NULL);
|
| @@ -1790,7 +1774,6 @@ 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() ||
|
| @@ -1869,7 +1852,6 @@ void EffectGraphVisitor::BuildConstructorTypeArguments(
|
|
|
|
|
| void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
|
| - InlineBailout("ValueGraphVisitor::VisitConstructorCallNode");
|
| if (node->constructor().IsFactory()) {
|
| EffectGraphVisitor::VisitConstructorCallNode(node);
|
| return;
|
| @@ -1897,7 +1879,7 @@ void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
|
|
|
|
|
| void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitConstructorCallNode");
|
| + InlineBailout("EffectGraphVisitor::VisitInstanceGetterNode (deopt)");
|
| ValueGraphVisitor for_receiver(owner(), temp_index());
|
| node->receiver()->Visit(&for_receiver);
|
| Append(for_receiver);
|
| @@ -1918,7 +1900,6 @@ 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);
|
| @@ -1939,7 +1920,7 @@ void EffectGraphVisitor::BuildInstanceSetterArguments(
|
|
|
|
|
| void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitInstanceSetterNode");
|
| + InlineBailout("EffectGraphVisitor::VisitInstanceSetterNode (deopt)");
|
| ZoneGrowableArray<PushArgumentInstr*>* arguments =
|
| new ZoneGrowableArray<PushArgumentInstr*>(2);
|
| BuildInstanceSetterArguments(node, arguments, kResultNotNeeded);
|
| @@ -1956,7 +1937,7 @@ void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
|
|
|
|
|
| void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
|
| - InlineBailout("ValueGraphVisitor::VisitInstanceSetterNode");
|
| + InlineBailout("ValueGraphVisitor::VisitInstanceSetterNode (deopt)");
|
| ZoneGrowableArray<PushArgumentInstr*>* arguments =
|
| new ZoneGrowableArray<PushArgumentInstr*>(2);
|
| BuildInstanceSetterArguments(node, arguments, kResultNeeded);
|
| @@ -1973,7 +1954,7 @@ void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
|
|
|
|
|
| void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitStaticGetterNode");
|
| + InlineBailout("EffectGraphVisitor::VisitStaticGetterNode (deopt)");
|
| const String& getter_name =
|
| String::Handle(Field::GetterName(node->field_name()));
|
| ZoneGrowableArray<PushArgumentInstr*>* arguments =
|
| @@ -2003,7 +1984,7 @@ void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
|
|
|
| void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node,
|
| bool result_is_needed) {
|
| - InlineBailout("EffectGraphVisitor::BuildStaticSetter");
|
| + InlineBailout("EffectGraphVisitor::VisitStaticSetter (deopt)");
|
| const String& setter_name =
|
| String::Handle(Field::SetterName(node->field_name()));
|
| // A super setter is an instance setter whose setter function is
|
| @@ -2050,13 +2031,11 @@ 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.
|
| }
|
|
|
| @@ -2069,7 +2048,6 @@ void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
|
|
|
|
|
| void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitPrimaryNode");
|
| // PrimaryNodes are temporary during parsing.
|
| UNREACHABLE();
|
| }
|
| @@ -2077,7 +2055,6 @@ 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);
|
| @@ -2087,7 +2064,6 @@ void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
|
|
|
|
|
| void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
|
| - InlineBailout("ValueGraphVisitor::VisitLoadLocalNode");
|
| EffectGraphVisitor::VisitLoadLocalNode(node);
|
| Definition* load = BuildLoadLocal(node->local());
|
| ReturnDefinition(load);
|
| @@ -2098,7 +2074,6 @@ void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
|
| // value: <Expression> }
|
| void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node,
|
| bool result_is_needed) {
|
| - InlineBailout("EffectGraphVisitor::VisitStoreLocalNode");
|
| ValueGraphVisitor for_value(owner(), temp_index());
|
| node->value()->Visit(&for_value);
|
| Append(for_value);
|
| @@ -2128,7 +2103,6 @@ void ValueGraphVisitor::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);
|
| @@ -2140,7 +2114,6 @@ 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);
|
| @@ -2165,13 +2138,11 @@ 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");
|
| LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field());
|
| ReturnDefinition(load);
|
| }
|
| @@ -2179,7 +2150,6 @@ void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
|
|
|
| Definition* EffectGraphVisitor::BuildStoreStaticField(
|
| StoreStaticFieldNode* node, bool result_is_needed) {
|
| - InlineBailout("EffectGraphVisitor::VisitStoreStaticFieldNode");
|
| ValueGraphVisitor for_value(owner(), temp_index());
|
| node->value()->Visit(&for_value);
|
| Append(for_value);
|
| @@ -2220,7 +2190,7 @@ void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
|
|
|
|
|
| void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitLoadIndexedNode");
|
| + InlineBailout("EffectGraphVisitor::VisitLoadIndexedNode (deopt)");
|
| ZoneGrowableArray<PushArgumentInstr*>* arguments =
|
| new ZoneGrowableArray<PushArgumentInstr*>(2);
|
| ValueGraphVisitor for_array(owner(), temp_index());
|
| @@ -2249,7 +2219,7 @@ void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
|
| Definition* EffectGraphVisitor::BuildStoreIndexedValues(
|
| StoreIndexedNode* node,
|
| bool result_is_needed) {
|
| - InlineBailout("EffectGraphVisitor::BuildStoreIndexedValues");
|
| + InlineBailout("EffectGraphVisitor::BuildStoreIndexedValues (deopt)");
|
| ZoneGrowableArray<PushArgumentInstr*>* arguments =
|
| new ZoneGrowableArray<PushArgumentInstr*>(3);
|
| ValueGraphVisitor for_array(owner(), temp_index());
|
| @@ -2292,13 +2262,11 @@ Definition* EffectGraphVisitor::BuildStoreIndexedValues(
|
|
|
|
|
| void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitStoreIndexedNode");
|
| ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded));
|
| }
|
|
|
|
|
| void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
|
| - InlineBailout("ValueGraphVisitor::VisitStoreIndexedNode");
|
| ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded));
|
| }
|
|
|
| @@ -2310,7 +2278,7 @@ bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const {
|
|
|
|
|
| void EffectGraphVisitor::UnchainContext() {
|
| - InlineBailout("EffectGraphVisitor::UnchainContext");
|
| + InlineBailout("EffectGraphVisitor::UnchainContext (deopt)");
|
| Value* context = Bind(new CurrentContextInstr());
|
| Value* parent = Bind(
|
| new LoadVMFieldInstr(context,
|
| @@ -2329,7 +2297,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)");
|
| + InlineBailout("EffectGraphVisitor::VisitSequenceNode (deopt)");
|
| // The loop local scope declares variables that are captured.
|
| // Allocate and chain a new context.
|
| // Allocate context computation (uses current CTX)
|
| @@ -2394,7 +2362,6 @@ 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;
|
| @@ -2540,7 +2507,6 @@ 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);
|
| @@ -2560,7 +2526,6 @@ void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) {
|
|
|
|
|
| void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) {
|
| - InlineBailout("EffectGraphVisitor::VisitThrowNode");
|
| BuildThrowNode(node);
|
| CloseFragment();
|
| }
|
| @@ -2570,7 +2535,6 @@ 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);
|
| ReturnDefinition(new ConstantInstr(Instance::ZoneHandle()));
|
| }
|
| @@ -2607,11 +2571,15 @@ void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
|
| }
|
|
|
|
|
| -FlowGraph* FlowGraphBuilder::BuildGraph() {
|
| +FlowGraph* FlowGraphBuilder::BuildGraph(InliningContext context) {
|
| if (FLAG_print_ast) {
|
| // Print the function ast before IL generation.
|
| AstPrinter::PrintFunctionNodes(parsed_function());
|
| }
|
| + // Set the inlining context.
|
| + ASSERT(inlining_context_ == kNotInlining);
|
| + inlining_context_ = context;
|
| + if (InInliningContext()) exits_ = new ZoneGrowableArray<ReturnInstr*>();
|
| // Compilation can be nested, preserve the computation-id.
|
| const Function& function = parsed_function().function();
|
| TargetEntryInstr* normal_entry = new TargetEntryInstr(
|
| @@ -2625,23 +2593,8 @@ FlowGraph* FlowGraphBuilder::BuildGraph() {
|
| AppendFragment(normal_entry, for_effect);
|
| // Check that the graph is properly terminated.
|
| ASSERT(!for_effect.is_open());
|
| - return new FlowGraph(*this, graph_entry_);
|
| -}
|
| -
|
| -
|
| -FlowGraph* FlowGraphBuilder::BuildGraphForInlining(InliningContext context) {
|
| - 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_);
|
| + if (InInliningContext()) graph->set_exits(exits_);
|
| return graph;
|
| }
|
|
|
|
|