diff options
Diffstat (limited to 'deps/v8/src/compiler/js-inlining-heuristic.cc')
-rw-r--r-- | deps/v8/src/compiler/js-inlining-heuristic.cc | 62 |
1 files changed, 25 insertions, 37 deletions
diff --git a/deps/v8/src/compiler/js-inlining-heuristic.cc b/deps/v8/src/compiler/js-inlining-heuristic.cc index 588626e292..413cd2fc6b 100644 --- a/deps/v8/src/compiler/js-inlining-heuristic.cc +++ b/deps/v8/src/compiler/js-inlining-heuristic.cc @@ -23,11 +23,15 @@ namespace compiler { namespace { int CollectFunctions(Node* node, Handle<JSFunction>* functions, - int functions_size, Handle<SharedFunctionInfo>& shared) { + Handle<BytecodeArray>* bytecode, int functions_size, + Handle<SharedFunctionInfo>& shared, Isolate* isolate) { DCHECK_NE(0, functions_size); HeapObjectMatcher m(node); if (m.HasValue() && m.Value()->IsJSFunction()) { functions[0] = Handle<JSFunction>::cast(m.Value()); + if (functions[0]->shared()->HasBytecodeArray()) { + bytecode[0] = handle(functions[0]->shared()->GetBytecodeArray(), isolate); + } return 1; } if (m.IsPhi()) { @@ -37,6 +41,10 @@ int CollectFunctions(Node* node, Handle<JSFunction>* functions, HeapObjectMatcher m(node->InputAt(n)); if (!m.HasValue() || !m.Value()->IsJSFunction()) return 0; functions[n] = Handle<JSFunction>::cast(m.Value()); + if (functions[n]->shared()->HasBytecodeArray()) { + bytecode[n] = + handle(functions[n]->shared()->GetBytecodeArray(), isolate); + } } return value_input_count; } @@ -44,36 +52,19 @@ int CollectFunctions(Node* node, Handle<JSFunction>* functions, CreateClosureParameters const& p = CreateClosureParametersOf(m.op()); functions[0] = Handle<JSFunction>::null(); shared = p.shared_info(); + if (shared->HasBytecodeArray()) { + bytecode[0] = handle(shared->GetBytecodeArray(), isolate); + } return 1; } return 0; } -bool CanInlineFunction(Handle<SharedFunctionInfo> shared) { - // Built-in functions are handled by the JSCallReducer. - if (shared->HasBuiltinFunctionId()) return false; - - // Only choose user code for inlining. - if (!shared->IsUserJavaScript()) return false; - - // If there is no bytecode array, it is either not compiled or it is compiled - // with WebAssembly for the asm.js pipeline. In either case we don't want to - // inline. - if (!shared->HasBytecodeArray()) return false; - - // Quick check on the size of the bytecode to avoid inlining large functions. - if (shared->GetBytecodeArray()->length() > FLAG_max_inlined_bytecode_size) { - return false; - } - - return true; -} - -bool IsSmallInlineFunction(Handle<SharedFunctionInfo> shared) { +bool IsSmallInlineFunction(Handle<BytecodeArray> bytecode) { // Forcibly inline small functions. // Don't forcibly inline functions that weren't compiled yet. - if (shared->HasBytecodeArray() && shared->GetBytecodeArray()->length() <= - FLAG_max_inlined_bytecode_size_small) { + if (!bytecode.is_null() && + bytecode->length() <= FLAG_max_inlined_bytecode_size_small) { return true; } return false; @@ -92,8 +83,9 @@ Reduction JSInliningHeuristic::Reduce(Node* node) { Node* callee = node->InputAt(0); Candidate candidate; candidate.node = node; - candidate.num_functions = CollectFunctions( - callee, candidate.functions, kMaxCallPolymorphism, candidate.shared_info); + candidate.num_functions = + CollectFunctions(callee, candidate.functions, candidate.bytecode, + kMaxCallPolymorphism, candidate.shared_info, isolate()); if (candidate.num_functions == 0) { return NoChange(); } else if (candidate.num_functions > 1 && !FLAG_polymorphic_inlining) { @@ -114,7 +106,7 @@ Reduction JSInliningHeuristic::Reduce(Node* node) { candidate.functions[i].is_null() ? candidate.shared_info : handle(candidate.functions[i]->shared(), isolate()); - candidate.can_inline_function[i] = CanInlineFunction(shared); + candidate.can_inline_function[i] = shared->IsInlineable(); // Do not allow direct recursion i.e. f() -> f(). We still allow indirect // recurion like f() -> g() -> f(). The indirect recursion is helpful in // cases where f() is a small dispatch function that calls the appropriate @@ -130,11 +122,12 @@ Reduction JSInliningHeuristic::Reduce(Node* node) { node->id(), node->op()->mnemonic()); candidate.can_inline_function[i] = false; } + Handle<BytecodeArray> bytecode = candidate.bytecode[i]; if (candidate.can_inline_function[i]) { can_inline = true; - candidate.total_size += shared->GetBytecodeArray()->length(); + candidate.total_size += bytecode->length(); } - if (!IsSmallInlineFunction(shared)) { + if (!IsSmallInlineFunction(bytecode)) { small_inline = false; } } @@ -604,13 +597,9 @@ Reduction JSInliningHeuristic::InlineCandidate(Candidate const& candidate, int const num_calls = candidate.num_functions; Node* const node = candidate.node; if (num_calls == 1) { - Handle<SharedFunctionInfo> shared = - candidate.functions[0].is_null() - ? candidate.shared_info - : handle(candidate.functions[0]->shared(), isolate()); Reduction const reduction = inliner_.ReduceJSCall(node); if (reduction.Changed()) { - cumulative_count_ += shared->GetBytecodeArray()->length(); + cumulative_count_ += candidate.bytecode[0]->length(); } return reduction; } @@ -669,7 +658,6 @@ Reduction JSInliningHeuristic::InlineCandidate(Candidate const& candidate, // Inline the individual, cloned call sites. for (int i = 0; i < num_calls; ++i) { - Handle<JSFunction> function = candidate.functions[i]; Node* node = calls[i]; if (small_function || (candidate.can_inline_function[i] && @@ -679,7 +667,7 @@ Reduction JSInliningHeuristic::InlineCandidate(Candidate const& candidate, // Killing the call node is not strictly necessary, but it is safer to // make sure we do not resurrect the node. node->Kill(); - cumulative_count_ += function->shared()->GetBytecodeArray()->length(); + cumulative_count_ += candidate.bytecode[i]->length(); } } } @@ -720,7 +708,7 @@ void JSInliningHeuristic::PrintCandidates() { candidate.functions[i].is_null() ? candidate.shared_info : handle(candidate.functions[i]->shared(), isolate()); - PrintF(" - size:%d, name: %s\n", shared->GetBytecodeArray()->length(), + PrintF(" - size:%d, name: %s\n", candidate.bytecode[i]->length(), shared->DebugName()->ToCString().get()); } } |