Revision: 21477
Author:   [email protected]
Date:     Mon May 26 07:05:56 2014 UTC
Log:      Fix leak in debug mirror cache.

When fetching loaded scripts, mirror objects are created and cached.
If the cache is not cleared, it holds script objects alive.

This also fixes a minor issue with script unloading.

[email protected]
BUG=376534
LOG=N

Review URL: https://codereview.chromium.org/296953005
http://code.google.com/p/v8/source/detail?r=21477

Added:
 /branches/bleeding_edge/test/mjsunit/regress/regress-debug-context-load.js
Modified:
 /branches/bleeding_edge/src/debug-debugger.js
 /branches/bleeding_edge/src/debug.cc
 /branches/bleeding_edge/test/mjsunit/debug-scripts-request.js
 /branches/bleeding_edge/tools/generate-runtime-tests.py

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-debug-context-load.js Mon May 26 07:05:56 2014 UTC
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+
+Debug = debug.Debug;
+Debug.setListener(null);
=======================================
--- /branches/bleeding_edge/src/debug-debugger.js Thu May 22 13:59:37 2014 UTC +++ /branches/bleeding_edge/src/debug-debugger.js Mon May 26 07:05:56 2014 UTC
@@ -484,6 +484,12 @@
   }
   return result;
 }
+
+
+function GetLoadedScripts() {
+  ClearMirrorCache();  // The mirror cache may be holding onto scripts.
+  return %DebugGetLoadedScripts();
+}


 Debug.setListener = function(listener, opt_data) {
@@ -915,7 +921,7 @@
 // scanning the heap.
 Debug.scripts = function() {
   // Collect all scripts in the heap.
-  return %DebugGetLoadedScripts();
+  return GetLoadedScripts();
 };


@@ -2244,7 +2250,7 @@
   }

   // Collect all scripts in the heap.
-  var scripts = %DebugGetLoadedScripts();
+  var scripts = GetLoadedScripts();

   response.body = [];

@@ -2316,7 +2322,7 @@
   var script_id = request.arguments.script_id;
   var preview_only = !!request.arguments.preview_only;

-  var scripts = %DebugGetLoadedScripts();
+  var scripts = GetLoadedScripts();

   var the_script = null;
   for (var i = 0; i < scripts.length; i++) {
=======================================
--- /branches/bleeding_edge/src/debug.cc        Thu May 22 11:13:37 2014 UTC
+++ /branches/bleeding_edge/src/debug.cc        Mon May 26 07:05:56 2014 UTC
@@ -3139,22 +3139,23 @@


 void Debugger::UpdateState() {
+  Debug* debug = isolate_->debug();
   bool activate = message_handler_ != NULL ||
                   !event_listener_.is_null() ||
-                  isolate_->debug()->InDebugger();
+                  debug->InDebugger();
   if (!is_active_ && activate) {
     // Note that the debug context could have already been loaded to
     // bootstrap test cases.
     isolate_->compilation_cache()->Disable();
-    activate = isolate_->debug()->Load();
-  } else if (is_active_ && !activate) {
+    activate = debug->Load();
+  } else if (debug->IsLoaded() && !activate) {
     isolate_->compilation_cache()->Enable();
-    isolate_->debug()->ClearAllBreakPoints();
-    isolate_->debug()->Unload();
+    debug->ClearAllBreakPoints();
+    debug->Unload();
   }
   is_active_ = activate;
   // At this point the debug context is loaded iff the debugger is active.
-  ASSERT(isolate_->debug()->IsLoaded() == is_active_);
+  ASSERT(debug->IsLoaded() == is_active_);
 }


@@ -3271,21 +3272,8 @@
     // JavaScript. This can happen if the v8::Debug::Call is used in which
     // case the exception should end up in the calling code.
     if (!isolate_->has_pending_exception()) {
-      // Try to avoid any pending debug break breaking in the clear mirror
-      // cache JavaScript code.
-      if (isolate_->stack_guard()->CheckDebugBreak()) {
-        debug->set_has_pending_interrupt(true);
-        isolate_->stack_guard()->ClearDebugBreak();
-      }
       debug->ClearMirrorCache();
     }
-
-    // Request debug break when leaving the last debugger entry
-    // if one was recorded while debugging.
-    if (debug->has_pending_interrupt()) {
-      debug->set_has_pending_interrupt(false);
-      isolate_->stack_guard()->RequestDebugBreak();
-    }

     // If there are commands in the queue when leaving the debugger request
     // that these commands are processed.
=======================================
--- /branches/bleeding_edge/test/mjsunit/debug-scripts-request.js Thu Apr 26 13:44:18 2012 UTC +++ /branches/bleeding_edge/test/mjsunit/debug-scripts-request.js Mon May 26 07:05:56 2014 UTC
@@ -108,3 +108,5 @@
 assertTrue(listenerComplete,
            "listener did not run to completion, exception: " + exception);
 assertFalse(exception, "exception in listener")
+
+Debug.setListener(null);
=======================================
--- /branches/bleeding_edge/tools/generate-runtime-tests.py Fri May 23 12:55:57 2014 UTC +++ /branches/bleeding_edge/tools/generate-runtime-tests.py Mon May 26 07:05:56 2014 UTC
@@ -51,7 +51,7 @@
 EXPECTED_FUZZABLE_COUNT = 325
 EXPECTED_CCTEST_COUNT = 6
 EXPECTED_UNKNOWN_COUNT = 5
-EXPECTED_BUILTINS_COUNT = 781
+EXPECTED_BUILTINS_COUNT = 782


 # Don't call these at all.

--
--
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