| Index: src/debug.cc
|
| diff --git a/src/debug.cc b/src/debug.cc
|
| index c1c2aad68279b549005857c631e8d3999e6b610d..7becd988782cfd809e3134734532c4928341771c 100644
|
| --- a/src/debug.cc
|
| +++ b/src/debug.cc
|
| @@ -594,10 +594,7 @@ ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch),
|
| Heap* heap = isolate_->heap();
|
| HandleScope scope(isolate_);
|
|
|
| - // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
|
| - // rid of all the cached script wrappers and the second gets rid of the
|
| - // scripts which are no longer referenced.
|
| - heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
|
| + // Perform a GC to get rid of all unreferenced scripts.
|
| heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
|
|
|
| // Scan heap for Script objects.
|
| @@ -694,13 +691,7 @@ void Debug::HandleWeakDebugInfo(
|
| Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug();
|
| DebugInfoListNode* node =
|
| reinterpret_cast<DebugInfoListNode*>(data.GetParameter());
|
| - // We need to clear all breakpoints associated with the function to restore
|
| - // original code and avoid patching the code twice later because
|
| - // the function will live in the heap until next gc, and can be found by
|
| - // Debug::FindSharedFunctionInfoInScript.
|
| - BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
|
| - it.ClearAllDebugBreak();
|
| - debug->RemoveDebugInfo(node->debug_info());
|
| + debug->RemoveDebugInfo(node->debug_info().location());
|
| #ifdef DEBUG
|
| for (DebugInfoListNode* n = debug->debug_info_list_;
|
| n != NULL;
|
| @@ -716,8 +707,8 @@ DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
|
| GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
|
| debug_info_ = Handle<DebugInfo>::cast(global_handles->Create(debug_info));
|
| GlobalHandles::MakeWeak(reinterpret_cast<Object**>(debug_info_.location()),
|
| - this,
|
| - Debug::HandleWeakDebugInfo);
|
| + this, Debug::HandleWeakDebugInfo,
|
| + GlobalHandles::Phantom);
|
| }
|
|
|
|
|
| @@ -1172,7 +1163,7 @@ void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
|
| // If there are no more break points left remove the debug info for this
|
| // function.
|
| if (debug_info->GetBreakPointCount() == 0) {
|
| - RemoveDebugInfo(debug_info);
|
| + RemoveDebugInfoAndClearFromShared(debug_info);
|
| }
|
|
|
| return;
|
| @@ -1193,7 +1184,7 @@ void Debug::ClearAllBreakPoints() {
|
|
|
| // Remove all debug info.
|
| while (debug_info_list_ != NULL) {
|
| - RemoveDebugInfo(debug_info_list_->debug_info());
|
| + RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info());
|
| }
|
| }
|
|
|
| @@ -2195,21 +2186,23 @@ bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
|
| }
|
|
|
|
|
| -void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) {
|
| +// This uses the location of a handle to look up the debug info in the debug
|
| +// info list, but it doesn't use the actual debug info for anything. Therefore
|
| +// if the debug info has been collected by the GC, we can be sure that this
|
| +// method will not attempt to resurrect it.
|
| +void Debug::RemoveDebugInfo(DebugInfo** debug_info) {
|
| DCHECK(debug_info_list_ != NULL);
|
| // Run through the debug info objects to find this one and remove it.
|
| DebugInfoListNode* prev = NULL;
|
| DebugInfoListNode* current = debug_info_list_;
|
| while (current != NULL) {
|
| - if (*current->debug_info() == *debug_info) {
|
| + if (current->debug_info().location() == debug_info) {
|
| // Unlink from list. If prev is NULL we are looking at the first element.
|
| if (prev == NULL) {
|
| debug_info_list_ = current->next();
|
| } else {
|
| prev->set_next(current->next());
|
| }
|
| - current->debug_info()->shared()->set_debug_info(
|
| - isolate_->heap()->undefined_value());
|
| delete current;
|
|
|
| // If there are no more debug info objects there are not more break
|
| @@ -2226,6 +2219,16 @@ void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) {
|
| }
|
|
|
|
|
| +void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) {
|
| + HandleScope scope(isolate_);
|
| + Handle<SharedFunctionInfo> shared(debug_info->shared());
|
| +
|
| + RemoveDebugInfo(debug_info.location());
|
| +
|
| + shared->set_debug_info(isolate_->heap()->undefined_value());
|
| +}
|
| +
|
| +
|
| void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
|
| after_break_target_ = NULL;
|
|
|
| @@ -2320,7 +2323,7 @@ bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
|
| HandleScope scope(isolate_);
|
|
|
| // If there are no break points this cannot be break at return, as
|
| - // the debugger statement and stack guard bebug break cannot be at
|
| + // the debugger statement and stack guard debug break cannot be at
|
| // return.
|
| if (!has_break_points_) {
|
| return false;
|
| @@ -3240,7 +3243,7 @@ v8::Handle<v8::String> MessageImpl::GetJSON() const {
|
| v8::Handle<v8::Context> MessageImpl::GetEventContext() const {
|
| Isolate* isolate = event_data_->GetIsolate();
|
| v8::Handle<v8::Context> context = GetDebugEventContext(isolate);
|
| - // Isolate::context() may be NULL when "script collected" event occures.
|
| + // Isolate::context() may be NULL when "script collected" event occurs.
|
| DCHECK(!context.IsEmpty());
|
| return context;
|
| }
|
|
|