[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:
parent
6b8ddeb96d
commit
83867ef69e
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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));
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user