Index: src/compiler/js-inlining.cc |
diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc |
index 03f8480dbba249a5954c7f259ca84a236041cb26..9efa4c1fb13a50b08836e5eebdc969f4a8fbd2e2 100644 |
--- a/src/compiler/js-inlining.cc |
+++ b/src/compiler/js-inlining.cc |
@@ -25,28 +25,57 @@ namespace v8 { |
namespace internal { |
namespace compiler { |
-class InlinerVisitor : public NullNodeVisitor { |
+ |
+// Provides convenience accessors for calls to JS functions. |
+class JSCallFunctionAccessor { |
public: |
- explicit InlinerVisitor(JSInliner* inliner) : inliner_(inliner) {} |
+ explicit JSCallFunctionAccessor(Node* call) : call_(call) { |
+ DCHECK_EQ(IrOpcode::kJSCallFunction, call->opcode()); |
+ } |
- void Post(Node* node) { |
- switch (node->opcode()) { |
- case IrOpcode::kJSCallFunction: |
- inliner_->TryInlineJSCall(node); |
- break; |
- default: |
- break; |
- } |
+ Node* jsfunction() { return call_->InputAt(0); } |
+ |
+ Node* receiver() { return call_->InputAt(1); } |
+ |
+ Node* formal_argument(size_t index) { |
+ DCHECK(index < formal_arguments()); |
+ return call_->InputAt(static_cast<int>(2 + index)); |
} |
+ size_t formal_arguments() { |
+ // {value_inputs} includes jsfunction and receiver. |
+ size_t value_inputs = call_->op()->ValueInputCount(); |
+ DCHECK_GE(call_->InputCount(), 2); |
+ return value_inputs - 2; |
+ } |
+ |
+ Node* frame_state() { return NodeProperties::GetFrameStateInput(call_); } |
+ |
private: |
- JSInliner* inliner_; |
+ Node* call_; |
}; |
-void JSInliner::Inline() { |
- InlinerVisitor visitor(this); |
- jsgraph_->graph()->VisitNodeInputsFromEnd(&visitor); |
+Reduction JSInliner::Reduce(Node* node) { |
+ if (node->opcode() != IrOpcode::kJSCallFunction) return NoChange(); |
+ |
+ JSCallFunctionAccessor call(node); |
+ HeapObjectMatcher<JSFunction> match(call.jsfunction()); |
+ if (!match.HasValue()) return NoChange(); |
+ |
+ Handle<JSFunction> jsfunction = match.Value().handle(); |
+ |
+ if (jsfunction->shared()->native()) { |
+ if (FLAG_trace_turbo_inlining) { |
+ SmartArrayPointer<char> name = |
+ jsfunction->shared()->DebugName()->ToCString(); |
+ PrintF("Not Inlining %s into %s because inlinee is native\n", name.get(), |
+ info_->shared_info()->DebugName()->ToCString().get()); |
+ } |
+ return NoChange(); |
+ } |
+ |
+ return TryInlineJSCall(node, jsfunction); |
} |
@@ -89,7 +118,7 @@ class Inlinee { |
// Inline this graph at {call}, use {jsgraph} and its zone to create |
// any new nodes. |
- void InlineAtCall(JSGraph* jsgraph, Node* call); |
+ Reduction InlineAtCall(JSGraph* jsgraph, Node* call); |
// Ensure that only a single return reaches the end node. |
static void UnifyReturn(JSGraph* jsgraph); |
@@ -213,7 +242,7 @@ class CopyVisitor : public NullNodeVisitor { |
}; |
-void Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) { |
+Reduction Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) { |
// The scheduler is smart enough to place our code; we just ensure {control} |
// becomes the control input of the start of the inlinee. |
Node* control = NodeProperties::GetControlInput(call); |
@@ -267,42 +296,10 @@ void Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) { |
} |
NodeProperties::ReplaceWithValue(call, value_output(), effect_output()); |
- call->RemoveAllInputs(); |
- DCHECK_EQ(0, call->UseCount()); |
+ return Reducer::Replace(value_output()); |
} |
-// TODO(turbofan) Provide such accessors for every node, possibly even |
-// generate them. |
-class JSCallFunctionAccessor { |
- public: |
- explicit JSCallFunctionAccessor(Node* call) : call_(call) { |
- DCHECK_EQ(IrOpcode::kJSCallFunction, call->opcode()); |
- } |
- |
- Node* jsfunction() { return call_->InputAt(0); } |
- |
- Node* receiver() { return call_->InputAt(1); } |
- |
- Node* formal_argument(size_t index) { |
- DCHECK(index < formal_arguments()); |
- return call_->InputAt(static_cast<int>(2 + index)); |
- } |
- |
- size_t formal_arguments() { |
- // {value_inputs} includes jsfunction and receiver. |
- size_t value_inputs = call_->op()->ValueInputCount(); |
- DCHECK_GE(call_->InputCount(), 2); |
- return value_inputs - 2; |
- } |
- |
- Node* frame_state() { return NodeProperties::GetFrameStateInput(call_); } |
- |
- private: |
- Node* call_; |
-}; |
- |
- |
void JSInliner::AddClosureToFrameState(Node* frame_state, |
Handle<JSFunction> jsfunction) { |
FrameStateCallInfo call_info = OpParameter<FrameStateCallInfo>(frame_state); |
@@ -336,30 +333,13 @@ Node* JSInliner::CreateArgumentsAdaptorFrameState(JSCallFunctionAccessor* call, |
} |
-void JSInliner::TryInlineJSCall(Node* call_node) { |
+Reduction JSInliner::TryInlineJSCall(Node* call_node, |
+ Handle<JSFunction> function) { |
JSCallFunctionAccessor call(call_node); |
- |
- HeapObjectMatcher<JSFunction> match(call.jsfunction()); |
- if (!match.HasValue()) { |
- return; |
- } |
- |
- Handle<JSFunction> function = match.Value().handle(); |
- |
- if (function->shared()->native()) { |
- if (FLAG_trace_turbo_inlining) { |
- SmartArrayPointer<char> name = |
- function->shared()->DebugName()->ToCString(); |
- PrintF("Not Inlining %s into %s because inlinee is native\n", name.get(), |
- info_->shared_info()->DebugName()->ToCString().get()); |
- } |
- return; |
- } |
- |
CompilationInfoWithZone info(function); |
- // TODO(wingo): ParseAndAnalyze can fail due to stack overflow. |
- CHECK(Compiler::ParseAndAnalyze(&info)); |
- CHECK(Compiler::EnsureDeoptimizationSupport(&info)); |
+ |
+ if (!Compiler::ParseAndAnalyze(&info)) return NoChange(); |
+ if (!Compiler::EnsureDeoptimizationSupport(&info)) return NoChange(); |
if (info.scope()->arguments() != NULL && is_sloppy(info.language_mode())) { |
// For now do not inline functions that use their arguments array. |
@@ -370,7 +350,7 @@ void JSInliner::TryInlineJSCall(Node* call_node) { |
"array\n", |
name.get(), info_->shared_info()->DebugName()->ToCString().get()); |
} |
- return; |
+ return NoChange(); |
} |
if (FLAG_trace_turbo_inlining) { |
@@ -408,7 +388,7 @@ void JSInliner::TryInlineJSCall(Node* call_node) { |
} |
} |
- inlinee.InlineAtCall(jsgraph_, call_node); |
+ return inlinee.InlineAtCall(jsgraph_, call_node); |
} |
} // namespace compiler |