Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: src/debug.cc

Issue 687003005: Introduce phantom weak handles in the API and use them internally for debug info (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/arguments.h" 8 #include "src/arguments.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 int Debug::ArchiveSpacePerThread() { 587 int Debug::ArchiveSpacePerThread() {
588 return sizeof(ThreadLocal); 588 return sizeof(ThreadLocal);
589 } 589 }
590 590
591 591
592 ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), 592 ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch),
593 isolate_(isolate) { 593 isolate_(isolate) {
594 Heap* heap = isolate_->heap(); 594 Heap* heap = isolate_->heap();
595 HandleScope scope(isolate_); 595 HandleScope scope(isolate_);
596 596
597 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets 597 // Perform a GC to get rid of all unreferenced scripts.
598 // rid of all the cached script wrappers and the second gets rid of the
599 // scripts which are no longer referenced.
600 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
601 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); 598 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
602 599
603 // Scan heap for Script objects. 600 // Scan heap for Script objects.
604 HeapIterator iterator(heap); 601 HeapIterator iterator(heap);
605 DisallowHeapAllocation no_allocation; 602 DisallowHeapAllocation no_allocation;
606 603
607 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 604 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
608 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { 605 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
609 Add(Handle<Script>(Script::cast(obj))); 606 Add(Handle<Script>(Script::cast(obj)));
610 } 607 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 // Clear the weak handle. 684 // Clear the weak handle.
688 GlobalHandles::Destroy(location); 685 GlobalHandles::Destroy(location);
689 } 686 }
690 687
691 688
692 void Debug::HandleWeakDebugInfo( 689 void Debug::HandleWeakDebugInfo(
693 const v8::WeakCallbackData<v8::Value, void>& data) { 690 const v8::WeakCallbackData<v8::Value, void>& data) {
694 Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug(); 691 Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug();
695 DebugInfoListNode* node = 692 DebugInfoListNode* node =
696 reinterpret_cast<DebugInfoListNode*>(data.GetParameter()); 693 reinterpret_cast<DebugInfoListNode*>(data.GetParameter());
697 // We need to clear all breakpoints associated with the function to restore 694 debug->RemoveDebugInfo(node->debug_info().location());
698 // original code and avoid patching the code twice later because
699 // the function will live in the heap until next gc, and can be found by
700 // Debug::FindSharedFunctionInfoInScript.
701 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
702 it.ClearAllDebugBreak();
703 debug->RemoveDebugInfo(node->debug_info());
704 #ifdef DEBUG 695 #ifdef DEBUG
705 for (DebugInfoListNode* n = debug->debug_info_list_; 696 for (DebugInfoListNode* n = debug->debug_info_list_;
706 n != NULL; 697 n != NULL;
707 n = n->next()) { 698 n = n->next()) {
708 DCHECK(n != node); 699 DCHECK(n != node);
709 } 700 }
710 #endif 701 #endif
711 } 702 }
712 703
713 704
714 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { 705 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
715 // Globalize the request debug info object and make it weak. 706 // Globalize the request debug info object and make it weak.
716 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); 707 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
717 debug_info_ = Handle<DebugInfo>::cast(global_handles->Create(debug_info)); 708 debug_info_ = Handle<DebugInfo>::cast(global_handles->Create(debug_info));
718 GlobalHandles::MakeWeak(reinterpret_cast<Object**>(debug_info_.location()), 709 GlobalHandles::MakeWeak(reinterpret_cast<Object**>(debug_info_.location()),
719 this, 710 this, Debug::HandleWeakDebugInfo,
720 Debug::HandleWeakDebugInfo); 711 GlobalHandles::Phantom);
721 } 712 }
722 713
723 714
724 DebugInfoListNode::~DebugInfoListNode() { 715 DebugInfoListNode::~DebugInfoListNode() {
725 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_.location())); 716 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_.location()));
726 } 717 }
727 718
728 719
729 bool Debug::CompileDebuggerScript(Isolate* isolate, int index) { 720 bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
730 Factory* factory = isolate->factory(); 721 Factory* factory = isolate->factory();
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 1156
1166 // Find the break point and clear it. 1157 // Find the break point and clear it.
1167 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); 1158 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
1168 it.FindBreakLocationFromAddress(debug_info->code()->entry() + 1159 it.FindBreakLocationFromAddress(debug_info->code()->entry() +
1169 break_point_info->code_position()->value()); 1160 break_point_info->code_position()->value());
1170 it.ClearBreakPoint(break_point_object); 1161 it.ClearBreakPoint(break_point_object);
1171 1162
1172 // If there are no more break points left remove the debug info for this 1163 // If there are no more break points left remove the debug info for this
1173 // function. 1164 // function.
1174 if (debug_info->GetBreakPointCount() == 0) { 1165 if (debug_info->GetBreakPointCount() == 0) {
1175 RemoveDebugInfo(debug_info); 1166 RemoveDebugInfoAndClearFromShared(debug_info);
1176 } 1167 }
1177 1168
1178 return; 1169 return;
1179 } 1170 }
1180 node = node->next(); 1171 node = node->next();
1181 } 1172 }
1182 } 1173 }
1183 1174
1184 1175
1185 void Debug::ClearAllBreakPoints() { 1176 void Debug::ClearAllBreakPoints() {
1186 DebugInfoListNode* node = debug_info_list_; 1177 DebugInfoListNode* node = debug_info_list_;
1187 while (node != NULL) { 1178 while (node != NULL) {
1188 // Remove all debug break code. 1179 // Remove all debug break code.
1189 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); 1180 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
1190 it.ClearAllDebugBreak(); 1181 it.ClearAllDebugBreak();
1191 node = node->next(); 1182 node = node->next();
1192 } 1183 }
1193 1184
1194 // Remove all debug info. 1185 // Remove all debug info.
1195 while (debug_info_list_ != NULL) { 1186 while (debug_info_list_ != NULL) {
1196 RemoveDebugInfo(debug_info_list_->debug_info()); 1187 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info());
1197 } 1188 }
1198 } 1189 }
1199 1190
1200 1191
1201 void Debug::FloodWithOneShot(Handle<JSFunction> function) { 1192 void Debug::FloodWithOneShot(Handle<JSFunction> function) {
1202 PrepareForBreakPoints(); 1193 PrepareForBreakPoints();
1203 1194
1204 // Make sure the function is compiled and has set up the debug info. 1195 // Make sure the function is compiled and has set up the debug info.
1205 Handle<SharedFunctionInfo> shared(function->shared()); 1196 Handle<SharedFunctionInfo> shared(function->shared());
1206 if (!EnsureDebugInfo(shared, function)) { 1197 if (!EnsureDebugInfo(shared, function)) {
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after
2204 2195
2205 // Add debug info to the list. 2196 // Add debug info to the list.
2206 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); 2197 DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
2207 node->set_next(debug_info_list_); 2198 node->set_next(debug_info_list_);
2208 debug_info_list_ = node; 2199 debug_info_list_ = node;
2209 2200
2210 return true; 2201 return true;
2211 } 2202 }
2212 2203
2213 2204
2214 void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) { 2205 // This uses the location of a handle to look up the debug info in the debug
2206 // info list, but it doesn't use the actual debug info for anything. Therefore
2207 // if the debug info has been collected by the GC, we can be sure that this
2208 // method will not attempt to resurrect it.
2209 void Debug::RemoveDebugInfo(DebugInfo** debug_info) {
2215 DCHECK(debug_info_list_ != NULL); 2210 DCHECK(debug_info_list_ != NULL);
2216 // Run through the debug info objects to find this one and remove it. 2211 // Run through the debug info objects to find this one and remove it.
2217 DebugInfoListNode* prev = NULL; 2212 DebugInfoListNode* prev = NULL;
2218 DebugInfoListNode* current = debug_info_list_; 2213 DebugInfoListNode* current = debug_info_list_;
2219 while (current != NULL) { 2214 while (current != NULL) {
2220 if (*current->debug_info() == *debug_info) { 2215 if (current->debug_info().location() == debug_info) {
2221 // Unlink from list. If prev is NULL we are looking at the first element. 2216 // Unlink from list. If prev is NULL we are looking at the first element.
2222 if (prev == NULL) { 2217 if (prev == NULL) {
2223 debug_info_list_ = current->next(); 2218 debug_info_list_ = current->next();
2224 } else { 2219 } else {
2225 prev->set_next(current->next()); 2220 prev->set_next(current->next());
2226 } 2221 }
2227 current->debug_info()->shared()->set_debug_info(
2228 isolate_->heap()->undefined_value());
2229 delete current; 2222 delete current;
2230 2223
2231 // If there are no more debug info objects there are not more break 2224 // If there are no more debug info objects there are not more break
2232 // points. 2225 // points.
2233 has_break_points_ = debug_info_list_ != NULL; 2226 has_break_points_ = debug_info_list_ != NULL;
2234 2227
2235 return; 2228 return;
2236 } 2229 }
2237 // Move to next in list. 2230 // Move to next in list.
2238 prev = current; 2231 prev = current;
2239 current = current->next(); 2232 current = current->next();
2240 } 2233 }
2241 UNREACHABLE(); 2234 UNREACHABLE();
2242 } 2235 }
2243 2236
2244 2237
2238 void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) {
2239 HandleScope scope(isolate_);
2240 Handle<SharedFunctionInfo> shared(debug_info->shared());
2241
2242 RemoveDebugInfo(debug_info.location());
2243
2244 shared->set_debug_info(isolate_->heap()->undefined_value());
2245 }
2246
2247
2245 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { 2248 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
2246 after_break_target_ = NULL; 2249 after_break_target_ = NULL;
2247 2250
2248 if (LiveEdit::SetAfterBreakTarget(this)) return; // LiveEdit did the job. 2251 if (LiveEdit::SetAfterBreakTarget(this)) return; // LiveEdit did the job.
2249 2252
2250 HandleScope scope(isolate_); 2253 HandleScope scope(isolate_);
2251 PrepareForBreakPoints(); 2254 PrepareForBreakPoints();
2252 2255
2253 // Get the executing function in which the debug break occurred. 2256 // Get the executing function in which the debug break occurred.
2254 Handle<JSFunction> function(JSFunction::cast(frame->function())); 2257 Handle<JSFunction> function(JSFunction::cast(frame->function()));
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2329 after_break_target_ = Assembler::target_address_at(addr, *code); 2332 after_break_target_ = Assembler::target_address_at(addr, *code);
2330 } 2333 }
2331 } 2334 }
2332 } 2335 }
2333 2336
2334 2337
2335 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { 2338 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
2336 HandleScope scope(isolate_); 2339 HandleScope scope(isolate_);
2337 2340
2338 // If there are no break points this cannot be break at return, as 2341 // If there are no break points this cannot be break at return, as
2339 // the debugger statement and stack guard bebug break cannot be at 2342 // the debugger statement and stack guard debug break cannot be at
2340 // return. 2343 // return.
2341 if (!has_break_points_) { 2344 if (!has_break_points_) {
2342 return false; 2345 return false;
2343 } 2346 }
2344 2347
2345 PrepareForBreakPoints(); 2348 PrepareForBreakPoints();
2346 2349
2347 // Get the executing function in which the debug break occurred. 2350 // Get the executing function in which the debug break occurred.
2348 Handle<JSFunction> function(JSFunction::cast(frame->function())); 2351 Handle<JSFunction> function(JSFunction::cast(frame->function()));
2349 Handle<SharedFunctionInfo> shared(function->shared()); 2352 Handle<SharedFunctionInfo> shared(function->shared());
(...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after
3250 return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json))); 3253 return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json)));
3251 } else { 3254 } else {
3252 return v8::Utils::ToLocal(response_json_); 3255 return v8::Utils::ToLocal(response_json_);
3253 } 3256 }
3254 } 3257 }
3255 3258
3256 3259
3257 v8::Handle<v8::Context> MessageImpl::GetEventContext() const { 3260 v8::Handle<v8::Context> MessageImpl::GetEventContext() const {
3258 Isolate* isolate = event_data_->GetIsolate(); 3261 Isolate* isolate = event_data_->GetIsolate();
3259 v8::Handle<v8::Context> context = GetDebugEventContext(isolate); 3262 v8::Handle<v8::Context> context = GetDebugEventContext(isolate);
3260 // Isolate::context() may be NULL when "script collected" event occures. 3263 // Isolate::context() may be NULL when "script collected" event occurs.
3261 DCHECK(!context.IsEmpty()); 3264 DCHECK(!context.IsEmpty());
3262 return context; 3265 return context;
3263 } 3266 }
3264 3267
3265 3268
3266 v8::Debug::ClientData* MessageImpl::GetClientData() const { 3269 v8::Debug::ClientData* MessageImpl::GetClientData() const {
3267 return client_data_; 3270 return client_data_;
3268 } 3271 }
3269 3272
3270 3273
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
3402 logger_->DebugEvent("Put", message.text()); 3405 logger_->DebugEvent("Put", message.text());
3403 } 3406 }
3404 3407
3405 3408
3406 void LockingCommandMessageQueue::Clear() { 3409 void LockingCommandMessageQueue::Clear() {
3407 base::LockGuard<base::Mutex> lock_guard(&mutex_); 3410 base::LockGuard<base::Mutex> lock_guard(&mutex_);
3408 queue_.Clear(); 3411 queue_.Clear();
3409 } 3412 }
3410 3413
3411 } } // namespace v8::internal 3414 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/global-handles.h » ('j') | src/global-handles.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698