| OLD | NEW |
| 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/debug/debug.h" | 5 #include "src/debug/debug.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 22 matching lines...) Expand all Loading... |
| 33 message_handler_(NULL), | 33 message_handler_(NULL), |
| 34 command_received_(0), | 34 command_received_(0), |
| 35 command_queue_(isolate->logger(), kQueueInitialSize), | 35 command_queue_(isolate->logger(), kQueueInitialSize), |
| 36 is_active_(false), | 36 is_active_(false), |
| 37 is_suppressed_(false), | 37 is_suppressed_(false), |
| 38 live_edit_enabled_(true), // TODO(yangguo): set to false by default. | 38 live_edit_enabled_(true), // TODO(yangguo): set to false by default. |
| 39 break_disabled_(false), | 39 break_disabled_(false), |
| 40 in_debug_event_listener_(false), | 40 in_debug_event_listener_(false), |
| 41 break_on_exception_(false), | 41 break_on_exception_(false), |
| 42 break_on_uncaught_exception_(false), | 42 break_on_uncaught_exception_(false), |
| 43 script_cache_(NULL), | |
| 44 debug_info_list_(NULL), | 43 debug_info_list_(NULL), |
| 45 isolate_(isolate) { | 44 isolate_(isolate) { |
| 46 ThreadInit(); | 45 ThreadInit(); |
| 47 } | 46 } |
| 48 | 47 |
| 49 | 48 |
| 50 static v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) { | 49 static v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) { |
| 51 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); | 50 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); |
| 52 // Isolate::context() may have been NULL when "script collected" event | 51 // Isolate::context() may have been NULL when "script collected" event |
| 53 // occured. | 52 // occured. |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); | 346 MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); |
| 348 return storage + ArchiveSpacePerThread(); | 347 return storage + ArchiveSpacePerThread(); |
| 349 } | 348 } |
| 350 | 349 |
| 351 | 350 |
| 352 int Debug::ArchiveSpacePerThread() { | 351 int Debug::ArchiveSpacePerThread() { |
| 353 return sizeof(ThreadLocal); | 352 return sizeof(ThreadLocal); |
| 354 } | 353 } |
| 355 | 354 |
| 356 | 355 |
| 357 ScriptCache::ScriptCache(Isolate* isolate) : isolate_(isolate) { | |
| 358 Heap* heap = isolate_->heap(); | |
| 359 HandleScope scope(isolate_); | |
| 360 | |
| 361 DCHECK(isolate_->debug()->is_active()); | |
| 362 | |
| 363 // Perform a GC to get rid of all unreferenced scripts. | |
| 364 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); | |
| 365 | |
| 366 // Scan heap for Script objects. | |
| 367 List<Handle<Script> > scripts; | |
| 368 { | |
| 369 HeapIterator iterator(heap, HeapIterator::kFilterUnreachable); | |
| 370 DisallowHeapAllocation no_allocation; | |
| 371 for (HeapObject* obj = iterator.next(); obj != NULL; | |
| 372 obj = iterator.next()) { | |
| 373 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { | |
| 374 scripts.Add(Handle<Script>(Script::cast(obj))); | |
| 375 } | |
| 376 } | |
| 377 } | |
| 378 | |
| 379 GlobalHandles* global_handles = isolate_->global_handles(); | |
| 380 table_ = Handle<WeakValueHashTable>::cast(global_handles->Create( | |
| 381 Object::cast(*WeakValueHashTable::New(isolate_, scripts.length())))); | |
| 382 for (int i = 0; i < scripts.length(); i++) Add(scripts[i]); | |
| 383 } | |
| 384 | |
| 385 | |
| 386 void ScriptCache::Add(Handle<Script> script) { | |
| 387 HandleScope scope(isolate_); | |
| 388 Handle<Smi> id(script->id(), isolate_); | |
| 389 | |
| 390 #ifdef DEBUG | |
| 391 Handle<Object> lookup(table_->LookupWeak(id), isolate_); | |
| 392 if (!lookup->IsTheHole()) { | |
| 393 Handle<Script> found = Handle<Script>::cast(lookup); | |
| 394 DCHECK(script->id() == found->id()); | |
| 395 DCHECK(!script->name()->IsString() || | |
| 396 String::cast(script->name())->Equals(String::cast(found->name()))); | |
| 397 } | |
| 398 #endif | |
| 399 | |
| 400 Handle<WeakValueHashTable> new_table = | |
| 401 WeakValueHashTable::PutWeak(table_, id, script); | |
| 402 | |
| 403 if (new_table.is_identical_to(table_)) return; | |
| 404 GlobalHandles* global_handles = isolate_->global_handles(); | |
| 405 global_handles->Destroy(Handle<Object>::cast(table_).location()); | |
| 406 table_ = Handle<WeakValueHashTable>::cast( | |
| 407 global_handles->Create(Object::cast(*new_table))); | |
| 408 } | |
| 409 | |
| 410 | |
| 411 ScriptCache::~ScriptCache() { | |
| 412 isolate_->global_handles()->Destroy(Handle<Object>::cast(table_).location()); | |
| 413 table_ = Handle<WeakValueHashTable>(); | |
| 414 } | |
| 415 | |
| 416 | |
| 417 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { | 356 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { |
| 418 // Globalize the request debug info object and make it weak. | 357 // Globalize the request debug info object and make it weak. |
| 419 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); | 358 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); |
| 420 debug_info_ = | 359 debug_info_ = |
| 421 Handle<DebugInfo>::cast(global_handles->Create(debug_info)).location(); | 360 Handle<DebugInfo>::cast(global_handles->Create(debug_info)).location(); |
| 422 } | 361 } |
| 423 | 362 |
| 424 | 363 |
| 425 DebugInfoListNode::~DebugInfoListNode() { | 364 DebugInfoListNode::~DebugInfoListNode() { |
| 426 if (debug_info_ == nullptr) return; | 365 if (debug_info_ == nullptr) return; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 } | 398 } |
| 460 | 399 |
| 461 | 400 |
| 462 void Debug::Unload() { | 401 void Debug::Unload() { |
| 463 ClearAllBreakPoints(); | 402 ClearAllBreakPoints(); |
| 464 ClearStepping(); | 403 ClearStepping(); |
| 465 | 404 |
| 466 // Return debugger is not loaded. | 405 // Return debugger is not loaded. |
| 467 if (!is_loaded()) return; | 406 if (!is_loaded()) return; |
| 468 | 407 |
| 469 // Clear the script cache. | |
| 470 if (script_cache_ != NULL) { | |
| 471 delete script_cache_; | |
| 472 script_cache_ = NULL; | |
| 473 } | |
| 474 | |
| 475 // Clear debugger context global handle. | 408 // Clear debugger context global handle. |
| 476 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location()); | 409 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location()); |
| 477 debug_context_ = Handle<Context>(); | 410 debug_context_ = Handle<Context>(); |
| 478 } | 411 } |
| 479 | 412 |
| 480 | 413 |
| 481 void Debug::Break(Arguments args, JavaScriptFrame* frame) { | 414 void Debug::Break(Arguments args, JavaScriptFrame* frame) { |
| 482 Heap* heap = isolate_->heap(); | 415 Heap* heap = isolate_->heap(); |
| 483 HandleScope scope(isolate_); | 416 HandleScope scope(isolate_); |
| 484 DCHECK(args.length() == 0); | 417 DCHECK(args.length() == 0); |
| (...skipping 1183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1668 | 1601 |
| 1669 | 1602 |
| 1670 void Debug::ClearMirrorCache() { | 1603 void Debug::ClearMirrorCache() { |
| 1671 PostponeInterruptsScope postpone(isolate_); | 1604 PostponeInterruptsScope postpone(isolate_); |
| 1672 HandleScope scope(isolate_); | 1605 HandleScope scope(isolate_); |
| 1673 CallFunction("ClearMirrorCache", 0, NULL); | 1606 CallFunction("ClearMirrorCache", 0, NULL); |
| 1674 } | 1607 } |
| 1675 | 1608 |
| 1676 | 1609 |
| 1677 Handle<FixedArray> Debug::GetLoadedScripts() { | 1610 Handle<FixedArray> Debug::GetLoadedScripts() { |
| 1678 // Create and fill the script cache when the loaded scripts is requested for | |
| 1679 // the first time. | |
| 1680 if (script_cache_ == NULL) script_cache_ = new ScriptCache(isolate_); | |
| 1681 | |
| 1682 // Perform GC to get unreferenced scripts evicted from the cache before | |
| 1683 // returning the content. | |
| 1684 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 1611 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 1685 "Debug::GetLoadedScripts"); | 1612 "Debug::GetLoadedScripts"); |
| 1686 | 1613 Factory* factory = isolate_->factory(); |
| 1687 // Get the scripts from the cache. | 1614 if (!factory->script_list()->IsWeakFixedArray()) { |
| 1688 return script_cache_->GetScripts(); | 1615 return factory->empty_fixed_array(); |
| 1616 } |
| 1617 Handle<WeakFixedArray> array = |
| 1618 Handle<WeakFixedArray>::cast(factory->script_list()); |
| 1619 Handle<FixedArray> results = factory->NewFixedArray(array->Length()); |
| 1620 int length = 0; |
| 1621 for (int i = 0; i < array->Length(); ++i) { |
| 1622 Object* item = array->Get(i); |
| 1623 if (item->IsScript() && Script::cast(item)->HasValidSource()) { |
| 1624 results->set(length++, item); |
| 1625 } |
| 1626 } |
| 1627 results->Shrink(length); |
| 1628 return results; |
| 1689 } | 1629 } |
| 1690 | 1630 |
| 1691 | 1631 |
| 1692 void Debug::GetStepinPositions(JavaScriptFrame* frame, StackFrame::Id frame_id, | 1632 void Debug::GetStepinPositions(JavaScriptFrame* frame, StackFrame::Id frame_id, |
| 1693 List<int>* results_out) { | 1633 List<int>* results_out) { |
| 1694 FrameSummary summary = GetFirstFrameSummary(frame); | 1634 FrameSummary summary = GetFirstFrameSummary(frame); |
| 1695 | 1635 |
| 1696 Handle<JSFunction> fun = Handle<JSFunction>(summary.function()); | 1636 Handle<JSFunction> fun = Handle<JSFunction>(summary.function()); |
| 1697 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(fun->shared()); | 1637 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(fun->shared()); |
| 1698 | 1638 |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1930 | 1870 |
| 1931 // Process debug event. | 1871 // Process debug event. |
| 1932 ProcessDebugEvent(v8::BeforeCompile, | 1872 ProcessDebugEvent(v8::BeforeCompile, |
| 1933 Handle<JSObject>::cast(event_data), | 1873 Handle<JSObject>::cast(event_data), |
| 1934 true); | 1874 true); |
| 1935 } | 1875 } |
| 1936 | 1876 |
| 1937 | 1877 |
| 1938 // Handle debugger actions when a new script is compiled. | 1878 // Handle debugger actions when a new script is compiled. |
| 1939 void Debug::OnAfterCompile(Handle<Script> script) { | 1879 void Debug::OnAfterCompile(Handle<Script> script) { |
| 1940 // Add the newly compiled script to the script cache. | |
| 1941 if (script_cache_ != NULL) script_cache_->Add(script); | |
| 1942 | |
| 1943 if (ignore_events()) return; | 1880 if (ignore_events()) return; |
| 1944 | 1881 |
| 1945 if (in_debug_scope()) { | 1882 if (in_debug_scope()) { |
| 1946 ProcessCompileEventInDebugScope(v8::AfterCompile, script); | 1883 ProcessCompileEventInDebugScope(v8::AfterCompile, script); |
| 1947 return; | 1884 return; |
| 1948 } | 1885 } |
| 1949 | 1886 |
| 1950 HandleScope scope(isolate_); | 1887 HandleScope scope(isolate_); |
| 1951 DebugScope debug_scope(this); | 1888 DebugScope debug_scope(this); |
| 1952 if (debug_scope.failed()) return; | 1889 if (debug_scope.failed()) return; |
| (...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2676 } | 2613 } |
| 2677 | 2614 |
| 2678 | 2615 |
| 2679 void LockingCommandMessageQueue::Clear() { | 2616 void LockingCommandMessageQueue::Clear() { |
| 2680 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 2617 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 2681 queue_.Clear(); | 2618 queue_.Clear(); |
| 2682 } | 2619 } |
| 2683 | 2620 |
| 2684 } // namespace internal | 2621 } // namespace internal |
| 2685 } // namespace v8 | 2622 } // namespace v8 |
| OLD | NEW |