Commit fe704477 authored by jarin's avatar jarin Committed by Commit bot

[deoptimizer] When deoptimizing code, unlink all functions referring to that code.

Drive by: remove two unused methods in optimized code visitor.

Review-Url: https://codereview.chromium.org/2730323002
Cr-Commit-Position: refs/heads/master@{#43611}
parent 8922cabb
......@@ -839,8 +839,6 @@ class DependentFunctionMarker: public OptimizedFunctionVisitor {
explicit DependentFunctionMarker(SharedFunctionInfo* shared_info)
: shared_info_(shared_info), found_(false) { }
virtual void EnterContext(Context* context) { } // Don't care.
virtual void LeaveContext(Context* context) { } // Don't care.
virtual void VisitFunction(JSFunction* function) {
// It should be guaranteed by the iterator that everything is optimized.
DCHECK(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
......
......@@ -145,8 +145,6 @@ void Deoptimizer::VisitAllOptimizedFunctionsForContext(
CHECK(context->IsNativeContext());
visitor->EnterContext(context);
// Visit the list of optimized functions, removing elements that
// no longer refer to optimized code.
JSFunction* prev = NULL;
......@@ -180,8 +178,29 @@ void Deoptimizer::VisitAllOptimizedFunctionsForContext(
}
element = next;
}
}
void Deoptimizer::UnlinkOptimizedCode(Code* code, Context* native_context) {
class CodeUnlinker : public OptimizedFunctionVisitor {
public:
explicit CodeUnlinker(Code* code) : code_(code) {}
virtual void VisitFunction(JSFunction* function) {
if (function->code() == code_) {
if (FLAG_trace_deopt) {
PrintF("[removing optimized code for: ");
function->ShortPrint();
PrintF("]\n");
}
function->set_code(function->shared()->code());
}
}
visitor->LeaveContext(context);
private:
Code* code_;
};
CodeUnlinker unlinker(code);
VisitAllOptimizedFunctionsForContext(native_context, &unlinker);
}
......@@ -209,8 +228,6 @@ void Deoptimizer::DeoptimizeMarkedCodeForContext(Context* context) {
// deoptimized from the functions that refer to it.
class SelectedCodeUnlinker: public OptimizedFunctionVisitor {
public:
virtual void EnterContext(Context* context) { } // Don't care.
virtual void LeaveContext(Context* context) { } // Don't care.
virtual void VisitFunction(JSFunction* function) {
Code* code = function->code();
if (!code->marked_for_deoptimization()) return;
......
......@@ -353,16 +353,7 @@ class TranslatedState {
class OptimizedFunctionVisitor BASE_EMBEDDED {
public:
virtual ~OptimizedFunctionVisitor() {}
// Function which is called before iteration of any optimized functions
// from given native context.
virtual void EnterContext(Context* context) = 0;
virtual void VisitFunction(JSFunction* function) = 0;
// Function which is called after iteration of all optimized functions
// from given native context.
virtual void LeaveContext(Context* context) = 0;
};
class Deoptimizer : public Malloced {
......@@ -476,6 +467,8 @@ class Deoptimizer : public Malloced {
static void VisitAllOptimizedFunctions(
Isolate* isolate, OptimizedFunctionVisitor* visitor);
static void UnlinkOptimizedCode(Code* code, Context* native_context);
// The size in bytes of the code required at a lazy deopt patch site.
static int patch_size();
......
......@@ -1413,9 +1413,6 @@ class EnumerateOptimizedFunctionsVisitor: public OptimizedFunctionVisitor {
int* count)
: sfis_(sfis), code_objects_(code_objects), count_(count) {}
virtual void EnterContext(Context* context) {}
virtual void LeaveContext(Context* context) {}
virtual void VisitFunction(JSFunction* function) {
SharedFunctionInfo* sfi = SharedFunctionInfo::cast(function->shared());
Object* maybe_script = sfi->script();
......
......@@ -213,14 +213,9 @@ RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
if (!activations_finder.has_code_activations_) {
if (function->code() == *optimized_code) {
if (FLAG_trace_deopt) {
PrintF("[removing optimized code for: ");
function->PrintName();
PrintF("]\n");
}
function->ReplaceCode(function->shared()->code());
}
Deoptimizer::UnlinkOptimizedCode(*optimized_code,
function->context()->native_context());
// Evict optimized code for this function from the cache so that it
// doesn't get used for new closures.
function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --noalways-opt
function foo() {
function g(o) {
return o.f;
}
return g;
}
let g1 = foo();
let g2 = foo();
g1({ f : 1});
g1({ f : 2});
g2({ f : 2});
g2({ f : 2});
%OptimizeFunctionOnNextCall(g1);
%OptimizeFunctionOnNextCall(g2);
g1({ f : 1});
g2({ f : 2});
g1({});
assertUnoptimized(g1);
// Deoptimization of g1 should also deoptimize g2 because they should share
// the optimized code object. (Unfortunately, this test bakes in various
// other assumptions about dealing with optimized code, and thus might break
// in future.)
assertUnoptimized(g2);
g2({});
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