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.

Reply via email to