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

Side by Side Diff: src/debug.cc

Issue 297303006: Some more debugger-related refactorings. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix Created 6 years, 6 months 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/execution.cc » ('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 "v8.h" 5 #include "v8.h"
6 6
7 #include "api.h" 7 #include "api.h"
8 #include "arguments.h" 8 #include "arguments.h"
9 #include "bootstrapper.h" 9 #include "bootstrapper.h"
10 #include "code-stubs.h" 10 #include "code-stubs.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 73
74 74
75 BreakLocationIterator::~BreakLocationIterator() { 75 BreakLocationIterator::~BreakLocationIterator() {
76 ASSERT(reloc_iterator_ != NULL); 76 ASSERT(reloc_iterator_ != NULL);
77 ASSERT(reloc_iterator_original_ != NULL); 77 ASSERT(reloc_iterator_original_ != NULL);
78 delete reloc_iterator_; 78 delete reloc_iterator_;
79 delete reloc_iterator_original_; 79 delete reloc_iterator_original_;
80 } 80 }
81 81
82 82
83 // Check whether a code stub with the specified major key is a possible break
84 // point location when looking for source break locations.
85 static bool IsSourceBreakStub(Code* code) {
86 CodeStub::Major major_key = CodeStub::GetMajorKey(code);
87 return major_key == CodeStub::CallFunction;
88 }
89
90
91 // Check whether a code stub with the specified major key is a possible break
92 // location.
93 static bool IsBreakStub(Code* code) {
94 CodeStub::Major major_key = CodeStub::GetMajorKey(code);
95 return major_key == CodeStub::CallFunction;
96 }
97
98
83 void BreakLocationIterator::Next() { 99 void BreakLocationIterator::Next() {
84 DisallowHeapAllocation no_gc; 100 DisallowHeapAllocation no_gc;
85 ASSERT(!RinfoDone()); 101 ASSERT(!RinfoDone());
86 102
87 // Iterate through reloc info for code and original code stopping at each 103 // Iterate through reloc info for code and original code stopping at each
88 // breakable code target. 104 // breakable code target.
89 bool first = break_point_ == -1; 105 bool first = break_point_ == -1;
90 while (!RinfoDone()) { 106 while (!RinfoDone()) {
91 if (!first) RinfoNext(); 107 if (!first) RinfoNext();
92 first = false; 108 first = false;
(...skipping 29 matching lines...) Expand all
122 !code->is_compare_ic_stub() && 138 !code->is_compare_ic_stub() &&
123 !code->is_to_boolean_ic_stub()) || 139 !code->is_to_boolean_ic_stub()) ||
124 RelocInfo::IsConstructCall(rmode())) { 140 RelocInfo::IsConstructCall(rmode())) {
125 break_point_++; 141 break_point_++;
126 return; 142 return;
127 } 143 }
128 if (code->kind() == Code::STUB) { 144 if (code->kind() == Code::STUB) {
129 if (IsDebuggerStatement()) { 145 if (IsDebuggerStatement()) {
130 break_point_++; 146 break_point_++;
131 return; 147 return;
132 } 148 } else if (type_ == ALL_BREAK_LOCATIONS) {
133 if (type_ == ALL_BREAK_LOCATIONS) { 149 if (IsBreakStub(code)) {
134 if (Debug::IsBreakStub(code)) {
135 break_point_++; 150 break_point_++;
136 return; 151 return;
137 } 152 }
138 } else { 153 } else {
139 ASSERT(type_ == SOURCE_BREAK_LOCATIONS); 154 ASSERT(type_ == SOURCE_BREAK_LOCATIONS);
140 if (Debug::IsSourceBreakStub(code)) { 155 if (IsSourceBreakStub(code)) {
141 break_point_++; 156 break_point_++;
142 return; 157 return;
143 } 158 }
144 } 159 }
145 } 160 }
146 } 161 }
147 162
148 // Check for break at return. 163 // Check for break at return.
149 if (RelocInfo::IsJSReturn(rmode())) { 164 if (RelocInfo::IsJSReturn(rmode())) {
150 // Set the positions to the end of the function. 165 // Set the positions to the end of the function.
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 if (RelocInfo::IsJSReturn(rmode())) { 430 if (RelocInfo::IsJSReturn(rmode())) {
416 return IsDebugBreakAtReturn(); 431 return IsDebugBreakAtReturn();
417 } else if (IsDebugBreakSlot()) { 432 } else if (IsDebugBreakSlot()) {
418 return IsDebugBreakAtSlot(); 433 return IsDebugBreakAtSlot();
419 } else { 434 } else {
420 return Debug::IsDebugBreak(rinfo()->target_address()); 435 return Debug::IsDebugBreak(rinfo()->target_address());
421 } 436 }
422 } 437 }
423 438
424 439
440 // Find the builtin to use for invoking the debug break
441 static Handle<Code> DebugBreakForIC(Handle<Code> code, RelocInfo::Mode mode) {
442 Isolate* isolate = code->GetIsolate();
443
444 // Find the builtin debug break function matching the calling convention
445 // used by the call site.
446 if (code->is_inline_cache_stub()) {
447 switch (code->kind()) {
448 case Code::CALL_IC:
449 return isolate->builtins()->CallICStub_DebugBreak();
450
451 case Code::LOAD_IC:
452 return isolate->builtins()->LoadIC_DebugBreak();
453
454 case Code::STORE_IC:
455 return isolate->builtins()->StoreIC_DebugBreak();
456
457 case Code::KEYED_LOAD_IC:
458 return isolate->builtins()->KeyedLoadIC_DebugBreak();
459
460 case Code::KEYED_STORE_IC:
461 return isolate->builtins()->KeyedStoreIC_DebugBreak();
462
463 case Code::COMPARE_NIL_IC:
464 return isolate->builtins()->CompareNilIC_DebugBreak();
465
466 default:
467 UNREACHABLE();
468 }
469 }
470 if (RelocInfo::IsConstructCall(mode)) {
471 if (code->has_function_cache()) {
472 return isolate->builtins()->CallConstructStub_Recording_DebugBreak();
473 } else {
474 return isolate->builtins()->CallConstructStub_DebugBreak();
475 }
476 }
477 if (code->kind() == Code::STUB) {
478 ASSERT(code->major_key() == CodeStub::CallFunction);
479 return isolate->builtins()->CallFunctionStub_DebugBreak();
480 }
481
482 UNREACHABLE();
483 return Handle<Code>::null();
484 }
485
486
425 void BreakLocationIterator::SetDebugBreakAtIC() { 487 void BreakLocationIterator::SetDebugBreakAtIC() {
426 // Patch the original code with the current address as the current address 488 // Patch the original code with the current address as the current address
427 // might have changed by the inline caching since the code was copied. 489 // might have changed by the inline caching since the code was copied.
428 original_rinfo()->set_target_address(rinfo()->target_address()); 490 original_rinfo()->set_target_address(rinfo()->target_address());
429 491
430 RelocInfo::Mode mode = rmode(); 492 RelocInfo::Mode mode = rmode();
431 if (RelocInfo::IsCodeTarget(mode)) { 493 if (RelocInfo::IsCodeTarget(mode)) {
432 Address target = rinfo()->target_address(); 494 Address target = rinfo()->target_address();
433 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); 495 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
434 496
435 // Patch the code to invoke the builtin debug break function matching the 497 // Patch the code to invoke the builtin debug break function matching the
436 // calling convention used by the call site. 498 // calling convention used by the call site.
437 Handle<Code> dbgbrk_code(Debug::FindDebugBreak(target_code, mode)); 499 Handle<Code> dbgbrk_code = DebugBreakForIC(target_code, mode);
438 rinfo()->set_target_address(dbgbrk_code->entry()); 500 rinfo()->set_target_address(dbgbrk_code->entry());
439 } 501 }
440 } 502 }
441 503
442 504
443 void BreakLocationIterator::ClearDebugBreakAtIC() { 505 void BreakLocationIterator::ClearDebugBreakAtIC() {
444 // Patch the code to the original invoke. 506 // Patch the code to the original invoke.
445 rinfo()->set_target_address(original_rinfo()->target_address()); 507 rinfo()->set_target_address(original_rinfo()->target_address());
446 } 508 }
447 509
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 thread_local_.break_frame_id_ = StackFrame::NO_ID; 559 thread_local_.break_frame_id_ = StackFrame::NO_ID;
498 thread_local_.last_step_action_ = StepNone; 560 thread_local_.last_step_action_ = StepNone;
499 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; 561 thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
500 thread_local_.step_count_ = 0; 562 thread_local_.step_count_ = 0;
501 thread_local_.last_fp_ = 0; 563 thread_local_.last_fp_ = 0;
502 thread_local_.queued_step_count_ = 0; 564 thread_local_.queued_step_count_ = 0;
503 thread_local_.step_into_fp_ = 0; 565 thread_local_.step_into_fp_ = 0;
504 thread_local_.step_out_fp_ = 0; 566 thread_local_.step_out_fp_ = 0;
505 // TODO(isolates): frames_are_dropped_? 567 // TODO(isolates): frames_are_dropped_?
506 thread_local_.debugger_entry_ = NULL; 568 thread_local_.debugger_entry_ = NULL;
507 thread_local_.has_pending_interrupt_ = false;
508 thread_local_.restarter_frame_function_pointer_ = NULL; 569 thread_local_.restarter_frame_function_pointer_ = NULL;
509 thread_local_.promise_on_stack_ = NULL; 570 thread_local_.promise_on_stack_ = NULL;
510 } 571 }
511 572
512 573
513 char* Debug::ArchiveDebug(char* storage) { 574 char* Debug::ArchiveDebug(char* storage) {
514 char* to = storage; 575 char* to = storage;
515 MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); 576 MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
516 ThreadInit(); 577 ThreadInit();
517 return storage + ArchiveSpacePerThread(); 578 return storage + ArchiveSpacePerThread();
518 } 579 }
519 580
520 581
521 char* Debug::RestoreDebug(char* storage) { 582 char* Debug::RestoreDebug(char* storage) {
522 char* from = storage; 583 char* from = storage;
523 MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); 584 MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
524 return storage + ArchiveSpacePerThread(); 585 return storage + ArchiveSpacePerThread();
525 } 586 }
526 587
527 588
528 int Debug::ArchiveSpacePerThread() { 589 int Debug::ArchiveSpacePerThread() {
529 return sizeof(ThreadLocal); 590 return sizeof(ThreadLocal);
530 } 591 }
531 592
532 593
594 ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch),
595 isolate_(isolate),
596 collected_scripts_(10) {
597 Heap* heap = isolate_->heap();
598 HandleScope scope(isolate_);
599
600 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
601 // rid of all the cached script wrappers and the second gets rid of the
602 // scripts which are no longer referenced.
603 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
604 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
605
606 // Scan heap for Script objects.
607 HeapIterator iterator(heap);
608 DisallowHeapAllocation no_allocation;
609
610 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
611 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
612 Add(Handle<Script>(Script::cast(obj)));
613 }
614 }
615 }
616
617
533 void ScriptCache::Add(Handle<Script> script) { 618 void ScriptCache::Add(Handle<Script> script) {
534 GlobalHandles* global_handles = isolate_->global_handles(); 619 GlobalHandles* global_handles = isolate_->global_handles();
535 // Create an entry in the hash map for the script. 620 // Create an entry in the hash map for the script.
536 int id = script->id()->value(); 621 int id = script->id()->value();
537 HashMap::Entry* entry = 622 HashMap::Entry* entry =
538 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true); 623 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true);
539 if (entry->value != NULL) { 624 if (entry->value != NULL) {
540 ASSERT(*script == *reinterpret_cast<Script**>(entry->value)); 625 ASSERT(*script == *reinterpret_cast<Script**>(entry->value));
541 return; 626 return;
542 } 627 }
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 ClearAllBreakPoints(); 863 ClearAllBreakPoints();
779 ClearStepping(); 864 ClearStepping();
780 865
781 // Match unmatched PromiseHandlePrologue calls. 866 // Match unmatched PromiseHandlePrologue calls.
782 while (thread_local_.promise_on_stack_) PromiseHandleEpilogue(); 867 while (thread_local_.promise_on_stack_) PromiseHandleEpilogue();
783 868
784 // Return debugger is not loaded. 869 // Return debugger is not loaded.
785 if (!is_loaded()) return; 870 if (!is_loaded()) return;
786 871
787 // Clear the script cache. 872 // Clear the script cache.
788 DestroyScriptCache(); 873 if (script_cache_ != NULL) {
874 delete script_cache_;
875 script_cache_ = NULL;
876 }
789 877
790 // Clear debugger context global handle. 878 // Clear debugger context global handle.
791 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location()); 879 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
792 debug_context_ = Handle<Context>(); 880 debug_context_ = Handle<Context>();
793 } 881 }
794 882
795 883
796 void Debug::Break(Arguments args, JavaScriptFrame* frame) { 884 void Debug::Break(Arguments args, JavaScriptFrame* frame) {
797 Heap* heap = isolate_->heap(); 885 Heap* heap = isolate_->heap();
798 HandleScope scope(isolate_); 886 HandleScope scope(isolate_);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 // triggered. 924 // triggered.
837 Handle<Object> break_points_hit(heap->undefined_value(), isolate_); 925 Handle<Object> break_points_hit(heap->undefined_value(), isolate_);
838 if (break_location_iterator.HasBreakPoint()) { 926 if (break_location_iterator.HasBreakPoint()) {
839 Handle<Object> break_point_objects = 927 Handle<Object> break_point_objects =
840 Handle<Object>(break_location_iterator.BreakPointObjects(), isolate_); 928 Handle<Object>(break_location_iterator.BreakPointObjects(), isolate_);
841 break_points_hit = CheckBreakPoints(break_point_objects); 929 break_points_hit = CheckBreakPoints(break_point_objects);
842 } 930 }
843 931
844 // If step out is active skip everything until the frame where we need to step 932 // If step out is active skip everything until the frame where we need to step
845 // out to is reached, unless real breakpoint is hit. 933 // out to is reached, unless real breakpoint is hit.
846 if (StepOutActive() && frame->fp() != step_out_fp() && 934 if (StepOutActive() &&
935 frame->fp() != thread_local_.step_out_fp_ &&
847 break_points_hit->IsUndefined() ) { 936 break_points_hit->IsUndefined() ) {
848 // Step count should always be 0 for StepOut. 937 // Step count should always be 0 for StepOut.
849 ASSERT(thread_local_.step_count_ == 0); 938 ASSERT(thread_local_.step_count_ == 0);
850 } else if (!break_points_hit->IsUndefined() || 939 } else if (!break_points_hit->IsUndefined() ||
851 (thread_local_.last_step_action_ != StepNone && 940 (thread_local_.last_step_action_ != StepNone &&
852 thread_local_.step_count_ == 0)) { 941 thread_local_.step_count_ == 0)) {
853 // Notify debugger if a real break point is triggered or if performing 942 // Notify debugger if a real break point is triggered or if performing
854 // single stepping with no more steps to perform. Otherwise do another step. 943 // single stepping with no more steps to perform. Otherwise do another step.
855 944
856 // Clear all current stepping setup. 945 // Clear all current stepping setup.
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
1185 1274
1186 bool Debug::IsBreakOnException(ExceptionBreakType type) { 1275 bool Debug::IsBreakOnException(ExceptionBreakType type) {
1187 if (type == BreakUncaughtException) { 1276 if (type == BreakUncaughtException) {
1188 return break_on_uncaught_exception_; 1277 return break_on_uncaught_exception_;
1189 } else { 1278 } else {
1190 return break_on_exception_; 1279 return break_on_exception_;
1191 } 1280 }
1192 } 1281 }
1193 1282
1194 1283
1195 Debug::PromiseOnStack::PromiseOnStack(Isolate* isolate, 1284 PromiseOnStack::PromiseOnStack(Isolate* isolate,
1196 PromiseOnStack* prev, 1285 PromiseOnStack* prev,
1197 Handle<JSFunction> getter) 1286 Handle<JSFunction> getter)
1198 : isolate_(isolate), prev_(prev) { 1287 : isolate_(isolate), prev_(prev) {
1199 handler_ = StackHandler::FromAddress( 1288 handler_ = StackHandler::FromAddress(
1200 Isolate::handler(isolate->thread_local_top())); 1289 Isolate::handler(isolate->thread_local_top()));
1201 getter_ = Handle<JSFunction>::cast( 1290 getter_ = Handle<JSFunction>::cast(
1202 isolate->global_handles()->Create(*getter)); 1291 isolate->global_handles()->Create(*getter));
1203 } 1292 }
1204 1293
1205 1294
1206 Debug::PromiseOnStack::~PromiseOnStack() { 1295 PromiseOnStack::~PromiseOnStack() {
1207 isolate_->global_handles()->Destroy(Handle<Object>::cast(getter_).location()); 1296 isolate_->global_handles()->Destroy(Handle<Object>::cast(getter_).location());
1208 } 1297 }
1209 1298
1210 1299
1211 void Debug::PromiseHandlePrologue(Handle<JSFunction> promise_getter) { 1300 void Debug::PromiseHandlePrologue(Handle<JSFunction> promise_getter) {
1212 PromiseOnStack* prev = thread_local_.promise_on_stack_; 1301 PromiseOnStack* prev = thread_local_.promise_on_stack_;
1213 thread_local_.promise_on_stack_ = 1302 thread_local_.promise_on_stack_ =
1214 new PromiseOnStack(isolate_, prev, promise_getter); 1303 new PromiseOnStack(isolate_, prev, promise_getter);
1215 } 1304 }
1216 1305
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
1523 1612
1524 1613
1525 // Check whether the code object at the specified address is a debug break code 1614 // Check whether the code object at the specified address is a debug break code
1526 // object. 1615 // object.
1527 bool Debug::IsDebugBreak(Address addr) { 1616 bool Debug::IsDebugBreak(Address addr) {
1528 Code* code = Code::GetCodeFromTargetAddress(addr); 1617 Code* code = Code::GetCodeFromTargetAddress(addr);
1529 return code->is_debug_stub() && code->extra_ic_state() == DEBUG_BREAK; 1618 return code->is_debug_stub() && code->extra_ic_state() == DEBUG_BREAK;
1530 } 1619 }
1531 1620
1532 1621
1533 // Check whether a code stub with the specified major key is a possible break
1534 // point location when looking for source break locations.
1535 bool Debug::IsSourceBreakStub(Code* code) {
1536 CodeStub::Major major_key = CodeStub::GetMajorKey(code);
1537 return major_key == CodeStub::CallFunction;
1538 }
1539 1622
1540 1623
1541 // Check whether a code stub with the specified major key is a possible break
1542 // location.
1543 bool Debug::IsBreakStub(Code* code) {
1544 CodeStub::Major major_key = CodeStub::GetMajorKey(code);
1545 return major_key == CodeStub::CallFunction;
1546 }
1547
1548
1549 // Find the builtin to use for invoking the debug break
1550 Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) {
1551 Isolate* isolate = code->GetIsolate();
1552
1553 // Find the builtin debug break function matching the calling convention
1554 // used by the call site.
1555 if (code->is_inline_cache_stub()) {
1556 switch (code->kind()) {
1557 case Code::CALL_IC:
1558 return isolate->builtins()->CallICStub_DebugBreak();
1559
1560 case Code::LOAD_IC:
1561 return isolate->builtins()->LoadIC_DebugBreak();
1562
1563 case Code::STORE_IC:
1564 return isolate->builtins()->StoreIC_DebugBreak();
1565
1566 case Code::KEYED_LOAD_IC:
1567 return isolate->builtins()->KeyedLoadIC_DebugBreak();
1568
1569 case Code::KEYED_STORE_IC:
1570 return isolate->builtins()->KeyedStoreIC_DebugBreak();
1571
1572 case Code::COMPARE_NIL_IC:
1573 return isolate->builtins()->CompareNilIC_DebugBreak();
1574
1575 default:
1576 UNREACHABLE();
1577 }
1578 }
1579 if (RelocInfo::IsConstructCall(mode)) {
1580 if (code->has_function_cache()) {
1581 return isolate->builtins()->CallConstructStub_Recording_DebugBreak();
1582 } else {
1583 return isolate->builtins()->CallConstructStub_DebugBreak();
1584 }
1585 }
1586 if (code->kind() == Code::STUB) {
1587 ASSERT(code->major_key() == CodeStub::CallFunction);
1588 return isolate->builtins()->CallFunctionStub_DebugBreak();
1589 }
1590
1591 UNREACHABLE();
1592 return Handle<Code>::null();
1593 }
1594
1595 1624
1596 // Simple function for returning the source positions for active break points. 1625 // Simple function for returning the source positions for active break points.
1597 Handle<Object> Debug::GetSourceBreakLocations( 1626 Handle<Object> Debug::GetSourceBreakLocations(
1598 Handle<SharedFunctionInfo> shared, 1627 Handle<SharedFunctionInfo> shared,
1599 BreakPositionAlignment position_alignment) { 1628 BreakPositionAlignment position_alignment) {
1600 Isolate* isolate = shared->GetIsolate(); 1629 Isolate* isolate = shared->GetIsolate();
1601 Heap* heap = isolate->heap(); 1630 Heap* heap = isolate->heap();
1602 if (!HasDebugInfo(shared)) { 1631 if (!HasDebugInfo(shared)) {
1603 return Handle<Object>(heap->undefined_value(), isolate); 1632 return Handle<Object>(heap->undefined_value(), isolate);
1604 } 1633 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1648 // For constructor functions skip another frame. 1677 // For constructor functions skip another frame.
1649 if (is_constructor) { 1678 if (is_constructor) {
1650 ASSERT(it.frame()->is_construct()); 1679 ASSERT(it.frame()->is_construct());
1651 it.Advance(); 1680 it.Advance();
1652 } 1681 }
1653 fp = it.frame()->fp(); 1682 fp = it.frame()->fp();
1654 } 1683 }
1655 1684
1656 // Flood the function with one-shot break points if it is called from where 1685 // Flood the function with one-shot break points if it is called from where
1657 // step into was requested. 1686 // step into was requested.
1658 if (fp == step_in_fp()) { 1687 if (fp == thread_local_.step_into_fp_) {
1659 if (function->shared()->bound()) { 1688 if (function->shared()->bound()) {
1660 // Handle Function.prototype.bind 1689 // Handle Function.prototype.bind
1661 Debug::FloodBoundFunctionWithOneShot(function); 1690 Debug::FloodBoundFunctionWithOneShot(function);
1662 } else if (!function->IsNative()) { 1691 } else if (!function->IsNative()) {
1663 // Don't allow step into functions in the native context. 1692 // Don't allow step into functions in the native context.
1664 if (function->shared()->code() == 1693 if (function->shared()->code() ==
1665 isolate->builtins()->builtin(Builtins::kFunctionApply) || 1694 isolate->builtins()->builtin(Builtins::kFunctionApply) ||
1666 function->shared()->code() == 1695 function->shared()->code() ==
1667 isolate->builtins()->builtin(Builtins::kFunctionCall)) { 1696 isolate->builtins()->builtin(Builtins::kFunctionCall)) {
1668 // Handle function.apply and function.call separately to flood the 1697 // Handle function.apply and function.call separately to flood the
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 1934
1906 1935
1907 class ActiveFunctionsRedirector : public ThreadVisitor { 1936 class ActiveFunctionsRedirector : public ThreadVisitor {
1908 public: 1937 public:
1909 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 1938 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1910 RedirectActivationsToRecompiledCodeOnThread(isolate, top); 1939 RedirectActivationsToRecompiledCodeOnThread(isolate, top);
1911 } 1940 }
1912 }; 1941 };
1913 1942
1914 1943
1915 void Debug::EnsureFunctionHasDebugBreakSlots(Handle<JSFunction> function) { 1944 static void EnsureFunctionHasDebugBreakSlots(Handle<JSFunction> function) {
1916 if (function->code()->kind() == Code::FUNCTION && 1945 if (function->code()->kind() == Code::FUNCTION &&
1917 function->code()->has_debug_break_slots()) { 1946 function->code()->has_debug_break_slots()) {
1918 // Nothing to do. Function code already had debug break slots. 1947 // Nothing to do. Function code already had debug break slots.
1919 return; 1948 return;
1920 } 1949 }
1921 // Make sure that the shared full code is compiled with debug 1950 // Make sure that the shared full code is compiled with debug
1922 // break slots. 1951 // break slots.
1923 if (!function->shared()->code()->has_debug_break_slots()) { 1952 if (!function->shared()->code()->has_debug_break_slots()) {
1924 MaybeHandle<Code> code = Compiler::GetCodeForDebugging(function); 1953 MaybeHandle<Code> code = Compiler::GetCodeForDebugging(function);
1925 // Recompilation can fail. In that case leave the code as it was. 1954 // Recompilation can fail. In that case leave the code as it was.
1926 if (!code.is_null()) function->ReplaceCode(*code.ToHandleChecked()); 1955 if (!code.is_null()) function->ReplaceCode(*code.ToHandleChecked());
1927 } else { 1956 } else {
1928 // Simply use shared code if it has debug break slots. 1957 // Simply use shared code if it has debug break slots.
1929 function->ReplaceCode(function->shared()->code()); 1958 function->ReplaceCode(function->shared()->code());
1930 } 1959 }
1931 } 1960 }
1932 1961
1933 1962
1934 void Debug::RecompileAndRelocateSuspendedGenerators( 1963 static void RecompileAndRelocateSuspendedGenerators(
1935 const List<Handle<JSGeneratorObject> > &generators) { 1964 const List<Handle<JSGeneratorObject> > &generators) {
1936 for (int i = 0; i < generators.length(); i++) { 1965 for (int i = 0; i < generators.length(); i++) {
1937 Handle<JSFunction> fun(generators[i]->function()); 1966 Handle<JSFunction> fun(generators[i]->function());
1938 1967
1939 EnsureFunctionHasDebugBreakSlots(fun); 1968 EnsureFunctionHasDebugBreakSlots(fun);
1940 1969
1941 int code_offset = generators[i]->continuation(); 1970 int code_offset = generators[i]->continuation();
1942 int pc_offset = ComputePcOffsetFromCodeOffset(fun->code(), code_offset); 1971 int pc_offset = ComputePcOffsetFromCodeOffset(fun->code(), code_offset);
1943 generators[i]->set_continuation(pc_offset); 1972 generators[i]->set_continuation(pc_offset);
1944 } 1973 }
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
2437 isolate_->global_object(), 2466 isolate_->global_object(),
2438 "ClearMirrorCache").ToHandleChecked(); 2467 "ClearMirrorCache").ToHandleChecked();
2439 ASSERT(fun->IsJSFunction()); 2468 ASSERT(fun->IsJSFunction());
2440 Execution::TryCall(Handle<JSFunction>::cast(fun), 2469 Execution::TryCall(Handle<JSFunction>::cast(fun),
2441 Handle<JSObject>(Debug::debug_context()->global_object()), 2470 Handle<JSObject>(Debug::debug_context()->global_object()),
2442 0, 2471 0,
2443 NULL); 2472 NULL);
2444 } 2473 }
2445 2474
2446 2475
2447 void Debug::CreateScriptCache() {
2448 Heap* heap = isolate_->heap();
2449 HandleScope scope(isolate_);
2450
2451 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
2452 // rid of all the cached script wrappers and the second gets rid of the
2453 // scripts which are no longer referenced. The second also sweeps precisely,
2454 // which saves us doing yet another GC to make the heap iterable.
2455 heap->CollectAllGarbage(Heap::kNoGCFlags, "Debug::CreateScriptCache");
2456
2457 ASSERT(script_cache_ == NULL);
2458 script_cache_ = new ScriptCache(isolate_);
2459
2460 // Scan heap for Script objects.
2461 int count = 0;
2462 HeapIterator iterator(heap);
2463
2464 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
2465 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
2466 script_cache_->Add(Handle<Script>(Script::cast(obj)));
2467 count++;
2468 }
2469 }
2470 }
2471
2472
2473 void Debug::DestroyScriptCache() {
2474 // Get rid of the script cache if it was created.
2475 if (script_cache_ != NULL) {
2476 delete script_cache_;
2477 script_cache_ = NULL;
2478 }
2479 }
2480
2481
2482 void Debug::AddScriptToScriptCache(Handle<Script> script) {
2483 if (script_cache_ != NULL) {
2484 script_cache_->Add(script);
2485 }
2486 }
2487
2488
2489 Handle<FixedArray> Debug::GetLoadedScripts() { 2476 Handle<FixedArray> Debug::GetLoadedScripts() {
2490 // Create and fill the script cache when the loaded scripts is requested for 2477 // Create and fill the script cache when the loaded scripts is requested for
2491 // the first time. 2478 // the first time.
2492 if (script_cache_ == NULL) { 2479 if (script_cache_ == NULL) script_cache_ = new ScriptCache(isolate_);
2493 CreateScriptCache();
2494 }
2495
2496 // If the script cache is not active just return an empty array.
2497 ASSERT(script_cache_ != NULL);
2498 if (script_cache_ == NULL) {
2499 isolate_->factory()->NewFixedArray(0);
2500 }
2501 2480
2502 // Perform GC to get unreferenced scripts evicted from the cache before 2481 // Perform GC to get unreferenced scripts evicted from the cache before
2503 // returning the content. 2482 // returning the content.
2504 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, 2483 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags,
2505 "Debug::GetLoadedScripts"); 2484 "Debug::GetLoadedScripts");
2506 2485
2507 // Get the scripts from the cache. 2486 // Get the scripts from the cache.
2508 return script_cache_->GetScripts(); 2487 return script_cache_->GetScripts();
2509 } 2488 }
2510 2489
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2597 Handle<Object> exec_state; 2576 Handle<Object> exec_state;
2598 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); 2577 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2599 // Create the script collected event object. 2578 // Create the script collected event object.
2600 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); 2579 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_);
2601 Handle<Object> argv[] = { exec_state, id_object }; 2580 Handle<Object> argv[] = { exec_state, id_object };
2602 return MakeJSObject("MakeScriptCollectedEvent", ARRAY_SIZE(argv), argv); 2581 return MakeJSObject("MakeScriptCollectedEvent", ARRAY_SIZE(argv), argv);
2603 } 2582 }
2604 2583
2605 2584
2606 void Debug::OnException(Handle<Object> exception, bool uncaught) { 2585 void Debug::OnException(Handle<Object> exception, bool uncaught) {
2586 if (is_entered() || ignore_events()) return;
2587
2607 HandleScope scope(isolate_); 2588 HandleScope scope(isolate_);
2608
2609 // Bail out based on state or if there is no listener for this event
2610 if (is_entered()) return;
2611 if (!EventActive()) return;
2612
2613 Handle<Object> promise = GetPromiseForUncaughtException(); 2589 Handle<Object> promise = GetPromiseForUncaughtException();
2614 uncaught |= !promise->IsUndefined(); 2590 uncaught |= !promise->IsUndefined();
2615 2591
2616 // Bail out if exception breaks are not active 2592 // Bail out if exception breaks are not active
2617 if (uncaught) { 2593 if (uncaught) {
2618 // Uncaught exceptions are reported by either flags. 2594 // Uncaught exceptions are reported by either flags.
2619 if (!(break_on_uncaught_exception() || break_on_exception())) return; 2595 if (!(break_on_uncaught_exception_ || break_on_exception_)) return;
2620 } else { 2596 } else {
2621 // Caught exceptions are reported is activated. 2597 // Caught exceptions are reported is activated.
2622 if (!break_on_exception()) return; 2598 if (!break_on_exception_) return;
2623 } 2599 }
2624 2600
2625 // Enter the debugger. 2601 // Enter the debugger.
2626 EnterDebugger debugger(isolate_); 2602 EnterDebugger debugger(isolate_);
2627 if (debugger.FailedToEnter()) return; 2603 if (debugger.FailedToEnter()) return;
2628 2604
2629 // Clear all current stepping setup. 2605 // Clear all current stepping setup.
2630 ClearStepping(); 2606 ClearStepping();
2631 2607
2632 // Create the event data object. 2608 // Create the event data object.
2633 Handle<Object> event_data; 2609 Handle<Object> event_data;
2634 // Bail out and don't call debugger if exception. 2610 // Bail out and don't call debugger if exception.
2635 if (!MakeExceptionEvent( 2611 if (!MakeExceptionEvent(
2636 exception, uncaught, promise).ToHandle(&event_data)) { 2612 exception, uncaught, promise).ToHandle(&event_data)) {
2637 return; 2613 return;
2638 } 2614 }
2639 2615
2640 // Process debug event. 2616 // Process debug event.
2641 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); 2617 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
2642 // Return to continue execution from where the exception was thrown. 2618 // Return to continue execution from where the exception was thrown.
2643 } 2619 }
2644 2620
2645 2621
2646 void Debug::OnDebugBreak(Handle<Object> break_points_hit, 2622 void Debug::OnDebugBreak(Handle<Object> break_points_hit,
2647 bool auto_continue) { 2623 bool auto_continue) {
2648 HandleScope scope(isolate_);
2649
2650 // Debugger has already been entered by caller. 2624 // Debugger has already been entered by caller.
2651 ASSERT(isolate_->context() == *debug_context()); 2625 ASSERT(isolate_->context() == *debug_context());
2626 // Bail out if there is no listener for this event
2627 if (ignore_events()) return;
2652 2628
2653 // Bail out if there is no listener for this event 2629 HandleScope scope(isolate_);
2654 if (!EventActive()) return;
2655
2656 // Create the event data object. 2630 // Create the event data object.
2657 Handle<Object> event_data; 2631 Handle<Object> event_data;
2658 // Bail out and don't call debugger if exception. 2632 // Bail out and don't call debugger if exception.
2659 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return; 2633 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
2660 2634
2661 // Process debug event. 2635 // Process debug event.
2662 ProcessDebugEvent(v8::Break, 2636 ProcessDebugEvent(v8::Break,
2663 Handle<JSObject>::cast(event_data), 2637 Handle<JSObject>::cast(event_data),
2664 auto_continue); 2638 auto_continue);
2665 } 2639 }
2666 2640
2667 2641
2668 void Debug::OnBeforeCompile(Handle<Script> script) { 2642 void Debug::OnBeforeCompile(Handle<Script> script) {
2643 if (is_entered() || ignore_events()) return;
2644
2669 HandleScope scope(isolate_); 2645 HandleScope scope(isolate_);
2670
2671 // Bail out based on state or if there is no listener for this event
2672 if (is_entered()) return;
2673 if (!EventActive()) return;
2674
2675 // Enter the debugger. 2646 // Enter the debugger.
2676 EnterDebugger debugger(isolate_); 2647 EnterDebugger debugger(isolate_);
2677 if (debugger.FailedToEnter()) return; 2648 if (debugger.FailedToEnter()) return;
2678 2649
2679 // Create the event data object. 2650 // Create the event data object.
2680 Handle<Object> event_data; 2651 Handle<Object> event_data;
2681 // Bail out and don't call debugger if exception. 2652 // Bail out and don't call debugger if exception.
2682 if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return; 2653 if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return;
2683 2654
2684 // Process debug event. 2655 // Process debug event.
2685 ProcessDebugEvent(v8::BeforeCompile, 2656 ProcessDebugEvent(v8::BeforeCompile,
2686 Handle<JSObject>::cast(event_data), 2657 Handle<JSObject>::cast(event_data),
2687 true); 2658 true);
2688 } 2659 }
2689 2660
2690 2661
2691 // Handle debugger actions when a new script is compiled. 2662 // Handle debugger actions when a new script is compiled.
2692 void Debug::OnAfterCompile(Handle<Script> script, 2663 void Debug::OnAfterCompile(Handle<Script> script,
2693 AfterCompileFlags after_compile_flags) { 2664 AfterCompileFlags after_compile_flags) {
2694 HandleScope scope(isolate_);
2695
2696 // Add the newly compiled script to the script cache. 2665 // Add the newly compiled script to the script cache.
2697 AddScriptToScriptCache(script); 2666 if (script_cache_ != NULL) script_cache_->Add(script);
2698 2667
2699 // No more to do if not debugging. 2668 // No more to do if not debugging.
2700 if (!EventActive()) return; 2669 if (is_entered() || ignore_events()) return;
2701 2670
2671 HandleScope scope(isolate_);
2702 // Store whether in debugger before entering debugger. 2672 // Store whether in debugger before entering debugger.
2703 bool in_debugger = is_entered(); 2673 bool in_debugger = is_entered();
2704 2674
2705 // Enter the debugger. 2675 // Enter the debugger.
2706 EnterDebugger debugger(isolate_); 2676 EnterDebugger debugger(isolate_);
2707 if (debugger.FailedToEnter()) return; 2677 if (debugger.FailedToEnter()) return;
2708 2678
2709 // If debugging there might be script break points registered for this 2679 // If debugging there might be script break points registered for this
2710 // script. Make sure that these break points are set. 2680 // script. Make sure that these break points are set.
2711 2681
(...skipping 29 matching lines...) Expand all
2741 Handle<Object> event_data; 2711 Handle<Object> event_data;
2742 // Bail out and don't call debugger if exception. 2712 // Bail out and don't call debugger if exception.
2743 if (!MakeCompileEvent(script, false).ToHandle(&event_data)) return; 2713 if (!MakeCompileEvent(script, false).ToHandle(&event_data)) return;
2744 2714
2745 // Process debug event. 2715 // Process debug event.
2746 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true); 2716 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true);
2747 } 2717 }
2748 2718
2749 2719
2750 void Debug::OnScriptCollected(int id) { 2720 void Debug::OnScriptCollected(int id) {
2721 if (is_entered() || ignore_events()) return;
2722
2751 HandleScope scope(isolate_); 2723 HandleScope scope(isolate_);
2752
2753 // No more to do if not debugging.
2754 if (is_entered()) return;
2755 if (!EventActive()) return;
2756
2757 // Enter the debugger. 2724 // Enter the debugger.
2758 EnterDebugger debugger(isolate_); 2725 EnterDebugger debugger(isolate_);
2759 if (debugger.FailedToEnter()) return; 2726 if (debugger.FailedToEnter()) return;
2760 2727
2761 // Create the script collected state object. 2728 // Create the script collected state object.
2762 Handle<Object> event_data; 2729 Handle<Object> event_data;
2763 // Bail out and don't call debugger if exception. 2730 // Bail out and don't call debugger if exception.
2764 if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return; 2731 if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return;
2765 2732
2766 // Process debug event. 2733 // Process debug event.
2767 ProcessDebugEvent(v8::ScriptCollected, 2734 ProcessDebugEvent(v8::ScriptCollected,
2768 Handle<JSObject>::cast(event_data), 2735 Handle<JSObject>::cast(event_data),
2769 true); 2736 true);
2770 } 2737 }
2771 2738
2772 2739
2773 void Debug::ProcessDebugEvent(v8::DebugEvent event, 2740 void Debug::ProcessDebugEvent(v8::DebugEvent event,
2774 Handle<JSObject> event_data, 2741 Handle<JSObject> event_data,
2775 bool auto_continue) { 2742 bool auto_continue) {
2776 HandleScope scope(isolate_); 2743 HandleScope scope(isolate_);
2777 2744
2778 // Clear any pending debug break if this is a real break.
2779 if (!auto_continue) thread_local_.has_pending_interrupt_ = false;
2780
2781 // Create the execution state. 2745 // Create the execution state.
2782 Handle<Object> exec_state; 2746 Handle<Object> exec_state;
2783 // Bail out and don't call debugger if exception. 2747 // Bail out and don't call debugger if exception.
2784 if (!MakeExecutionState().ToHandle(&exec_state)) return; 2748 if (!MakeExecutionState().ToHandle(&exec_state)) return;
2785 2749
2786 // First notify the message handler if any. 2750 // First notify the message handler if any.
2787 if (message_handler_ != NULL) { 2751 if (message_handler_ != NULL) {
2788 NotifyMessageHandler(event, 2752 NotifyMessageHandler(event,
2789 Handle<JSObject>::cast(exec_state), 2753 Handle<JSObject>::cast(exec_state),
2790 event_data, 2754 event_data,
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
3088 Handle<Object> argv[] = { exec_state, data }; 3052 Handle<Object> argv[] = { exec_state, data };
3089 return Execution::Call( 3053 return Execution::Call(
3090 isolate_, 3054 isolate_,
3091 fun, 3055 fun,
3092 Handle<Object>(debug_context()->global_proxy(), isolate_), 3056 Handle<Object>(debug_context()->global_proxy(), isolate_),
3093 ARRAY_SIZE(argv), 3057 ARRAY_SIZE(argv),
3094 argv); 3058 argv);
3095 } 3059 }
3096 3060
3097 3061
3098 void Debug::DebugBreakHelper() { 3062 void Debug::HandleDebugBreak() {
3099 // Ignore debug break during bootstrapping. 3063 // Ignore debug break during bootstrapping.
3100 if (isolate_->bootstrapper()->IsActive()) return; 3064 if (isolate_->bootstrapper()->IsActive()) return;
3101 // Just continue if breaks are disabled. 3065 // Just continue if breaks are disabled.
3102 if (break_disabled_) return; 3066 if (break_disabled_) return;
3103 // Ignore debug break if debugger is not active. 3067 // Ignore debug break if debugger is not active.
3104 if (!is_active()) return; 3068 if (!is_active()) return;
3105 3069
3106 StackLimitCheck check(isolate_); 3070 StackLimitCheck check(isolate_);
3107 if (check.HasOverflowed()) return; 3071 if (check.HasOverflowed()) return;
3108 3072
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3154 // Link recursive debugger entry. 3118 // Link recursive debugger entry.
3155 debug->thread_local_.debugger_entry_ = this; 3119 debug->thread_local_.debugger_entry_ = this;
3156 3120
3157 // Store the previous break id and frame id. 3121 // Store the previous break id and frame id.
3158 break_id_ = debug->break_id(); 3122 break_id_ = debug->break_id();
3159 break_frame_id_ = debug->break_frame_id(); 3123 break_frame_id_ = debug->break_frame_id();
3160 3124
3161 // Create the new break info. If there is no JavaScript frames there is no 3125 // Create the new break info. If there is no JavaScript frames there is no
3162 // break frame id. 3126 // break frame id.
3163 JavaScriptFrameIterator it(isolate_); 3127 JavaScriptFrameIterator it(isolate_);
3164 has_js_frames_ = !it.done(); 3128 bool has_js_frames = !it.done();
3165 debug->thread_local_.break_frame_id_ = has_js_frames_ ? it.frame()->id() 3129 debug->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id()
3166 : StackFrame::NO_ID; 3130 : StackFrame::NO_ID;
3167 debug->SetNextBreakId(); 3131 debug->SetNextBreakId();
3168 3132
3169 debug->UpdateState(); 3133 debug->UpdateState();
3170 // Make sure that debugger is loaded and enter the debugger context. 3134 // Make sure that debugger is loaded and enter the debugger context.
3171 // The previous context is kept in save_. 3135 // The previous context is kept in save_.
3172 load_failed_ = !debug->is_loaded(); 3136 load_failed_ = !debug->is_loaded();
3173 if (!load_failed_) isolate_->set_context(*debug->debug_context()); 3137 if (!load_failed_) isolate_->set_context(*debug->debug_context());
3174 } 3138 }
3175 3139
3176 3140
3177 EnterDebugger::~EnterDebugger() { 3141 EnterDebugger::~EnterDebugger() {
3178 Debug* debug = isolate_->debug(); 3142 Debug* debug = isolate_->debug();
3179 3143
3180 // Restore to the previous break state. 3144 // Restore to the previous break state.
3181 debug->thread_local_.break_frame_id_ = break_frame_id_; 3145 debug->thread_local_.break_frame_id_ = break_frame_id_;
3182 debug->thread_local_.break_id_ = break_id_; 3146 debug->thread_local_.break_id_ = break_id_;
3183 3147
3184 // Check for leaving the debugger. 3148 // Check for leaving the debugger.
3185 if (!load_failed_ && prev_ == NULL) { 3149 if (!load_failed_ && prev_ == NULL) {
3186 // Clear mirror cache when leaving the debugger. Skip this if there is a 3150 // Clear mirror cache when leaving the debugger. Skip this if there is a
3187 // pending exception as clearing the mirror cache calls back into 3151 // pending exception as clearing the mirror cache calls back into
3188 // JavaScript. This can happen if the v8::Debug::Call is used in which 3152 // JavaScript. This can happen if the v8::Debug::Call is used in which
3189 // case the exception should end up in the calling code. 3153 // case the exception should end up in the calling code.
3190 if (!isolate_->has_pending_exception()) { 3154 if (!isolate_->has_pending_exception()) debug->ClearMirrorCache();
3191 debug->ClearMirrorCache();
3192 }
3193 3155
3194 // If there are commands in the queue when leaving the debugger request 3156 // If there are commands in the queue when leaving the debugger request
3195 // that these commands are processed. 3157 // that these commands are processed.
3196 if (debug->has_commands()) isolate_->stack_guard()->RequestDebugCommand(); 3158 if (debug->has_commands()) isolate_->stack_guard()->RequestDebugCommand();
3197 } 3159 }
3198 3160
3199 // Leaving this debugger entry. 3161 // Leaving this debugger entry.
3200 debug->thread_local_.debugger_entry_ = prev_; 3162 debug->thread_local_.debugger_entry_ = prev_;
3201 3163
3202 debug->UpdateState(); 3164 debug->UpdateState();
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
3362 } 3324 }
3363 3325
3364 3326
3365 CommandMessage::CommandMessage(const Vector<uint16_t>& text, 3327 CommandMessage::CommandMessage(const Vector<uint16_t>& text,
3366 v8::Debug::ClientData* data) 3328 v8::Debug::ClientData* data)
3367 : text_(text), 3329 : text_(text),
3368 client_data_(data) { 3330 client_data_(data) {
3369 } 3331 }
3370 3332
3371 3333
3372 CommandMessage::~CommandMessage() {
3373 }
3374
3375
3376 void CommandMessage::Dispose() { 3334 void CommandMessage::Dispose() {
3377 text_.Dispose(); 3335 text_.Dispose();
3378 delete client_data_; 3336 delete client_data_;
3379 client_data_ = NULL; 3337 client_data_ = NULL;
3380 } 3338 }
3381 3339
3382 3340
3383 CommandMessage CommandMessage::New(const Vector<uint16_t>& command, 3341 CommandMessage CommandMessage::New(const Vector<uint16_t>& command,
3384 v8::Debug::ClientData* data) { 3342 v8::Debug::ClientData* data) {
3385 return CommandMessage(command.Clone(), data); 3343 return CommandMessage(command.Clone(), data);
3386 } 3344 }
3387 3345
3388 3346
3389 CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0), 3347 CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
3390 size_(size) { 3348 size_(size) {
3391 messages_ = NewArray<CommandMessage>(size); 3349 messages_ = NewArray<CommandMessage>(size);
3392 } 3350 }
3393 3351
3394 3352
3395 CommandMessageQueue::~CommandMessageQueue() { 3353 CommandMessageQueue::~CommandMessageQueue() {
3396 while (!IsEmpty()) { 3354 while (!IsEmpty()) Get().Dispose();
3397 CommandMessage m = Get();
3398 m.Dispose();
3399 }
3400 DeleteArray(messages_); 3355 DeleteArray(messages_);
3401 } 3356 }
3402 3357
3403 3358
3404 CommandMessage CommandMessageQueue::Get() { 3359 CommandMessage CommandMessageQueue::Get() {
3405 ASSERT(!IsEmpty()); 3360 ASSERT(!IsEmpty());
3406 int result = start_; 3361 int result = start_;
3407 start_ = (start_ + 1) % size_; 3362 start_ = (start_ + 1) % size_;
3408 return messages_[result]; 3363 return messages_[result];
3409 } 3364 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3456 logger_->DebugEvent("Put", message.text()); 3411 logger_->DebugEvent("Put", message.text());
3457 } 3412 }
3458 3413
3459 3414
3460 void LockingCommandMessageQueue::Clear() { 3415 void LockingCommandMessageQueue::Clear() {
3461 LockGuard<Mutex> lock_guard(&mutex_); 3416 LockGuard<Mutex> lock_guard(&mutex_);
3462 queue_.Clear(); 3417 queue_.Clear();
3463 } 3418 }
3464 3419
3465 } } // namespace v8::internal 3420 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/execution.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698