[cleanup] Rename DeoptimizeBaseline to DiscardBaselineCode

- Baseline is to be consider non-optimized code, so for consistency we rename these functions to DiscardBaselineCode.
- Move to debug/, since discarding baseline code is only used by the debugger.
- %DeoptimizeNow and %DeoptimizeFunction are not to be used to tier down from Sparkplug to Ignition

Change-Id: I050607d4d6978907c589e54c57e940979b0a9a15
Bug: v8:11429
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2692699
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72732}
This commit is contained in:
Victor Gomes 2021-02-15 10:04:21 +01:00 committed by Commit Bot
parent 6b8ddeb96d
commit 83867ef69e
6 changed files with 73 additions and 105 deletions

View File

@ -1241,13 +1241,80 @@ void Debug::ClearOneShot() {
}
}
namespace {
class DiscardBaselineCodeVisitor : public ThreadVisitor {
public:
explicit DiscardBaselineCodeVisitor(SharedFunctionInfo shared)
: shared_(shared) {}
DiscardBaselineCodeVisitor() : shared_(SharedFunctionInfo()) {}
void VisitThread(Isolate* isolate, ThreadLocalTop* top) override {
bool deopt_all = shared_ == SharedFunctionInfo();
for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
if (it.frame()->type() == StackFrame::BASELINE) {
BaselineFrame* frame = BaselineFrame::cast(it.frame());
if (!deopt_all && frame->function().shared() != shared_) continue;
frame->InterpretedFrame::PatchBytecodeOffset(
frame->GetBytecodeOffset());
Address* pc_addr = frame->pc_address();
Address advance = BUILTIN_CODE(isolate, InterpreterEnterBytecodeAdvance)
->InstructionStart();
PointerAuthentication::ReplacePC(pc_addr, advance, kSystemPointerSize);
}
}
}
private:
SharedFunctionInfo shared_;
DISALLOW_GARBAGE_COLLECTION(no_gc_)
};
} // namespace
void Debug::DiscardBaselineCode(SharedFunctionInfo shared) {
DCHECK_EQ(shared.GetCode().kind(), CodeKind::BASELINE);
Isolate* isolate = shared.GetIsolate();
DiscardBaselineCodeVisitor visitor(shared);
visitor.VisitThread(isolate, isolate->thread_local_top());
isolate->thread_manager()->IterateArchivedThreads(&visitor);
// TODO(v8:11429): Avoid this heap walk somehow.
HeapObjectIterator iterator(isolate->heap());
auto trampoline = BUILTIN_CODE(isolate, InterpreterEntryTrampoline);
shared.flush_baseline_data();
for (HeapObject obj = iterator.Next(); !obj.is_null();
obj = iterator.Next()) {
if (obj.IsJSFunction()) {
JSFunction fun = JSFunction::cast(obj);
if (fun.shared() == shared && fun.code().kind() == CodeKind::BASELINE) {
fun.set_code(*trampoline);
}
}
}
}
void Debug::DiscardAllBaselineCode() {
DiscardBaselineCodeVisitor visitor;
visitor.VisitThread(isolate_, isolate_->thread_local_top());
HeapObjectIterator iterator(isolate_->heap());
auto trampoline = BUILTIN_CODE(isolate_, InterpreterEntryTrampoline);
isolate_->thread_manager()->IterateArchivedThreads(&visitor);
for (HeapObject obj = iterator.Next(); !obj.is_null();
obj = iterator.Next()) {
if (obj.IsJSFunction()) {
JSFunction fun = JSFunction::cast(obj);
if (fun.shared().HasBaselineData()) {
fun.set_code(*trampoline);
}
}
}
}
void Debug::DeoptimizeFunction(Handle<SharedFunctionInfo> shared) {
// Deoptimize all code compiled from this shared function info including
// inlining.
isolate_->AbortConcurrentOptimization(BlockingBehavior::kBlock);
if (shared->GetCode().kind() == CodeKind::BASELINE) {
Deoptimizer::DeoptimizeBaseline(*shared);
if (shared->HasBaselineData()) {
DiscardBaselineCode(*shared);
}
bool found_something = false;
@ -1284,6 +1351,7 @@ void Debug::PrepareFunctionForDebugExecution(
if (debug_info->CanBreakAtEntry()) {
// Deopt everything in case the function is inlined anywhere.
Deoptimizer::DeoptimizeAll(isolate_);
DiscardAllBaselineCode();
InstallDebugBreakTrampoline();
} else {
DeoptimizeFunction(shared);

View File

@ -265,6 +265,9 @@ class V8_EXPORT_PRIVATE Debug {
void SetBreakOnNextFunctionCall();
void ClearBreakOnNextFunctionCall();
void DiscardBaselineCode(SharedFunctionInfo shared);
void DiscardAllBaselineCode();
void DeoptimizeFunction(Handle<SharedFunctionInfo> shared);
void PrepareFunctionForDebugExecution(Handle<SharedFunctionInfo> shared);
void InstallDebugBreakTrampoline();

View File

@ -382,7 +382,6 @@ void Deoptimizer::DeoptimizeAll(Isolate* isolate) {
TraceDeoptAll(isolate);
isolate->AbortConcurrentOptimization(BlockingBehavior::kBlock);
DisallowGarbageCollection no_gc;
DeoptimizeAllBaseline(isolate);
// For all contexts, mark all code, then deoptimize.
Object context = isolate->heap()->native_contexts_list();
while (!context.IsUndefined(isolate)) {
@ -421,73 +420,6 @@ void Deoptimizer::MarkAllCodeForContext(NativeContext native_context) {
}
}
namespace {
class DeoptimizeBaselineVisitor : public ThreadVisitor {
public:
explicit DeoptimizeBaselineVisitor(SharedFunctionInfo shared)
: shared_(shared) {}
DeoptimizeBaselineVisitor() : shared_(SharedFunctionInfo()) {}
void VisitThread(Isolate* isolate, ThreadLocalTop* top) override {
bool deopt_all = shared_ == SharedFunctionInfo();
for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
if (it.frame()->type() == StackFrame::BASELINE) {
BaselineFrame* frame = BaselineFrame::cast(it.frame());
if (!deopt_all && frame->function().shared() != shared_) continue;
frame->InterpretedFrame::PatchBytecodeOffset(
frame->GetBytecodeOffset());
Address* pc_addr = frame->pc_address();
Address advance = BUILTIN_CODE(isolate, InterpreterEnterBytecodeAdvance)
->InstructionStart();
PointerAuthentication::ReplacePC(pc_addr, advance, kSystemPointerSize);
}
}
}
private:
SharedFunctionInfo shared_;
DISALLOW_GARBAGE_COLLECTION(no_gc_)
};
} // namespace
void Deoptimizer::DeoptimizeBaseline(SharedFunctionInfo shared) {
DCHECK_EQ(shared.GetCode().kind(), CodeKind::BASELINE);
Isolate* isolate = shared.GetIsolate();
DeoptimizeBaselineVisitor visitor(shared);
visitor.VisitThread(isolate, isolate->thread_local_top());
isolate->thread_manager()->IterateArchivedThreads(&visitor);
// TODO(v8:11429): Avoid this heap walk somehow.
HeapObjectIterator iterator(isolate->heap());
auto trampoline = BUILTIN_CODE(isolate, InterpreterEntryTrampoline);
shared.flush_baseline_data();
for (HeapObject obj = iterator.Next(); !obj.is_null();
obj = iterator.Next()) {
if (obj.IsJSFunction()) {
JSFunction fun = JSFunction::cast(obj);
if (fun.shared() == shared && fun.code().kind() == CodeKind::BASELINE) {
fun.set_code(*trampoline);
}
}
}
}
void Deoptimizer::DeoptimizeAllBaseline(Isolate* isolate) {
DeoptimizeBaselineVisitor visitor;
visitor.VisitThread(isolate, isolate->thread_local_top());
HeapObjectIterator iterator(isolate->heap());
auto trampoline = BUILTIN_CODE(isolate, InterpreterEntryTrampoline);
isolate->thread_manager()->IterateArchivedThreads(&visitor);
for (HeapObject obj = iterator.Next(); !obj.is_null();
obj = iterator.Next()) {
if (obj.IsJSFunction()) {
JSFunction fun = JSFunction::cast(obj);
if (fun.shared().HasBaselineData()) {
fun.set_code(*trampoline);
}
}
}
}
void Deoptimizer::DeoptimizeFunction(JSFunction function, Code code) {
Isolate* isolate = function.GetIsolate();
RuntimeCallTimerScope runtimeTimer(isolate,

View File

@ -66,12 +66,6 @@ class Deoptimizer : public Malloced {
// instead of the function code (e.g. OSR code not installed on function).
static void DeoptimizeFunction(JSFunction function, Code code = Code());
// From Baseline to Ignition.
// TODO(v8:11429): Consider moving this to the debugger, since it's only for
// debug.
static void DeoptimizeBaseline(SharedFunctionInfo shared);
static void DeoptimizeAllBaseline(Isolate* isolate);
// Deoptimize all code in the given isolate.
V8_EXPORT_PRIVATE static void DeoptimizeAll(Isolate* isolate);

View File

@ -190,10 +190,6 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
if (function->HasAttachedOptimizedCode()) {
Deoptimizer::DeoptimizeFunction(*function);
} else if (function->code().kind() == CodeKind::BASELINE) {
// TODO(v8:11429): This should either be in Deoptimizer::DeoptimizeFunction,
// or not be considered deoptimization at all.
Deoptimizer::DeoptimizeBaseline(function->shared());
}
return ReadOnlyRoots(isolate).undefined_value();
@ -212,8 +208,6 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeNow) {
if (function->HasAttachedOptimizedCode()) {
Deoptimizer::DeoptimizeFunction(*function);
} else if (function->code().kind() == CodeKind::BASELINE) {
Deoptimizer::DeoptimizeBaseline(function->shared());
}
return ReadOnlyRoots(isolate).undefined_value();

View File

@ -310,26 +310,3 @@ assertEquals(run((x)=>{
assertTrue(isBaseline(f1));
assertTrue(isBaseline(f2));
})();
// DeoptNow to Ignition
(function() {
function f() { %DeoptimizeNow(); }
f();
assertTrue(isInterpreted(f));
%CompileBaseline(f);
f();
assertTrue(isInterpreted(f));
})();
// Deopt to Ignition
(function() {
function f() {}
f();
assertTrue(isInterpreted(f));
%CompileBaseline(f);
f();
assertTrue(isBaseline(f));
%DeoptimizeFunction(f);
f();
assertTrue(isInterpreted(f));
})();