Revision: 21560
Author: [email protected]
Date: Wed May 28 10:41:13 2014 UTC
Log: Refactor after break target computation.
[email protected]
Review URL: https://codereview.chromium.org/301563004
http://code.google.com/p/v8/source/detail?r=21560
Modified:
/branches/bleeding_edge/src/debug.cc
/branches/bleeding_edge/src/debug.h
/branches/bleeding_edge/src/liveedit.cc
/branches/bleeding_edge/src/liveedit.h
=======================================
--- /branches/bleeding_edge/src/debug.cc Wed May 28 10:21:46 2014 UTC
+++ /branches/bleeding_edge/src/debug.cc Wed May 28 10:41:13 2014 UTC
@@ -514,7 +514,6 @@
thread_local_.queued_step_count_ = 0;
thread_local_.step_into_fp_ = 0;
thread_local_.step_out_fp_ = 0;
- thread_local_.after_break_target_ = 0;
// TODO(isolates): frames_are_dropped_?
thread_local_.debugger_entry_ = NULL;
thread_local_.has_pending_interrupt_ = false;
@@ -806,28 +805,21 @@
}
-Object* Debug::Break(Arguments args) {
+void Debug::Break(Arguments args, JavaScriptFrame* frame) {
Heap* heap = isolate_->heap();
HandleScope scope(isolate_);
ASSERT(args.length() == 0);
- thread_local_.frame_drop_mode_ = LiveEdit::FRAMES_UNTOUCHED;
-
- // Get the top-most JavaScript frame.
- JavaScriptFrameIterator it(isolate_);
- JavaScriptFrame* frame = it.frame();
+ if (live_edit_enabled()) {
+ thread_local_.frame_drop_mode_ = LiveEdit::FRAMES_UNTOUCHED;
+ }
// Just continue if breaks are disabled or debugger cannot be loaded.
- if (disable_break()) {
- SetAfterBreakTarget(frame);
- return heap->undefined_value();
- }
+ if (disable_break()) return;
// Enter the debugger.
EnterDebugger debugger(isolate_);
- if (debugger.FailedToEnter()) {
- return heap->undefined_value();
- }
+ if (debugger.FailedToEnter()) return;
// Postpone interrupt during breakpoint processing.
PostponeInterruptsScope postpone(isolate_);
@@ -923,40 +915,15 @@
// Set up for the remaining steps.
PrepareStep(step_action, step_count, StackFrame::NO_ID);
}
-
- if (thread_local_.frame_drop_mode_ == LiveEdit::FRAMES_UNTOUCHED) {
- SetAfterBreakTarget(frame);
- } else if (thread_local_.frame_drop_mode_ ==
- LiveEdit::FRAME_DROPPED_IN_IC_CALL) {
- // We must have been calling IC stub. Do not go there anymore.
- Code* plain_return = isolate_->builtins()->builtin(
- Builtins::kPlainReturn_LiveEdit);
- thread_local_.after_break_target_ = plain_return->entry();
- } else if (thread_local_.frame_drop_mode_ ==
- LiveEdit::FRAME_DROPPED_IN_DEBUG_SLOT_CALL) {
- // Debug break slot stub does not return normally, instead it manually
- // cleans the stack and jumps. We should patch the jump address.
- Code* plain_return = isolate_->builtins()->builtin(
- Builtins::kFrameDropper_LiveEdit);
- thread_local_.after_break_target_ = plain_return->entry();
- } else if (thread_local_.frame_drop_mode_ ==
- LiveEdit::FRAME_DROPPED_IN_DIRECT_CALL) {
- // Nothing to do, after_break_target is not used here.
- } else if (thread_local_.frame_drop_mode_ ==
- LiveEdit::FRAME_DROPPED_IN_RETURN_CALL) {
- Code* plain_return = isolate_->builtins()->builtin(
- Builtins::kFrameDropper_LiveEdit);
- thread_local_.after_break_target_ = plain_return->entry();
- } else {
- UNREACHABLE();
- }
-
- return heap->undefined_value();
}
RUNTIME_FUNCTION(Debug_Break) {
- return isolate->debug()->Break(args);
+ // Get the top-most JavaScript frame.
+ JavaScriptFrameIterator it(isolate);
+ isolate->debug()->Break(args, it.frame());
+ isolate->debug()->SetAfterBreakTarget(it.frame());
+ return isolate->heap()->undefined_value();
}
@@ -2335,8 +2302,13 @@
void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
+ if (live_edit_enabled()) {
+ after_break_target_ =
+ LiveEdit::AfterBreakTarget(thread_local_.frame_drop_mode_,
isolate_);
+ if (after_break_target_ != NULL) return; // LiveEdit did the job.
+ }
+
HandleScope scope(isolate_);
-
PrepareForBreakPoints();
// Get the executing function in which the debug break occurred.
@@ -2385,18 +2357,17 @@
// place in the original code. If not the break point was removed
during
// break point processing.
if (break_at_js_return_active) {
- addr += original_code->instruction_start() -
code->instruction_start();
+ addr += original_code->instruction_start() -
code->instruction_start();
}
// Move back to where the call instruction sequence started.
- thread_local_.after_break_target_ =
- addr - Assembler::kPatchReturnSequenceAddressOffset;
+ after_break_target_ = addr -
Assembler::kPatchReturnSequenceAddressOffset;
} else if (at_debug_break_slot) {
// Address of where the debug break slot starts.
addr = addr - Assembler::kPatchDebugBreakSlotAddressOffset;
// Continue just after the slot.
- thread_local_.after_break_target_ = addr +
Assembler::kDebugBreakSlotLength;
+ after_break_target_ = addr + Assembler::kDebugBreakSlotLength;
} else if (IsDebugBreak(Assembler::target_address_at(addr, *code))) {
// We now know that there is still a debug break call at the target
address,
// so the break point is still there and the original code will hold
the
@@ -2408,15 +2379,13 @@
// Install jump to the call address in the original code. This will be
the
// call which was overwritten by the call to DebugBreakXXX.
- thread_local_.after_break_target_ =
- Assembler::target_address_at(addr, *original_code);
+ after_break_target_ = Assembler::target_address_at(addr,
*original_code);
} else {
// There is no longer a break point present. Don't try to look in the
// original code as the running code will have the right address. This
takes
// care of the case where the last break point is removed from the
function
// and therefore no "original code" is available.
- thread_local_.after_break_target_ =
- Assembler::target_address_at(addr, *code);
+ after_break_target_ = Assembler::target_address_at(addr, *code);
}
}
=======================================
--- /branches/bleeding_edge/src/debug.h Wed May 28 10:21:46 2014 UTC
+++ /branches/bleeding_edge/src/debug.h Wed May 28 10:41:13 2014 UTC
@@ -413,7 +413,8 @@
bool IsLoaded() { return !debug_context_.is_null(); }
bool InDebugger() { return thread_local_.debugger_entry_ != NULL; }
- Object* Break(Arguments args);
+ void Break(Arguments args, JavaScriptFrame*);
+ void SetAfterBreakTarget(JavaScriptFrame* frame);
bool SetBreakPoint(Handle<JSFunction> function,
Handle<Object> break_point_object,
int* source_position);
@@ -539,7 +540,7 @@
// Support for setting the address to jump to when returning from break
point.
Address after_break_target_address() {
- return reinterpret_cast<Address>(&thread_local_.after_break_target_);
+ return reinterpret_cast<Address>(&after_break_target_);
}
Address restarter_frame_function_pointer_address() {
@@ -634,7 +635,6 @@
void ClearStepNext();
// Returns whether the compile succeeded.
void RemoveDebugInfo(Handle<DebugInfo> debug_info);
- void SetAfterBreakTarget(JavaScriptFrame* frame);
Handle<Object> CheckBreakPoints(Handle<Object> break_point);
bool CheckBreakPoint(Handle<Object> break_point_object);
@@ -683,6 +683,11 @@
ScriptCache* script_cache_; // Cache of all scripts in the heap.
DebugInfoListNode* debug_info_list_; // List of active debug info
objects.
+ // Storage location for jump when exiting debug break calls.
+ // Note that this address is not GC safe. It should be computed
immediately
+ // before returning to the DebugBreakCallHelper.
+ Address after_break_target_;
+
// Per-thread data.
class ThreadLocal {
public:
@@ -720,9 +725,6 @@
// step out action is completed.
Address step_out_fp_;
- // Storage location for jump when exiting debug break calls.
- Address after_break_target_;
-
// Pending interrupts scheduled while debugging.
bool has_pending_interrupt_;
=======================================
--- /branches/bleeding_edge/src/liveedit.cc Wed May 28 10:21:46 2014 UTC
+++ /branches/bleeding_edge/src/liveedit.cc Wed May 28 10:41:13 2014 UTC
@@ -805,6 +805,35 @@
};
+Address LiveEdit::AfterBreakTarget(FrameDropMode mode, Isolate* isolate) {
+ Code* code = NULL;
+ switch (mode) {
+ case FRAMES_UNTOUCHED:
+ break;
+ case FRAME_DROPPED_IN_IC_CALL:
+ // We must have been calling IC stub. Do not go there anymore.
+ code = isolate->builtins()->builtin(Builtins::kPlainReturn_LiveEdit);
+ break;
+ case FRAME_DROPPED_IN_DEBUG_SLOT_CALL:
+ // Debug break slot stub does not return normally, instead it
manually
+ // cleans the stack and jumps. We should patch the jump address.
+ code =
isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit);
+ break;
+ case FRAME_DROPPED_IN_DIRECT_CALL:
+ // Nothing to do, after_break_target is not used here.
+ break;
+ case FRAME_DROPPED_IN_RETURN_CALL:
+ code =
isolate->builtins()->builtin(Builtins::kFrameDropper_LiveEdit);
+ break;
+ case CURRENTLY_SET_MODE:
+ UNREACHABLE();
+ break;
+ }
+ if (code == NULL) return NULL;
+ return code->entry();
+}
+
+
MaybeHandle<JSArray> LiveEdit::GatherCompileInfo(Handle<Script> script,
Handle<String> source) {
Isolate* isolate = script->GetIsolate();
=======================================
--- /branches/bleeding_edge/src/liveedit.h Wed May 28 10:21:46 2014 UTC
+++ /branches/bleeding_edge/src/liveedit.h Wed May 28 10:41:13 2014 UTC
@@ -58,6 +58,24 @@
class LiveEdit : AllStatic {
public:
+ // Describes how exactly a frame has been dropped from stack.
+ enum FrameDropMode {
+ // No frame has been dropped.
+ FRAMES_UNTOUCHED,
+ // The top JS frame had been calling IC stub. IC stub mustn't be
called now.
+ FRAME_DROPPED_IN_IC_CALL,
+ // The top JS frame had been calling debug break slot stub. Patch the
+ // address this stub jumps to in the end.
+ FRAME_DROPPED_IN_DEBUG_SLOT_CALL,
+ // The top JS frame had been calling some C++ function. The return
address
+ // gets patched automatically.
+ FRAME_DROPPED_IN_DIRECT_CALL,
+ FRAME_DROPPED_IN_RETURN_CALL,
+ CURRENTLY_SET_MODE
+ };
+
+ static Address AfterBreakTarget(FrameDropMode mode, Isolate* isolate);
+
MUST_USE_RESULT static MaybeHandle<JSArray> GatherCompileInfo(
Handle<Script> script,
Handle<String> source);
@@ -162,23 +180,6 @@
// A value that padding words are filled with (in form of Smi). Going
// bottom-top, the first word not having this value is a counter word.
static const int kFramePaddingValue = kFramePaddingInitialSize + 1;
-
-
- // Describes how exactly a frame has been dropped from stack.
- enum FrameDropMode {
- // No frame has been dropped.
- FRAMES_UNTOUCHED,
- // The top JS frame had been calling IC stub. IC stub mustn't be
called now.
- FRAME_DROPPED_IN_IC_CALL,
- // The top JS frame had been calling debug break slot stub. Patch the
- // address this stub jumps to in the end.
- FRAME_DROPPED_IN_DEBUG_SLOT_CALL,
- // The top JS frame had been calling some C++ function. The return
address
- // gets patched automatically.
- FRAME_DROPPED_IN_DIRECT_CALL,
- FRAME_DROPPED_IN_RETURN_CALL,
- CURRENTLY_SET_MODE
- };
};
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.