[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:
parent
bfaca03f79
commit
93f85699e2
11
BUILD.gn
11
BUILD.gn
@ -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",
|
||||
|
@ -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
|
||||
|
@ -2272,7 +2272,7 @@ void BaselineCompiler::VisitGetIterator() {
|
||||
|
||||
void BaselineCompiler::VisitDebugger() {
|
||||
SaveAccumulatorScope accumulator_scope(&basm_);
|
||||
CallBuiltin<Builtins::kHandleDebuggerStatement>();
|
||||
CallRuntime(Runtime::kHandleDebuggerStatement);
|
||||
}
|
||||
|
||||
void BaselineCompiler::VisitIncBlockCounter() {
|
||||
|
@ -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
|
@ -200,8 +200,6 @@ namespace internal {
|
||||
\
|
||||
/* Debugger */ \
|
||||
TFJ(DebugBreakTrampoline, kDontAdaptArgumentsSentinel) \
|
||||
ASM(FrameDropperTrampoline, FrameDropperTrampoline) \
|
||||
ASM(HandleDebuggerStatement, ContextOnly) \
|
||||
\
|
||||
/* Type conversions */ \
|
||||
TFC(ToNumber, TypeConversion) \
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -1901,9 +1901,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
|
||||
|
||||
// ---- Code generation helpers ----
|
||||
|
||||
// Frame restart support
|
||||
void MaybeDropFrames();
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Support functions.
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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(
|
||||
|
@ -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, \
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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(); }
|
||||
|
@ -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
|
@ -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
|
@ -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;
|
||||
};
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -1,5 +0,0 @@
|
||||
junyan@redhat.com
|
||||
joransiu@ca.ibm.com
|
||||
midawson@redhat.com
|
||||
mfarazma@redhat.com
|
||||
vasili.skurydzin@ibm.com
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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(
|
||||
|
@ -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()));
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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); \
|
||||
}
|
||||
|
@ -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 =
|
||||
|
@ -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=");
|
@ -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'
|
||||
|
||||
##############################################################################
|
||||
|
@ -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
|
@ -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));
|
||||
}
|
@ -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>
|
||||
}
|
||||
|
@ -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();
|
||||
})()
|
||||
|
@ -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],
|
||||
|
Loading…
Reference in New Issue
Block a user