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

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: Created 6 years, 7 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. The second also sweeps precisely,
603 // which saves us doing yet another GC to make the heap iterable.
604 heap->CollectAllGarbage(Heap::kNoGCFlags, "Debug::CreateScriptCache");
ulan 2014/05/28 13:24:32 The comment is out of sync: there is only one GC a
Yang 2014/06/02 12:19:31 The comment actually makes sense: Script wrappers
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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
2595 Handle<Object> exec_state; 2574 Handle<Object> exec_state;
2596 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); 2575 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2597 // Create the script collected event object. 2576 // Create the script collected event object.
2598 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); 2577 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_);
2599 Handle<Object> argv[] = { exec_state, id_object }; 2578 Handle<Object> argv[] = { exec_state, id_object };
2600 return MakeJSObject("MakeScriptCollectedEvent", ARRAY_SIZE(argv), argv); 2579 return MakeJSObject("MakeScriptCollectedEvent", ARRAY_SIZE(argv), argv);
2601 } 2580 }
2602 2581
2603 2582
2604 void Debug::OnException(Handle<Object> exception, bool uncaught) { 2583 void Debug::OnException(Handle<Object> exception, bool uncaught) {
2584 if (is_entered() || ignore_events()) return;
2585
2605 HandleScope scope(isolate_); 2586 HandleScope scope(isolate_);
2606
2607 // Bail out based on state or if there is no listener for this event
2608 if (is_entered()) return;
2609 if (!EventActive()) return;
2610
2611 Handle<Object> promise = GetPromiseForUncaughtException(); 2587 Handle<Object> promise = GetPromiseForUncaughtException();
2612 uncaught |= !promise->IsUndefined(); 2588 uncaught |= !promise->IsUndefined();
2613 2589
2614 // Bail out if exception breaks are not active 2590 // Bail out if exception breaks are not active
2615 if (uncaught) { 2591 if (uncaught) {
2616 // Uncaught exceptions are reported by either flags. 2592 // Uncaught exceptions are reported by either flags.
2617 if (!(break_on_uncaught_exception() || break_on_exception())) return; 2593 if (!(break_on_uncaught_exception_ || break_on_exception_)) return;
2618 } else { 2594 } else {
2619 // Caught exceptions are reported is activated. 2595 // Caught exceptions are reported is activated.
2620 if (!break_on_exception()) return; 2596 if (!break_on_exception_) return;
2621 } 2597 }
2622 2598
2623 // Enter the debugger. 2599 // Enter the debugger.
2624 EnterDebugger debugger(isolate_); 2600 EnterDebugger debugger(isolate_);
2625 if (debugger.FailedToEnter()) return; 2601 if (debugger.FailedToEnter()) return;
2626 2602
2627 // Clear all current stepping setup. 2603 // Clear all current stepping setup.
2628 ClearStepping(); 2604 ClearStepping();
2629 2605
2630 // Create the event data object. 2606 // Create the event data object.
2631 Handle<Object> event_data; 2607 Handle<Object> event_data;
2632 // Bail out and don't call debugger if exception. 2608 // Bail out and don't call debugger if exception.
2633 if (!MakeExceptionEvent( 2609 if (!MakeExceptionEvent(
2634 exception, uncaught, promise).ToHandle(&event_data)) { 2610 exception, uncaught, promise).ToHandle(&event_data)) {
2635 return; 2611 return;
2636 } 2612 }
2637 2613
2638 // Process debug event. 2614 // Process debug event.
2639 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); 2615 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
2640 // Return to continue execution from where the exception was thrown. 2616 // Return to continue execution from where the exception was thrown.
2641 } 2617 }
2642 2618
2643 2619
2644 void Debug::OnDebugBreak(Handle<Object> break_points_hit, 2620 void Debug::OnDebugBreak(Handle<Object> break_points_hit,
2645 bool auto_continue) { 2621 bool auto_continue) {
2646 HandleScope scope(isolate_);
2647
2648 // Debugger has already been entered by caller. 2622 // Debugger has already been entered by caller.
2649 ASSERT(isolate_->context() == *debug_context()); 2623 ASSERT(isolate_->context() == *debug_context());
2624 // Bail out if there is no listener for this event
2625 if (ignore_events()) return;
2650 2626
2651 // Bail out if there is no listener for this event 2627 HandleScope scope(isolate_);
2652 if (!EventActive()) return;
2653
2654 // Create the event data object. 2628 // Create the event data object.
2655 Handle<Object> event_data; 2629 Handle<Object> event_data;
2656 // Bail out and don't call debugger if exception. 2630 // Bail out and don't call debugger if exception.
2657 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return; 2631 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
2658 2632
2659 // Process debug event. 2633 // Process debug event.
2660 ProcessDebugEvent(v8::Break, 2634 ProcessDebugEvent(v8::Break,
2661 Handle<JSObject>::cast(event_data), 2635 Handle<JSObject>::cast(event_data),
2662 auto_continue); 2636 auto_continue);
2663 } 2637 }
2664 2638
2665 2639
2666 void Debug::OnBeforeCompile(Handle<Script> script) { 2640 void Debug::OnBeforeCompile(Handle<Script> script) {
2641 if (is_entered() || ignore_events()) return;
2642
2667 HandleScope scope(isolate_); 2643 HandleScope scope(isolate_);
2668
2669 // Bail out based on state or if there is no listener for this event
2670 if (is_entered()) return;
2671 if (!EventActive()) return;
2672
2673 // Enter the debugger. 2644 // Enter the debugger.
2674 EnterDebugger debugger(isolate_); 2645 EnterDebugger debugger(isolate_);
2675 if (debugger.FailedToEnter()) return; 2646 if (debugger.FailedToEnter()) return;
2676 2647
2677 // Create the event data object. 2648 // Create the event data object.
2678 Handle<Object> event_data; 2649 Handle<Object> event_data;
2679 // Bail out and don't call debugger if exception. 2650 // Bail out and don't call debugger if exception.
2680 if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return; 2651 if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return;
2681 2652
2682 // Process debug event. 2653 // Process debug event.
2683 ProcessDebugEvent(v8::BeforeCompile, 2654 ProcessDebugEvent(v8::BeforeCompile,
2684 Handle<JSObject>::cast(event_data), 2655 Handle<JSObject>::cast(event_data),
2685 true); 2656 true);
2686 } 2657 }
2687 2658
2688 2659
2689 // Handle debugger actions when a new script is compiled. 2660 // Handle debugger actions when a new script is compiled.
2690 void Debug::OnAfterCompile(Handle<Script> script, 2661 void Debug::OnAfterCompile(Handle<Script> script,
2691 AfterCompileFlags after_compile_flags) { 2662 AfterCompileFlags after_compile_flags) {
2692 HandleScope scope(isolate_);
2693
2694 // Add the newly compiled script to the script cache. 2663 // Add the newly compiled script to the script cache.
2695 AddScriptToScriptCache(script); 2664 if (script_cache_ != NULL) script_cache_->Add(script);
2696 2665
2697 // No more to do if not debugging. 2666 // No more to do if not debugging.
2698 if (!EventActive()) return; 2667 if (is_entered() || ignore_events()) return;
2699 2668
2669 HandleScope scope(isolate_);
2700 // Store whether in debugger before entering debugger. 2670 // Store whether in debugger before entering debugger.
2701 bool in_debugger = is_entered(); 2671 bool in_debugger = is_entered();
2702 2672
2703 // Enter the debugger. 2673 // Enter the debugger.
2704 EnterDebugger debugger(isolate_); 2674 EnterDebugger debugger(isolate_);
2705 if (debugger.FailedToEnter()) return; 2675 if (debugger.FailedToEnter()) return;
2706 2676
2707 // If debugging there might be script break points registered for this 2677 // If debugging there might be script break points registered for this
2708 // script. Make sure that these break points are set. 2678 // script. Make sure that these break points are set.
2709 2679
(...skipping 29 matching lines...) Expand all
2739 Handle<Object> event_data; 2709 Handle<Object> event_data;
2740 // Bail out and don't call debugger if exception. 2710 // Bail out and don't call debugger if exception.
2741 if (!MakeCompileEvent(script, false).ToHandle(&event_data)) return; 2711 if (!MakeCompileEvent(script, false).ToHandle(&event_data)) return;
2742 2712
2743 // Process debug event. 2713 // Process debug event.
2744 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true); 2714 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true);
2745 } 2715 }
2746 2716
2747 2717
2748 void Debug::OnScriptCollected(int id) { 2718 void Debug::OnScriptCollected(int id) {
2719 if (is_entered() || ignore_events()) return;
2720
2749 HandleScope scope(isolate_); 2721 HandleScope scope(isolate_);
2750
2751 // No more to do if not debugging.
2752 if (is_entered()) return;
2753 if (!EventActive()) return;
2754
2755 // Enter the debugger. 2722 // Enter the debugger.
2756 EnterDebugger debugger(isolate_); 2723 EnterDebugger debugger(isolate_);
2757 if (debugger.FailedToEnter()) return; 2724 if (debugger.FailedToEnter()) return;
2758 2725
2759 // Create the script collected state object. 2726 // Create the script collected state object.
2760 Handle<Object> event_data; 2727 Handle<Object> event_data;
2761 // Bail out and don't call debugger if exception. 2728 // Bail out and don't call debugger if exception.
2762 if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return; 2729 if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return;
2763 2730
2764 // Process debug event. 2731 // Process debug event.
2765 ProcessDebugEvent(v8::ScriptCollected, 2732 ProcessDebugEvent(v8::ScriptCollected,
2766 Handle<JSObject>::cast(event_data), 2733 Handle<JSObject>::cast(event_data),
2767 true); 2734 true);
2768 } 2735 }
2769 2736
2770 2737
2771 void Debug::ProcessDebugEvent(v8::DebugEvent event, 2738 void Debug::ProcessDebugEvent(v8::DebugEvent event,
2772 Handle<JSObject> event_data, 2739 Handle<JSObject> event_data,
2773 bool auto_continue) { 2740 bool auto_continue) {
2774 HandleScope scope(isolate_); 2741 HandleScope scope(isolate_);
2775 2742
2776 // Clear any pending debug break if this is a real break.
2777 if (!auto_continue) thread_local_.has_pending_interrupt_ = false;
2778
2779 // Create the execution state. 2743 // Create the execution state.
2780 Handle<Object> exec_state; 2744 Handle<Object> exec_state;
2781 // Bail out and don't call debugger if exception. 2745 // Bail out and don't call debugger if exception.
2782 if (!MakeExecutionState().ToHandle(&exec_state)) return; 2746 if (!MakeExecutionState().ToHandle(&exec_state)) return;
2783 2747
2784 // First notify the message handler if any. 2748 // First notify the message handler if any.
2785 if (message_handler_ != NULL) { 2749 if (message_handler_ != NULL) {
2786 NotifyMessageHandler(event, 2750 NotifyMessageHandler(event,
2787 Handle<JSObject>::cast(exec_state), 2751 Handle<JSObject>::cast(exec_state),
2788 event_data, 2752 event_data,
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
3083 Handle<Object> argv[] = { exec_state, data }; 3047 Handle<Object> argv[] = { exec_state, data };
3084 return Execution::Call( 3048 return Execution::Call(
3085 isolate_, 3049 isolate_,
3086 fun, 3050 fun,
3087 Handle<Object>(debug_context()->global_proxy(), isolate_), 3051 Handle<Object>(debug_context()->global_proxy(), isolate_),
3088 ARRAY_SIZE(argv), 3052 ARRAY_SIZE(argv),
3089 argv); 3053 argv);
3090 } 3054 }
3091 3055
3092 3056
3093 void Debug::DebugBreakHelper() { 3057 void Debug::HandleDebugBreak() {
3094 // Ignore debug break during bootstrapping. 3058 // Ignore debug break during bootstrapping.
3095 if (isolate_->bootstrapper()->IsActive()) return; 3059 if (isolate_->bootstrapper()->IsActive()) return;
3096 // Just continue if breaks are disabled. 3060 // Just continue if breaks are disabled.
3097 if (break_disabled_) return; 3061 if (break_disabled_) return;
3098 // Ignore debug break if debugger is not active. 3062 // Ignore debug break if debugger is not active.
3099 if (!is_active()) return; 3063 if (!is_active()) return;
3100 3064
3101 StackLimitCheck check(isolate_); 3065 StackLimitCheck check(isolate_);
3102 if (check.HasOverflowed()) return; 3066 if (check.HasOverflowed()) return;
3103 3067
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3149 // Link recursive debugger entry. 3113 // Link recursive debugger entry.
3150 debug->thread_local_.debugger_entry_ = this; 3114 debug->thread_local_.debugger_entry_ = this;
3151 3115
3152 // Store the previous break id and frame id. 3116 // Store the previous break id and frame id.
3153 break_id_ = debug->break_id(); 3117 break_id_ = debug->break_id();
3154 break_frame_id_ = debug->break_frame_id(); 3118 break_frame_id_ = debug->break_frame_id();
3155 3119
3156 // Create the new break info. If there is no JavaScript frames there is no 3120 // Create the new break info. If there is no JavaScript frames there is no
3157 // break frame id. 3121 // break frame id.
3158 JavaScriptFrameIterator it(isolate_); 3122 JavaScriptFrameIterator it(isolate_);
3159 has_js_frames_ = !it.done(); 3123 bool has_js_frames = !it.done();
3160 debug->thread_local_.break_frame_id_ = has_js_frames_ ? it.frame()->id() 3124 debug->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id()
3161 : StackFrame::NO_ID; 3125 : StackFrame::NO_ID;
3162 debug->SetNextBreakId(); 3126 debug->SetNextBreakId();
3163 3127
3164 debug->UpdateState(); 3128 debug->UpdateState();
3165 // Make sure that debugger is loaded and enter the debugger context. 3129 // Make sure that debugger is loaded and enter the debugger context.
3166 // The previous context is kept in save_. 3130 // The previous context is kept in save_.
3167 load_failed_ = !debug->is_loaded(); 3131 load_failed_ = !debug->is_loaded();
3168 if (!load_failed_) isolate_->set_context(*debug->debug_context()); 3132 if (!load_failed_) isolate_->set_context(*debug->debug_context());
3169 } 3133 }
3170 3134
3171 3135
3172 EnterDebugger::~EnterDebugger() { 3136 EnterDebugger::~EnterDebugger() {
3173 Debug* debug = isolate_->debug(); 3137 Debug* debug = isolate_->debug();
3174 3138
3175 // Restore to the previous break state. 3139 // Restore to the previous break state.
3176 debug->thread_local_.break_frame_id_ = break_frame_id_; 3140 debug->thread_local_.break_frame_id_ = break_frame_id_;
3177 debug->thread_local_.break_id_ = break_id_; 3141 debug->thread_local_.break_id_ = break_id_;
3178 3142
3179 // Check for leaving the debugger. 3143 // Check for leaving the debugger.
3180 if (!load_failed_ && prev_ == NULL) { 3144 if (!load_failed_ && prev_ == NULL) {
3181 // Clear mirror cache when leaving the debugger. Skip this if there is a 3145 // Clear mirror cache when leaving the debugger. Skip this if there is a
3182 // pending exception as clearing the mirror cache calls back into 3146 // pending exception as clearing the mirror cache calls back into
3183 // JavaScript. This can happen if the v8::Debug::Call is used in which 3147 // JavaScript. This can happen if the v8::Debug::Call is used in which
3184 // case the exception should end up in the calling code. 3148 // case the exception should end up in the calling code.
3185 if (!isolate_->has_pending_exception()) { 3149 if (!isolate_->has_pending_exception()) debug->ClearMirrorCache();
3186 debug->ClearMirrorCache();
3187 }
3188 3150
3189 // If there are commands in the queue when leaving the debugger request 3151 // If there are commands in the queue when leaving the debugger request
3190 // that these commands are processed. 3152 // that these commands are processed.
3191 if (debug->has_commands()) isolate_->stack_guard()->RequestDebugCommand(); 3153 if (debug->has_commands()) isolate_->stack_guard()->RequestDebugCommand();
3192 } 3154 }
3193 3155
3194 // Leaving this debugger entry. 3156 // Leaving this debugger entry.
3195 debug->thread_local_.debugger_entry_ = prev_; 3157 debug->thread_local_.debugger_entry_ = prev_;
3196 3158
3197 debug->UpdateState(); 3159 debug->UpdateState();
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
3357 } 3319 }
3358 3320
3359 3321
3360 CommandMessage::CommandMessage(const Vector<uint16_t>& text, 3322 CommandMessage::CommandMessage(const Vector<uint16_t>& text,
3361 v8::Debug::ClientData* data) 3323 v8::Debug::ClientData* data)
3362 : text_(text), 3324 : text_(text),
3363 client_data_(data) { 3325 client_data_(data) {
3364 } 3326 }
3365 3327
3366 3328
3367 CommandMessage::~CommandMessage() {
3368 }
3369
3370
3371 void CommandMessage::Dispose() { 3329 void CommandMessage::Dispose() {
3372 text_.Dispose(); 3330 text_.Dispose();
3373 delete client_data_; 3331 delete client_data_;
3374 client_data_ = NULL; 3332 client_data_ = NULL;
3375 } 3333 }
3376 3334
3377 3335
3378 CommandMessage CommandMessage::New(const Vector<uint16_t>& command, 3336 CommandMessage CommandMessage::New(const Vector<uint16_t>& command,
3379 v8::Debug::ClientData* data) { 3337 v8::Debug::ClientData* data) {
3380 return CommandMessage(command.Clone(), data); 3338 return CommandMessage(command.Clone(), data);
3381 } 3339 }
3382 3340
3383 3341
3384 CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0), 3342 CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
3385 size_(size) { 3343 size_(size) {
3386 messages_ = NewArray<CommandMessage>(size); 3344 messages_ = NewArray<CommandMessage>(size);
3387 } 3345 }
3388 3346
3389 3347
3390 CommandMessageQueue::~CommandMessageQueue() { 3348 CommandMessageQueue::~CommandMessageQueue() {
3391 while (!IsEmpty()) { 3349 while (!IsEmpty()) Get().Dispose();
3392 CommandMessage m = Get();
3393 m.Dispose();
3394 }
3395 DeleteArray(messages_); 3350 DeleteArray(messages_);
3396 } 3351 }
3397 3352
3398 3353
3399 CommandMessage CommandMessageQueue::Get() { 3354 CommandMessage CommandMessageQueue::Get() {
3400 ASSERT(!IsEmpty()); 3355 ASSERT(!IsEmpty());
3401 int result = start_; 3356 int result = start_;
3402 start_ = (start_ + 1) % size_; 3357 start_ = (start_ + 1) % size_;
3403 return messages_[result]; 3358 return messages_[result];
3404 } 3359 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3451 logger_->DebugEvent("Put", message.text()); 3406 logger_->DebugEvent("Put", message.text());
3452 } 3407 }
3453 3408
3454 3409
3455 void LockingCommandMessageQueue::Clear() { 3410 void LockingCommandMessageQueue::Clear() {
3456 LockGuard<Mutex> lock_guard(&mutex_); 3411 LockGuard<Mutex> lock_guard(&mutex_);
3457 queue_.Clear(); 3412 queue_.Clear();
3458 } 3413 }
3459 3414
3460 } } // namespace v8::internal 3415 } } // 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