Reviewers: ulan,
Description:
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
Please review this at https://codereview.chromium.org/296953005/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+18, -31 lines):
M src/debug.cc
A + test/mjsunit/regress/regress-debug-context-load.js
Index: src/debug.cc
diff --git a/src/debug.cc b/src/debug.cc
index
8956e92c7d9628343dedd1721a637de53cb8719e..750d53ded9d6e607dd35ba3196253d8a1fe06930
100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -2500,9 +2500,11 @@ bool Debug::IsDebugGlobal(GlobalObject* global) {
void Debug::ClearMirrorCache() {
+ if (isolate_->has_pending_exception()) return;
PostponeInterruptsScope postpone(isolate_);
HandleScope scope(isolate_);
- ASSERT(isolate_->context() == *Debug::debug_context());
+ SaveContext save(isolate_);
+ isolate_->set_context(*debug_context());
// Clear the mirror cache.
Handle<String> function_name =
isolate_->factory()->InternalizeOneByteString(
@@ -2573,6 +2575,9 @@ Handle<FixedArray> Debug::GetLoadedScripts() {
isolate_->factory()->NewFixedArray(0);
}
+ // Clear mirrors that might be holding onto scripts.
+ if (IsLoaded()) ClearMirrorCache();
+
// Perform GC to get unreferenced scripts evicted from the cache before
// returning the content.
isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags,
@@ -3139,22 +3144,24 @@ void
Debugger::SetMessageHandler(v8::Debug::MessageHandler handler) {
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->ClearMirrorCache();
+ 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_);
}
@@ -3266,27 +3273,6 @@ EnterDebugger::~EnterDebugger() {
// Check for leaving the debugger.
if (!load_failed_ && prev_ == NULL) {
- // Clear mirror cache when leaving the debugger. Skip this if there is
a
- // pending exception as clearing the mirror cache calls back into
- // 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.
if (isolate_->debugger()->HasCommands()) {
Index: test/mjsunit/regress/regress-debug-context-load.js
diff --git a/test/mjsunit/readonly-accessor.js
b/test/mjsunit/regress/regress-debug-context-load.js
similarity index 67%
copy from test/mjsunit/readonly-accessor.js
copy to test/mjsunit/regress/regress-debug-context-load.js
index
5a73525fea60d67074d81e392d08d8448f8ae39d..0b3c275f99b016825cd563a700772bbddb7e4bad
100644
--- a/test/mjsunit/readonly-accessor.js
+++ b/test/mjsunit/regress/regress-debug-context-load.js
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-var foo = {};
-foo.__proto__ = new String("bar");
-foo.length = 20;
+// Flags: --expose-debug-as debug
+
+Debug = debug.Debug;
+Debug.setListener(null);
--
--
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.