From: yangguo@chromium.org Date: Wed, 28 May 2014 10:41:13 +0000 (+0000) Subject: Refactor after break target computation. X-Git-Tag: upstream/4.7.83~8912 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e84bf720f910eecca2e262198fea9cf69a71b094;p=platform%2Fupstream%2Fv8.git Refactor after break target computation. R=ulan@chromium.org Review URL: https://codereview.chromium.org/301563004 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21560 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/debug.cc b/src/debug.cc index 893cd64..87e28f8 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -514,7 +514,6 @@ void Debug::ThreadInit() { 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 @@ void Debug::Unload() { } -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 @@ Object* Debug::Break(Arguments args) { // 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::RemoveDebugInfo(Handle debug_info) { void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { - HandleScope scope(isolate_); + 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 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { // 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 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { // 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); } } diff --git a/src/debug.h b/src/debug.h index e6c1d26..e63af4a 100644 --- a/src/debug.h +++ b/src/debug.h @@ -413,7 +413,8 @@ class Debug { 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 function, Handle break_point_object, int* source_position); @@ -539,7 +540,7 @@ class Debug { // Support for setting the address to jump to when returning from break point. Address after_break_target_address() { - return reinterpret_cast
(&thread_local_.after_break_target_); + return reinterpret_cast
(&after_break_target_); } Address restarter_frame_function_pointer_address() { @@ -634,7 +635,6 @@ class Debug { void ClearStepNext(); // Returns whether the compile succeeded. void RemoveDebugInfo(Handle debug_info); - void SetAfterBreakTarget(JavaScriptFrame* frame); Handle CheckBreakPoints(Handle break_point); bool CheckBreakPoint(Handle break_point_object); @@ -683,6 +683,11 @@ class Debug { 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 @@ class Debug { // 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_; diff --git a/src/liveedit.cc b/src/liveedit.cc index e55f24e..3983a37 100644 --- a/src/liveedit.cc +++ b/src/liveedit.cc @@ -805,6 +805,35 @@ class FunctionInfoListener { }; +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 LiveEdit::GatherCompileInfo(Handle