Simplify debugger state.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 16 May 2014 14:58:03 +0000 (14:58 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 16 May 2014 14:58:03 +0000 (14:58 +0000)
R=ulan@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21346 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/bootstrapper.cc
src/d8.cc
src/debug.cc
src/debug.h
src/execution.cc
src/isolate.cc
src/runtime.cc
test/cctest/test-debug.cc
test/cctest/test-heap-profiler.cc
test/mjsunit/debug-stepin-positions.js

index 892f90edaca6d0b6d5fe7d896d01ca81cae96467..5a42036420fcb5694524edc20beca7f77bb084d1 100644 (file)
@@ -2120,20 +2120,18 @@ bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
 
   // Expose the debug global object in global if a name for it is specified.
   if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
-    Debug* debug = isolate->debug();
     // If loading fails we just bail out without installing the
     // debugger but without tanking the whole context.
+    Debug* debug = isolate->debug();
     if (!debug->Load()) return true;
+    Handle<Context> debug_context = debug->debug_context();
     // Set the security token for the debugger context to the same as
     // the shell native context to allow calling between these (otherwise
     // exposing debug global object doesn't make much sense).
-    debug->debug_context()->set_security_token(
-        native_context->security_token());
-
+    debug_context->set_security_token(native_context->security_token());
     Handle<String> debug_string =
         factory->InternalizeUtf8String(FLAG_expose_debug_as);
-    Handle<Object> global_proxy(
-        debug->debug_context()->global_proxy(), isolate);
+    Handle<Object> global_proxy(debug_context->global_proxy(), isolate);
     RETURN_ON_EXCEPTION_VALUE(
         isolate,
         JSObject::SetLocalPropertyIgnoreAttributes(
index 502187a9a70d9d9437689d4c98df7104910a3666..a467333060ee6635e5cce1aac7b83d6474a72afa 100644 (file)
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -753,11 +753,12 @@ void Shell::InstallUtilityScript(Isolate* isolate) {
   // Install the debugger object in the utility scope
   i::Debug* debug = reinterpret_cast<i::Isolate*>(isolate)->debug();
   debug->Load();
+  i::Handle<i::Context> debug_context = debug->debug_context();
   i::Handle<i::JSObject> js_debug
-      = i::Handle<i::JSObject>(debug->debug_context()->global_object());
+      = i::Handle<i::JSObject>(debug_context->global_object());
   utility_context->Global()->Set(String::NewFromUtf8(isolate, "$debug"),
                                  Utils::ToLocal(js_debug));
-  debug->debug_context()->set_security_token(
+  debug_context->set_security_token(
       reinterpret_cast<i::Isolate*>(isolate)->heap()->undefined_value());
 
   // Run the d8 shell utility script in the utility context
index e3cbf326c8e533bd97702bc8285c92270d41522b..059c144832ffa66d21d7da85c564675b364b6c86 100644 (file)
@@ -45,10 +45,6 @@ Debug::Debug(Isolate* isolate)
 }
 
 
-Debug::~Debug() {
-}
-
-
 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) {
   Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
   // Isolate::context() may have been NULL when "script collected" event
@@ -694,9 +690,7 @@ bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
   HandleScope scope(isolate);
 
   // Bail out if the index is invalid.
-  if (index == -1) {
-    return false;
-  }
+  if (index == -1) return false;
 
   // Find source and name for the requested script.
   Handle<String> source_code =
@@ -762,13 +756,11 @@ bool Debug::Load() {
   // Return if debugger is already loaded.
   if (IsLoaded()) return true;
 
-  Debugger* debugger = isolate_->debugger();
-
   // Bail out if we're already in the process of compiling the native
   // JavaScript source code for the debugger.
-  if (debugger->ignore_debugger()) return false;
+  if (isolate_->debugger()->ignore_debugger()) return false;
+  Debugger::IgnoreScope during_create(isolate_->debugger());
 
-  Debugger::IgnoreScope during_load(debugger);
   // Disable breakpoints and interrupts while compiling and running the
   // debugger scripts including the context creation code.
   DisableBreak disable(isolate_, true);
@@ -793,14 +785,13 @@ bool Debug::Load() {
   // Expose the builtins object in the debugger context.
   Handle<String> key = isolate_->factory()->InternalizeOneByteString(
       STATIC_ASCII_VECTOR("builtins"));
-  Handle<GlobalObject> global = Handle<GlobalObject>(context->global_object());
+  Handle<GlobalObject> global =
+      Handle<GlobalObject>(context->global_object(), isolate_);
+  Handle<JSBuiltinsObject> builtin =
+      Handle<JSBuiltinsObject>(global->builtins(), isolate_);
   RETURN_ON_EXCEPTION_VALUE(
       isolate_,
-      JSReceiver::SetProperty(global,
-                              key,
-                              Handle<Object>(global->builtins(), isolate_),
-                              NONE,
-                              SLOPPY),
+      JSReceiver::SetProperty(global, key, builtin, NONE, SLOPPY),
       false);
 
   // Compile the JavaScript for the debugger in the debugger context.
@@ -812,32 +803,24 @@ bool Debug::Load() {
     caught_exception = caught_exception ||
         !CompileDebuggerScript(isolate_, Natives::GetIndex("liveedit"));
   }
-
-  // Make sure we mark the debugger as not loading before we might
-  // return.
-
   // Check for caught exceptions.
   if (caught_exception) return false;
 
-  // Debugger loaded, create debugger context global handle.
   debug_context_ = Handle<Context>::cast(
       isolate_->global_handles()->Create(*context));
-
   return true;
 }
 
 
 void Debug::Unload() {
   // Return debugger is not loaded.
-  if (!IsLoaded()) {
-    return;
-  }
+  if (!IsLoaded()) return;
 
   // Clear the script cache.
   DestroyScriptCache();
 
   // Clear debugger context global handle.
-  GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location()));
+  GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
   debug_context_ = Handle<Context>();
 }
 
@@ -854,7 +837,7 @@ Object* Debug::Break(Arguments args) {
   JavaScriptFrame* frame = it.frame();
 
   // Just continue if breaks are disabled or debugger cannot be loaded.
-  if (disable_break() || !Load()) {
+  if (disable_break()) {
     SetAfterBreakTarget(frame);
     return heap->undefined_value();
   }
@@ -2629,9 +2612,7 @@ Debugger::Debugger(Isolate* isolate)
       is_active_(false),
       ignore_debugger_(false),
       live_edit_enabled_(true),
-      never_unload_debugger_(false),
       message_handler_(NULL),
-      debugger_unload_pending_(false),
       command_queue_(isolate->logger(), kQueueInitialSize),
       command_received_(0),
       event_command_queue_(isolate->logger(), kQueueInitialSize),
@@ -2988,36 +2969,17 @@ void Debugger::CallJSEventCallback(v8::DebugEvent event,
 
 
 Handle<Context> Debugger::GetDebugContext() {
-  never_unload_debugger_ = true;
   EnterDebugger debugger(isolate_);
   return isolate_->debug()->debug_context();
 }
 
 
-void Debugger::UnloadDebugger() {
-  Debug* debug = isolate_->debug();
-
-  // Make sure that there are no breakpoints left.
-  debug->ClearAllBreakPoints();
-
-  // Unload the debugger if feasible.
-  if (!never_unload_debugger_) {
-    debug->Unload();
-  }
-
-  // Clear the flag indicating that the debugger should be unloaded.
-  debugger_unload_pending_ = false;
-}
-
-
 void Debugger::NotifyMessageHandler(v8::DebugEvent event,
                                     Handle<JSObject> exec_state,
                                     Handle<JSObject> event_data,
                                     bool auto_continue) {
+  ASSERT(is_active_);
   HandleScope scope(isolate_);
-
-  if (!isolate_->debug()->Load()) return;
-
   // Process the individual events.
   bool sendEventMessage = false;
   switch (event) {
@@ -3145,77 +3107,60 @@ void Debugger::NotifyMessageHandler(v8::DebugEvent event,
 
 void Debugger::SetEventListener(Handle<Object> callback,
                                 Handle<Object> data) {
-  HandleScope scope(isolate_);
   GlobalHandles* global_handles = isolate_->global_handles();
 
-  // Clear the global handles for the event listener and the event listener data
-  // object.
-  if (!event_listener_.is_null()) {
-    GlobalHandles::Destroy(
-        reinterpret_cast<Object**>(event_listener_.location()));
-    event_listener_ = Handle<Object>();
-  }
-  if (!event_listener_data_.is_null()) {
-    GlobalHandles::Destroy(
-        reinterpret_cast<Object**>(event_listener_data_.location()));
-    event_listener_data_ = Handle<Object>();
-  }
+  // Remove existing entry.
+  GlobalHandles::Destroy(event_listener_.location());
+  event_listener_ = Handle<Object>();
+  GlobalHandles::Destroy(event_listener_data_.location());
+  event_listener_data_ = Handle<Object>();
 
-  // If there is a new debug event listener register it together with its data
-  // object.
+  // Set new entry.
   if (!callback->IsUndefined() && !callback->IsNull()) {
-    event_listener_ = Handle<Object>::cast(
-        global_handles->Create(*callback));
-    if (data.is_null()) {
-      data = isolate_->factory()->undefined_value();
-    }
-    event_listener_data_ = Handle<Object>::cast(
-        global_handles->Create(*data));
+    event_listener_ = global_handles->Create(*callback);
+    if (data.is_null()) data = isolate_->factory()->undefined_value();
+    event_listener_data_ = global_handles->Create(*data);
   }
 
-  ListenersChanged();
+  UpdateState();
 }
 
 
 void Debugger::SetMessageHandler(v8::Debug::MessageHandler handler) {
-  LockGuard<RecursiveMutex> with(&debugger_access_);
-
   message_handler_ = handler;
-  ListenersChanged();
-  if (handler == NULL) {
+  UpdateState();
+  if (handler == NULL && isolate_->debug()->InDebugger()) {
     // Send an empty command to the debugger if in a break to make JavaScript
     // run again if the debugger is closed.
-    if (isolate_->debug()->InDebugger()) {
-      EnqueueCommandMessage(Vector<const uint16_t>::empty());
-    }
+    EnqueueCommandMessage(Vector<const uint16_t>::empty());
   }
 }
 
 
-void Debugger::ListenersChanged() {
-  LockGuard<RecursiveMutex> with(&debugger_access_);
-  is_active_ = message_handler_ != NULL || !event_listener_.is_null();
-  if (is_active_) {
-    // Disable the compilation cache when the debugger is active.
+void Debugger::UpdateState() {
+  bool activate = message_handler_ != NULL ||
+                  !event_listener_.is_null() ||
+                  isolate_->debug()->InDebugger();
+  if (!is_active_ && activate) {
+    // Note that the debug context could have already been loaded to
+    // bootstrap test cases.
     isolate_->compilation_cache()->Disable();
-    debugger_unload_pending_ = false;
-  } else {
+    activate = isolate_->debug()->Load();
+  } else if (is_active_ && !activate) {
     isolate_->compilation_cache()->Enable();
-    // Unload the debugger if event listener and message handler cleared.
-    // Schedule this for later, because we may be in non-V8 thread.
-    debugger_unload_pending_ = true;
+    isolate_->debug()->ClearAllBreakPoints();
+    isolate_->debug()->Unload();
   }
+  is_active_ = activate;
+  // At this point the debug context is loaded iff the debugger is active.
+  ASSERT(isolate_->debug()->IsLoaded() == is_active_);
 }
 
 
 // Calls the registered debug message handler. This callback is part of the
 // public API.
 void Debugger::InvokeMessageHandler(MessageImpl message) {
-  LockGuard<RecursiveMutex> with(&debugger_access_);
-
-  if (message_handler_ != NULL) {
-    message_handler_(message);
-  }
+  if (message_handler_ != NULL) message_handler_(message);
 }
 
 
@@ -3259,9 +3204,6 @@ void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) {
 
 MaybeHandle<Object> Debugger::Call(Handle<JSFunction> fun,
                                    Handle<Object> data) {
-  // When calling functions in the debugger prevent it from beeing unloaded.
-  Debugger::never_unload_debugger_ = true;
-
   // Enter the debugger.
   EnterDebugger debugger(isolate_);
   if (debugger.FailedToEnter()) {
@@ -3288,10 +3230,9 @@ MaybeHandle<Object> Debugger::Call(Handle<JSFunction> fun,
 EnterDebugger::EnterDebugger(Isolate* isolate)
     : isolate_(isolate),
       prev_(isolate_->debug()->debugger_entry()),
-      it_(isolate_),
-      has_js_frames_(!it_.done()),
       save_(isolate_) {
   Debug* debug = isolate_->debug();
+
   // Link recursive debugger entry.
   debug->set_debugger_entry(this);
 
@@ -3301,25 +3242,24 @@ EnterDebugger::EnterDebugger(Isolate* isolate)
 
   // Create the new break info. If there is no JavaScript frames there is no
   // break frame id.
-  if (has_js_frames_) {
-    debug->NewBreak(it_.frame()->id());
-  } else {
-    debug->NewBreak(StackFrame::NO_ID);
-  }
+  JavaScriptFrameIterator it(isolate_);
+  has_js_frames_ = !it.done();
+  debug->NewBreak(has_js_frames_ ? it.frame()->id() : StackFrame::NO_ID);
 
+  isolate_->debugger()->UpdateState();
   // Make sure that debugger is loaded and enter the debugger context.
-  load_failed_ = !debug->Load();
-  if (!load_failed_) {
-    // NOTE the member variable save which saves the previous context before
-    // this change.
-    isolate_->set_context(*debug->debug_context());
-  }
+  // The previous context is kept in save_.
+  load_failed_ = !debug->IsLoaded();
+  if (!load_failed_) isolate_->set_context(*debug->debug_context());
 }
 
 
 EnterDebugger::~EnterDebugger() {
   Debug* debug = isolate_->debug();
 
+  // Leaving this debugger entry.
+  debug->set_debugger_entry(prev_);
+
   // Restore to the previous break state.
   debug->SetBreak(break_frame_id_, break_id_);
 
@@ -3351,15 +3291,9 @@ EnterDebugger::~EnterDebugger() {
     if (isolate_->debugger()->HasCommands()) {
       isolate_->stack_guard()->RequestDebugCommand();
     }
-
-    // If leaving the debugger with the debugger no longer active unload it.
-    if (!isolate_->debugger()->is_active()) {
-      isolate_->debugger()->UnloadDebugger();
-    }
   }
 
-  // Leaving this debugger entry.
-  debug->set_debugger_entry(prev_);
+  isolate_->debugger()->UpdateState();
 }
 
 
index 35b29c0d22c6d1d0f84af9724bc7c28086b16f33..80e6970e34caccbceb0d0f499443b9b6f7bd1dc2 100644 (file)
@@ -490,7 +490,6 @@ class Debug {
 
  private:
   explicit Debug(Isolate* isolate);
-  ~Debug();
 
   static bool CompileDebuggerScript(Isolate* isolate, int index);
   void ClearOneShot();
@@ -743,25 +742,6 @@ class LockingCommandMessageQueue BASE_EMBEDDED {
 
 class Debugger {
  public:
-  ~Debugger();
-
-  void DebugRequest(const uint16_t* json_request, int length);
-
-  MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
-      Vector<const char> constructor_name,
-      int argc,
-      Handle<Object> argv[]);
-  MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
-  MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
-      Handle<Object> break_points_hit);
-  MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
-      Handle<Object> exception,
-      bool uncaught,
-      Handle<Object> promise);
-  MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
-      Handle<Script> script, bool before);
-  MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id);
-
   void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
   void OnException(Handle<Object> exception, bool uncaught);
   void OnBeforeCompile(Handle<Script> script);
@@ -773,13 +753,7 @@ class Debugger {
   void OnAfterCompile(Handle<Script> script,
                       AfterCompileFlags after_compile_flags);
   void OnScriptCollected(int id);
-  void ProcessDebugEvent(v8::DebugEvent event,
-                         Handle<JSObject> event_data,
-                         bool auto_continue);
-  void NotifyMessageHandler(v8::DebugEvent event,
-                            Handle<JSObject> exec_state,
-                            Handle<JSObject> event_data,
-                            bool auto_continue);
+
   void SetEventListener(Handle<Object> callback, Handle<Object> data);
   void SetMessageHandler(v8::Debug::MessageHandler handler);
 
@@ -798,36 +772,13 @@ class Debugger {
 
   Handle<Context> GetDebugContext();
 
-  // Unload the debugger if possible. Only called when no debugger is currently
-  // active.
-  void UnloadDebugger();
-  friend void ForceUnloadDebugger();  // In test-debug.cc
-
-  inline bool EventActive() {
-    LockGuard<RecursiveMutex> lock_guard(&debugger_access_);
-
-    // Check whether the message handler was been cleared.
-    // TODO(yangguo): handle loading and unloading of the debugger differently.
-    if (debugger_unload_pending_) {
-      if (isolate_->debug()->debugger_entry() == NULL) {
-        UnloadDebugger();
-      }
-    }
-
-    // Currently argument event is not used.
-    return !ignore_debugger_ && is_active_;
-  }
-
   bool ignore_debugger() const { return ignore_debugger_; }
   void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; }
   bool live_edit_enabled() const {
     return FLAG_enable_liveedit && live_edit_enabled_ ;
   }
 
-  bool is_active() {
-    LockGuard<RecursiveMutex> lock_guard(&debugger_access_);
-    return is_active_;
-  }
+  bool is_active() { return is_active_; }
 
   class IgnoreScope {
    public:
@@ -849,6 +800,22 @@ class Debugger {
 
  private:
   explicit Debugger(Isolate* isolate);
+  ~Debugger();
+
+  MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
+      Vector<const char> constructor_name,
+      int argc,
+      Handle<Object> argv[]);
+  MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
+  MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
+      Handle<Object> break_points_hit);
+  MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
+      Handle<Object> exception,
+      bool uncaught,
+      Handle<Object> promise);
+  MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
+      Handle<Script> script, bool before);
+  MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id);
 
   void CallEventCallback(v8::DebugEvent event,
                          Handle<Object> exec_state,
@@ -861,18 +828,31 @@ class Debugger {
   void CallJSEventCallback(v8::DebugEvent event,
                            Handle<Object> exec_state,
                            Handle<Object> event_data);
-  void ListenersChanged();
+  void UpdateState();
+
+  void ProcessDebugEvent(v8::DebugEvent event,
+                         Handle<JSObject> event_data,
+                         bool auto_continue);
+  void NotifyMessageHandler(v8::DebugEvent event,
+                            Handle<JSObject> exec_state,
+                            Handle<JSObject> event_data,
+                            bool auto_continue);
 
   // Invoke the message handler function.
   void InvokeMessageHandler(MessageImpl message);
 
-  RecursiveMutex debugger_access_;  // Mutex guarding debugger variables.
+  inline bool EventActive() {
+    // Check whether the message handler was been cleared.
+    // TODO(yangguo): handle loading and unloading of the debugger differently.
+    // Currently argument event is not used.
+    return !ignore_debugger_ && is_active_;
+  }
+
   Handle<Object> event_listener_;  // Global handle to listener.
   Handle<Object> event_listener_data_;
   bool is_active_;
   bool ignore_debugger_;  // Are we temporarily ignoring the debugger?
   bool live_edit_enabled_;  // Enable LiveEdit.
-  bool never_unload_debugger_;  // Can we unload the debugger?
   v8::Debug::MessageHandler message_handler_;
   bool debugger_unload_pending_;  // Was message handler cleared?
 
@@ -911,8 +891,7 @@ class EnterDebugger BASE_EMBEDDED {
  private:
   Isolate* isolate_;
   EnterDebugger* prev_;  // Previous debugger entry if entered recursively.
-  JavaScriptFrameIterator it_;
-  const bool has_js_frames_;  // Were there any JavaScript frames?
+  bool has_js_frames_;  // Were there any JavaScript frames?
   StackFrame::Id break_frame_id_;  // Previous break frame id.
   int break_id_;  // Previous break id.
   bool load_failed_;  // Did the debugger fail to load?
index 8f8c1530436f5c3eecb8546248ebfb765f64ad12..b88cdd54353f0fab1a3ba53d38a5f4a9062b33aa 100644 (file)
@@ -714,9 +714,6 @@ void Execution::DebugBreakHelper(Isolate* isolate) {
 
 void Execution::ProcessDebugMessages(Isolate* isolate,
                                      bool debug_command_only) {
-  // Assert that we are on the main thread of the isolate.
-  ASSERT(ThreadId::Current().Equals(isolate->thread_id()));
-
   isolate->stack_guard()->ClearDebugCommand();
 
   StackLimitCheck check(isolate);
index 06df1f67c25bc380097c2cc8ca471105ec65b071..490bdb9786b00608f373079d30f451e12dbf3cdb 100644 (file)
@@ -1546,8 +1546,6 @@ void Isolate::Deinit() {
   if (state_ == INITIALIZED) {
     TRACE_ISOLATE(deinit);
 
-    debugger()->UnloadDebugger();
-
     if (concurrent_recompilation_enabled()) {
       optimizing_compiler_thread_->Stop();
       delete optimizing_compiler_thread_;
index 8148cc8d8263291be92b3d2d749df0e8d12101c7..7a854986905cf67800c28af406f3c5d98cf4a1b3 100644 (file)
@@ -11042,8 +11042,9 @@ RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
 
 
 static bool CheckExecutionState(Isolate* isolate, int break_id) {
-  return (isolate->debug()->break_id() != 0 &&
-          break_id == isolate->debug()->break_id());
+  return !isolate->debug()->debug_context().is_null() &&
+         isolate->debug()->break_id() != 0 &&
+         isolate->debug()->break_id() == break_id;
 }
 
 
index 2a2ca3e7cfd46b151742d307ea646432598b718e..91b610247f5a54756cb9b67d7560cdc5e50a69d7 100644 (file)
@@ -98,10 +98,11 @@ class DebugLocalContext {
     v8::internal::Isolate* isolate =
         reinterpret_cast<v8::internal::Isolate*>(context_->GetIsolate());
     v8::internal::Factory* factory = isolate->factory();
-    v8::internal::Debug* debug = isolate->debug();
     // Expose the debug context global object in the global object for testing.
-    debug->Load();
-    debug->debug_context()->set_security_token(
+    CHECK(isolate->debug()->Load());
+    Handle<v8::internal::Context> debug_context =
+        isolate->debug()->debug_context();
+    debug_context->set_security_token(
         v8::Utils::OpenHandle(*context_)->security_token());
 
     Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast(
@@ -109,7 +110,7 @@ class DebugLocalContext {
     Handle<v8::internal::String> debug_string =
         factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("debug"));
     v8::internal::Runtime::SetObjectProperty(isolate, global, debug_string,
-        Handle<Object>(debug->debug_context()->global_proxy(), isolate),
+        Handle<Object>(debug_context->global_proxy(), isolate),
         DONT_ENUM,
         ::v8::internal::SLOPPY).Check();
   }
@@ -421,12 +422,6 @@ void CheckDebuggerUnloaded(bool check_functions) {
 }
 
 
-void ForceUnloadDebugger() {
-  CcTest::i_isolate()->debugger()->never_unload_debugger_ = false;
-  CcTest::i_isolate()->debugger()->UnloadDebugger();
-}
-
-
 } }  // namespace v8::internal
 
 
@@ -5500,13 +5495,12 @@ static void CheckDataParameter(
       v8::String::NewFromUtf8(args.GetIsolate(), "Test");
   CHECK(v8::Debug::Call(debugger_call_with_data, data)->IsString());
 
-  CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty());
-  CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty());
-
-  v8::TryCatch catcher;
-  v8::Debug::Call(debugger_call_with_data);
-  CHECK(catcher.HasCaught());
-  CHECK(catcher.Exception()->IsString());
+  for (int i = 0; i < 3; i++) {
+    v8::TryCatch catcher;
+    CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty());
+    CHECK(catcher.HasCaught());
+    CHECK(catcher.Exception()->IsString());
+  }
 }
 
 
@@ -6872,9 +6866,11 @@ TEST(CallingContextIsNotDebugContext) {
 
 TEST(DebugContextIsPreservedBetweenAccesses) {
   v8::HandleScope scope(CcTest::isolate());
+  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
   v8::Local<v8::Context> context1 = v8::Debug::GetDebugContext();
   v8::Local<v8::Context> context2 = v8::Debug::GetDebugContext();
   CHECK_EQ(*context1, *context2);
+  v8::Debug::SetDebugEventListener(NULL);
 }
 
 
index eeafc7093cca7332579d0d9cee37273e9d354328..0417ace2c2bab5c32519e1534bdd8a5967f3facd 100644 (file)
@@ -1888,7 +1888,7 @@ TEST(NoDebugObjectInSnapshot) {
   v8::HandleScope scope(env->GetIsolate());
   v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
 
-  CcTest::i_isolate()->debug()->Load();
+  CHECK(CcTest::i_isolate()->debug()->Load());
   CompileRun("foo = {};");
   const v8::HeapSnapshot* snapshot =
       heap_profiler->TakeHeapSnapshot(v8_str("snapshot"));
index 722df53666aea9587aebafb2ff78a92d26ddb004..ff532e3dd740a1d78df532475e6c981d179b089a 100644 (file)
@@ -37,12 +37,13 @@ function TestCase(fun, frame_number) {
   var exception = false;
   var codeSnippet = undefined;
   var resultPositions = undefined;
+  var step = 0;
 
   function listener(event, exec_state, event_data, data) {
     try {
       if (event == Debug.DebugEvent.Break ||
           event == Debug.DebugEvent.Exception) {
-        Debug.setListener(null);
+        if (step++ > 0) return;
         assertHasLineMark(/pause/, exec_state.frame(0));
         assertHasLineMark(/positions/, exec_state.frame(frame_number));
         var frame = exec_state.frame(frame_number);