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

Side by Side Diff: src/debug.cc

Issue 649563006: 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: Rebase 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
« no previous file with comments | « src/debug.h ('k') | src/global-handles.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 981 matching lines...) Expand 10 before | Expand all | Expand 10 after
2188 2179
2189 // Add debug info to the list. 2180 // Add debug info to the list.
2190 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); 2181 DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
2191 node->set_next(debug_info_list_); 2182 node->set_next(debug_info_list_);
2192 debug_info_list_ = node; 2183 debug_info_list_ = node;
2193 2184
2194 return true; 2185 return true;
2195 } 2186 }
2196 2187
2197 2188
2198 void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) { 2189 // This uses the location of a handle to look up the debug info in the debug
2190 // info list, but it doesn't use the actual debug info for anything. Therefore
2191 // if the debug info has been collected by the GC, we can be sure that this
2192 // method will not attempt to resurrect it.
2193 void Debug::RemoveDebugInfo(DebugInfo** debug_info) {
2199 DCHECK(debug_info_list_ != NULL); 2194 DCHECK(debug_info_list_ != NULL);
2200 // Run through the debug info objects to find this one and remove it. 2195 // Run through the debug info objects to find this one and remove it.
2201 DebugInfoListNode* prev = NULL; 2196 DebugInfoListNode* prev = NULL;
2202 DebugInfoListNode* current = debug_info_list_; 2197 DebugInfoListNode* current = debug_info_list_;
2203 while (current != NULL) { 2198 while (current != NULL) {
2204 if (*current->debug_info() == *debug_info) { 2199 if (current->debug_info().location() == debug_info) {
2205 // Unlink from list. If prev is NULL we are looking at the first element. 2200 // Unlink from list. If prev is NULL we are looking at the first element.
2206 if (prev == NULL) { 2201 if (prev == NULL) {
2207 debug_info_list_ = current->next(); 2202 debug_info_list_ = current->next();
2208 } else { 2203 } else {
2209 prev->set_next(current->next()); 2204 prev->set_next(current->next());
2210 } 2205 }
2211 current->debug_info()->shared()->set_debug_info(
2212 isolate_->heap()->undefined_value());
2213 delete current; 2206 delete current;
2214 2207
2215 // If there are no more debug info objects there are not more break 2208 // If there are no more debug info objects there are not more break
2216 // points. 2209 // points.
2217 has_break_points_ = debug_info_list_ != NULL; 2210 has_break_points_ = debug_info_list_ != NULL;
2218 2211
2219 return; 2212 return;
2220 } 2213 }
2221 // Move to next in list. 2214 // Move to next in list.
2222 prev = current; 2215 prev = current;
2223 current = current->next(); 2216 current = current->next();
2224 } 2217 }
2225 UNREACHABLE(); 2218 UNREACHABLE();
2226 } 2219 }
2227 2220
2228 2221
2222 void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) {
2223 HandleScope scope(isolate_);
2224 Handle<SharedFunctionInfo> shared(debug_info->shared());
2225
2226 RemoveDebugInfo(debug_info.location());
2227
2228 shared->set_debug_info(isolate_->heap()->undefined_value());
2229 }
2230
2231
2229 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { 2232 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
2230 after_break_target_ = NULL; 2233 after_break_target_ = NULL;
2231 2234
2232 if (LiveEdit::SetAfterBreakTarget(this)) return; // LiveEdit did the job. 2235 if (LiveEdit::SetAfterBreakTarget(this)) return; // LiveEdit did the job.
2233 2236
2234 HandleScope scope(isolate_); 2237 HandleScope scope(isolate_);
2235 PrepareForBreakPoints(); 2238 PrepareForBreakPoints();
2236 2239
2237 // Get the executing function in which the debug break occurred. 2240 // Get the executing function in which the debug break occurred.
2238 Handle<JSFunction> function(JSFunction::cast(frame->function())); 2241 Handle<JSFunction> function(JSFunction::cast(frame->function()));
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2313 after_break_target_ = Assembler::target_address_at(addr, *code); 2316 after_break_target_ = Assembler::target_address_at(addr, *code);
2314 } 2317 }
2315 } 2318 }
2316 } 2319 }
2317 2320
2318 2321
2319 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { 2322 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
2320 HandleScope scope(isolate_); 2323 HandleScope scope(isolate_);
2321 2324
2322 // If there are no break points this cannot be break at return, as 2325 // If there are no break points this cannot be break at return, as
2323 // the debugger statement and stack guard bebug break cannot be at 2326 // the debugger statement and stack guard debug break cannot be at
2324 // return. 2327 // return.
2325 if (!has_break_points_) { 2328 if (!has_break_points_) {
2326 return false; 2329 return false;
2327 } 2330 }
2328 2331
2329 PrepareForBreakPoints(); 2332 PrepareForBreakPoints();
2330 2333
2331 // Get the executing function in which the debug break occurred. 2334 // Get the executing function in which the debug break occurred.
2332 Handle<JSFunction> function(JSFunction::cast(frame->function())); 2335 Handle<JSFunction> function(JSFunction::cast(frame->function()));
2333 Handle<SharedFunctionInfo> shared(function->shared()); 2336 Handle<SharedFunctionInfo> shared(function->shared());
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after
3233 return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json))); 3236 return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json)));
3234 } else { 3237 } else {
3235 return v8::Utils::ToLocal(response_json_); 3238 return v8::Utils::ToLocal(response_json_);
3236 } 3239 }
3237 } 3240 }
3238 3241
3239 3242
3240 v8::Handle<v8::Context> MessageImpl::GetEventContext() const { 3243 v8::Handle<v8::Context> MessageImpl::GetEventContext() const {
3241 Isolate* isolate = event_data_->GetIsolate(); 3244 Isolate* isolate = event_data_->GetIsolate();
3242 v8::Handle<v8::Context> context = GetDebugEventContext(isolate); 3245 v8::Handle<v8::Context> context = GetDebugEventContext(isolate);
3243 // Isolate::context() may be NULL when "script collected" event occures. 3246 // Isolate::context() may be NULL when "script collected" event occurs.
3244 DCHECK(!context.IsEmpty()); 3247 DCHECK(!context.IsEmpty());
3245 return context; 3248 return context;
3246 } 3249 }
3247 3250
3248 3251
3249 v8::Debug::ClientData* MessageImpl::GetClientData() const { 3252 v8::Debug::ClientData* MessageImpl::GetClientData() const {
3250 return client_data_; 3253 return client_data_;
3251 } 3254 }
3252 3255
3253 3256
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
3385 logger_->DebugEvent("Put", message.text()); 3388 logger_->DebugEvent("Put", message.text());
3386 } 3389 }
3387 3390
3388 3391
3389 void LockingCommandMessageQueue::Clear() { 3392 void LockingCommandMessageQueue::Clear() {
3390 base::LockGuard<base::Mutex> lock_guard(&mutex_); 3393 base::LockGuard<base::Mutex> lock_guard(&mutex_);
3391 queue_.Clear(); 3394 queue_.Clear();
3392 } 3395 }
3393 3396
3394 } } // namespace v8::internal 3397 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/global-handles.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698