Commit 0738f53d authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[heap] Make link from optimized code to inlined code explicit.

This makes the strong link from optimized code to code objects for all
inlined functions explicit. It adds direct references to code objects
into deoptimization data as literals. Note that this is not necessarily
the code that will be deoptimized to, because the code on the shared
function info might be replaced by other components (e.g. debugger).
Those replacement code objects however are all non-flushable, marking
explicit strong links for reachability unnecessary.

R=hpayer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#32654}
parent 95844d94
......@@ -92,6 +92,14 @@ Handle<Code> CodeGenerator::GenerateCode() {
}
inlined_function_count_ = deoptimization_literals_.size();
// Define deoptimization literals for all unoptimized code objects of inlined
// functions. This ensures unoptimized code is kept alive by optimized code.
for (auto& inlined : info->inlined_functions()) {
if (!inlined.shared_info.is_identical_to(info->shared_info())) {
DefineDeoptimizationLiteral(inlined.inlined_code_object_root);
}
}
// Assemble all non-deferred blocks, followed by deferred ones.
for (int deferred = 0; deferred < 2; ++deferred) {
for (auto const block : code()->instruction_blocks()) {
......
......@@ -332,10 +332,17 @@ void LCodeGenBase::PopulateDeoptimizationData(Handle<Code> code) {
void LCodeGenBase::PopulateDeoptimizationLiteralsWithInlinedFunctions() {
DCHECK_EQ(0, deoptimization_literals_.length());
for (auto function : chunk()->inlined_functions()) {
for (Handle<SharedFunctionInfo> function : chunk()->inlined_functions()) {
DefineDeoptimizationLiteral(function);
}
inlined_function_count_ = deoptimization_literals_.length();
// Define deoptimization literals for all unoptimized code objects of inlined
// functions. This ensures unoptimized code is kept alive by optimized code.
AllowDeferredHandleDereference allow_shared_function_info_dereference;
for (Handle<SharedFunctionInfo> function : chunk()->inlined_functions()) {
DefineDeoptimizationLiteral(handle(function->code()));
}
}
......
......@@ -428,13 +428,6 @@ void StaticMarkingVisitor<StaticVisitor>::VisitCode(Map* map,
if (FLAG_age_code && !heap->isolate()->serializer_enabled()) {
code->MakeOlder(heap->mark_compact_collector()->marking_parity());
}
MarkCompactCollector* collector = heap->mark_compact_collector();
if (collector->is_code_flushing_enabled()) {
if (code->kind() == Code::OPTIMIZED_FUNCTION) {
// Visit all unoptimized code objects to prevent flushing them.
MarkInlinedFunctionsCode(heap, code);
}
}
CodeBodyVisitor::Visit(map, object);
}
......@@ -618,25 +611,6 @@ void StaticMarkingVisitor<StaticVisitor>::MarkOptimizedCodeMap(
}
template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::MarkInlinedFunctionsCode(Heap* heap,
Code* code) {
// For optimized functions we should retain both non-optimized version
// of its code and non-optimized version of all inlined functions.
// This is required to support bailing out from inlined code.
if (code->deoptimization_data() != heap->empty_fixed_array()) {
DeoptimizationInputData* const data =
DeoptimizationInputData::cast(code->deoptimization_data());
FixedArray* const literals = data->LiteralArray();
int const inlined_count = data->InlinedFunctionCount()->value();
for (int i = 0; i < inlined_count; ++i) {
StaticVisitor::MarkObject(
heap, SharedFunctionInfo::cast(literals->get(i))->code());
}
}
}
inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) {
Object* undefined = heap->undefined_value();
return (info->script() != undefined) &&
......
......@@ -381,10 +381,6 @@ class StaticMarkingVisitor : public StaticVisitorBase {
// references, possibly treating some entries weak.
static void MarkOptimizedCodeMap(Heap* heap, FixedArray* code_map);
// Mark non-optimized code for functions inlined into the given optimized
// code. This will prevent it from being flushed.
static void MarkInlinedFunctionsCode(Heap* heap, Code* code);
// Code flushing support.
INLINE(static bool IsFlushable(Heap* heap, JSFunction* function));
INLINE(static bool IsFlushable(Heap* heap, SharedFunctionInfo* shared_info));
......
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