[debugger] Remove "Restart frame" feature.

The "Restart frame" feature was implemented as part of LiveEdit and
primarily used to support LiveEdit of active functions, but that was
previously disabled as part of https://crrev.com/c/2846892 because it's
too brittle and causes crashes when using seemingly unrelated features.
The "Restart frame" feature was also available as a context menu item
separately in the DevTools front-end, but that was also already removed
as part of https://crrev.com/c/2854681 earlier. So all uses are gone
now.

This change works by marking Debugger.restartFrame as deprecated and
having it respond with a ServerError all the time. It thus allows us to
remove a whole bunch of machinery that was essentially just put in
various places to support the restart_fp_ magic. In particular the
debugger no longer needs any machine specific builtins now.

Bug: chromium:1195927
Change-Id: I1153ba6b00e979620af57dd9f58aa1c035ec4484
Fixed: chromium:1203606
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2854750
Reviewed-by: Yang Guo <yangguo@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74276}
This commit is contained in:
Benedikt Meurer 2021-04-28 11:46:12 +02:00 committed by V8 LUCI CQ
parent bfaca03f79
commit 93f85699e2
67 changed files with 19 additions and 1151 deletions

View File

@ -2060,7 +2060,6 @@ v8_source_set("v8_initializers") {
"src/builtins/builtins-conversion-gen.cc",
"src/builtins/builtins-data-view-gen.h",
"src/builtins/builtins-date-gen.cc",
"src/builtins/builtins-debug-gen.cc",
"src/builtins/builtins-generator-gen.cc",
"src/builtins/builtins-global-gen.cc",
"src/builtins/builtins-handler-gen.cc",
@ -4105,7 +4104,6 @@ v8_source_set("v8_base_without_compiler") {
"src/compiler/backend/ia32/code-generator-ia32.cc",
"src/compiler/backend/ia32/instruction-scheduler-ia32.cc",
"src/compiler/backend/ia32/instruction-selector-ia32.cc",
"src/debug/ia32/debug-ia32.cc",
"src/deoptimizer/ia32/deoptimizer-ia32.cc",
"src/diagnostics/ia32/disasm-ia32.cc",
"src/diagnostics/ia32/unwinder-ia32.cc",
@ -4122,7 +4120,6 @@ v8_source_set("v8_base_without_compiler") {
"src/compiler/backend/x64/instruction-scheduler-x64.cc",
"src/compiler/backend/x64/instruction-selector-x64.cc",
"src/compiler/backend/x64/unwinding-info-writer-x64.cc",
"src/debug/x64/debug-x64.cc",
"src/deoptimizer/x64/deoptimizer-x64.cc",
"src/diagnostics/x64/disasm-x64.cc",
"src/diagnostics/x64/eh-frame-x64.cc",
@ -4156,7 +4153,6 @@ v8_source_set("v8_base_without_compiler") {
"src/compiler/backend/arm/instruction-scheduler-arm.cc",
"src/compiler/backend/arm/instruction-selector-arm.cc",
"src/compiler/backend/arm/unwinding-info-writer-arm.cc",
"src/debug/arm/debug-arm.cc",
"src/deoptimizer/arm/deoptimizer-arm.cc",
"src/diagnostics/arm/disasm-arm.cc",
"src/diagnostics/arm/eh-frame-arm.cc",
@ -4179,7 +4175,6 @@ v8_source_set("v8_base_without_compiler") {
"src/compiler/backend/arm64/instruction-scheduler-arm64.cc",
"src/compiler/backend/arm64/instruction-selector-arm64.cc",
"src/compiler/backend/arm64/unwinding-info-writer-arm64.cc",
"src/debug/arm64/debug-arm64.cc",
"src/deoptimizer/arm64/deoptimizer-arm64.cc",
"src/diagnostics/arm64/disasm-arm64.cc",
"src/diagnostics/arm64/eh-frame-arm64.cc",
@ -4209,7 +4204,6 @@ v8_source_set("v8_base_without_compiler") {
"src/compiler/backend/mips/code-generator-mips.cc",
"src/compiler/backend/mips/instruction-scheduler-mips.cc",
"src/compiler/backend/mips/instruction-selector-mips.cc",
"src/debug/mips/debug-mips.cc",
"src/deoptimizer/mips/deoptimizer-mips.cc",
"src/diagnostics/mips/disasm-mips.cc",
"src/diagnostics/mips/unwinder-mips.cc",
@ -4227,7 +4221,6 @@ v8_source_set("v8_base_without_compiler") {
"src/compiler/backend/mips64/code-generator-mips64.cc",
"src/compiler/backend/mips64/instruction-scheduler-mips64.cc",
"src/compiler/backend/mips64/instruction-selector-mips64.cc",
"src/debug/mips64/debug-mips64.cc",
"src/deoptimizer/mips64/deoptimizer-mips64.cc",
"src/diagnostics/mips64/disasm-mips64.cc",
"src/diagnostics/mips64/unwinder-mips64.cc",
@ -4245,7 +4238,6 @@ v8_source_set("v8_base_without_compiler") {
"src/compiler/backend/ppc/instruction-scheduler-ppc.cc",
"src/compiler/backend/ppc/instruction-selector-ppc.cc",
"src/compiler/backend/ppc/unwinding-info-writer-ppc.cc",
"src/debug/ppc/debug-ppc.cc",
"src/deoptimizer/ppc/deoptimizer-ppc.cc",
"src/diagnostics/ppc/disasm-ppc.cc",
"src/diagnostics/ppc/eh-frame-ppc.cc",
@ -4264,7 +4256,6 @@ v8_source_set("v8_base_without_compiler") {
"src/compiler/backend/ppc/instruction-scheduler-ppc.cc",
"src/compiler/backend/ppc/instruction-selector-ppc.cc",
"src/compiler/backend/ppc/unwinding-info-writer-ppc.cc",
"src/debug/ppc/debug-ppc.cc",
"src/deoptimizer/ppc/deoptimizer-ppc.cc",
"src/diagnostics/ppc/disasm-ppc.cc",
"src/diagnostics/ppc/eh-frame-ppc.cc",
@ -4283,7 +4274,6 @@ v8_source_set("v8_base_without_compiler") {
"src/compiler/backend/s390/instruction-scheduler-s390.cc",
"src/compiler/backend/s390/instruction-selector-s390.cc",
"src/compiler/backend/s390/unwinding-info-writer-s390.cc",
"src/debug/s390/debug-s390.cc",
"src/deoptimizer/s390/deoptimizer-s390.cc",
"src/diagnostics/s390/disasm-s390.cc",
"src/diagnostics/s390/eh-frame-s390.cc",
@ -4305,7 +4295,6 @@ v8_source_set("v8_base_without_compiler") {
"src/compiler/backend/riscv64/code-generator-riscv64.cc",
"src/compiler/backend/riscv64/instruction-scheduler-riscv64.cc",
"src/compiler/backend/riscv64/instruction-selector-riscv64.cc",
"src/debug/riscv64/debug-riscv64.cc",
"src/deoptimizer/riscv64/deoptimizer-riscv64.cc",
"src/diagnostics/riscv64/disasm-riscv64.cc",
"src/diagnostics/riscv64/unwinder-riscv64.cc",

View File

@ -267,7 +267,7 @@ domain Debugger
BreakpointId breakpointId
# Restarts particular call frame from the beginning.
command restartFrame
deprecated command restartFrame
parameters
# Call frame identifier to evaluate on.
CallFrameId callFrameId

View File

@ -2272,7 +2272,7 @@ void BaselineCompiler::VisitGetIterator() {
void BaselineCompiler::VisitDebugger() {
SaveAccumulatorScope accumulator_scope(&basm_);
CallBuiltin<Builtins::kHandleDebuggerStatement>();
CallRuntime(Runtime::kHandleDebuggerStatement);
}
void BaselineCompiler::VisitIncBlockCounter() {

View File

@ -1,22 +0,0 @@
// Copyright 2016 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.
#include "src/builtins/builtins-utils.h"
#include "src/builtins/builtins.h"
#include "src/debug/debug.h"
#include "src/objects/objects-inl.h"
namespace v8 {
namespace internal {
void Builtins::Generate_FrameDropperTrampoline(MacroAssembler* masm) {
DebugCodegen::GenerateFrameDropperTrampoline(masm);
}
void Builtins::Generate_HandleDebuggerStatement(MacroAssembler* masm) {
DebugCodegen::GenerateHandleDebuggerStatement(masm);
}
} // namespace internal
} // namespace v8

View File

@ -200,8 +200,6 @@ namespace internal {
\
/* Debugger */ \
TFJ(DebugBreakTrampoline, kDontAdaptArgumentsSentinel) \
ASM(FrameDropperTrampoline, FrameDropperTrampoline) \
ASM(HandleDebuggerStatement, ContextOnly) \
\
/* Type conversions */ \
TFC(ToNumber, TypeConversion) \

View File

@ -243,11 +243,6 @@ constexpr auto ResumeGeneratorDescriptor::registers() {
r1); // the JSGeneratorObject to resume
}
// static
constexpr auto FrameDropperTrampolineDescriptor::registers() {
return RegisterArray(r1); // loaded new FP
}
// static
constexpr auto RunMicrotasksEntryDescriptor::registers() {
return RegisterArray(r0, r1);

View File

@ -1811,17 +1811,6 @@ void MacroAssembler::InvokeFunction(Register function,
actual_parameter_count, flag);
}
void MacroAssembler::MaybeDropFrames() {
// Check whether we need to drop frames to restart a function on the stack.
ExternalReference restart_fp =
ExternalReference::debug_restart_fp_address(isolate());
Move(r1, restart_fp);
ldr(r1, MemOperand(r1));
tst(r1, r1);
Jump(BUILTIN_CODE(isolate(), FrameDropperTrampoline), RelocInfo::CODE_TARGET,
ne);
}
void MacroAssembler::PushStackHandler() {
// Adjust this code if not the case.
STATIC_ASSERT(StackHandlerConstants::kSize == 2 * kPointerSize);

View File

@ -705,9 +705,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
void InvokeFunction(Register function, Register expected_parameter_count,
Register actual_parameter_count, InvokeFlag flag);
// Frame restart support
void MaybeDropFrames();
// Exception handling
// Push a new stack handler and link into stack handler chain.

View File

@ -252,11 +252,6 @@ constexpr auto ResumeGeneratorDescriptor::registers() {
x1); // the JSGeneratorObject to resume
}
// static
constexpr auto FrameDropperTrampolineDescriptor::registers() {
return RegisterArray(x1); // loaded new FP
}
// static
constexpr auto RunMicrotasksEntryDescriptor::registers() {
return RegisterArray(x0, x1);

View File

@ -2716,15 +2716,6 @@ void MacroAssembler::DecrementCounter(StatsCounter* counter, int value,
IncrementCounter(counter, -value, scratch1, scratch2);
}
void MacroAssembler::MaybeDropFrames() {
// Check whether we need to drop frames to restart a function on the stack.
Mov(x1, ExternalReference::debug_restart_fp_address(isolate()));
Ldr(x1, MemOperand(x1));
Tst(x1, x1);
Jump(BUILTIN_CODE(isolate(), FrameDropperTrampoline), RelocInfo::CODE_TARGET,
ne);
}
void MacroAssembler::JumpIfObjectType(Register object, Register map,
Register type_reg, InstanceType type,
Label* if_cond_pass, Condition cond) {

View File

@ -1901,9 +1901,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// ---- Code generation helpers ----
// Frame restart support
void MaybeDropFrames();
// ---------------------------------------------------------------------------
// Support functions.

View File

@ -232,16 +232,6 @@ Callable CodeFactory::ResumeGenerator(Isolate* isolate) {
return Builtins::CallableFor(isolate, Builtins::kResumeGeneratorTrampoline);
}
// static
Callable CodeFactory::FrameDropperTrampoline(Isolate* isolate) {
return Builtins::CallableFor(isolate, Builtins::kFrameDropperTrampoline);
}
// static
Callable CodeFactory::HandleDebuggerStatement(Isolate* isolate) {
return Builtins::CallableFor(isolate, Builtins::kHandleDebuggerStatement);
}
// static
Callable CodeFactory::FastNewFunctionContext(Isolate* isolate,
ScopeType scope_type) {

View File

@ -49,9 +49,6 @@ class V8_EXPORT_PRIVATE CodeFactory final {
static Callable ResumeGenerator(Isolate* isolate);
static Callable FrameDropperTrampoline(Isolate* isolate);
static Callable HandleDebuggerStatement(Isolate* isolate);
static Callable BinaryOperation(Isolate* isolate, Operation op);
static Callable ApiGetter(Isolate* isolate);

View File

@ -1017,11 +1017,6 @@ ExternalReference ExternalReference::debug_suspended_generator_address(
return ExternalReference(isolate->debug()->suspended_generator_address());
}
ExternalReference ExternalReference::debug_restart_fp_address(
Isolate* isolate) {
return ExternalReference(isolate->debug()->restart_fp_address());
}
ExternalReference ExternalReference::fast_c_call_caller_fp_address(
Isolate* isolate) {
return ExternalReference(

View File

@ -62,7 +62,6 @@ class StatsCounter;
V(is_profiling_address, "Isolate::is_profiling") \
V(debug_suspended_generator_address, \
"Debug::step_suspended_generator_address()") \
V(debug_restart_fp_address, "Debug::restart_fp_address()") \
V(fast_c_call_caller_fp_address, \
"IsolateData::fast_c_call_caller_fp_address") \
V(fast_c_call_caller_pc_address, \

View File

@ -240,11 +240,6 @@ constexpr auto ResumeGeneratorDescriptor::registers() {
edx); // the JSGeneratorObject to resume
}
// static
constexpr auto FrameDropperTrampolineDescriptor::registers() {
return RegisterArray(eax); // loaded new FP
}
// static
constexpr auto RunMicrotasksEntryDescriptor::registers() {
return RegisterArray();

View File

@ -555,19 +555,6 @@ void MacroAssembler::RecordWrite(Register object, Register address,
}
}
void MacroAssembler::MaybeDropFrames() {
// Check whether we need to drop frames to restart a function on the stack.
Label dont_drop;
ExternalReference restart_fp =
ExternalReference::debug_restart_fp_address(isolate());
mov(eax, ExternalReferenceAsOperand(restart_fp, eax));
test(eax, eax);
j(zero, &dont_drop, Label::kNear);
Jump(BUILTIN_CODE(isolate(), FrameDropperTrampoline), RelocInfo::CODE_TARGET);
bind(&dont_drop);
}
void TurboAssembler::Cvtsi2ss(XMMRegister dst, Operand src) {
xorps(dst, dst);
cvtsi2ss(dst, src);

View File

@ -551,9 +551,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
SmiCheck smi_check = INLINE_SMI_CHECK);
// Frame restart support
void MaybeDropFrames();
// Enter specific kind of exit frame. Expects the number of
// arguments in register eax and sets up the number of arguments in
// register edi and the pointer to the first argument in register

View File

@ -69,7 +69,6 @@ namespace internal {
V(EphemeronKeyBarrier) \
V(FastNewObject) \
V(ForInPrepare) \
V(FrameDropperTrampoline) \
V(GetIteratorStackParameter) \
V(GetProperty) \
V(GrowArrayElements) \
@ -1689,16 +1688,6 @@ class SuspendGeneratorBaselineDescriptor final
DECLARE_DESCRIPTOR(SuspendGeneratorBaselineDescriptor)
};
class FrameDropperTrampolineDescriptor final
: public StaticCallInterfaceDescriptor<FrameDropperTrampolineDescriptor> {
public:
DEFINE_PARAMETERS(kRestartFp)
DEFINE_PARAMETER_TYPES(MachineType::Pointer())
DECLARE_DESCRIPTOR(FrameDropperTrampolineDescriptor)
static constexpr inline auto registers();
};
class RunMicrotasksEntryDescriptor final
: public StaticCallInterfaceDescriptor<RunMicrotasksEntryDescriptor> {
public:

View File

@ -245,12 +245,6 @@ constexpr auto ResumeGeneratorDescriptor::registers() {
return RegisterArray(v0, a1);
}
// static
constexpr auto FrameDropperTrampolineDescriptor::registers() {
// a1 : loaded new FP
return RegisterArray(a1);
}
// static
constexpr auto RunMicrotasksEntryDescriptor::registers() {
return RegisterArray(a0, a1);

View File

@ -4177,14 +4177,6 @@ void TurboAssembler::PushArray(Register array, Register size, Register scratch,
}
}
void MacroAssembler::MaybeDropFrames() {
// Check whether we need to drop frames to restart a function on the stack.
li(a1, ExternalReference::debug_restart_fp_address(isolate()));
lw(a1, MemOperand(a1));
Jump(BUILTIN_CODE(isolate(), FrameDropperTrampoline), RelocInfo::CODE_TARGET,
ne, a1, Operand(zero_reg));
}
// ---------------------------------------------------------------------------
// Exception handling.

View File

@ -1032,9 +1032,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
void InvokeFunction(Register function, Register expected_parameter_count,
Register actual_parameter_count, InvokeFlag flag);
// Frame restart support.
void MaybeDropFrames();
// Exception handling.
// Push a new stack handler and link into stack handler chain.

View File

@ -245,12 +245,6 @@ constexpr auto ResumeGeneratorDescriptor::registers() {
return RegisterArray(v0, a1);
}
// static
constexpr auto FrameDropperTrampolineDescriptor::registers() {
// a1 : loaded new FP
return RegisterArray(a1);
}
// static
constexpr auto RunMicrotasksEntryDescriptor::registers() {
return RegisterArray(a0, a1);

View File

@ -4688,14 +4688,6 @@ void TurboAssembler::PushArray(Register array, Register size, Register scratch,
}
}
void MacroAssembler::MaybeDropFrames() {
// Check whether we need to drop frames to restart a function on the stack.
li(a1, ExternalReference::debug_restart_fp_address(isolate()));
Ld(a1, MemOperand(a1));
Jump(BUILTIN_CODE(isolate(), FrameDropperTrampoline), RelocInfo::CODE_TARGET,
ne, a1, Operand(zero_reg));
}
// ---------------------------------------------------------------------------
// Exception handling.

View File

@ -1087,9 +1087,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
void InvokeFunction(Register function, Register expected_parameter_count,
Register actual_parameter_count, InvokeFlag flag);
// Frame restart support.
void MaybeDropFrames();
// Exception handling.
// Push a new stack handler and link into stack handler chain.

View File

@ -243,11 +243,6 @@ constexpr auto ResumeGeneratorDescriptor::registers() {
r4); // the JSGeneratorObject to resume
}
// static
constexpr auto FrameDropperTrampolineDescriptor::registers() {
return RegisterArray(r4); // loaded new FP
}
// static
constexpr auto RunMicrotasksEntryDescriptor::registers() {
return RegisterArray(r3, r4);

View File

@ -1604,17 +1604,6 @@ void MacroAssembler::InvokeFunction(Register function,
actual_parameter_count, flag);
}
void MacroAssembler::MaybeDropFrames() {
// Check whether we need to drop frames to restart a function on the stack.
ExternalReference restart_fp =
ExternalReference::debug_restart_fp_address(isolate());
Move(r4, restart_fp);
LoadP(r4, MemOperand(r4));
cmpi(r4, Operand::Zero());
Jump(BUILTIN_CODE(isolate(), FrameDropperTrampoline), RelocInfo::CODE_TARGET,
ne);
}
void MacroAssembler::PushStackHandler() {
// Adjust this code if not the case.
STATIC_ASSERT(StackHandlerConstants::kSize == 2 * kSystemPointerSize);

View File

@ -850,9 +850,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
void InvokeFunction(Register function, Register expected_parameter_count,
Register actual_parameter_count, InvokeFlag flag);
// Frame restart support
void MaybeDropFrames();
// Exception handling
// Push a new stack handler and link into stack handler chain.

View File

@ -252,11 +252,6 @@ constexpr auto ResumeGeneratorDescriptor::registers() {
a1); // the JSGeneratorObject to resume
}
// static
constexpr auto FrameDropperTrampolineDescriptor::registers() {
return RegisterArray(a1); // loaded new FP
}
// static
constexpr auto RunMicrotasksEntryDescriptor::registers() {
return RegisterArray(a0, a1);

View File

@ -3378,14 +3378,6 @@ void TurboAssembler::Push(Handle<HeapObject> handle) {
push(scratch);
}
void MacroAssembler::MaybeDropFrames() {
// Check whether we need to drop frames to restart a function on the stack.
li(a1, ExternalReference::debug_restart_fp_address(isolate()));
Ld(a1, MemOperand(a1));
Jump(BUILTIN_CODE(isolate(), FrameDropperTrampoline), RelocInfo::CODE_TARGET,
ne, a1, Operand(zero_reg));
}
// ---------------------------------------------------------------------------
// Exception handling.

View File

@ -1045,9 +1045,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
void InvokeFunction(Register function, Register expected_parameter_count,
Register actual_parameter_count, InvokeFlag flag);
// Frame restart support.
void MaybeDropFrames();
// Exception handling.
// Push a new stack handler and link into stack handler chain.

View File

@ -243,11 +243,6 @@ constexpr auto ResumeGeneratorDescriptor::registers() {
r3); // the JSGeneratorObject to resume
}
// static
constexpr auto FrameDropperTrampolineDescriptor::registers() {
return RegisterArray(r3); // loaded new FP
}
// static
constexpr auto RunMicrotasksEntryDescriptor::registers() {
return RegisterArray(r2, r3);

View File

@ -1784,17 +1784,6 @@ void MacroAssembler::InvokeFunction(Register function,
actual_parameter_count, flag);
}
void MacroAssembler::MaybeDropFrames() {
// Check whether we need to drop frames to restart a function on the stack.
ExternalReference restart_fp =
ExternalReference::debug_restart_fp_address(isolate());
Move(r3, restart_fp);
LoadU64(r3, MemOperand(r3));
CmpS64(r3, Operand::Zero());
Jump(BUILTIN_CODE(isolate(), FrameDropperTrampoline), RelocInfo::CODE_TARGET,
ne);
}
void MacroAssembler::PushStackHandler() {
// Adjust this code if not the case.
STATIC_ASSERT(StackHandlerConstants::kSize == 2 * kSystemPointerSize);

View File

@ -1244,9 +1244,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
void InvokeFunction(Register function, Register expected_parameter_count,
Register actual_parameter_count, InvokeFlag flag);
// Frame restart support
void MaybeDropFrames();
// Exception handling
// Push a new stack handler and link into stack handler chain.

View File

@ -245,11 +245,6 @@ constexpr auto ResumeGeneratorDescriptor::registers() {
rdx); // the JSGeneratorObject / JSAsyncGeneratorObject to resume
}
// static
constexpr auto FrameDropperTrampolineDescriptor::registers() {
return RegisterArray(rbx); // loaded new FP
}
// static
constexpr auto RunMicrotasksEntryDescriptor::registers() {
return RegisterArray(arg_reg_1, arg_reg_2);

View File

@ -2705,20 +2705,6 @@ void MacroAssembler::DecrementCounter(StatsCounter* counter, int value) {
}
}
void MacroAssembler::MaybeDropFrames() {
// Check whether we need to drop frames to restart a function on the stack.
ExternalReference restart_fp =
ExternalReference::debug_restart_fp_address(isolate());
Load(rbx, restart_fp);
testq(rbx, rbx);
Label dont_drop;
j(zero, &dont_drop, Label::kNear);
Jump(BUILTIN_CODE(isolate(), FrameDropperTrampoline), RelocInfo::CODE_TARGET);
bind(&dont_drop);
}
void TurboAssembler::PrepareForTailCall(Register callee_args_count,
Register caller_args_count,
Register scratch0, Register scratch1) {

View File

@ -681,9 +681,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
SmiCheck smi_check = INLINE_SMI_CHECK);
// Frame restart support.
void MaybeDropFrames();
// Enter specific kind of exit frame; either in normal or
// debug mode. Expects the number of arguments in register rax and
// sets up the number of arguments in register rdi and the pointer

View File

@ -1444,7 +1444,7 @@ void JSGenericLowering::LowerJSStackCheck(Node* node) {
}
void JSGenericLowering::LowerJSDebugger(Node* node) {
ReplaceWithBuiltinCall(node, Builtins::kHandleDebuggerStatement);
ReplaceWithRuntimeCall(node, Runtime::kHandleDebuggerStatement);
}
Zone* JSGenericLowering::zone() const { return graph()->zone(); }

View File

@ -1,57 +0,0 @@
// Copyright 2012 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.
#if V8_TARGET_ARCH_ARM
#include "src/debug/debug.h"
#include "src/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/debug/liveedit.h"
#include "src/execution/frames-inl.h"
#include "src/objects/objects-inl.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ CallRuntime(Runtime::kHandleDebuggerStatement, 0);
}
__ MaybeDropFrames();
// Return to caller.
__ Ret();
}
void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
// Frame is being dropped:
// - Drop to the target frame specified by r1.
// - Look up current function on the frame.
// - Leave the frame.
// - Restart the frame by calling the function.
__ mov(fp, r1);
__ ldr(r1, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ ldr(r0, MemOperand(fp, StandardFrameConstants::kArgCOffset));
__ LeaveFrame(StackFrame::INTERNAL);
// The arguments are already in the stack (including any necessary padding),
// we should not try to massage the arguments again.
__ mov(r2, Operand(kDontAdaptArgumentsSentinel));
__ InvokeFunction(r1, r2, r0, JUMP_FUNCTION);
}
const bool LiveEdit::kFrameDropperSupported = true;
#undef __
} // namespace internal
} // namespace v8
#endif // V8_TARGET_ARCH_ARM

View File

@ -1,58 +0,0 @@
// Copyright 2013 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.
#if V8_TARGET_ARCH_ARM64
#include "src/debug/debug.h"
#include "src/codegen/arm64/macro-assembler-arm64-inl.h"
#include "src/debug/liveedit.h"
#include "src/execution/frame-constants.h"
#include "src/execution/frames-inl.h"
#include "src/objects/objects-inl.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ CallRuntime(Runtime::kHandleDebuggerStatement, 0);
}
__ MaybeDropFrames();
// Return to caller.
__ Ret();
}
void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
// Frame is being dropped:
// - Drop to the target frame specified by x1.
// - Look up current function on the frame.
// - Leave the frame.
// - Restart the frame by calling the function.
__ Mov(fp, x1);
__ Ldr(x1, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ ldr(x0, MemOperand(fp, StandardFrameConstants::kArgCOffset));
__ Mov(sp, fp);
__ Pop<TurboAssembler::kAuthLR>(fp, lr);
// The arguments are already in the stack (including any necessary padding),
// we should not try to massage the arguments again.
__ Mov(x3, kDontAdaptArgumentsSentinel);
__ InvokeFunctionWithNewTarget(x1, x3, x0, JUMP_FUNCTION);
}
const bool LiveEdit::kFrameDropperSupported = true;
} // namespace internal
} // namespace v8
#undef __
#endif // V8_TARGET_ARCH_ARM64

View File

@ -476,7 +476,6 @@ class V8_EXPORT_PRIVATE StackTraceIterator {
virtual v8::Local<v8::Function> GetFunction() const = 0;
virtual std::unique_ptr<ScopeIterator> GetScopeIterator() const = 0;
virtual bool Restart() = 0;
virtual v8::MaybeLocal<v8::Value> Evaluate(v8::Local<v8::String> source,
bool throw_on_side_effect) = 0;
};

View File

@ -172,14 +172,6 @@ DebugStackTraceIterator::GetScopeIterator() const {
return std::make_unique<DebugScopeIterator>(isolate_, frame_inspector_.get());
}
bool DebugStackTraceIterator::Restart() {
DCHECK(!Done());
#if V8_ENABLE_WEBASSEMBLY
if (iterator_.is_wasm()) return false;
#endif // V8_ENABLE_WEBASSEMBLY
return LiveEdit::RestartFrame(iterator_.javascript_frame());
}
v8::MaybeLocal<v8::Value> DebugStackTraceIterator::Evaluate(
v8::Local<v8::String> source, bool throw_on_side_effect) {
DCHECK(!Done());

View File

@ -31,7 +31,6 @@ class DebugStackTraceIterator final : public debug::StackTraceIterator {
v8::Local<v8::Function> GetFunction() const override;
std::unique_ptr<v8::debug::ScopeIterator> GetScopeIterator() const override;
bool Restart() override;
v8::MaybeLocal<v8::Value> Evaluate(v8::Local<v8::String> source,
bool throw_on_side_effect) override;

View File

@ -352,7 +352,6 @@ void Debug::ThreadInit() {
thread_local_.return_value_ = Smi::zero();
thread_local_.last_breakpoint_id_ = 0;
clear_suspended_generator();
thread_local_.restart_fp_ = kNullAddress;
base::Relaxed_Store(&thread_local_.current_debug_scope_,
static_cast<base::AtomicWord>(0));
thread_local_.break_on_next_function_call_ = false;
@ -439,9 +438,6 @@ void Debug::Unload() {
}
void Debug::Break(JavaScriptFrame* frame, Handle<JSFunction> break_target) {
// Initialize LiveEdit.
LiveEdit::InitializeThreadLocal(this);
// Just continue if breaks are disabled or debugger cannot be loaded.
if (break_disabled()) return;
@ -1873,27 +1869,6 @@ bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
return location.IsReturn();
}
void Debug::ScheduleFrameRestart(StackFrame* frame) {
// Set a target FP for the FrameDropperTrampoline builtin to drop to once
// we return from the debugger.
DCHECK(frame->is_java_script());
// Only reschedule to a frame further below a frame we already scheduled for.
if (frame->fp() <= thread_local_.restart_fp_) return;
// If the frame is optimized, trigger a deopt and jump into the
// FrameDropperTrampoline in the deoptimizer.
thread_local_.restart_fp_ = frame->fp();
// Reset break frame ID to the frame below the restarted frame.
StackTraceFrameIterator it(isolate_);
thread_local_.break_frame_id_ = StackFrameId::NO_ID;
for (StackTraceFrameIterator it(isolate_); !it.done(); it.Advance()) {
if (it.frame()->fp() > thread_local_.restart_fp_) {
thread_local_.break_frame_id_ = it.frame()->id();
return;
}
}
}
Handle<FixedArray> Debug::GetLoadedScripts() {
isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags,
GarbageCollectionReason::kDebugger);
@ -2245,8 +2220,6 @@ void Debug::UpdateHookOnFunctionCall() {
}
void Debug::HandleDebugBreak(IgnoreBreakMode ignore_break_mode) {
// Initialize LiveEdit.
LiveEdit::InitializeThreadLocal(this);
// Ignore debug break during bootstrapping.
if (isolate_->bootstrapper()->IsActive()) return;
// Just continue if breaks are disabled.

View File

@ -311,9 +311,6 @@ class V8_EXPORT_PRIVATE Debug {
// Check whether this frame is just about to return.
bool IsBreakAtReturn(JavaScriptFrame* frame);
// Support for LiveEdit
void ScheduleFrameRestart(StackFrame* frame);
bool AllFramesOnStackAreBlackboxed();
// Set new script source, throw an exception if error occurred. When preview
@ -380,13 +377,6 @@ class V8_EXPORT_PRIVATE Debug {
return reinterpret_cast<Address>(&thread_local_.suspended_generator_);
}
Address restart_fp_address() {
return reinterpret_cast<Address>(&thread_local_.restart_fp_);
}
bool will_restart() const {
return thread_local_.restart_fp_ != kNullAddress;
}
StepAction last_step_action() { return thread_local_.last_step_action_; }
bool break_on_next_function_call() const {
return thread_local_.break_on_next_function_call_;
@ -548,9 +538,6 @@ class V8_EXPORT_PRIVATE Debug {
// The suspended generator object to track when stepping.
Object suspended_generator_;
// The new frame pointer to drop to when restarting a frame.
Address restart_fp_;
// Last used inspector breakpoint id.
int last_breakpoint_id_;
@ -669,25 +656,6 @@ class SuppressDebug {
bool old_state_;
};
// Code generator routines.
class DebugCodegen : public AllStatic {
public:
enum DebugBreakCallHelperMode {
SAVE_RESULT_REGISTER,
IGNORE_RESULT_REGISTER
};
// Builtin to drop frames to restart function.
static void GenerateFrameDropperTrampoline(MacroAssembler* masm);
// Builtin to atomically (wrt deopts) handle debugger statement and
// drop frames to restart function if necessary.
static void GenerateHandleDebuggerStatement(MacroAssembler* masm);
// Builtin to trigger a debug break before entering the function.
static void GenerateDebugBreakTrampoline(MacroAssembler* masm);
};
} // namespace internal
} // namespace v8

View File

@ -1,54 +0,0 @@
// Copyright 2012 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.
#if V8_TARGET_ARCH_IA32
#include "src/debug/debug.h"
#include "src/codegen/macro-assembler.h"
#include "src/debug/liveedit.h"
#include "src/execution/frames-inl.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ CallRuntime(Runtime::kHandleDebuggerStatement, 0);
}
__ MaybeDropFrames();
// Return to caller.
__ ret(0);
}
void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
// Frame is being dropped:
// - Drop to the target frame specified by eax.
// - Look up current function on the frame.
// - Leave the frame.
// - Restart the frame by calling the function.
__ mov(ebp, eax);
__ mov(edi, Operand(ebp, StandardFrameConstants::kFunctionOffset));
__ mov(eax, Operand(ebp, StandardFrameConstants::kArgCOffset));
__ leave();
// The arguments are already in the stack (including any necessary padding),
// we should not try to massage the arguments again.
__ mov(ecx, Immediate(kDontAdaptArgumentsSentinel));
__ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
__ InvokeFunctionCode(edi, no_reg, ecx, eax, JUMP_FUNCTION);
}
const bool LiveEdit::kFrameDropperSupported = true;
#undef __
} // namespace internal
} // namespace v8
#endif // V8_TARGET_ARCH_IA32

View File

@ -1190,42 +1190,6 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script,
result->script = ToApiHandle<v8::debug::Script>(new_script);
}
void LiveEdit::InitializeThreadLocal(Debug* debug) {
debug->thread_local_.restart_fp_ = 0;
}
bool LiveEdit::RestartFrame(JavaScriptFrame* frame) {
if (!LiveEdit::kFrameDropperSupported) return false;
Isolate* isolate = frame->isolate();
StackFrameId break_frame_id = isolate->debug()->break_frame_id();
bool break_frame_found = break_frame_id == StackFrameId::NO_ID;
for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
StackFrame* current = it.frame();
break_frame_found = break_frame_found || break_frame_id == current->id();
if (current->fp() == frame->fp()) {
if (break_frame_found) {
isolate->debug()->ScheduleFrameRestart(current);
return true;
} else {
return false;
}
}
if (!break_frame_found) continue;
if (current->is_exit() || current->is_builtin_exit()) {
return false;
}
if (!current->is_java_script()) continue;
std::vector<Handle<SharedFunctionInfo>> shareds;
JavaScriptFrame::cast(current)->GetFunctions(&shareds);
for (auto& shared : shareds) {
if (IsResumableFunction(shared->kind())) {
return false;
}
}
}
return false;
}
void LiveEdit::CompareStrings(Isolate* isolate, Handle<String> s1,
Handle<String> s2,
std::vector<SourceChangeRange>* diffs) {

View File

@ -56,11 +56,6 @@ struct SourceChangeRange {
class V8_EXPORT_PRIVATE LiveEdit : AllStatic {
public:
static void InitializeThreadLocal(Debug* debug);
// Restarts the call frame and completely drops all frames above it.
static bool RestartFrame(JavaScriptFrame* frame);
static void CompareStrings(Isolate* isolate, Handle<String> a,
Handle<String> b,
std::vector<SourceChangeRange>* diffs);
@ -69,8 +64,6 @@ class V8_EXPORT_PRIVATE LiveEdit : AllStatic {
static void PatchScript(Isolate* isolate, Handle<Script> script,
Handle<String> source, bool preview,
debug::LiveEditResult* result);
// Architecture-specific constant.
static const bool kFrameDropperSupported;
};
} // namespace internal
} // namespace v8

View File

@ -1,55 +0,0 @@
// Copyright 2012 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.
#if V8_TARGET_ARCH_MIPS
#include "src/debug/debug.h"
#include "src/codegen/macro-assembler.h"
#include "src/debug/liveedit.h"
#include "src/execution/frames-inl.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ CallRuntime(Runtime::kHandleDebuggerStatement, 0);
}
__ MaybeDropFrames();
// Return to caller.
__ Ret();
}
void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
// Frame is being dropped:
// - Drop to the target frame specified by a1.
// - Look up current function on the frame.
// - Leave the frame.
// - Restart the frame by calling the function.
__ mov(fp, a1);
__ lw(a1, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ lw(a0, MemOperand(fp, StandardFrameConstants::kArgCOffset));
// Pop return address and frame.
__ LeaveFrame(StackFrame::INTERNAL);
__ li(a2, Operand(kDontAdaptArgumentsSentinel));
__ InvokeFunction(a1, a2, a0, JUMP_FUNCTION);
}
const bool LiveEdit::kFrameDropperSupported = true;
#undef __
} // namespace internal
} // namespace v8
#endif // V8_TARGET_ARCH_MIPS

View File

@ -1,55 +0,0 @@
// Copyright 2012 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.
#if V8_TARGET_ARCH_MIPS64
#include "src/debug/debug.h"
#include "src/codegen/macro-assembler.h"
#include "src/debug/liveedit.h"
#include "src/execution/frames-inl.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ CallRuntime(Runtime::kHandleDebuggerStatement, 0);
}
__ MaybeDropFrames();
// Return to caller.
__ Ret();
}
void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
// Frame is being dropped:
// - Drop to the target frame specified by a1.
// - Look up current function on the frame.
// - Leave the frame.
// - Restart the frame by calling the function.
__ mov(fp, a1);
__ Ld(a1, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ Ld(a0, MemOperand(fp, StandardFrameConstants::kArgCOffset));
// Pop return address and frame.
__ LeaveFrame(StackFrame::INTERNAL);
__ li(a2, Operand(kDontAdaptArgumentsSentinel));
__ InvokeFunction(a1, a2, a0, JUMP_FUNCTION);
}
const bool LiveEdit::kFrameDropperSupported = true;
#undef __
} // namespace internal
} // namespace v8
#endif // V8_TARGET_ARCH_MIPS64

View File

@ -1,5 +0,0 @@
junyan@redhat.com
joransiu@ca.ibm.com
midawson@redhat.com
mfarazma@redhat.com
vasili.skurydzin@ibm.com

View File

@ -1,53 +0,0 @@
// Copyright 2014 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.
#if V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
#include "src/debug/debug.h"
#include "src/codegen/macro-assembler.h"
#include "src/debug/liveedit.h"
#include "src/execution/frames-inl.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ CallRuntime(Runtime::kHandleDebuggerStatement, 0);
}
__ MaybeDropFrames();
// Return to caller.
__ Ret();
}
void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
// Frame is being dropped:
// - Drop to the target frame specified by r4.
// - Look up current function on the frame.
// - Leave the frame.
// - Restart the frame by calling the function.
__ mr(fp, r4);
__ LoadP(r4, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ LoadP(r3, MemOperand(fp, StandardFrameConstants::kArgCOffset));
__ LeaveFrame(StackFrame::INTERNAL);
// The arguments are already in the stack (including any necessary padding),
// we should not try to massage the arguments again.
__ mov(r5, Operand(kDontAdaptArgumentsSentinel));
__ InvokeFunction(r4, r5, r3, JUMP_FUNCTION);
}
const bool LiveEdit::kFrameDropperSupported = true;
#undef __
} // namespace internal
} // namespace v8
#endif // V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64

View File

@ -1,53 +0,0 @@
// Copyright 2021 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.
#if V8_TARGET_ARCH_RISCV64
#include "src/codegen/macro-assembler.h"
#include "src/debug/debug.h"
#include "src/debug/liveedit.h"
#include "src/execution/frames-inl.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ CallRuntime(Runtime::kHandleDebuggerStatement, 0);
}
__ MaybeDropFrames();
// Return to caller.
__ Ret();
}
void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
// Frame is being dropped:
// - Drop to the target frame specified by a1.
// - Look up current function on the frame.
// - Leave the frame.
// - Restart the frame by calling the function.
__ mv(fp, a1);
__ Ld(a1, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ Ld(a0, MemOperand(fp, StandardFrameConstants::kArgCOffset));
// Pop return address and frame.
__ LeaveFrame(StackFrame::INTERNAL);
__ li(a2, Operand(kDontAdaptArgumentsSentinel));
__ InvokeFunction(a1, a2, a0, JUMP_FUNCTION);
}
const bool LiveEdit::kFrameDropperSupported = true;
#undef __
} // namespace internal
} // namespace v8
#endif // V8_TARGET_ARCH_RISCV64

View File

@ -1,55 +0,0 @@
// Copyright 2015 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.
#include "src/init/v8.h"
#if V8_TARGET_ARCH_S390
#include "src/debug/debug.h"
#include "src/codegen/macro-assembler.h"
#include "src/debug/liveedit.h"
#include "src/execution/frames-inl.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ CallRuntime(Runtime::kHandleDebuggerStatement, 0);
}
__ MaybeDropFrames();
// Return to caller.
__ Ret();
}
void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
// Frame is being dropped:
// - Drop to the target frame specified by r3.
// - Look up current function on the frame.
// - Leave the frame.
// - Restart the frame by calling the function.
__ mov(fp, r3);
__ LoadU64(r3, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ LoadU64(r2, MemOperand(fp, StandardFrameConstants::kArgCOffset));
__ LeaveFrame(StackFrame::INTERNAL);
// The arguments are already in the stack (including any necessary padding),
// we should not try to massage the arguments again.
__ mov(r4, Operand(kDontAdaptArgumentsSentinel));
__ InvokeFunction(r3, r4, r2, JUMP_FUNCTION);
}
const bool LiveEdit::kFrameDropperSupported = true;
#undef __
} // namespace internal
} // namespace v8
#endif // V8_TARGET_ARCH_S390

View File

@ -1,55 +0,0 @@
// Copyright 2012 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.
#if V8_TARGET_ARCH_X64
#include "src/debug/debug.h"
#include "src/codegen/assembler.h"
#include "src/codegen/macro-assembler.h"
#include "src/debug/liveedit.h"
#include "src/execution/frames-inl.h"
#include "src/objects/objects-inl.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ CallRuntime(Runtime::kHandleDebuggerStatement, 0);
}
__ MaybeDropFrames();
// Return to caller.
__ ret(0);
}
void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
// Frame is being dropped:
// - Drop to the target frame specified by rbx.
// - Look up current function on the frame.
// - Leave the frame.
// - Restart the frame by calling the function.
__ movq(rbp, rbx);
__ movq(rdi, Operand(rbp, StandardFrameConstants::kFunctionOffset));
__ movq(rax, Operand(rbp, StandardFrameConstants::kArgCOffset));
__ leave();
// The arguments are already in the stack (including any necessary padding),
// we should not try to massage the arguments again.
__ movq(rbx, Immediate(kDontAdaptArgumentsSentinel));
__ InvokeFunction(rdi, no_reg, rbx, rax, JUMP_FUNCTION);
}
const bool LiveEdit::kFrameDropperSupported = true;
#undef __
} // namespace internal
} // namespace v8
#endif // V8_TARGET_ARCH_X64

View File

@ -1036,23 +1036,7 @@ Response V8DebuggerAgentImpl::restartFrame(
std::unique_ptr<Array<CallFrame>>* newCallFrames,
Maybe<protocol::Runtime::StackTrace>* asyncStackTrace,
Maybe<protocol::Runtime::StackTraceId>* asyncStackTraceId) {
if (!isPaused()) return Response::ServerError(kDebuggerNotPaused);
InjectedScript::CallFrameScope scope(m_session, callFrameId);
Response response = scope.initialize();
if (!response.IsSuccess()) return response;
int frameOrdinal = static_cast<int>(scope.frameOrdinal());
auto it = v8::debug::StackTraceIterator::Create(m_isolate, frameOrdinal);
if (it->Done()) {
return Response::ServerError("Could not find call frame with given id");
}
if (!it->Restart()) {
return Response::InternalError();
}
response = currentCallFrames(newCallFrames);
if (!response.IsSuccess()) return response;
*asyncStackTrace = currentAsyncStackTrace();
*asyncStackTraceId = currentExternalStackTrace();
return Response::Success();
return Response::ServerError("Frame restarting not supported");
}
Response V8DebuggerAgentImpl::getScriptSource(

View File

@ -1310,26 +1310,6 @@ void InterpreterAssembler::AbortIfWordNotEqual(TNode<WordT> lhs,
BIND(&ok);
}
void InterpreterAssembler::MaybeDropFrames(TNode<Context> context) {
TNode<ExternalReference> restart_fp_address =
ExternalConstant(ExternalReference::debug_restart_fp_address(isolate()));
TNode<IntPtrT> restart_fp = Load<IntPtrT>(restart_fp_address);
TNode<IntPtrT> null = IntPtrConstant(0);
Label ok(this), drop_frames(this);
Branch(IntPtrEqual(restart_fp, null), &ok, &drop_frames);
BIND(&drop_frames);
// We don't expect this call to return since the frame dropper tears down
// the stack and jumps into the function on the target frame to restart it.
CallStub(CodeFactory::FrameDropperTrampoline(isolate()), context, restart_fp);
Abort(AbortReason::kUnexpectedReturnFromFrameDropper);
Goto(&ok);
BIND(&ok);
}
void InterpreterAssembler::OnStackReplacement(TNode<Context> context,
TNode<IntPtrT> relative_jump) {
TNode<JSFunction> function = CAST(LoadRegister(Register::function_closure()));

View File

@ -241,9 +241,6 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
TNode<FixedArrayBase> parameters_and_registers,
TNode<IntPtrT> formal_parameter_count, TNode<UintPtrT> register_count);
// Dispatch to frame dropper trampoline if necessary.
void MaybeDropFrames(TNode<Context> context);
// Perform OnStackReplacement.
void OnStackReplacement(TNode<Context> context, TNode<IntPtrT> relative_jump);

View File

@ -2776,7 +2776,7 @@ IGNITION_HANDLER(ThrowIfNotSuperConstructor, InterpreterAssembler) {
// Call runtime to handle debugger statement.
IGNITION_HANDLER(Debugger, InterpreterAssembler) {
TNode<Context> context = GetContext();
CallStub(CodeFactory::HandleDebuggerStatement(isolate()), context);
CallRuntime(Runtime::kHandleDebuggerStatement, context);
Dispatch();
}
@ -2791,7 +2791,6 @@ IGNITION_HANDLER(Debugger, InterpreterAssembler) {
Runtime::kDebugBreakOnBytecode, context, accumulator); \
TNode<Object> return_value = Projection<0>(result_pair); \
TNode<IntPtrT> original_bytecode = SmiUntag(Projection<1>(result_pair)); \
MaybeDropFrames(context); \
SetAccumulator(return_value); \
DispatchToBytecodeWithOptionalStarLookahead(original_bytecode); \
}

View File

@ -61,13 +61,6 @@ RUNTIME_FUNCTION_RETURN_PAIR(Runtime_DebugBreakOnBytecode) {
handle(it.frame()->function(), isolate));
}
// If we are dropping frames, there is no need to get a return value or
// bytecode, since we will be restarting execution at a different frame.
if (isolate->debug()->will_restart()) {
return MakePair(ReadOnlyRoots(isolate).undefined_value(),
Smi::FromInt(static_cast<uint8_t>(Bytecode::kIllegal)));
}
// Return the handler from the original bytecode array.
DCHECK(it.frame()->is_interpreted());
InterpretedFrame* interpreted_frame =

View File

@ -1,154 +0,0 @@
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Flags: --noanalyze-environment-liveness
Debug = debug.Debug
function FindCallFrame(exec_state, frame_code) {
var number = Number(frame_code);
if (number >= 0) {
return exec_state.frame(number);
} else {
for (var i = 0; i < exec_state.frameCount(); i++) {
var frame = exec_state.frame(i);
var func_mirror = frame.func();
if (frame_code == func_mirror.name()) {
return frame;
}
}
}
throw new Error("Failed to find function name " + function_name);
}
function TestCase(test_scenario, expected_output) {
// Global variable, accessed from eval'd script.
test_output = "";
function TestCode() {
function A() {
// Extra stack variable. To make function not slim.
// Restarter doesn't work on slim function when stopped on 'debugger'
// statement. (There is no padding for 'debugger' statement).
var o = {};
test_output += 'A';
test_output += '=';
debugger;
return 'Capybara';
}
function B(p1, p2) {
test_output += 'B';
return A();
}
function C() {
test_output += 'C';
// Function call with argument adaptor is intentional.
return B();
}
function D() {
test_output += 'D';
// Function call with argument adaptor is intentional.
return C(1, 2);
}
function E() {
test_output += 'E';
return D();
}
function F() {
test_output += 'F';
return E();
}
return F();
}
var scenario_pos = 0;
function DebuggerStatementHandler(exec_state) {
while (true) {
assertTrue(scenario_pos < test_scenario.length);
var change_code = test_scenario[scenario_pos++];
if (change_code == '=') {
// Continue.
return;
}
var frame = FindCallFrame(exec_state, change_code);
var error = frame.restart();
if (typeof error === 'string')
throw new Error(error);
}
}
var saved_exception = null;
function listener(event, exec_state, event_data, data) {
if (saved_exception != null) {
return;
}
if (event == Debug.DebugEvent.Break) {
try {
DebuggerStatementHandler(exec_state);
} catch (e) {
saved_exception = e;
}
} else {
print("Other: " + event);
}
}
Debug.setListener(listener);
assertEquals("Capybara", TestCode());
Debug.setListener(null);
if (saved_exception) {
print("Exception: " + saved_exception);
print("Stack: " + saved_exception.stack);
assertUnreachable();
}
print(test_output);
assertEquals(expected_output, test_output);
}
TestCase('0==', "FEDCBA=A=");
TestCase('1==', "FEDCBA=BA=");
TestCase('2==', "FEDCBA=CBA=");
TestCase('3==', "FEDCBA=DCBA=");
TestCase('4==', "FEDCBA=EDCBA=");
TestCase('5==', "FEDCBA=FEDCBA=");
TestCase('=', "FEDCBA=");
TestCase('C==', "FEDCBA=CBA=");
TestCase('B=C=A=D==', "FEDCBA=BA=CBA=A=DCBA=");
// Successive restarts don't work now and require additional fix.
//TestCase('BCDE==', "FEDCBA=EDCBA=");
//TestCase('BC=BCDE==', "FEDCBA=CBA=EDCBA=");
//TestCase('EF==', "FEDCBA=FEDCBA=");

View File

@ -125,7 +125,6 @@
# Stack manipulations in LiveEdit is not implemented for this arch.
'debug/debug-liveedit-check-stack': [SKIP],
'debug/debug-liveedit-restart-frame': [SKIP],
}], # 'arch == s390 or arch == s390x'
##############################################################################

View File

@ -1,9 +0,0 @@
Tests that accessing no longer valid call frames returns an error
Paused on 'debugger;'
resume
restartFrame
PASS, error message as expected
evaluateOnFrame
PASS, error message as expected
setVariableValue
PASS, error message as expected

View File

@ -1,69 +0,0 @@
// Copyright 2016 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Tests that accessing no longer valid call frames returns an error');
contextGroup.addScript(`
function testFunction()
{
debugger;
}
//# sourceURL=foo.js`);
Protocol.Debugger.enable();
Protocol.Debugger.oncePaused().then(handleDebuggerPausedOne);
Protocol.Runtime.evaluate({ "expression": "setTimeout(testFunction, 0)" });
var obsoleteTopFrameId;
function handleDebuggerPausedOne(messageObject)
{
InspectorTest.log("Paused on 'debugger;'");
var topFrame = messageObject.params.callFrames[0];
obsoleteTopFrameId = topFrame.callFrameId;
Protocol.Debugger.resume().then(callbackResume);
}
function callbackResume(response)
{
InspectorTest.log("resume");
InspectorTest.log("restartFrame");
Protocol.Debugger.restartFrame({ callFrameId: obsoleteTopFrameId }).then(callbackRestartFrame);
}
function callbackRestartFrame(response)
{
logErrorResponse(response);
InspectorTest.log("evaluateOnFrame");
Protocol.Debugger.evaluateOnCallFrame({ callFrameId: obsoleteTopFrameId, expression: "0"}).then(callbackEvaluate);
}
function callbackEvaluate(response)
{
logErrorResponse(response);
InspectorTest.log("setVariableValue");
Protocol.Debugger.setVariableValue({ callFrameId: obsoleteTopFrameId, scopeNumber: 0, variableName: "a", newValue: { value: 0 } }).then(callbackSetVariableValue);
}
function callbackSetVariableValue(response)
{
logErrorResponse(response);
InspectorTest.completeTest();
}
function logErrorResponse(response)
{
if (response.error) {
if (response.error.message.indexOf("Can only perform operation while paused.") !== -1) {
InspectorTest.log("PASS, error message as expected");
return;
}
}
InspectorTest.log("FAIL, unexpected error message");
InspectorTest.log(JSON.stringify(response));
}

View File

@ -1,10 +1,12 @@
Checks that Debugger.restartFrame works
Checks that Debugger.restartFrame returns an error
Paused at debugger:
function foo() { #debugger; }; foo();
Call restart and dump location of restart:
function foo() { debugger; }; #foo();
Location after restart:
function foo() { #debugger; }; foo();
restartFrame result:
{
error : {
code : -32000
message : Frame restarting not supported
}
id : <messageId>
}

View File

@ -3,7 +3,7 @@
// found in the LICENSE file.
const {session, Protocol} =
InspectorTest.start('Checks that Debugger.restartFrame works');
InspectorTest.start('Checks that Debugger.restartFrame returns an error');
session.setupScriptMap();
@ -16,18 +16,9 @@ session.setupScriptMap();
const { params: { callFrames: before } } =
await Protocol.Debugger.oncePaused();
await session.logSourceLocation(before[0].location);
InspectorTest.log('Call restart and dump location of restart:');
const { result: { callFrames: restart }} =
await Protocol.Debugger.restartFrame({
callFrameId: before[0].callFrameId
});
await session.logSourceLocation(restart[0].location);
InspectorTest.log('Location after restart:');
Protocol.Debugger.resume();
const { params: { callFrames: after } } =
await Protocol.Debugger.oncePaused();
await session.logSourceLocation(after[0].location);
Protocol.Debugger.resume();
await evalPromise;
const result = await Protocol.Debugger.restartFrame({ callFrameId: before[0].callFrameId });
InspectorTest.log('restartFrame result:');
InspectorTest.logMessage(result);
await Promise.all([Protocol.Debugger.resume(), evalPromise]);
InspectorTest.completeTest();
})()

View File

@ -220,7 +220,6 @@
'cpu-profiler/enable-disable': [SKIP],
'cpu-profiler/record-cpu-profile': [SKIP],
'cpu-profiler/stop-without-preceeding-start': [SKIP],
'debugger/access-obsolete-frame': [SKIP],
'debugger/asm-js-breakpoint-before-exec': [SKIP],
'debugger/asm-js-breakpoint-during-exec': [SKIP],
'debugger/asm-js-stack': [SKIP],