Commit 14ba9c3d authored by jarin's avatar jarin Committed by Commit bot

Introduce a reference to the code object of inlined functions in CompilationInfo.

The newly introduced root makes sure that we do not flush the
optimized code while the function is being compiled.

BUG=v8:4493
LOG=n

Review URL: https://codereview.chromium.org/1415133002

Cr-Commit-Position: refs/heads/master@{#31444}
parent 218c06e8
......@@ -404,12 +404,27 @@ class CompilationInfo {
bool has_simple_parameters();
typedef std::vector<Handle<SharedFunctionInfo>> InlinedFunctionList;
struct InlinedFunctionHolder {
Handle<SharedFunctionInfo> shared_info;
// Root that holds the unoptimized code of the inlined function alive
// (and out of reach of code flushing) until we finish compilation.
// Do not remove.
Handle<Code> inlined_code_object_root;
explicit InlinedFunctionHolder(
Handle<SharedFunctionInfo> inlined_shared_info)
: shared_info(inlined_shared_info),
inlined_code_object_root(inlined_shared_info->code()) {}
};
typedef std::vector<InlinedFunctionHolder> InlinedFunctionList;
InlinedFunctionList const& inlined_functions() const {
return inlined_functions_;
}
void AddInlinedFunction(Handle<SharedFunctionInfo> inlined_function) {
inlined_functions_.push_back(inlined_function);
inlined_functions_.push_back(InlinedFunctionHolder(inlined_function));
}
base::SmartArrayPointer<char> GetDebugName() const;
......
......@@ -83,9 +83,9 @@ Handle<Code> CodeGenerator::GenerateCode() {
// Define deoptimization literals for all inlined functions.
DCHECK_EQ(0u, deoptimization_literals_.size());
for (auto shared_info : info->inlined_functions()) {
if (!shared_info.is_identical_to(info->shared_info())) {
DefineDeoptimizationLiteral(shared_info);
for (auto& inlined : info->inlined_functions()) {
if (!inlined.shared_info.is_identical_to(info->shared_info())) {
DefineDeoptimizationLiteral(inlined.shared_info);
}
}
inlined_function_count_ = deoptimization_literals_.size();
......
......@@ -348,6 +348,14 @@ Reduction JSInliner::ReduceJSCallFunction(Node* node,
info_->shared_info()->DebugName()->ToCString().get());
return NoChange();
}
// Remember that we inlined this function. This needs to be called right
// after we ensure deoptimization support so that the code flusher
// does not remove the code with the deoptimization support.
info_->AddInlinedFunction(info.shared_info());
// ----------------------------------------------------------------
// After this point, we've made a decision to inline this function.
// We shall not bailout from inlining if we got here.
TRACE("Inlining %s into %s\n",
function->shared()->DebugName()->ToCString().get(),
......@@ -399,6 +407,8 @@ Reduction JSInliner::ReduceJSCallFunction(Node* node,
if (call.formal_arguments() != inlinee_formal_parameters) {
// In strong mode, in case of too few arguments we need to throw a
// TypeError so we must not inline this call.
// TODO(jarin) This check should be moved before the decision point
// above so that we do not compile the function uselessly.
if (is_strong(info.language_mode()) &&
call.formal_arguments() < inlinee_formal_parameters) {
return NoChange();
......@@ -407,9 +417,6 @@ Reduction JSInliner::ReduceJSCallFunction(Node* node,
info.zone());
}
// Remember that we inlined this function.
info_->AddInlinedFunction(info.shared_info());
return InlineCall(node, context, frame_state, start, end);
}
......
......@@ -8411,13 +8411,6 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
}
}
// Generate the deoptimization data for the unoptimized version of
// the target function if we don't already have it.
if (!Compiler::EnsureDeoptimizationSupport(&target_info)) {
TraceInline(target, caller, "could not generate deoptimization info");
return false;
}
// In strong mode it is an error to call a function with too few arguments.
// In that case do not inline because then the arity check would be skipped.
if (is_strong(function->language_mode()) &&
......@@ -8427,6 +8420,17 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
return false;
}
// Generate the deoptimization data for the unoptimized version of
// the target function if we don't already have it.
if (!Compiler::EnsureDeoptimizationSupport(&target_info)) {
TraceInline(target, caller, "could not generate deoptimization info");
return false;
}
// Remember that we inlined this function. This needs to be called right
// after the EnsureDeoptimizationSupport call so that the code flusher
// does not remove the code with the deoptimization support.
top_info()->AddInlinedFunction(target_info.shared_info());
// ----------------------------------------------------------------
// After this point, we've made a decision to inline this function (so
// TryInline should always return true).
......
......@@ -276,8 +276,7 @@
'readonly': [PASS, SLOW],
'regress/regress-1200351': [PASS, ['mode == debug', SLOW]],
'regress/regress-crbug-474297': [PASS, ['mode == debug', SLOW]],
# Issue 4493: The 'implicit-conversions' is only NO_VARIANTS because of 4493.
'strong/implicit-conversions': [PASS, SLOW, NO_VARIANTS],
'strong/implicit-conversions': [PASS, SLOW],
'strong/load-element-mutate-backing-store': [PASS, SLOW],
}], # ALWAYS
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment