Commit 25d2b247 authored by machenbach's avatar machenbach Committed by Commit bot

Revert of [Interpreter] Adds support to fetch return value on break at return....

Revert of [Interpreter] Adds support to fetch return value on break at return. (patchset #9 id:160001 of https://codereview.chromium.org/1818873003/ )

Reason for revert:
[Sheriff] Seems to break nosnap debug:
https://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20nosnap%20-%20debug/builds/6019

Original issue's description:
> [Interpreter] Adds support to fetch return value on break at return.
>
> Debugger fetches the return value of a function when we break at return.
> Interpreter holds the return value in accumulator. This is not stored in a
> specified location on stack and hence it is not possible to look it up from
> stack similar to full-codegen or optimized frames. This cl adds support to
> store the value of accumulator on debug breaks. The value of accumulator is
> passed to the runtime function and is then stored in thread local data.
>
> Also changes full-codegen implementation to match that of ignition.
> The return value from full-codegen is also stored in thread local data.
> The return value is fetched directly thread local data instead of
> finding it by iterating over frames.
>
> BUG=v8:4280, v8:4690
> LOG=N
>
> Committed: https://crrev.com/fb65527b75754bcf3b173f16f5d0b04a1c6d9b99
> Cr-Commit-Position: refs/heads/master@{#35060}

TBR=rmcilroy@chromium.org,yangguo@chromium.org,weiliang.lin@intel.com,balazs.kilvady@imgtec.com,jyan@ca.ibm.com,mythria@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:4280, v8:4690

Review URL: https://codereview.chromium.org/1834733002

Cr-Commit-Position: refs/heads/master@{#35065}
parent 2e87c7f5
...@@ -81,15 +81,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -81,15 +81,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
__ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); __ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
__ push(ip); __ push(ip);
// Push arguments for DebugBreak call. if (mode == SAVE_RESULT_REGISTER) __ push(r0);
if (mode == SAVE_RESULT_REGISTER) {
// Break on return. __ mov(r0, Operand::Zero()); // no arguments
__ push(r0);
} else {
// Non-return breaks.
__ Push(masm->isolate()->factory()->the_hole_value());
}
__ mov(r0, Operand(1));
__ mov(r1, __ mov(r1,
Operand(ExternalReference( Operand(ExternalReference(
Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate()))); Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())));
...@@ -100,14 +94,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -100,14 +94,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
if (FLAG_debug_code) { if (FLAG_debug_code) {
for (int i = 0; i < kNumJSCallerSaved; i++) { for (int i = 0; i < kNumJSCallerSaved; i++) {
Register reg = {JSCallerSavedCode(i)}; Register reg = {JSCallerSavedCode(i)};
// Do not clobber r0 if SAVE_RESULT_REGISTER is set. It will __ mov(reg, Operand(kDebugZapValue));
// contain return value of the function.
if (!(reg.is(r0) && SAVE_RESULT_REGISTER)) {
__ mov(reg, Operand(kDebugZapValue));
}
} }
} }
if (mode == SAVE_RESULT_REGISTER) __ pop(r0);
// Don't bother removing padding bytes pushed on the stack // Don't bother removing padding bytes pushed on the stack
// as the frame is going to be restored right away. // as the frame is going to be restored right away.
......
...@@ -92,15 +92,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -92,15 +92,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
__ Mov(scratch, Smi::FromInt(LiveEdit::kFramePaddingInitialSize)); __ Mov(scratch, Smi::FromInt(LiveEdit::kFramePaddingInitialSize));
__ Push(scratch); __ Push(scratch);
// Push arguments for DebugBreak call. if (mode == SAVE_RESULT_REGISTER) __ Push(x0);
if (mode == SAVE_RESULT_REGISTER) {
// Break on return. __ Mov(x0, 0); // No arguments.
__ Push(x0);
} else {
// Non-return breaks.
__ Push(masm->isolate()->factory()->the_hole_value());
}
__ Mov(x0, 1);
__ Mov(x1, ExternalReference(Runtime::FunctionForId(Runtime::kDebugBreak), __ Mov(x1, ExternalReference(Runtime::FunctionForId(Runtime::kDebugBreak),
masm->isolate())); masm->isolate()));
...@@ -110,14 +104,13 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -110,14 +104,13 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
if (FLAG_debug_code) { if (FLAG_debug_code) {
for (int i = 0; i < kNumJSCallerSaved; i++) { for (int i = 0; i < kNumJSCallerSaved; i++) {
Register reg = Register::XRegFromCode(JSCallerSavedCode(i)); Register reg = Register::XRegFromCode(JSCallerSavedCode(i));
// Do not clobber x0 if SAVE_RESULT_REGISTER is set. It will __ Mov(reg, Operand(kDebugZapValue));
// contain return value of the function.
if (!(reg.is(x0) && SAVE_RESULT_REGISTER)) {
__ Mov(reg, Operand(kDebugZapValue));
}
} }
} }
// Restore the register values from the expression stack.
if (mode == SAVE_RESULT_REGISTER) __ Pop(x0);
// Don't bother removing padding bytes pushed on the stack // Don't bother removing padding bytes pushed on the stack
// as the frame is going to be restored right away. // as the frame is going to be restored right away.
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "src/frames-inl.h" #include "src/frames-inl.h"
#include "src/full-codegen/full-codegen.h" #include "src/full-codegen/full-codegen.h"
#include "src/global-handles.h" #include "src/global-handles.h"
#include "src/interpreter/bytecodes.h"
#include "src/interpreter/interpreter.h" #include "src/interpreter/interpreter.h"
#include "src/isolate-inl.h" #include "src/isolate-inl.h"
#include "src/list.h" #include "src/list.h"
...@@ -473,7 +474,6 @@ void Debug::ThreadInit() { ...@@ -473,7 +474,6 @@ void Debug::ThreadInit() {
thread_local_.last_fp_ = 0; thread_local_.last_fp_ = 0;
thread_local_.target_fp_ = 0; thread_local_.target_fp_ = 0;
thread_local_.step_in_enabled_ = false; thread_local_.step_in_enabled_ = false;
thread_local_.return_value_ = Handle<Object>();
// TODO(isolates): frames_are_dropped_? // TODO(isolates): frames_are_dropped_?
base::NoBarrier_Store(&thread_local_.current_debug_scope_, base::NoBarrier_Store(&thread_local_.current_debug_scope_,
static_cast<base::AtomicWord>(0)); static_cast<base::AtomicWord>(0));
...@@ -560,8 +560,10 @@ void Debug::Unload() { ...@@ -560,8 +560,10 @@ void Debug::Unload() {
debug_context_ = Handle<Context>(); debug_context_ = Handle<Context>();
} }
void Debug::Break(JavaScriptFrame* frame) {
void Debug::Break(Arguments args, JavaScriptFrame* frame) {
HandleScope scope(isolate_); HandleScope scope(isolate_);
DCHECK(args.length() == 0);
// Initialize LiveEdit. // Initialize LiveEdit.
LiveEdit::InitializeThreadLocal(this); LiveEdit::InitializeThreadLocal(this);
...@@ -1567,11 +1569,25 @@ void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) { ...@@ -1567,11 +1569,25 @@ void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) {
UNREACHABLE(); UNREACHABLE();
} }
void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { Object* Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
after_break_target_ = NULL; if (frame->is_interpreted()) {
if (!LiveEdit::SetAfterBreakTarget(this)) { // Find the handler from the original bytecode array.
// Continue just after the slot. InterpretedFrame* interpreted_frame =
after_break_target_ = frame->pc(); reinterpret_cast<InterpretedFrame*>(frame);
SharedFunctionInfo* shared = interpreted_frame->function()->shared();
BytecodeArray* bytecode_array = shared->bytecode_array();
int bytecode_offset = interpreted_frame->GetBytecodeOffset();
interpreter::Bytecode bytecode =
interpreter::Bytecodes::FromByte(bytecode_array->get(bytecode_offset));
return isolate_->interpreter()->GetBytecodeHandler(
bytecode, interpreter::OperandScale::kSingle);
} else {
after_break_target_ = NULL;
if (!LiveEdit::SetAfterBreakTarget(this)) {
// Continue just after the slot.
after_break_target_ = frame->pc();
}
return isolate_->heap()->undefined_value();
} }
} }
...@@ -2312,10 +2328,9 @@ DebugScope::DebugScope(Debug* debug) ...@@ -2312,10 +2328,9 @@ DebugScope::DebugScope(Debug* debug)
base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
reinterpret_cast<base::AtomicWord>(this)); reinterpret_cast<base::AtomicWord>(this));
// Store the previous break id, frame id and return value. // Store the previous break id and frame id.
break_id_ = debug_->break_id(); break_id_ = debug_->break_id();
break_frame_id_ = debug_->break_frame_id(); break_frame_id_ = debug_->break_frame_id();
return_value_ = debug_->return_value();
// Create the new break info. If there is no JavaScript frames there is no // Create the new break info. If there is no JavaScript frames there is no
// break frame id. // break frame id.
...@@ -2353,7 +2368,6 @@ DebugScope::~DebugScope() { ...@@ -2353,7 +2368,6 @@ DebugScope::~DebugScope() {
// Restore to the previous break state. // Restore to the previous break state.
debug_->thread_local_.break_frame_id_ = break_frame_id_; debug_->thread_local_.break_frame_id_ = break_frame_id_;
debug_->thread_local_.break_id_ = break_id_; debug_->thread_local_.break_id_ = break_id_;
debug_->thread_local_.return_value_ = return_value_;
debug_->UpdateState(); debug_->UpdateState();
} }
......
...@@ -427,8 +427,8 @@ class Debug { ...@@ -427,8 +427,8 @@ class Debug {
// Internal logic // Internal logic
bool Load(); bool Load();
void Break(JavaScriptFrame* frame); void Break(Arguments args, JavaScriptFrame*);
void SetAfterBreakTarget(JavaScriptFrame* frame); Object* SetAfterBreakTarget(JavaScriptFrame* frame);
// Scripts handling. // Scripts handling.
Handle<FixedArray> GetLoadedScripts(); Handle<FixedArray> GetLoadedScripts();
...@@ -524,11 +524,6 @@ class Debug { ...@@ -524,11 +524,6 @@ class Debug {
StackFrame::Id break_frame_id() { return thread_local_.break_frame_id_; } StackFrame::Id break_frame_id() { return thread_local_.break_frame_id_; }
int break_id() { return thread_local_.break_id_; } int break_id() { return thread_local_.break_id_; }
Handle<Object> return_value() { return thread_local_.return_value_; }
void set_return_value(Handle<Object> value) {
thread_local_.return_value_ = value;
}
// Support for embedding into generated code. // Support for embedding into generated code.
Address is_active_address() { Address is_active_address() {
return reinterpret_cast<Address>(&is_active_); return reinterpret_cast<Address>(&is_active_);
...@@ -683,10 +678,6 @@ class Debug { ...@@ -683,10 +678,6 @@ class Debug {
// Stores the way how LiveEdit has patched the stack. It is used when // Stores the way how LiveEdit has patched the stack. It is used when
// debugger returns control back to user script. // debugger returns control back to user script.
LiveEdit::FrameDropMode frame_drop_mode_; LiveEdit::FrameDropMode frame_drop_mode_;
// Value of accumulator in interpreter frames. In non-interpreter frames
// this value will be the hole.
Handle<Object> return_value_;
}; };
// Storage location for registers when handling debug break calls // Storage location for registers when handling debug break calls
...@@ -728,7 +719,6 @@ class DebugScope BASE_EMBEDDED { ...@@ -728,7 +719,6 @@ class DebugScope BASE_EMBEDDED {
DebugScope* prev_; // Previous scope if entered recursively. DebugScope* prev_; // Previous scope if entered recursively.
StackFrame::Id break_frame_id_; // Previous break frame id. StackFrame::Id break_frame_id_; // Previous break frame id.
int break_id_; // Previous break id. int break_id_; // Previous break id.
Handle<Object> return_value_; // Previous result.
bool failed_; // Did the debug context fail to load? bool failed_; // Did the debug context fail to load?
SaveContext save_; // Saves previous context. SaveContext save_; // Saves previous context.
PostponeInterruptsScope no_termination_exceptons_; PostponeInterruptsScope no_termination_exceptons_;
......
...@@ -68,15 +68,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -68,15 +68,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
} }
__ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
// Push arguments for DebugBreak call. if (mode == SAVE_RESULT_REGISTER) __ push(eax);
if (mode == SAVE_RESULT_REGISTER) {
// Break on return. __ Move(eax, Immediate(0)); // No arguments.
__ push(eax);
} else {
// Non-return breaks.
__ Push(masm->isolate()->factory()->the_hole_value());
}
__ Move(eax, Immediate(1));
__ mov(ebx, __ mov(ebx,
Immediate(ExternalReference( Immediate(ExternalReference(
Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate()))); Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())));
...@@ -87,14 +81,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -87,14 +81,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
if (FLAG_debug_code) { if (FLAG_debug_code) {
for (int i = 0; i < kNumJSCallerSaved; ++i) { for (int i = 0; i < kNumJSCallerSaved; ++i) {
Register reg = {JSCallerSavedCode(i)}; Register reg = {JSCallerSavedCode(i)};
// Do not clobber eax if SAVE_RESULT_REGISTER is set. It will __ Move(reg, Immediate(kDebugZapValue));
// contain return value of the function.
if (!(reg.is(eax) && SAVE_RESULT_REGISTER)) {
__ Move(reg, Immediate(kDebugZapValue));
}
} }
} }
if (mode == SAVE_RESULT_REGISTER) __ pop(eax);
__ pop(ebx); __ pop(ebx);
// We divide stored value by 2 (untagging) and multiply it by word's size. // We divide stored value by 2 (untagging) and multiply it by word's size.
STATIC_ASSERT(kSmiTagSize == 1 && kSmiShiftSize == 0); STATIC_ASSERT(kSmiTagSize == 1 && kSmiShiftSize == 0);
......
...@@ -77,15 +77,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -77,15 +77,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
__ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
__ push(at); __ push(at);
// Push arguments for DebugBreak call. if (mode == SAVE_RESULT_REGISTER) __ push(v0);
if (mode == SAVE_RESULT_REGISTER) {
// Break on return. __ PrepareCEntryArgs(0); // No arguments.
__ push(v0);
} else {
// Non-return breaks.
__ Push(masm->isolate()->factory()->the_hole_value());
}
__ PrepareCEntryArgs(1);
__ PrepareCEntryFunction(ExternalReference( __ PrepareCEntryFunction(ExternalReference(
Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())); Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate()));
...@@ -95,14 +89,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -95,14 +89,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
if (FLAG_debug_code) { if (FLAG_debug_code) {
for (int i = 0; i < kNumJSCallerSaved; i++) { for (int i = 0; i < kNumJSCallerSaved; i++) {
Register reg = {JSCallerSavedCode(i)}; Register reg = {JSCallerSavedCode(i)};
// Do not clobber v0 if SAVE_RESULT_REGISTER is set. It will __ li(reg, kDebugZapValue);
// contain return value of the function returned by DebugBreak.
if (!(reg.is(v0) && SAVE_RESULT_REGISTER)) {
__ li(reg, kDebugZapValue);
}
} }
} }
if (mode == SAVE_RESULT_REGISTER) __ pop(v0);
// Don't bother removing padding bytes pushed on the stack // Don't bother removing padding bytes pushed on the stack
// as the frame is going to be restored right away. // as the frame is going to be restored right away.
......
...@@ -79,15 +79,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -79,15 +79,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
__ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
__ push(at); __ push(at);
// Push arguments for DebugBreak call. if (mode == SAVE_RESULT_REGISTER) __ push(v0);
if (mode == SAVE_RESULT_REGISTER) {
// Break on return. __ PrepareCEntryArgs(0); // No arguments.
__ push(v0);
} else {
// Non-return breaks.
__ Push(masm->isolate()->factory()->the_hole_value());
}
__ PrepareCEntryArgs(1);
__ PrepareCEntryFunction(ExternalReference( __ PrepareCEntryFunction(ExternalReference(
Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())); Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate()));
...@@ -97,14 +91,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -97,14 +91,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
if (FLAG_debug_code) { if (FLAG_debug_code) {
for (int i = 0; i < kNumJSCallerSaved; i++) { for (int i = 0; i < kNumJSCallerSaved; i++) {
Register reg = {JSCallerSavedCode(i)}; Register reg = {JSCallerSavedCode(i)};
// Do not clobber v0 if SAVE_RESULT_REGISTER is set. It will __ li(reg, kDebugZapValue);
// contain return value of the function returned by DebugBreak.
if (!(reg.is(v0) && SAVE_RESULT_REGISTER)) {
__ li(reg, kDebugZapValue);
}
} }
} }
if (mode == SAVE_RESULT_REGISTER) __ pop(v0);
// Don't bother removing padding bytes pushed on the stack // Don't bother removing padding bytes pushed on the stack
// as the frame is going to be restored right away. // as the frame is going to be restored right away.
......
...@@ -83,15 +83,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -83,15 +83,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
__ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingInitialSize)); __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingInitialSize));
__ push(ip); __ push(ip);
// Push arguments for DebugBreak call. if (mode == SAVE_RESULT_REGISTER) __ push(r3);
if (mode == SAVE_RESULT_REGISTER) {
// Break on return. __ mov(r3, Operand::Zero()); // no arguments
__ push(r3);
} else {
// Non-return breaks.
__ Push(masm->isolate()->factory()->the_hole_value());
}
__ mov(r3, Operand(1));
__ mov(r4, __ mov(r4,
Operand(ExternalReference( Operand(ExternalReference(
Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate()))); Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())));
...@@ -102,14 +96,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -102,14 +96,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
if (FLAG_debug_code) { if (FLAG_debug_code) {
for (int i = 0; i < kNumJSCallerSaved; i++) { for (int i = 0; i < kNumJSCallerSaved; i++) {
Register reg = {JSCallerSavedCode(i)}; Register reg = {JSCallerSavedCode(i)};
// Do not clobber r3 if SAVE_RESULT_REGISTER is set. It will __ mov(reg, Operand(kDebugZapValue));
// contain return value of the function.
if (!(reg.is(r3) && SAVE_RESULT_REGISTER)) {
__ mov(reg, Operand(kDebugZapValue));
}
} }
} }
if (mode == SAVE_RESULT_REGISTER) __ pop(r3);
// Don't bother removing padding bytes pushed on the stack // Don't bother removing padding bytes pushed on the stack
// as the frame is going to be restored right away. // as the frame is going to be restored right away.
......
...@@ -88,15 +88,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -88,15 +88,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
__ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingInitialSize)); __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingInitialSize));
__ push(ip); __ push(ip);
// Push arguments for DebugBreak call. if (mode == SAVE_RESULT_REGISTER) __ push(r2);
if (mode == SAVE_RESULT_REGISTER) {
// Break on return. __ mov(r2, Operand::Zero()); // no arguments
__ push(r2);
} else {
// Non-return breaks.
__ Push(masm->isolate()->factory()->the_hole_value());
}
__ mov(r2, Operand(1));
__ mov(r3, __ mov(r3,
Operand(ExternalReference( Operand(ExternalReference(
Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate()))); Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())));
...@@ -107,14 +101,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -107,14 +101,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
if (FLAG_debug_code) { if (FLAG_debug_code) {
for (int i = 0; i < kNumJSCallerSaved; i++) { for (int i = 0; i < kNumJSCallerSaved; i++) {
Register reg = {JSCallerSavedCode(i)}; Register reg = {JSCallerSavedCode(i)};
// Do not clobber r2 if SAVE_RESULT_REGISTER is set. It will __ mov(reg, Operand(kDebugZapValue));
// contain return value of the function.
if (!(reg.is(r2) && SAVE_RESULT_REGISTER)) {
__ mov(reg, Operand(kDebugZapValue));
}
} }
} }
if (mode == SAVE_RESULT_REGISTER) __ pop(r2);
// Don't bother removing padding bytes pushed on the stack // Don't bother removing padding bytes pushed on the stack
// as the frame is going to be restored right away. // as the frame is going to be restored right away.
......
...@@ -69,15 +69,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -69,15 +69,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
} }
__ Push(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)); __ Push(Smi::FromInt(LiveEdit::kFramePaddingInitialSize));
// Push arguments for DebugBreak call. if (mode == SAVE_RESULT_REGISTER) __ Push(rax);
if (mode == SAVE_RESULT_REGISTER) {
// Break on return. __ Set(rax, 0); // No arguments (argc == 0).
__ Push(rax);
} else {
// Non-return breaks.
__ Push(masm->isolate()->factory()->the_hole_value());
}
__ Set(rax, 1);
__ Move(rbx, ExternalReference(Runtime::FunctionForId(Runtime::kDebugBreak), __ Move(rbx, ExternalReference(Runtime::FunctionForId(Runtime::kDebugBreak),
masm->isolate())); masm->isolate()));
...@@ -87,14 +81,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -87,14 +81,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
if (FLAG_debug_code) { if (FLAG_debug_code) {
for (int i = 0; i < kNumJSCallerSaved; ++i) { for (int i = 0; i < kNumJSCallerSaved; ++i) {
Register reg = {JSCallerSavedCode(i)}; Register reg = {JSCallerSavedCode(i)};
// Do not clobber rax if SAVE_RESULT_REGISTER is set. It will __ Set(reg, kDebugZapValue);
// contain return value of the function.
if (!(reg.is(rax) && SAVE_RESULT_REGISTER)) {
__ Set(reg, kDebugZapValue);
}
} }
} }
if (mode == SAVE_RESULT_REGISTER) __ Pop(rax);
// Read current padding counter and skip corresponding number of words. // Read current padding counter and skip corresponding number of words.
__ Pop(kScratchRegister); __ Pop(kScratchRegister);
__ SmiToInteger32(kScratchRegister, kScratchRegister); __ SmiToInteger32(kScratchRegister, kScratchRegister);
......
...@@ -68,15 +68,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -68,15 +68,9 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
} }
__ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
// Push arguments for DebugBreak call. if (mode == SAVE_RESULT_REGISTER) __ push(eax);
if (mode == SAVE_RESULT_REGISTER) {
// Break on return. __ Move(eax, Immediate(0)); // No arguments.
__ push(eax);
} else {
// Non-return breaks.
__ Push(masm->isolate()->factory()->the_hole_value());
}
__ Move(eax, Immediate(1));
__ mov(ebx, __ mov(ebx,
Immediate(ExternalReference( Immediate(ExternalReference(
Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate()))); Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate())));
...@@ -87,14 +81,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, ...@@ -87,14 +81,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm,
if (FLAG_debug_code) { if (FLAG_debug_code) {
for (int i = 0; i < kNumJSCallerSaved; ++i) { for (int i = 0; i < kNumJSCallerSaved; ++i) {
Register reg = {JSCallerSavedCode(i)}; Register reg = {JSCallerSavedCode(i)};
// Do not clobber eax if SAVE_RESULT_REGISTER is set. It will __ Move(reg, Immediate(kDebugZapValue));
// contain return value of the function.
if (!(reg.is(eax) && SAVE_RESULT_REGISTER)) {
__ Move(reg, Immediate(kDebugZapValue));
}
} }
} }
if (mode == SAVE_RESULT_REGISTER) __ pop(eax);
__ pop(ebx); __ pop(ebx);
// We divide stored value by 2 (untagging) and multiply it by word's size. // We divide stored value by 2 (untagging) and multiply it by word's size.
STATIC_ASSERT(kSmiTagSize == 1 && kSmiShiftSize == 0); STATIC_ASSERT(kSmiTagSize == 1 && kSmiShiftSize == 0);
......
...@@ -1485,13 +1485,11 @@ void Interpreter::DoDebugger(InterpreterAssembler* assembler) { ...@@ -1485,13 +1485,11 @@ void Interpreter::DoDebugger(InterpreterAssembler* assembler) {
// DebugBreak // DebugBreak
// //
// Call runtime to handle a debug break. // Call runtime to handle a debug break.
#define DEBUG_BREAK(Name, ...) \ #define DEBUG_BREAK(Name, ...) \
void Interpreter::Do##Name(InterpreterAssembler* assembler) { \ void Interpreter::Do##Name(InterpreterAssembler* assembler) { \
Node* context = __ GetContext(); \ Node* context = __ GetContext(); \
Node* accumulator = __ GetAccumulator(); \ Node* original_handler = __ CallRuntime(Runtime::kDebugBreak, context); \
Node* original_handler = \ __ DispatchToBytecodeHandler(original_handler); \
__ CallRuntime(Runtime::kDebugBreakOnBytecode, context, accumulator); \
__ DispatchToBytecodeHandler(original_handler); \
} }
DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK); DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
#undef DEBUG_BREAK #undef DEBUG_BREAK
......
...@@ -5,13 +5,11 @@ ...@@ -5,13 +5,11 @@
#include "src/runtime/runtime-utils.h" #include "src/runtime/runtime-utils.h"
#include "src/arguments.h" #include "src/arguments.h"
#include "src/debug/debug.h"
#include "src/debug/debug-evaluate.h" #include "src/debug/debug-evaluate.h"
#include "src/debug/debug-frames.h" #include "src/debug/debug-frames.h"
#include "src/debug/debug-scopes.h" #include "src/debug/debug-scopes.h"
#include "src/debug/debug.h"
#include "src/frames-inl.h" #include "src/frames-inl.h"
#include "src/interpreter/bytecodes.h"
#include "src/interpreter/interpreter.h"
#include "src/isolate-inl.h" #include "src/isolate-inl.h"
#include "src/runtime/runtime.h" #include "src/runtime/runtime.h"
...@@ -20,39 +18,11 @@ namespace internal { ...@@ -20,39 +18,11 @@ namespace internal {
RUNTIME_FUNCTION(Runtime_DebugBreak) { RUNTIME_FUNCTION(Runtime_DebugBreak) {
SealHandleScope shs(isolate); SealHandleScope shs(isolate);
DCHECK(args.length() == 1); DCHECK(args.length() == 0);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
isolate->debug()->set_return_value(value);
// Get the top-most JavaScript frame.
JavaScriptFrameIterator it(isolate);
isolate->debug()->Break(it.frame());
isolate->debug()->SetAfterBreakTarget(it.frame());
return *isolate->debug()->return_value();
}
RUNTIME_FUNCTION(Runtime_DebugBreakOnBytecode) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
isolate->debug()->set_return_value(value);
// Get the top-most JavaScript frame. // Get the top-most JavaScript frame.
JavaScriptFrameIterator it(isolate); JavaScriptFrameIterator it(isolate);
isolate->debug()->Break(it.frame()); isolate->debug()->Break(args, it.frame());
return isolate->debug()->SetAfterBreakTarget(it.frame());
// Return the handler from the original bytecode array.
DCHECK(it.frame()->is_interpreted());
InterpretedFrame* interpreted_frame =
reinterpret_cast<InterpretedFrame*>(it.frame());
SharedFunctionInfo* shared = interpreted_frame->function()->shared();
BytecodeArray* bytecode_array = shared->bytecode_array();
int bytecode_offset = interpreted_frame->GetBytecodeOffset();
interpreter::Bytecode bytecode =
interpreter::Bytecodes::FromByte(bytecode_array->get(bytecode_offset));
return isolate->interpreter()->GetBytecodeHandler(
bytecode, interpreter::OperandScale::kSingle);
} }
...@@ -621,7 +591,31 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { ...@@ -621,7 +591,31 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
// to the frame information. // to the frame information.
Handle<Object> return_value = isolate->factory()->undefined_value(); Handle<Object> return_value = isolate->factory()->undefined_value();
if (at_return) { if (at_return) {
return_value = isolate->debug()->return_value(); StackFrameIterator it2(isolate);
Address internal_frame_sp = NULL;
while (!it2.done()) {
if (it2.frame()->is_internal()) {
internal_frame_sp = it2.frame()->sp();
} else {
if (it2.frame()->is_java_script()) {
if (it2.frame()->id() == it.frame()->id()) {
// The internal frame just before the JavaScript frame contains the
// value to return on top. A debug break at return will create an
// internal frame to store the return value (eax/rax/r0) before
// entering the debug break exit frame.
if (internal_frame_sp != NULL) {
return_value =
Handle<Object>(Memory::Object_at(internal_frame_sp), isolate);
break;
}
}
}
// Indicate that the previous frame was not an internal frame.
internal_frame_sp = NULL;
}
it2.Advance();
}
} }
// Now advance to the arguments adapter frame (if any). It contains all // Now advance to the arguments adapter frame (if any). It contains all
......
...@@ -137,10 +137,10 @@ namespace internal { ...@@ -137,10 +137,10 @@ namespace internal {
F(DateCurrentTime, 0, 1) \ F(DateCurrentTime, 0, 1) \
F(ThrowNotDateError, 0, 1) F(ThrowNotDateError, 0, 1)
#define FOR_EACH_INTRINSIC_DEBUG(F) \ #define FOR_EACH_INTRINSIC_DEBUG(F) \
F(HandleDebuggerStatement, 0, 1) \ F(HandleDebuggerStatement, 0, 1) \
F(DebugBreak, 1, 1) \ F(DebugBreak, 0, 1) \
F(DebugBreakOnBytecode, 1, 1) \
F(SetDebugEventListener, 2, 1) \ F(SetDebugEventListener, 2, 1) \
F(ScheduleBreak, 0, 1) \ F(ScheduleBreak, 0, 1) \
F(DebugGetInternalProperties, 1, 1) \ F(DebugGetInternalProperties, 1, 1) \
...@@ -195,6 +195,7 @@ namespace internal { ...@@ -195,6 +195,7 @@ namespace internal {
F(DebugIsActive, 0, 1) \ F(DebugIsActive, 0, 1) \
F(DebugBreakInOptimizedCode, 0, 1) F(DebugBreakInOptimizedCode, 0, 1)
#define FOR_EACH_INTRINSIC_FORIN(F) \ #define FOR_EACH_INTRINSIC_FORIN(F) \
F(ForInDone, 2, 1) \ F(ForInDone, 2, 1) \
F(ForInEnumerate, 1, 1) \ F(ForInEnumerate, 1, 1) \
......
...@@ -756,6 +756,7 @@ ...@@ -756,6 +756,7 @@
['ignition == True', { ['ignition == True', {
# TODO(yangguo,4690): assertion failures in debugger tests. # TODO(yangguo,4690): assertion failures in debugger tests.
'debug-allscopes-on-debugger': [FAIL], 'debug-allscopes-on-debugger': [FAIL],
'debug-return-value': [FAIL],
'es6/debug-stepnext-for': [FAIL], 'es6/debug-stepnext-for': [FAIL],
'es6/debug-stepin-string-template': [FAIL], 'es6/debug-stepin-string-template': [FAIL],
'es6/debug-promises/stepin-constructor': [FAIL], 'es6/debug-promises/stepin-constructor': [FAIL],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment