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

Side by Side Diff: src/debug.cc

Issue 298863011: Merge the classes Debug and Debugger. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rename EnterDebugger 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.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "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 13 matching lines...) Expand all
24 #include "natives.h" 24 #include "natives.h"
25 #include "stub-cache.h" 25 #include "stub-cache.h"
26 #include "log.h" 26 #include "log.h"
27 27
28 #include "../include/v8-debug.h" 28 #include "../include/v8-debug.h"
29 29
30 namespace v8 { 30 namespace v8 {
31 namespace internal { 31 namespace internal {
32 32
33 Debug::Debug(Isolate* isolate) 33 Debug::Debug(Isolate* isolate)
34 : has_break_points_(false), 34 : debug_context_(Handle<Context>()),
35 event_listener_(Handle<Object>()),
36 event_listener_data_(Handle<Object>()),
37 message_handler_(NULL),
38 command_received_(0),
39 command_queue_(isolate->logger(), kQueueInitialSize),
40 event_command_queue_(isolate->logger(), kQueueInitialSize),
41 is_active_(false),
42 is_suppressed_(false),
43 live_edit_enabled_(true), // TODO(yangguo): set to false by default.
44 has_break_points_(false),
45 break_disabled_(false),
46 break_on_exception_(false),
47 break_on_uncaught_exception_(false),
35 script_cache_(NULL), 48 script_cache_(NULL),
36 debug_info_list_(NULL), 49 debug_info_list_(NULL),
37 disable_break_(false),
38 break_on_exception_(false),
39 break_on_uncaught_exception_(false),
40 isolate_(isolate) { 50 isolate_(isolate) {
41 ThreadInit(); 51 ThreadInit();
42 } 52 }
43 53
44 54
45 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) { 55 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) {
46 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); 56 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
47 // Isolate::context() may have been NULL when "script collected" event 57 // Isolate::context() may have been NULL when "script collected" event
48 // occured. 58 // occured.
49 if (context.is_null()) return v8::Local<v8::Context>(); 59 if (context.is_null()) return v8::Local<v8::Context>();
(...skipping 13 matching lines...) Expand all
63 73
64 74
65 BreakLocationIterator::~BreakLocationIterator() { 75 BreakLocationIterator::~BreakLocationIterator() {
66 ASSERT(reloc_iterator_ != NULL); 76 ASSERT(reloc_iterator_ != NULL);
67 ASSERT(reloc_iterator_original_ != NULL); 77 ASSERT(reloc_iterator_original_ != NULL);
68 delete reloc_iterator_; 78 delete reloc_iterator_;
69 delete reloc_iterator_original_; 79 delete reloc_iterator_original_;
70 } 80 }
71 81
72 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
73 void BreakLocationIterator::Next() { 99 void BreakLocationIterator::Next() {
74 DisallowHeapAllocation no_gc; 100 DisallowHeapAllocation no_gc;
75 ASSERT(!RinfoDone()); 101 ASSERT(!RinfoDone());
76 102
77 // 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
78 // breakable code target. 104 // breakable code target.
79 bool first = break_point_ == -1; 105 bool first = break_point_ == -1;
80 while (!RinfoDone()) { 106 while (!RinfoDone()) {
81 if (!first) RinfoNext(); 107 if (!first) RinfoNext();
82 first = false; 108 first = false;
(...skipping 29 matching lines...) Expand all
112 !code->is_compare_ic_stub() && 138 !code->is_compare_ic_stub() &&
113 !code->is_to_boolean_ic_stub()) || 139 !code->is_to_boolean_ic_stub()) ||
114 RelocInfo::IsConstructCall(rmode())) { 140 RelocInfo::IsConstructCall(rmode())) {
115 break_point_++; 141 break_point_++;
116 return; 142 return;
117 } 143 }
118 if (code->kind() == Code::STUB) { 144 if (code->kind() == Code::STUB) {
119 if (IsDebuggerStatement()) { 145 if (IsDebuggerStatement()) {
120 break_point_++; 146 break_point_++;
121 return; 147 return;
122 } 148 } else if (type_ == ALL_BREAK_LOCATIONS) {
123 if (type_ == ALL_BREAK_LOCATIONS) { 149 if (IsBreakStub(code)) {
124 if (Debug::IsBreakStub(code)) {
125 break_point_++; 150 break_point_++;
126 return; 151 return;
127 } 152 }
128 } else { 153 } else {
129 ASSERT(type_ == SOURCE_BREAK_LOCATIONS); 154 ASSERT(type_ == SOURCE_BREAK_LOCATIONS);
130 if (Debug::IsSourceBreakStub(code)) { 155 if (IsSourceBreakStub(code)) {
131 break_point_++; 156 break_point_++;
132 return; 157 return;
133 } 158 }
134 } 159 }
135 } 160 }
136 } 161 }
137 162
138 // Check for break at return. 163 // Check for break at return.
139 if (RelocInfo::IsJSReturn(rmode())) { 164 if (RelocInfo::IsJSReturn(rmode())) {
140 // Set the positions to the end of the function. 165 // Set the positions to the end of the function.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 265
241 266
242 bool BreakLocationIterator::Done() const { 267 bool BreakLocationIterator::Done() const {
243 return RinfoDone(); 268 return RinfoDone();
244 } 269 }
245 270
246 271
247 void BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) { 272 void BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) {
248 // If there is not already a real break point here patch code with debug 273 // If there is not already a real break point here patch code with debug
249 // break. 274 // break.
250 if (!HasBreakPoint()) { 275 if (!HasBreakPoint()) SetDebugBreak();
251 SetDebugBreak();
252 }
253 ASSERT(IsDebugBreak() || IsDebuggerStatement()); 276 ASSERT(IsDebugBreak() || IsDebuggerStatement());
254 // Set the break point information. 277 // Set the break point information.
255 DebugInfo::SetBreakPoint(debug_info_, code_position(), 278 DebugInfo::SetBreakPoint(debug_info_, code_position(),
256 position(), statement_position(), 279 position(), statement_position(),
257 break_point_object); 280 break_point_object);
258 } 281 }
259 282
260 283
261 void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) { 284 void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) {
262 // Clear the break point information. 285 // Clear the break point information.
263 DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object); 286 DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object);
264 // If there are no more break points here remove the debug break. 287 // If there are no more break points here remove the debug break.
265 if (!HasBreakPoint()) { 288 if (!HasBreakPoint()) {
266 ClearDebugBreak(); 289 ClearDebugBreak();
267 ASSERT(!IsDebugBreak()); 290 ASSERT(!IsDebugBreak());
268 } 291 }
269 } 292 }
270 293
271 294
272 void BreakLocationIterator::SetOneShot() { 295 void BreakLocationIterator::SetOneShot() {
273 // Debugger statement always calls debugger. No need to modify it. 296 // Debugger statement always calls debugger. No need to modify it.
274 if (IsDebuggerStatement()) { 297 if (IsDebuggerStatement()) return;
275 return;
276 }
277 298
278 // If there is a real break point here no more to do. 299 // If there is a real break point here no more to do.
279 if (HasBreakPoint()) { 300 if (HasBreakPoint()) {
280 ASSERT(IsDebugBreak()); 301 ASSERT(IsDebugBreak());
281 return; 302 return;
282 } 303 }
283 304
284 // Patch code with debug break. 305 // Patch code with debug break.
285 SetDebugBreak(); 306 SetDebugBreak();
286 } 307 }
287 308
288 309
289 void BreakLocationIterator::ClearOneShot() { 310 void BreakLocationIterator::ClearOneShot() {
290 // Debugger statement always calls debugger. No need to modify it. 311 // Debugger statement always calls debugger. No need to modify it.
291 if (IsDebuggerStatement()) { 312 if (IsDebuggerStatement()) return;
292 return;
293 }
294 313
295 // If there is a real break point here no more to do. 314 // If there is a real break point here no more to do.
296 if (HasBreakPoint()) { 315 if (HasBreakPoint()) {
297 ASSERT(IsDebugBreak()); 316 ASSERT(IsDebugBreak());
298 return; 317 return;
299 } 318 }
300 319
301 // Patch code removing debug break. 320 // Patch code removing debug break.
302 ClearDebugBreak(); 321 ClearDebugBreak();
303 ASSERT(!IsDebugBreak()); 322 ASSERT(!IsDebugBreak());
304 } 323 }
305 324
306 325
307 void BreakLocationIterator::SetDebugBreak() { 326 void BreakLocationIterator::SetDebugBreak() {
308 // Debugger statement always calls debugger. No need to modify it. 327 // Debugger statement always calls debugger. No need to modify it.
309 if (IsDebuggerStatement()) { 328 if (IsDebuggerStatement()) return;
310 return;
311 }
312 329
313 // If there is already a break point here just return. This might happen if 330 // If there is already a break point here just return. This might happen if
314 // the same code is flooded with break points twice. Flooding the same 331 // the same code is flooded with break points twice. Flooding the same
315 // function twice might happen when stepping in a function with an exception 332 // function twice might happen when stepping in a function with an exception
316 // handler as the handler and the function is the same. 333 // handler as the handler and the function is the same.
317 if (IsDebugBreak()) { 334 if (IsDebugBreak()) return;
318 return;
319 }
320 335
321 if (RelocInfo::IsJSReturn(rmode())) { 336 if (RelocInfo::IsJSReturn(rmode())) {
322 // Patch the frame exit code with a break point. 337 // Patch the frame exit code with a break point.
323 SetDebugBreakAtReturn(); 338 SetDebugBreakAtReturn();
324 } else if (IsDebugBreakSlot()) { 339 } else if (IsDebugBreakSlot()) {
325 // Patch the code in the break slot. 340 // Patch the code in the break slot.
326 SetDebugBreakAtSlot(); 341 SetDebugBreakAtSlot();
327 } else { 342 } else {
328 // Patch the IC call. 343 // Patch the IC call.
329 SetDebugBreakAtIC(); 344 SetDebugBreakAtIC();
330 } 345 }
331 ASSERT(IsDebugBreak()); 346 ASSERT(IsDebugBreak());
332 } 347 }
333 348
334 349
335 void BreakLocationIterator::ClearDebugBreak() { 350 void BreakLocationIterator::ClearDebugBreak() {
336 // Debugger statement always calls debugger. No need to modify it. 351 // Debugger statement always calls debugger. No need to modify it.
337 if (IsDebuggerStatement()) { 352 if (IsDebuggerStatement()) return;
338 return;
339 }
340 353
341 if (RelocInfo::IsJSReturn(rmode())) { 354 if (RelocInfo::IsJSReturn(rmode())) {
342 // Restore the frame exit code. 355 // Restore the frame exit code.
343 ClearDebugBreakAtReturn(); 356 ClearDebugBreakAtReturn();
344 } else if (IsDebugBreakSlot()) { 357 } else if (IsDebugBreakSlot()) {
345 // Restore the code in the break slot. 358 // Restore the code in the break slot.
346 ClearDebugBreakAtSlot(); 359 ClearDebugBreakAtSlot();
347 } else { 360 } else {
348 // Patch the IC call. 361 // Patch the IC call.
349 ClearDebugBreakAtIC(); 362 ClearDebugBreakAtIC();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 if (RelocInfo::IsJSReturn(rmode())) { 430 if (RelocInfo::IsJSReturn(rmode())) {
418 return IsDebugBreakAtReturn(); 431 return IsDebugBreakAtReturn();
419 } else if (IsDebugBreakSlot()) { 432 } else if (IsDebugBreakSlot()) {
420 return IsDebugBreakAtSlot(); 433 return IsDebugBreakAtSlot();
421 } else { 434 } else {
422 return Debug::IsDebugBreak(rinfo()->target_address()); 435 return Debug::IsDebugBreak(rinfo()->target_address());
423 } 436 }
424 } 437 }
425 438
426 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
427 void BreakLocationIterator::SetDebugBreakAtIC() { 487 void BreakLocationIterator::SetDebugBreakAtIC() {
428 // 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
429 // 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.
430 original_rinfo()->set_target_address(rinfo()->target_address()); 490 original_rinfo()->set_target_address(rinfo()->target_address());
431 491
432 RelocInfo::Mode mode = rmode(); 492 RelocInfo::Mode mode = rmode();
433 if (RelocInfo::IsCodeTarget(mode)) { 493 if (RelocInfo::IsCodeTarget(mode)) {
434 Address target = rinfo()->target_address(); 494 Address target = rinfo()->target_address();
435 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); 495 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
436 496
437 // 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
438 // calling convention used by the call site. 498 // calling convention used by the call site.
439 Handle<Code> dbgbrk_code(Debug::FindDebugBreak(target_code, mode)); 499 Handle<Code> dbgbrk_code = DebugBreakForIC(target_code, mode);
440 rinfo()->set_target_address(dbgbrk_code->entry()); 500 rinfo()->set_target_address(dbgbrk_code->entry());
441 } 501 }
442 } 502 }
443 503
444 504
445 void BreakLocationIterator::ClearDebugBreakAtIC() { 505 void BreakLocationIterator::ClearDebugBreakAtIC() {
446 // Patch the code to the original invoke. 506 // Patch the code to the original invoke.
447 rinfo()->set_target_address(original_rinfo()->target_address()); 507 rinfo()->set_target_address(original_rinfo()->target_address());
448 } 508 }
449 509
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 thread_local_.break_count_ = 0; 557 thread_local_.break_count_ = 0;
498 thread_local_.break_id_ = 0; 558 thread_local_.break_id_ = 0;
499 thread_local_.break_frame_id_ = StackFrame::NO_ID; 559 thread_local_.break_frame_id_ = StackFrame::NO_ID;
500 thread_local_.last_step_action_ = StepNone; 560 thread_local_.last_step_action_ = StepNone;
501 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; 561 thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
502 thread_local_.step_count_ = 0; 562 thread_local_.step_count_ = 0;
503 thread_local_.last_fp_ = 0; 563 thread_local_.last_fp_ = 0;
504 thread_local_.queued_step_count_ = 0; 564 thread_local_.queued_step_count_ = 0;
505 thread_local_.step_into_fp_ = 0; 565 thread_local_.step_into_fp_ = 0;
506 thread_local_.step_out_fp_ = 0; 566 thread_local_.step_out_fp_ = 0;
507 thread_local_.after_break_target_ = 0;
508 // TODO(isolates): frames_are_dropped_? 567 // TODO(isolates): frames_are_dropped_?
509 thread_local_.debugger_entry_ = NULL; 568 thread_local_.current_debug_scope_ = NULL;
510 thread_local_.has_pending_interrupt_ = false;
511 thread_local_.restarter_frame_function_pointer_ = NULL; 569 thread_local_.restarter_frame_function_pointer_ = NULL;
512 thread_local_.promise_on_stack_ = NULL; 570 thread_local_.promise_on_stack_ = NULL;
513 } 571 }
514 572
515 573
516 char* Debug::ArchiveDebug(char* storage) { 574 char* Debug::ArchiveDebug(char* storage) {
517 char* to = storage; 575 char* to = storage;
518 OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); 576 OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
519 ThreadInit(); 577 ThreadInit();
520 return storage + ArchiveSpacePerThread(); 578 return storage + ArchiveSpacePerThread();
521 } 579 }
522 580
523 581
524 char* Debug::RestoreDebug(char* storage) { 582 char* Debug::RestoreDebug(char* storage) {
525 char* from = storage; 583 char* from = storage;
526 OS::MemCopy( 584 OS::MemCopy(
527 reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); 585 reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
528 return storage + ArchiveSpacePerThread(); 586 return storage + ArchiveSpacePerThread();
529 } 587 }
530 588
531 589
532 int Debug::ArchiveSpacePerThread() { 590 int Debug::ArchiveSpacePerThread() {
533 return sizeof(ThreadLocal); 591 return sizeof(ThreadLocal);
534 } 592 }
535 593
536 594
537 // Frame structure (conforms InternalFrame structure): 595 ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch),
538 // -- code 596 isolate_(isolate),
539 // -- SMI maker 597 collected_scripts_(10) {
540 // -- function (slot is called "context") 598 Heap* heap = isolate_->heap();
541 // -- frame base 599 HandleScope scope(isolate_);
542 Object** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
543 Handle<Code> code) {
544 ASSERT(bottom_js_frame->is_java_script());
545 600
546 Address fp = bottom_js_frame->fp(); 601 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
602 // rid of all the cached script wrappers and the second gets rid of the
603 // scripts which are no longer referenced. The second also sweeps precisely,
604 // which saves us doing yet another GC to make the heap iterable.
605 heap->CollectAllGarbage(Heap::kNoGCFlags, "Debug::CreateScriptCache");
547 606
548 // Move function pointer into "context" slot. 607 // Scan heap for Script objects.
549 Memory::Object_at(fp + StandardFrameConstants::kContextOffset) = 608 HeapIterator iterator(heap);
550 Memory::Object_at(fp + JavaScriptFrameConstants::kFunctionOffset); 609 DisallowHeapAllocation no_allocation;
551 610
552 Memory::Object_at(fp + InternalFrameConstants::kCodeOffset) = *code; 611 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
553 Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset) = 612 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
554 Smi::FromInt(StackFrame::INTERNAL); 613 Add(Handle<Script>(Script::cast(obj)));
555 614 }
556 return reinterpret_cast<Object**>(&Memory::Object_at( 615 }
557 fp + StandardFrameConstants::kContextOffset));
558 } 616 }
559 617
560 const int Debug::kFrameDropperFrameSize = 4;
561
562 618
563 void ScriptCache::Add(Handle<Script> script) { 619 void ScriptCache::Add(Handle<Script> script) {
564 GlobalHandles* global_handles = isolate_->global_handles(); 620 GlobalHandles* global_handles = isolate_->global_handles();
565 // Create an entry in the hash map for the script. 621 // Create an entry in the hash map for the script.
566 int id = script->id()->value(); 622 int id = script->id()->value();
567 HashMap::Entry* entry = 623 HashMap::Entry* entry =
568 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true); 624 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true);
569 if (entry->value != NULL) { 625 if (entry->value != NULL) {
570 ASSERT(*script == *reinterpret_cast<Script**>(entry->value)); 626 ASSERT(*script == *reinterpret_cast<Script**>(entry->value));
571 return; 627 return;
(...skipping 18 matching lines...) Expand all
590 if (entry->value != NULL) { 646 if (entry->value != NULL) {
591 instances->set(count, *reinterpret_cast<Script**>(entry->value)); 647 instances->set(count, *reinterpret_cast<Script**>(entry->value));
592 count++; 648 count++;
593 } 649 }
594 } 650 }
595 return instances; 651 return instances;
596 } 652 }
597 653
598 654
599 void ScriptCache::ProcessCollectedScripts() { 655 void ScriptCache::ProcessCollectedScripts() {
600 Debugger* debugger = isolate_->debugger(); 656 Debug* debug = isolate_->debug();
601 for (int i = 0; i < collected_scripts_.length(); i++) { 657 for (int i = 0; i < collected_scripts_.length(); i++) {
602 debugger->OnScriptCollected(collected_scripts_[i]); 658 debug->OnScriptCollected(collected_scripts_[i]);
603 } 659 }
604 collected_scripts_.Clear(); 660 collected_scripts_.Clear();
605 } 661 }
606 662
607 663
608 void ScriptCache::Clear() { 664 void ScriptCache::Clear() {
609 // Iterate the script cache to get rid of all the weak handles. 665 // Iterate the script cache to get rid of all the weak handles.
610 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { 666 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
611 ASSERT(entry != NULL); 667 ASSERT(entry != NULL);
612 Object** location = reinterpret_cast<Object**>(entry->value); 668 Object** location = reinterpret_cast<Object**>(entry->value);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 795
740 // Mark this script as native and return successfully. 796 // Mark this script as native and return successfully.
741 Handle<Script> script(Script::cast(function->shared()->script())); 797 Handle<Script> script(Script::cast(function->shared()->script()));
742 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 798 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
743 return true; 799 return true;
744 } 800 }
745 801
746 802
747 bool Debug::Load() { 803 bool Debug::Load() {
748 // Return if debugger is already loaded. 804 // Return if debugger is already loaded.
749 if (IsLoaded()) return true; 805 if (is_loaded()) return true;
750 806
751 // Bail out if we're already in the process of compiling the native 807 // Bail out if we're already in the process of compiling the native
752 // JavaScript source code for the debugger. 808 // JavaScript source code for the debugger.
753 if (isolate_->debugger()->ignore_debugger()) return false; 809 if (is_suppressed_) return false;
754 Debugger::IgnoreScope during_create(isolate_->debugger()); 810 SuppressDebug while_loading(this);
755 811
756 // Disable breakpoints and interrupts while compiling and running the 812 // Disable breakpoints and interrupts while compiling and running the
757 // debugger scripts including the context creation code. 813 // debugger scripts including the context creation code.
758 DisableBreak disable(isolate_, true); 814 DisableBreak disable(this, true);
759 PostponeInterruptsScope postpone(isolate_); 815 PostponeInterruptsScope postpone(isolate_);
760 816
761 // Create the debugger context. 817 // Create the debugger context.
762 HandleScope scope(isolate_); 818 HandleScope scope(isolate_);
763 ExtensionConfiguration no_extensions; 819 ExtensionConfiguration no_extensions;
764 Handle<Context> context = 820 Handle<Context> context =
765 isolate_->bootstrapper()->CreateEnvironment( 821 isolate_->bootstrapper()->CreateEnvironment(
766 Handle<Object>::null(), 822 Handle<Object>::null(),
767 v8::Handle<ObjectTemplate>(), 823 v8::Handle<ObjectTemplate>(),
768 &no_extensions); 824 &no_extensions);
(...skipping 30 matching lines...) Expand all
799 if (caught_exception) return false; 855 if (caught_exception) return false;
800 856
801 debug_context_ = Handle<Context>::cast( 857 debug_context_ = Handle<Context>::cast(
802 isolate_->global_handles()->Create(*context)); 858 isolate_->global_handles()->Create(*context));
803 return true; 859 return true;
804 } 860 }
805 861
806 862
807 void Debug::Unload() { 863 void Debug::Unload() {
808 // Return debugger is not loaded. 864 // Return debugger is not loaded.
809 if (!IsLoaded()) return; 865 if (!is_loaded()) return;
810 866
811 // Clear the script cache. 867 // Clear the script cache.
812 DestroyScriptCache(); 868 if (script_cache_ != NULL) {
869 delete script_cache_;
870 script_cache_ = NULL;
871 }
813 872
814 // Clear debugger context global handle. 873 // Clear debugger context global handle.
815 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location()); 874 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
816 debug_context_ = Handle<Context>(); 875 debug_context_ = Handle<Context>();
817 } 876 }
818 877
819 878
820 Object* Debug::Break(Arguments args) { 879 void Debug::Break(Arguments args, JavaScriptFrame* frame) {
821 Heap* heap = isolate_->heap(); 880 Heap* heap = isolate_->heap();
822 HandleScope scope(isolate_); 881 HandleScope scope(isolate_);
823 ASSERT(args.length() == 0); 882 ASSERT(args.length() == 0);
824 883
825 thread_local_.frame_drop_mode_ = FRAMES_UNTOUCHED; 884 if (live_edit_enabled()) {
826 885 thread_local_.frame_drop_mode_ = LiveEdit::FRAMES_UNTOUCHED;
827 // Get the top-most JavaScript frame. 886 }
828 JavaScriptFrameIterator it(isolate_);
829 JavaScriptFrame* frame = it.frame();
830 887
831 // Just continue if breaks are disabled or debugger cannot be loaded. 888 // Just continue if breaks are disabled or debugger cannot be loaded.
832 if (disable_break()) { 889 if (break_disabled_) return;
833 SetAfterBreakTarget(frame);
834 return heap->undefined_value();
835 }
836 890
837 // Enter the debugger. 891 // Enter the debugger.
838 EnterDebugger debugger(isolate_); 892 DebugScope debug_scope(this);
839 if (debugger.FailedToEnter()) { 893 if (debug_scope.failed()) return;
840 return heap->undefined_value();
841 }
842 894
843 // Postpone interrupt during breakpoint processing. 895 // Postpone interrupt during breakpoint processing.
844 PostponeInterruptsScope postpone(isolate_); 896 PostponeInterruptsScope postpone(isolate_);
845 897
846 // Get the debug info (create it if it does not exist). 898 // Get the debug info (create it if it does not exist).
847 Handle<SharedFunctionInfo> shared = 899 Handle<SharedFunctionInfo> shared =
848 Handle<SharedFunctionInfo>(frame->function()->shared()); 900 Handle<SharedFunctionInfo>(frame->function()->shared());
849 Handle<DebugInfo> debug_info = GetDebugInfo(shared); 901 Handle<DebugInfo> debug_info = GetDebugInfo(shared);
850 902
851 // Find the break point where execution has stopped. 903 // Find the break point where execution has stopped.
(...skipping 15 matching lines...) Expand all
867 // triggered. 919 // triggered.
868 Handle<Object> break_points_hit(heap->undefined_value(), isolate_); 920 Handle<Object> break_points_hit(heap->undefined_value(), isolate_);
869 if (break_location_iterator.HasBreakPoint()) { 921 if (break_location_iterator.HasBreakPoint()) {
870 Handle<Object> break_point_objects = 922 Handle<Object> break_point_objects =
871 Handle<Object>(break_location_iterator.BreakPointObjects(), isolate_); 923 Handle<Object>(break_location_iterator.BreakPointObjects(), isolate_);
872 break_points_hit = CheckBreakPoints(break_point_objects); 924 break_points_hit = CheckBreakPoints(break_point_objects);
873 } 925 }
874 926
875 // If step out is active skip everything until the frame where we need to step 927 // If step out is active skip everything until the frame where we need to step
876 // out to is reached, unless real breakpoint is hit. 928 // out to is reached, unless real breakpoint is hit.
877 if (StepOutActive() && frame->fp() != step_out_fp() && 929 if (StepOutActive() &&
930 frame->fp() != thread_local_.step_out_fp_ &&
878 break_points_hit->IsUndefined() ) { 931 break_points_hit->IsUndefined() ) {
879 // Step count should always be 0 for StepOut. 932 // Step count should always be 0 for StepOut.
880 ASSERT(thread_local_.step_count_ == 0); 933 ASSERT(thread_local_.step_count_ == 0);
881 } else if (!break_points_hit->IsUndefined() || 934 } else if (!break_points_hit->IsUndefined() ||
882 (thread_local_.last_step_action_ != StepNone && 935 (thread_local_.last_step_action_ != StepNone &&
883 thread_local_.step_count_ == 0)) { 936 thread_local_.step_count_ == 0)) {
884 // Notify debugger if a real break point is triggered or if performing 937 // Notify debugger if a real break point is triggered or if performing
885 // single stepping with no more steps to perform. Otherwise do another step. 938 // single stepping with no more steps to perform. Otherwise do another step.
886 939
887 // Clear all current stepping setup. 940 // Clear all current stepping setup.
888 ClearStepping(); 941 ClearStepping();
889 942
890 if (thread_local_.queued_step_count_ > 0) { 943 if (thread_local_.queued_step_count_ > 0) {
891 // Perform queued steps 944 // Perform queued steps
892 int step_count = thread_local_.queued_step_count_; 945 int step_count = thread_local_.queued_step_count_;
893 946
894 // Clear queue 947 // Clear queue
895 thread_local_.queued_step_count_ = 0; 948 thread_local_.queued_step_count_ = 0;
896 949
897 PrepareStep(StepNext, step_count, StackFrame::NO_ID); 950 PrepareStep(StepNext, step_count, StackFrame::NO_ID);
898 } else { 951 } else {
899 // Notify the debug event listeners. 952 // Notify the debug event listeners.
900 isolate_->debugger()->OnDebugBreak(break_points_hit, false); 953 OnDebugBreak(break_points_hit, false);
901 } 954 }
902 } else if (thread_local_.last_step_action_ != StepNone) { 955 } else if (thread_local_.last_step_action_ != StepNone) {
903 // Hold on to last step action as it is cleared by the call to 956 // Hold on to last step action as it is cleared by the call to
904 // ClearStepping. 957 // ClearStepping.
905 StepAction step_action = thread_local_.last_step_action_; 958 StepAction step_action = thread_local_.last_step_action_;
906 int step_count = thread_local_.step_count_; 959 int step_count = thread_local_.step_count_;
907 960
908 // If StepNext goes deeper in code, StepOut until original frame 961 // If StepNext goes deeper in code, StepOut until original frame
909 // and keep step count queued up in the meantime. 962 // and keep step count queued up in the meantime.
910 if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) { 963 if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) {
(...skipping 16 matching lines...) Expand all
927 step_action = StepOut; 980 step_action = StepOut;
928 step_count = count; 981 step_count = count;
929 } 982 }
930 983
931 // Clear all current stepping setup. 984 // Clear all current stepping setup.
932 ClearStepping(); 985 ClearStepping();
933 986
934 // Set up for the remaining steps. 987 // Set up for the remaining steps.
935 PrepareStep(step_action, step_count, StackFrame::NO_ID); 988 PrepareStep(step_action, step_count, StackFrame::NO_ID);
936 } 989 }
937
938 if (thread_local_.frame_drop_mode_ == FRAMES_UNTOUCHED) {
939 SetAfterBreakTarget(frame);
940 } else if (thread_local_.frame_drop_mode_ ==
941 FRAME_DROPPED_IN_IC_CALL) {
942 // We must have been calling IC stub. Do not go there anymore.
943 Code* plain_return = isolate_->builtins()->builtin(
944 Builtins::kPlainReturn_LiveEdit);
945 thread_local_.after_break_target_ = plain_return->entry();
946 } else if (thread_local_.frame_drop_mode_ ==
947 FRAME_DROPPED_IN_DEBUG_SLOT_CALL) {
948 // Debug break slot stub does not return normally, instead it manually
949 // cleans the stack and jumps. We should patch the jump address.
950 Code* plain_return = isolate_->builtins()->builtin(
951 Builtins::kFrameDropper_LiveEdit);
952 thread_local_.after_break_target_ = plain_return->entry();
953 } else if (thread_local_.frame_drop_mode_ ==
954 FRAME_DROPPED_IN_DIRECT_CALL) {
955 // Nothing to do, after_break_target is not used here.
956 } else if (thread_local_.frame_drop_mode_ ==
957 FRAME_DROPPED_IN_RETURN_CALL) {
958 Code* plain_return = isolate_->builtins()->builtin(
959 Builtins::kFrameDropper_LiveEdit);
960 thread_local_.after_break_target_ = plain_return->entry();
961 } else {
962 UNREACHABLE();
963 }
964
965 return heap->undefined_value();
966 } 990 }
967 991
968 992
969 RUNTIME_FUNCTION(Debug_Break) { 993 RUNTIME_FUNCTION(Debug_Break) {
970 return isolate->debug()->Break(args); 994 // Get the top-most JavaScript frame.
995 JavaScriptFrameIterator it(isolate);
996 isolate->debug()->Break(args, it.frame());
997 isolate->debug()->SetAfterBreakTarget(it.frame());
998 return isolate->heap()->undefined_value();
971 } 999 }
972 1000
973 1001
974 // Check the break point objects for whether one or more are actually 1002 // Check the break point objects for whether one or more are actually
975 // triggered. This function returns a JSArray with the break point objects 1003 // triggered. This function returns a JSArray with the break point objects
976 // which is triggered. 1004 // which is triggered.
977 Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) { 1005 Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) {
978 Factory* factory = isolate_->factory(); 1006 Factory* factory = isolate_->factory();
979 1007
980 // Count the number of break points hit. If there are multiple break points 1008 // Count the number of break points hit. If there are multiple break points
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 1269
1242 bool Debug::IsBreakOnException(ExceptionBreakType type) { 1270 bool Debug::IsBreakOnException(ExceptionBreakType type) {
1243 if (type == BreakUncaughtException) { 1271 if (type == BreakUncaughtException) {
1244 return break_on_uncaught_exception_; 1272 return break_on_uncaught_exception_;
1245 } else { 1273 } else {
1246 return break_on_exception_; 1274 return break_on_exception_;
1247 } 1275 }
1248 } 1276 }
1249 1277
1250 1278
1251 Debug::PromiseOnStack::PromiseOnStack(Isolate* isolate, 1279 PromiseOnStack::PromiseOnStack(Isolate* isolate,
1252 PromiseOnStack* prev, 1280 PromiseOnStack* prev,
1253 Handle<JSFunction> getter) 1281 Handle<JSFunction> getter)
1254 : isolate_(isolate), prev_(prev) { 1282 : isolate_(isolate), prev_(prev) {
1255 handler_ = StackHandler::FromAddress( 1283 handler_ = StackHandler::FromAddress(
1256 Isolate::handler(isolate->thread_local_top())); 1284 Isolate::handler(isolate->thread_local_top()));
1257 getter_ = Handle<JSFunction>::cast( 1285 getter_ = Handle<JSFunction>::cast(
1258 isolate->global_handles()->Create(*getter)); 1286 isolate->global_handles()->Create(*getter));
1259 } 1287 }
1260 1288
1261 1289
1262 Debug::PromiseOnStack::~PromiseOnStack() { 1290 PromiseOnStack::~PromiseOnStack() {
1263 isolate_->global_handles()->Destroy(Handle<Object>::cast(getter_).location()); 1291 isolate_->global_handles()->Destroy(Handle<Object>::cast(getter_).location());
1264 } 1292 }
1265 1293
1266 1294
1267 void Debug::PromiseHandlePrologue(Handle<JSFunction> promise_getter) { 1295 void Debug::PromiseHandlePrologue(Handle<JSFunction> promise_getter) {
1268 PromiseOnStack* prev = thread_local_.promise_on_stack_; 1296 PromiseOnStack* prev = thread_local_.promise_on_stack_;
1269 thread_local_.promise_on_stack_ = 1297 thread_local_.promise_on_stack_ =
1270 new PromiseOnStack(isolate_, prev, promise_getter); 1298 new PromiseOnStack(isolate_, prev, promise_getter);
1271 } 1299 }
1272 1300
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 } 1336 }
1309 1337
1310 1338
1311 void Debug::PrepareStep(StepAction step_action, 1339 void Debug::PrepareStep(StepAction step_action,
1312 int step_count, 1340 int step_count,
1313 StackFrame::Id frame_id) { 1341 StackFrame::Id frame_id) {
1314 HandleScope scope(isolate_); 1342 HandleScope scope(isolate_);
1315 1343
1316 PrepareForBreakPoints(); 1344 PrepareForBreakPoints();
1317 1345
1318 ASSERT(Debug::InDebugger()); 1346 ASSERT(in_debug_scope());
1319 1347
1320 // Remember this step action and count. 1348 // Remember this step action and count.
1321 thread_local_.last_step_action_ = step_action; 1349 thread_local_.last_step_action_ = step_action;
1322 if (step_action == StepOut) { 1350 if (step_action == StepOut) {
1323 // For step out target frame will be found on the stack so there is no need 1351 // For step out target frame will be found on the stack so there is no need
1324 // to set step counter for it. It's expected to always be 0 for StepOut. 1352 // to set step counter for it. It's expected to always be 0 for StepOut.
1325 thread_local_.step_count_ = 0; 1353 thread_local_.step_count_ = 0;
1326 } else { 1354 } else {
1327 thread_local_.step_count_ = step_count; 1355 thread_local_.step_count_ = step_count;
1328 } 1356 }
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 1607
1580 1608
1581 // Check whether the code object at the specified address is a debug break code 1609 // Check whether the code object at the specified address is a debug break code
1582 // object. 1610 // object.
1583 bool Debug::IsDebugBreak(Address addr) { 1611 bool Debug::IsDebugBreak(Address addr) {
1584 Code* code = Code::GetCodeFromTargetAddress(addr); 1612 Code* code = Code::GetCodeFromTargetAddress(addr);
1585 return code->is_debug_stub() && code->extra_ic_state() == DEBUG_BREAK; 1613 return code->is_debug_stub() && code->extra_ic_state() == DEBUG_BREAK;
1586 } 1614 }
1587 1615
1588 1616
1589 // Check whether a code stub with the specified major key is a possible break
1590 // point location when looking for source break locations.
1591 bool Debug::IsSourceBreakStub(Code* code) {
1592 CodeStub::Major major_key = CodeStub::GetMajorKey(code);
1593 return major_key == CodeStub::CallFunction;
1594 }
1595 1617
1596 1618
1597 // Check whether a code stub with the specified major key is a possible break
1598 // location.
1599 bool Debug::IsBreakStub(Code* code) {
1600 CodeStub::Major major_key = CodeStub::GetMajorKey(code);
1601 return major_key == CodeStub::CallFunction;
1602 }
1603
1604
1605 // Find the builtin to use for invoking the debug break
1606 Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) {
1607 Isolate* isolate = code->GetIsolate();
1608
1609 // Find the builtin debug break function matching the calling convention
1610 // used by the call site.
1611 if (code->is_inline_cache_stub()) {
1612 switch (code->kind()) {
1613 case Code::CALL_IC:
1614 return isolate->builtins()->CallICStub_DebugBreak();
1615
1616 case Code::LOAD_IC:
1617 return isolate->builtins()->LoadIC_DebugBreak();
1618
1619 case Code::STORE_IC:
1620 return isolate->builtins()->StoreIC_DebugBreak();
1621
1622 case Code::KEYED_LOAD_IC:
1623 return isolate->builtins()->KeyedLoadIC_DebugBreak();
1624
1625 case Code::KEYED_STORE_IC:
1626 return isolate->builtins()->KeyedStoreIC_DebugBreak();
1627
1628 case Code::COMPARE_NIL_IC:
1629 return isolate->builtins()->CompareNilIC_DebugBreak();
1630
1631 default:
1632 UNREACHABLE();
1633 }
1634 }
1635 if (RelocInfo::IsConstructCall(mode)) {
1636 if (code->has_function_cache()) {
1637 return isolate->builtins()->CallConstructStub_Recording_DebugBreak();
1638 } else {
1639 return isolate->builtins()->CallConstructStub_DebugBreak();
1640 }
1641 }
1642 if (code->kind() == Code::STUB) {
1643 ASSERT(code->major_key() == CodeStub::CallFunction);
1644 return isolate->builtins()->CallFunctionStub_DebugBreak();
1645 }
1646
1647 UNREACHABLE();
1648 return Handle<Code>::null();
1649 }
1650
1651 1619
1652 // Simple function for returning the source positions for active break points. 1620 // Simple function for returning the source positions for active break points.
1653 Handle<Object> Debug::GetSourceBreakLocations( 1621 Handle<Object> Debug::GetSourceBreakLocations(
1654 Handle<SharedFunctionInfo> shared, 1622 Handle<SharedFunctionInfo> shared,
1655 BreakPositionAlignment position_alignment) { 1623 BreakPositionAlignment position_alignment) {
1656 Isolate* isolate = shared->GetIsolate(); 1624 Isolate* isolate = shared->GetIsolate();
1657 Heap* heap = isolate->heap(); 1625 Heap* heap = isolate->heap();
1658 if (!HasDebugInfo(shared)) { 1626 if (!HasDebugInfo(shared)) {
1659 return Handle<Object>(heap->undefined_value(), isolate); 1627 return Handle<Object>(heap->undefined_value(), isolate);
1660 } 1628 }
(...skipping 23 matching lines...) Expand all
1684 } 1652 }
1685 1653
1686 locations->set(count++, position); 1654 locations->set(count++, position);
1687 } 1655 }
1688 } 1656 }
1689 } 1657 }
1690 return locations; 1658 return locations;
1691 } 1659 }
1692 1660
1693 1661
1694 void Debug::NewBreak(StackFrame::Id break_frame_id) {
1695 thread_local_.break_frame_id_ = break_frame_id;
1696 thread_local_.break_id_ = ++thread_local_.break_count_;
1697 }
1698
1699
1700 void Debug::SetBreak(StackFrame::Id break_frame_id, int break_id) {
1701 thread_local_.break_frame_id_ = break_frame_id;
1702 thread_local_.break_id_ = break_id;
1703 }
1704
1705
1706 // Handle stepping into a function. 1662 // Handle stepping into a function.
1707 void Debug::HandleStepIn(Handle<JSFunction> function, 1663 void Debug::HandleStepIn(Handle<JSFunction> function,
1708 Handle<Object> holder, 1664 Handle<Object> holder,
1709 Address fp, 1665 Address fp,
1710 bool is_constructor) { 1666 bool is_constructor) {
1711 Isolate* isolate = function->GetIsolate(); 1667 Isolate* isolate = function->GetIsolate();
1712 // If the frame pointer is not supplied by the caller find it. 1668 // If the frame pointer is not supplied by the caller find it.
1713 if (fp == 0) { 1669 if (fp == 0) {
1714 StackFrameIterator it(isolate); 1670 StackFrameIterator it(isolate);
1715 it.Advance(); 1671 it.Advance();
1716 // For constructor functions skip another frame. 1672 // For constructor functions skip another frame.
1717 if (is_constructor) { 1673 if (is_constructor) {
1718 ASSERT(it.frame()->is_construct()); 1674 ASSERT(it.frame()->is_construct());
1719 it.Advance(); 1675 it.Advance();
1720 } 1676 }
1721 fp = it.frame()->fp(); 1677 fp = it.frame()->fp();
1722 } 1678 }
1723 1679
1724 // Flood the function with one-shot break points if it is called from where 1680 // Flood the function with one-shot break points if it is called from where
1725 // step into was requested. 1681 // step into was requested.
1726 if (fp == step_in_fp()) { 1682 if (fp == thread_local_.step_into_fp_) {
1727 if (function->shared()->bound()) { 1683 if (function->shared()->bound()) {
1728 // Handle Function.prototype.bind 1684 // Handle Function.prototype.bind
1729 Debug::FloodBoundFunctionWithOneShot(function); 1685 Debug::FloodBoundFunctionWithOneShot(function);
1730 } else if (!function->IsBuiltin()) { 1686 } else if (!function->IsBuiltin()) {
1731 // Don't allow step into functions in the native context. 1687 // Don't allow step into functions in the native context.
1732 if (function->shared()->code() == 1688 if (function->shared()->code() ==
1733 isolate->builtins()->builtin(Builtins::kFunctionApply) || 1689 isolate->builtins()->builtin(Builtins::kFunctionApply) ||
1734 function->shared()->code() == 1690 function->shared()->code() ==
1735 isolate->builtins()->builtin(Builtins::kFunctionCall)) { 1691 isolate->builtins()->builtin(Builtins::kFunctionCall)) {
1736 // Handle function.apply and function.call separately to flood the 1692 // Handle function.apply and function.call separately to flood the
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1973 1929
1974 1930
1975 class ActiveFunctionsRedirector : public ThreadVisitor { 1931 class ActiveFunctionsRedirector : public ThreadVisitor {
1976 public: 1932 public:
1977 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 1933 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1978 RedirectActivationsToRecompiledCodeOnThread(isolate, top); 1934 RedirectActivationsToRecompiledCodeOnThread(isolate, top);
1979 } 1935 }
1980 }; 1936 };
1981 1937
1982 1938
1983 void Debug::EnsureFunctionHasDebugBreakSlots(Handle<JSFunction> function) { 1939 static void EnsureFunctionHasDebugBreakSlots(Handle<JSFunction> function) {
1984 if (function->code()->kind() == Code::FUNCTION && 1940 if (function->code()->kind() == Code::FUNCTION &&
1985 function->code()->has_debug_break_slots()) { 1941 function->code()->has_debug_break_slots()) {
1986 // Nothing to do. Function code already had debug break slots. 1942 // Nothing to do. Function code already had debug break slots.
1987 return; 1943 return;
1988 } 1944 }
1989 // Make sure that the shared full code is compiled with debug 1945 // Make sure that the shared full code is compiled with debug
1990 // break slots. 1946 // break slots.
1991 if (!function->shared()->code()->has_debug_break_slots()) { 1947 if (!function->shared()->code()->has_debug_break_slots()) {
1992 MaybeHandle<Code> code = Compiler::GetCodeForDebugging(function); 1948 MaybeHandle<Code> code = Compiler::GetCodeForDebugging(function);
1993 // Recompilation can fail. In that case leave the code as it was. 1949 // Recompilation can fail. In that case leave the code as it was.
1994 if (!code.is_null()) function->ReplaceCode(*code.ToHandleChecked()); 1950 if (!code.is_null()) function->ReplaceCode(*code.ToHandleChecked());
1995 } else { 1951 } else {
1996 // Simply use shared code if it has debug break slots. 1952 // Simply use shared code if it has debug break slots.
1997 function->ReplaceCode(function->shared()->code()); 1953 function->ReplaceCode(function->shared()->code());
1998 } 1954 }
1999 } 1955 }
2000 1956
2001 1957
2002 void Debug::RecompileAndRelocateSuspendedGenerators( 1958 static void RecompileAndRelocateSuspendedGenerators(
2003 const List<Handle<JSGeneratorObject> > &generators) { 1959 const List<Handle<JSGeneratorObject> > &generators) {
2004 for (int i = 0; i < generators.length(); i++) { 1960 for (int i = 0; i < generators.length(); i++) {
2005 Handle<JSFunction> fun(generators[i]->function()); 1961 Handle<JSFunction> fun(generators[i]->function());
2006 1962
2007 EnsureFunctionHasDebugBreakSlots(fun); 1963 EnsureFunctionHasDebugBreakSlots(fun);
2008 1964
2009 int code_offset = generators[i]->continuation(); 1965 int code_offset = generators[i]->continuation();
2010 int pc_offset = ComputePcOffsetFromCodeOffset(fun->code(), code_offset); 1966 int pc_offset = ComputePcOffsetFromCodeOffset(fun->code(), code_offset);
2011 generators[i]->set_continuation(pc_offset); 1967 generators[i]->set_continuation(pc_offset);
2012 } 1968 }
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
2339 } 2295 }
2340 // Move to next in list. 2296 // Move to next in list.
2341 prev = current; 2297 prev = current;
2342 current = current->next(); 2298 current = current->next();
2343 } 2299 }
2344 UNREACHABLE(); 2300 UNREACHABLE();
2345 } 2301 }
2346 2302
2347 2303
2348 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { 2304 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
2305 if (live_edit_enabled()) {
2306 after_break_target_ =
2307 LiveEdit::AfterBreakTarget(thread_local_.frame_drop_mode_, isolate_);
2308 if (after_break_target_ != NULL) return; // LiveEdit did the job.
2309 }
2310
2349 HandleScope scope(isolate_); 2311 HandleScope scope(isolate_);
2350
2351 PrepareForBreakPoints(); 2312 PrepareForBreakPoints();
2352 2313
2353 // Get the executing function in which the debug break occurred. 2314 // Get the executing function in which the debug break occurred.
2354 Handle<JSFunction> function(JSFunction::cast(frame->function())); 2315 Handle<JSFunction> function(JSFunction::cast(frame->function()));
2355 Handle<SharedFunctionInfo> shared(function->shared()); 2316 Handle<SharedFunctionInfo> shared(function->shared());
2356 if (!EnsureDebugInfo(shared, function)) { 2317 if (!EnsureDebugInfo(shared, function)) {
2357 // Return if we failed to retrieve the debug info. 2318 // Return if we failed to retrieve the debug info.
2358 return; 2319 return;
2359 } 2320 }
2360 Handle<DebugInfo> debug_info = GetDebugInfo(shared); 2321 Handle<DebugInfo> debug_info = GetDebugInfo(shared);
(...skipping 28 matching lines...) Expand all
2389 it.next(); 2350 it.next();
2390 } 2351 }
2391 2352
2392 // Handle the jump to continue execution after break point depending on the 2353 // Handle the jump to continue execution after break point depending on the
2393 // break location. 2354 // break location.
2394 if (at_js_return) { 2355 if (at_js_return) {
2395 // If the break point as return is still active jump to the corresponding 2356 // If the break point as return is still active jump to the corresponding
2396 // place in the original code. If not the break point was removed during 2357 // place in the original code. If not the break point was removed during
2397 // break point processing. 2358 // break point processing.
2398 if (break_at_js_return_active) { 2359 if (break_at_js_return_active) {
2399 addr += original_code->instruction_start() - code->instruction_start(); 2360 addr += original_code->instruction_start() - code->instruction_start();
2400 } 2361 }
2401 2362
2402 // Move back to where the call instruction sequence started. 2363 // Move back to where the call instruction sequence started.
2403 thread_local_.after_break_target_ = 2364 after_break_target_ = addr - Assembler::kPatchReturnSequenceAddressOffset;
2404 addr - Assembler::kPatchReturnSequenceAddressOffset;
2405 } else if (at_debug_break_slot) { 2365 } else if (at_debug_break_slot) {
2406 // Address of where the debug break slot starts. 2366 // Address of where the debug break slot starts.
2407 addr = addr - Assembler::kPatchDebugBreakSlotAddressOffset; 2367 addr = addr - Assembler::kPatchDebugBreakSlotAddressOffset;
2408 2368
2409 // Continue just after the slot. 2369 // Continue just after the slot.
2410 thread_local_.after_break_target_ = addr + Assembler::kDebugBreakSlotLength; 2370 after_break_target_ = addr + Assembler::kDebugBreakSlotLength;
2411 } else if (IsDebugBreak(Assembler::target_address_at(addr, *code))) { 2371 } else if (IsDebugBreak(Assembler::target_address_at(addr, *code))) {
2412 // We now know that there is still a debug break call at the target address, 2372 // We now know that there is still a debug break call at the target address,
2413 // so the break point is still there and the original code will hold the 2373 // so the break point is still there and the original code will hold the
2414 // address to jump to in order to complete the call which is replaced by a 2374 // address to jump to in order to complete the call which is replaced by a
2415 // call to DebugBreakXXX. 2375 // call to DebugBreakXXX.
2416 2376
2417 // Find the corresponding address in the original code. 2377 // Find the corresponding address in the original code.
2418 addr += original_code->instruction_start() - code->instruction_start(); 2378 addr += original_code->instruction_start() - code->instruction_start();
2419 2379
2420 // Install jump to the call address in the original code. This will be the 2380 // Install jump to the call address in the original code. This will be the
2421 // call which was overwritten by the call to DebugBreakXXX. 2381 // call which was overwritten by the call to DebugBreakXXX.
2422 thread_local_.after_break_target_ = 2382 after_break_target_ = Assembler::target_address_at(addr, *original_code);
2423 Assembler::target_address_at(addr, *original_code);
2424 } else { 2383 } else {
2425 // There is no longer a break point present. Don't try to look in the 2384 // There is no longer a break point present. Don't try to look in the
2426 // original code as the running code will have the right address. This takes 2385 // original code as the running code will have the right address. This takes
2427 // care of the case where the last break point is removed from the function 2386 // care of the case where the last break point is removed from the function
2428 // and therefore no "original code" is available. 2387 // and therefore no "original code" is available.
2429 thread_local_.after_break_target_ = 2388 after_break_target_ = Assembler::target_address_at(addr, *code);
2430 Assembler::target_address_at(addr, *code);
2431 } 2389 }
2432 } 2390 }
2433 2391
2434 2392
2435 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { 2393 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
2436 HandleScope scope(isolate_); 2394 HandleScope scope(isolate_);
2437 2395
2438 // If there are no break points this cannot be break at return, as 2396 // If there are no break points this cannot be break at return, as
2439 // the debugger statement and stack guard bebug break cannot be at 2397 // the debugger statement and stack guard bebug break cannot be at
2440 // return. 2398 // return.
(...skipping 28 matching lines...) Expand all
2469 return (it.rinfo()->pc() == 2427 return (it.rinfo()->pc() ==
2470 addr - Assembler::kPatchReturnSequenceAddressOffset); 2428 addr - Assembler::kPatchReturnSequenceAddressOffset);
2471 } 2429 }
2472 it.next(); 2430 it.next();
2473 } 2431 }
2474 return false; 2432 return false;
2475 } 2433 }
2476 2434
2477 2435
2478 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, 2436 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
2479 FrameDropMode mode, 2437 LiveEdit::FrameDropMode mode,
2480 Object** restarter_frame_function_pointer) { 2438 Object** restarter_frame_function_pointer) {
2481 if (mode != CURRENTLY_SET_MODE) { 2439 if (mode != LiveEdit::CURRENTLY_SET_MODE) {
2482 thread_local_.frame_drop_mode_ = mode; 2440 thread_local_.frame_drop_mode_ = mode;
2483 } 2441 }
2484 thread_local_.break_frame_id_ = new_break_frame_id; 2442 thread_local_.break_frame_id_ = new_break_frame_id;
2485 thread_local_.restarter_frame_function_pointer_ = 2443 thread_local_.restarter_frame_function_pointer_ =
2486 restarter_frame_function_pointer; 2444 restarter_frame_function_pointer;
2487 } 2445 }
2488 2446
2489 2447
2490 const int Debug::FramePaddingLayout::kInitialSize = 1;
2491
2492
2493 // Any even value bigger than kInitialSize as needed for stack scanning.
2494 const int Debug::FramePaddingLayout::kPaddingValue = kInitialSize + 1;
2495
2496
2497 bool Debug::IsDebugGlobal(GlobalObject* global) { 2448 bool Debug::IsDebugGlobal(GlobalObject* global) {
2498 return IsLoaded() && global == debug_context()->global_object(); 2449 return is_loaded() && global == debug_context()->global_object();
2499 } 2450 }
2500 2451
2501 2452
2502 void Debug::ClearMirrorCache() { 2453 void Debug::ClearMirrorCache() {
2503 PostponeInterruptsScope postpone(isolate_); 2454 PostponeInterruptsScope postpone(isolate_);
2504 HandleScope scope(isolate_); 2455 HandleScope scope(isolate_);
2505 ASSERT(isolate_->context() == *Debug::debug_context()); 2456 AssertDebugContext();
2506 2457
2507 // Clear the mirror cache. 2458 // Clear the mirror cache.
2508 Handle<String> function_name = isolate_->factory()->InternalizeOneByteString(
2509 STATIC_ASCII_VECTOR("ClearMirrorCache"));
2510 Handle<Object> fun = Object::GetProperty( 2459 Handle<Object> fun = Object::GetProperty(
2511 isolate_->global_object(), function_name).ToHandleChecked(); 2460 isolate_,
2461 isolate_->global_object(),
2462 "ClearMirrorCache").ToHandleChecked();
2512 ASSERT(fun->IsJSFunction()); 2463 ASSERT(fun->IsJSFunction());
2513 Execution::TryCall( 2464 Execution::TryCall(Handle<JSFunction>::cast(fun),
2514 Handle<JSFunction>::cast(fun), 2465 Handle<JSObject>(Debug::debug_context()->global_object()),
2515 Handle<JSObject>(Debug::debug_context()->global_object()), 2466 0,
2516 0, 2467 NULL);
2517 NULL);
2518 }
2519
2520
2521 void Debug::CreateScriptCache() {
2522 Heap* heap = isolate_->heap();
2523 HandleScope scope(isolate_);
2524
2525 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
2526 // rid of all the cached script wrappers and the second gets rid of the
2527 // scripts which are no longer referenced. The second also sweeps precisely,
2528 // which saves us doing yet another GC to make the heap iterable.
2529 heap->CollectAllGarbage(Heap::kNoGCFlags, "Debug::CreateScriptCache");
2530
2531 ASSERT(script_cache_ == NULL);
2532 script_cache_ = new ScriptCache(isolate_);
2533
2534 // Scan heap for Script objects.
2535 int count = 0;
2536 HeapIterator iterator(heap);
2537
2538 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
2539 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
2540 script_cache_->Add(Handle<Script>(Script::cast(obj)));
2541 count++;
2542 }
2543 }
2544 }
2545
2546
2547 void Debug::DestroyScriptCache() {
2548 // Get rid of the script cache if it was created.
2549 if (script_cache_ != NULL) {
2550 delete script_cache_;
2551 script_cache_ = NULL;
2552 }
2553 }
2554
2555
2556 void Debug::AddScriptToScriptCache(Handle<Script> script) {
2557 if (script_cache_ != NULL) {
2558 script_cache_->Add(script);
2559 }
2560 } 2468 }
2561 2469
2562 2470
2563 Handle<FixedArray> Debug::GetLoadedScripts() { 2471 Handle<FixedArray> Debug::GetLoadedScripts() {
2564 // Create and fill the script cache when the loaded scripts is requested for 2472 // Create and fill the script cache when the loaded scripts is requested for
2565 // the first time. 2473 // the first time.
2566 if (script_cache_ == NULL) { 2474 if (script_cache_ == NULL) script_cache_ = new ScriptCache(isolate_);
2567 CreateScriptCache();
2568 }
2569
2570 // If the script cache is not active just return an empty array.
2571 ASSERT(script_cache_ != NULL);
2572 if (script_cache_ == NULL) {
2573 isolate_->factory()->NewFixedArray(0);
2574 }
2575 2475
2576 // Perform GC to get unreferenced scripts evicted from the cache before 2476 // Perform GC to get unreferenced scripts evicted from the cache before
2577 // returning the content. 2477 // returning the content.
2578 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, 2478 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags,
2579 "Debug::GetLoadedScripts"); 2479 "Debug::GetLoadedScripts");
2580 2480
2581 // Get the scripts from the cache. 2481 // Get the scripts from the cache.
2582 return script_cache_->GetScripts(); 2482 return script_cache_->GetScripts();
2583 } 2483 }
2584 2484
(...skipping 14 matching lines...) Expand all
2599 2499
2600 2500
2601 void Debug::AfterGarbageCollection() { 2501 void Debug::AfterGarbageCollection() {
2602 // Generate events for collected scripts. 2502 // Generate events for collected scripts.
2603 if (script_cache_ != NULL) { 2503 if (script_cache_ != NULL) {
2604 script_cache_->ProcessCollectedScripts(); 2504 script_cache_->ProcessCollectedScripts();
2605 } 2505 }
2606 } 2506 }
2607 2507
2608 2508
2609 Debugger::Debugger(Isolate* isolate) 2509 MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name,
2610 : event_listener_(Handle<Object>()), 2510 int argc,
2611 event_listener_data_(Handle<Object>()), 2511 Handle<Object> argv[]) {
2612 is_active_(false), 2512 AssertDebugContext();
2613 ignore_debugger_(false), 2513 // Create the execution state object.
2614 live_edit_enabled_(true), 2514 Handle<Object> constructor = Object::GetProperty(
2615 message_handler_(NULL), 2515 isolate_, isolate_->global_object(), constructor_name).ToHandleChecked();
2616 command_queue_(isolate->logger(), kQueueInitialSize), 2516 ASSERT(constructor->IsJSFunction());
2617 command_received_(0), 2517 if (!constructor->IsJSFunction()) return MaybeHandle<Object>();
2618 event_command_queue_(isolate->logger(), kQueueInitialSize), 2518 return Execution::TryCall(Handle<JSFunction>::cast(constructor),
2619 isolate_(isolate) { 2519 Handle<JSObject>(debug_context()->global_object()),
2520 argc,
2521 argv);
2620 } 2522 }
2621 2523
2622 2524
2623 Debugger::~Debugger() {} 2525 MaybeHandle<Object> Debug::MakeExecutionState() {
2624
2625
2626 MaybeHandle<Object> Debugger::MakeJSObject(
2627 Vector<const char> constructor_name,
2628 int argc,
2629 Handle<Object> argv[]) {
2630 ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
2631
2632 // Create the execution state object. 2526 // Create the execution state object.
2633 Handle<String> constructor_str = 2527 Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()) };
2634 isolate_->factory()->InternalizeUtf8String(constructor_name); 2528 return MakeJSObject("MakeExecutionState", ARRAY_SIZE(argv), argv);
2635 ASSERT(!constructor_str.is_null());
2636 Handle<Object> constructor = Object::GetProperty(
2637 isolate_->global_object(), constructor_str).ToHandleChecked();
2638 ASSERT(constructor->IsJSFunction());
2639 if (!constructor->IsJSFunction()) return MaybeHandle<Object>();
2640 return Execution::TryCall(
2641 Handle<JSFunction>::cast(constructor),
2642 Handle<JSObject>(isolate_->debug()->debug_context()->global_object()),
2643 argc,
2644 argv);
2645 } 2529 }
2646 2530
2647 2531
2648 MaybeHandle<Object> Debugger::MakeExecutionState() { 2532 MaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) {
2649 // Create the execution state object.
2650 Handle<Object> break_id = isolate_->factory()->NewNumberFromInt(
2651 isolate_->debug()->break_id());
2652 Handle<Object> argv[] = { break_id };
2653 return MakeJSObject(CStrVector("MakeExecutionState"), ARRAY_SIZE(argv), argv);
2654 }
2655
2656
2657 MaybeHandle<Object> Debugger::MakeBreakEvent(Handle<Object> break_points_hit) {
2658 Handle<Object> exec_state; 2533 Handle<Object> exec_state;
2659 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); 2534 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2660 // Create the new break event object. 2535 // Create the new break event object.
2661 Handle<Object> argv[] = { exec_state, break_points_hit }; 2536 Handle<Object> argv[] = { exec_state, break_points_hit };
2662 return MakeJSObject(CStrVector("MakeBreakEvent"), ARRAY_SIZE(argv), argv); 2537 return MakeJSObject("MakeBreakEvent", ARRAY_SIZE(argv), argv);
2663 } 2538 }
2664 2539
2665 2540
2666 MaybeHandle<Object> Debugger::MakeExceptionEvent(Handle<Object> exception, 2541 MaybeHandle<Object> Debug::MakeExceptionEvent(Handle<Object> exception,
2667 bool uncaught, 2542 bool uncaught,
2668 Handle<Object> promise) { 2543 Handle<Object> promise) {
2669 Handle<Object> exec_state; 2544 Handle<Object> exec_state;
2670 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); 2545 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2671 // Create the new exception event object. 2546 // Create the new exception event object.
2672 Handle<Object> argv[] = { exec_state, 2547 Handle<Object> argv[] = { exec_state,
2673 exception, 2548 exception,
2674 isolate_->factory()->ToBoolean(uncaught), 2549 isolate_->factory()->ToBoolean(uncaught),
2675 promise }; 2550 promise };
2676 return MakeJSObject(CStrVector("MakeExceptionEvent"), ARRAY_SIZE(argv), argv); 2551 return MakeJSObject("MakeExceptionEvent", ARRAY_SIZE(argv), argv);
2677 } 2552 }
2678 2553
2679 2554
2680 MaybeHandle<Object> Debugger::MakeCompileEvent(Handle<Script> script, 2555 MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
2681 bool before) { 2556 bool before) {
2682 Handle<Object> exec_state; 2557 Handle<Object> exec_state;
2683 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); 2558 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2684 // Create the compile event object. 2559 // Create the compile event object.
2685 Handle<Object> script_wrapper = Script::GetWrapper(script); 2560 Handle<Object> script_wrapper = Script::GetWrapper(script);
2686 Handle<Object> argv[] = { exec_state, 2561 Handle<Object> argv[] = { exec_state,
2687 script_wrapper, 2562 script_wrapper,
2688 isolate_->factory()->ToBoolean(before) }; 2563 isolate_->factory()->ToBoolean(before) };
2689 return MakeJSObject(CStrVector("MakeCompileEvent"), ARRAY_SIZE(argv), argv); 2564 return MakeJSObject("MakeCompileEvent", ARRAY_SIZE(argv), argv);
2690 } 2565 }
2691 2566
2692 2567
2693 MaybeHandle<Object> Debugger::MakeScriptCollectedEvent(int id) { 2568 MaybeHandle<Object> Debug::MakeScriptCollectedEvent(int id) {
2694 Handle<Object> exec_state; 2569 Handle<Object> exec_state;
2695 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); 2570 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2696 // Create the script collected event object. 2571 // Create the script collected event object.
2697 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); 2572 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_);
2698 Handle<Object> argv[] = { exec_state, id_object }; 2573 Handle<Object> argv[] = { exec_state, id_object };
2699 2574 return MakeJSObject("MakeScriptCollectedEvent", ARRAY_SIZE(argv), argv);
2700 return MakeJSObject(
2701 CStrVector("MakeScriptCollectedEvent"), ARRAY_SIZE(argv), argv);
2702 } 2575 }
2703 2576
2704 2577
2705 void Debugger::OnException(Handle<Object> exception, bool uncaught) { 2578 void Debug::OnException(Handle<Object> exception, bool uncaught) {
2579 if (in_debug_scope() || ignore_events()) return;
2580
2706 HandleScope scope(isolate_); 2581 HandleScope scope(isolate_);
2707 Debug* debug = isolate_->debug(); 2582 Handle<Object> promise = GetPromiseForUncaughtException();
2708
2709 // Bail out based on state or if there is no listener for this event
2710 if (debug->InDebugger()) return;
2711 if (!Debugger::EventActive()) return;
2712
2713 Handle<Object> promise = debug->GetPromiseForUncaughtException();
2714 uncaught |= !promise->IsUndefined(); 2583 uncaught |= !promise->IsUndefined();
2715 2584
2716 // Bail out if exception breaks are not active 2585 // Bail out if exception breaks are not active
2717 if (uncaught) { 2586 if (uncaught) {
2718 // Uncaught exceptions are reported by either flags. 2587 // Uncaught exceptions are reported by either flags.
2719 if (!(debug->break_on_uncaught_exception() || 2588 if (!(break_on_uncaught_exception_ || break_on_exception_)) return;
2720 debug->break_on_exception())) return;
2721 } else { 2589 } else {
2722 // Caught exceptions are reported is activated. 2590 // Caught exceptions are reported is activated.
2723 if (!debug->break_on_exception()) return; 2591 if (!break_on_exception_) return;
2724 } 2592 }
2725 2593
2726 // Enter the debugger. 2594 DebugScope debug_scope(this);
2727 EnterDebugger debugger(isolate_); 2595 if (debug_scope.failed()) return;
2728 if (debugger.FailedToEnter()) return;
2729 2596
2730 // Clear all current stepping setup. 2597 // Clear all current stepping setup.
2731 debug->ClearStepping(); 2598 ClearStepping();
2732 2599
2733 // Create the event data object. 2600 // Create the event data object.
2734 Handle<Object> event_data; 2601 Handle<Object> event_data;
2735 // Bail out and don't call debugger if exception. 2602 // Bail out and don't call debugger if exception.
2736 if (!MakeExceptionEvent( 2603 if (!MakeExceptionEvent(
2737 exception, uncaught, promise).ToHandle(&event_data)) { 2604 exception, uncaught, promise).ToHandle(&event_data)) {
2738 return; 2605 return;
2739 } 2606 }
2740 2607
2741 // Process debug event. 2608 // Process debug event.
2742 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); 2609 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
2743 // Return to continue execution from where the exception was thrown. 2610 // Return to continue execution from where the exception was thrown.
2744 } 2611 }
2745 2612
2746 2613
2747 void Debugger::OnDebugBreak(Handle<Object> break_points_hit, 2614 void Debug::OnDebugBreak(Handle<Object> break_points_hit,
2748 bool auto_continue) { 2615 bool auto_continue) {
2616 // The caller provided for DebugScope.
2617 AssertDebugContext();
2618 // Bail out if there is no listener for this event
2619 if (ignore_events()) return;
2620
2749 HandleScope scope(isolate_); 2621 HandleScope scope(isolate_);
2750
2751 // Debugger has already been entered by caller.
2752 ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
2753
2754 // Bail out if there is no listener for this event
2755 if (!Debugger::EventActive()) return;
2756
2757 // Debugger must be entered in advance.
2758 ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
2759
2760 // Create the event data object. 2622 // Create the event data object.
2761 Handle<Object> event_data; 2623 Handle<Object> event_data;
2762 // Bail out and don't call debugger if exception. 2624 // Bail out and don't call debugger if exception.
2763 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return; 2625 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
2764 2626
2765 // Process debug event. 2627 // Process debug event.
2766 ProcessDebugEvent(v8::Break, 2628 ProcessDebugEvent(v8::Break,
2767 Handle<JSObject>::cast(event_data), 2629 Handle<JSObject>::cast(event_data),
2768 auto_continue); 2630 auto_continue);
2769 } 2631 }
2770 2632
2771 2633
2772 void Debugger::OnBeforeCompile(Handle<Script> script) { 2634 void Debug::OnBeforeCompile(Handle<Script> script) {
2635 if (in_debug_scope() || ignore_events()) return;
2636
2773 HandleScope scope(isolate_); 2637 HandleScope scope(isolate_);
2774 2638 DebugScope debug_scope(this);
2775 // Bail out based on state or if there is no listener for this event 2639 if (debug_scope.failed()) return;
2776 if (isolate_->debug()->InDebugger()) return;
2777 if (!EventActive()) return;
2778
2779 // Enter the debugger.
2780 EnterDebugger debugger(isolate_);
2781 if (debugger.FailedToEnter()) return;
2782 2640
2783 // Create the event data object. 2641 // Create the event data object.
2784 Handle<Object> event_data; 2642 Handle<Object> event_data;
2785 // Bail out and don't call debugger if exception. 2643 // Bail out and don't call debugger if exception.
2786 if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return; 2644 if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return;
2787 2645
2788 // Process debug event. 2646 // Process debug event.
2789 ProcessDebugEvent(v8::BeforeCompile, 2647 ProcessDebugEvent(v8::BeforeCompile,
2790 Handle<JSObject>::cast(event_data), 2648 Handle<JSObject>::cast(event_data),
2791 true); 2649 true);
2792 } 2650 }
2793 2651
2794 2652
2795 // Handle debugger actions when a new script is compiled. 2653 // Handle debugger actions when a new script is compiled.
2796 void Debugger::OnAfterCompile(Handle<Script> script, 2654 void Debug::OnAfterCompile(Handle<Script> script,
2797 AfterCompileFlags after_compile_flags) { 2655 AfterCompileFlags after_compile_flags) {
2798 HandleScope scope(isolate_);
2799 Debug* debug = isolate_->debug();
2800
2801 // Add the newly compiled script to the script cache. 2656 // Add the newly compiled script to the script cache.
2802 debug->AddScriptToScriptCache(script); 2657 if (script_cache_ != NULL) script_cache_->Add(script);
2803 2658
2804 // No more to do if not debugging. 2659 // No more to do if not debugging.
2805 if (!Debugger::EventActive()) return; 2660 if (in_debug_scope() || ignore_events()) return;
2806 2661
2662 HandleScope scope(isolate_);
2807 // Store whether in debugger before entering debugger. 2663 // Store whether in debugger before entering debugger.
2808 bool in_debugger = debug->InDebugger(); 2664 bool was_in_scope = in_debug_scope();
2809 2665
2810 // Enter the debugger. 2666 DebugScope debug_scope(this);
2811 EnterDebugger debugger(isolate_); 2667 if (debug_scope.failed()) return;
2812 if (debugger.FailedToEnter()) return;
2813 2668
2814 // If debugging there might be script break points registered for this 2669 // If debugging there might be script break points registered for this
2815 // script. Make sure that these break points are set. 2670 // script. Make sure that these break points are set.
2816 2671
2817 // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js). 2672 // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js).
2818 Handle<String> update_script_break_points_string = 2673 Handle<String> update_script_break_points_string =
2819 isolate_->factory()->InternalizeOneByteString( 2674 isolate_->factory()->InternalizeOneByteString(
2820 STATIC_ASCII_VECTOR("UpdateScriptBreakPoints")); 2675 STATIC_ASCII_VECTOR("UpdateScriptBreakPoints"));
2821 Handle<GlobalObject> debug_global(debug->debug_context()->global_object()); 2676 Handle<GlobalObject> debug_global(debug_context()->global_object());
2822 Handle<Object> update_script_break_points = 2677 Handle<Object> update_script_break_points =
2823 Object::GetProperty( 2678 Object::GetProperty(
2824 debug_global, update_script_break_points_string).ToHandleChecked(); 2679 debug_global, update_script_break_points_string).ToHandleChecked();
2825 if (!update_script_break_points->IsJSFunction()) { 2680 if (!update_script_break_points->IsJSFunction()) {
2826 return; 2681 return;
2827 } 2682 }
2828 ASSERT(update_script_break_points->IsJSFunction()); 2683 ASSERT(update_script_break_points->IsJSFunction());
2829 2684
2830 // Wrap the script object in a proper JS object before passing it 2685 // Wrap the script object in a proper JS object before passing it
2831 // to JavaScript. 2686 // to JavaScript.
2832 Handle<Object> wrapper = Script::GetWrapper(script); 2687 Handle<Object> wrapper = Script::GetWrapper(script);
2833 2688
2834 // Call UpdateScriptBreakPoints expect no exceptions. 2689 // Call UpdateScriptBreakPoints expect no exceptions.
2835 Handle<Object> argv[] = { wrapper }; 2690 Handle<Object> argv[] = { wrapper };
2836 if (Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points), 2691 if (Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points),
2837 isolate_->js_builtins_object(), 2692 isolate_->js_builtins_object(),
2838 ARRAY_SIZE(argv), 2693 ARRAY_SIZE(argv),
2839 argv).is_null()) { 2694 argv).is_null()) {
2840 return; 2695 return;
2841 } 2696 }
2842 // Bail out based on state or if there is no listener for this event 2697 // Bail out based on state or if there is no listener for this event
2843 if (in_debugger && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return; 2698 if (was_in_scope && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return;
2844 2699
2845 // Create the compile state object. 2700 // Create the compile state object.
2846 Handle<Object> event_data; 2701 Handle<Object> event_data;
2847 // Bail out and don't call debugger if exception. 2702 // Bail out and don't call debugger if exception.
2848 if (!MakeCompileEvent(script, false).ToHandle(&event_data)) return; 2703 if (!MakeCompileEvent(script, false).ToHandle(&event_data)) return;
2849 2704
2850 // Process debug event. 2705 // Process debug event.
2851 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true); 2706 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true);
2852 } 2707 }
2853 2708
2854 2709
2855 void Debugger::OnScriptCollected(int id) { 2710 void Debug::OnScriptCollected(int id) {
2711 if (in_debug_scope() || ignore_events()) return;
2712
2856 HandleScope scope(isolate_); 2713 HandleScope scope(isolate_);
2857 2714 DebugScope debug_scope(this);
2858 // No more to do if not debugging. 2715 if (debug_scope.failed()) return;
2859 if (isolate_->debug()->InDebugger()) return;
2860 if (!Debugger::EventActive()) return;
2861
2862 // Enter the debugger.
2863 EnterDebugger debugger(isolate_);
2864 if (debugger.FailedToEnter()) return;
2865 2716
2866 // Create the script collected state object. 2717 // Create the script collected state object.
2867 Handle<Object> event_data; 2718 Handle<Object> event_data;
2868 // Bail out and don't call debugger if exception. 2719 // Bail out and don't call debugger if exception.
2869 if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return; 2720 if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return;
2870 2721
2871 // Process debug event. 2722 // Process debug event.
2872 ProcessDebugEvent(v8::ScriptCollected, 2723 ProcessDebugEvent(v8::ScriptCollected,
2873 Handle<JSObject>::cast(event_data), 2724 Handle<JSObject>::cast(event_data),
2874 true); 2725 true);
2875 } 2726 }
2876 2727
2877 2728
2878 void Debugger::ProcessDebugEvent(v8::DebugEvent event, 2729 void Debug::ProcessDebugEvent(v8::DebugEvent event,
2879 Handle<JSObject> event_data, 2730 Handle<JSObject> event_data,
2880 bool auto_continue) { 2731 bool auto_continue) {
2881 HandleScope scope(isolate_); 2732 HandleScope scope(isolate_);
2882 2733
2883 // Clear any pending debug break if this is a real break.
2884 if (!auto_continue) {
2885 isolate_->debug()->set_has_pending_interrupt(false);
2886 }
2887
2888 // Create the execution state. 2734 // Create the execution state.
2889 Handle<Object> exec_state; 2735 Handle<Object> exec_state;
2890 // Bail out and don't call debugger if exception. 2736 // Bail out and don't call debugger if exception.
2891 if (!MakeExecutionState().ToHandle(&exec_state)) return; 2737 if (!MakeExecutionState().ToHandle(&exec_state)) return;
2892 2738
2893 // First notify the message handler if any. 2739 // First notify the message handler if any.
2894 if (message_handler_ != NULL) { 2740 if (message_handler_ != NULL) {
2895 NotifyMessageHandler(event, 2741 NotifyMessageHandler(event,
2896 Handle<JSObject>::cast(exec_state), 2742 Handle<JSObject>::cast(exec_state),
2897 event_data, 2743 event_data,
(...skipping 14 matching lines...) Expand all
2912 exec_state, 2758 exec_state,
2913 event_data, 2759 event_data,
2914 command.client_data()); 2760 command.client_data());
2915 } 2761 }
2916 command.Dispose(); 2762 command.Dispose();
2917 } 2763 }
2918 } 2764 }
2919 } 2765 }
2920 2766
2921 2767
2922 void Debugger::CallEventCallback(v8::DebugEvent event, 2768 void Debug::CallEventCallback(v8::DebugEvent event,
2923 Handle<Object> exec_state, 2769 Handle<Object> exec_state,
2924 Handle<Object> event_data, 2770 Handle<Object> event_data,
2925 v8::Debug::ClientData* client_data) { 2771 v8::Debug::ClientData* client_data) {
2926 if (event_listener_->IsForeign()) { 2772 if (event_listener_->IsForeign()) {
2927 CallCEventCallback(event, exec_state, event_data, client_data); 2773 // Invoke the C debug event listener.
2774 v8::Debug::EventCallback2 callback =
2775 FUNCTION_CAST<v8::Debug::EventCallback2>(
2776 Handle<Foreign>::cast(event_listener_)->foreign_address());
2777 EventDetailsImpl event_details(event,
2778 Handle<JSObject>::cast(exec_state),
2779 Handle<JSObject>::cast(event_data),
2780 event_listener_data_,
2781 client_data);
2782 callback(event_details);
2783 ASSERT(!isolate_->has_scheduled_exception());
2928 } else { 2784 } else {
2929 CallJSEventCallback(event, exec_state, event_data); 2785 // Invoke the JavaScript debug event listener.
2786 ASSERT(event_listener_->IsJSFunction());
2787 Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_),
2788 exec_state,
2789 event_data,
2790 event_listener_data_ };
2791 Execution::TryCall(Handle<JSFunction>::cast(event_listener_),
2792 isolate_->global_object(),
2793 ARRAY_SIZE(argv),
2794 argv);
2930 } 2795 }
2931 } 2796 }
2932 2797
2933 2798
2934 void Debugger::CallCEventCallback(v8::DebugEvent event, 2799 Handle<Context> Debug::GetDebugContext() {
2935 Handle<Object> exec_state, 2800 DebugScope debug_scope(this);
2936 Handle<Object> event_data, 2801 // The global handle may be destroyed soon after. Return it reboxed.
2937 v8::Debug::ClientData* client_data) { 2802 return handle(*debug_context(), isolate_);
2938 Handle<Foreign> callback_obj(Handle<Foreign>::cast(event_listener_));
2939 v8::Debug::EventCallback2 callback =
2940 FUNCTION_CAST<v8::Debug::EventCallback2>(
2941 callback_obj->foreign_address());
2942 EventDetailsImpl event_details(
2943 event,
2944 Handle<JSObject>::cast(exec_state),
2945 Handle<JSObject>::cast(event_data),
2946 event_listener_data_,
2947 client_data);
2948 callback(event_details);
2949 } 2803 }
2950 2804
2951 2805
2952 void Debugger::CallJSEventCallback(v8::DebugEvent event, 2806 void Debug::NotifyMessageHandler(v8::DebugEvent event,
2953 Handle<Object> exec_state, 2807 Handle<JSObject> exec_state,
2954 Handle<Object> event_data) { 2808 Handle<JSObject> event_data,
2955 ASSERT(event_listener_->IsJSFunction()); 2809 bool auto_continue) {
2956 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_));
2957
2958 // Invoke the JavaScript debug event listener.
2959 Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_),
2960 exec_state,
2961 event_data,
2962 event_listener_data_ };
2963 Execution::TryCall(fun,
2964 isolate_->global_object(),
2965 ARRAY_SIZE(argv),
2966 argv);
2967 // Silently ignore exceptions from debug event listeners.
2968 }
2969
2970
2971 Handle<Context> Debugger::GetDebugContext() {
2972 EnterDebugger debugger(isolate_);
2973 // The global handle may be destroyed soon after. Return it reboxed.
2974 return handle(*isolate_->debug()->debug_context(), isolate_);
2975 }
2976
2977
2978 void Debugger::NotifyMessageHandler(v8::DebugEvent event,
2979 Handle<JSObject> exec_state,
2980 Handle<JSObject> event_data,
2981 bool auto_continue) {
2982 ASSERT(is_active_); 2810 ASSERT(is_active_);
2983 HandleScope scope(isolate_); 2811 HandleScope scope(isolate_);
2984 // Process the individual events. 2812 // Process the individual events.
2985 bool sendEventMessage = false; 2813 bool sendEventMessage = false;
2986 switch (event) { 2814 switch (event) {
2987 case v8::Break: 2815 case v8::Break:
2988 case v8::BreakForCommand: 2816 case v8::BreakForCommand:
2989 sendEventMessage = !auto_continue; 2817 sendEventMessage = !auto_continue;
2990 break; 2818 break;
2991 case v8::Exception: 2819 case v8::Exception:
2992 sendEventMessage = true; 2820 sendEventMessage = true;
2993 break; 2821 break;
2994 case v8::BeforeCompile: 2822 case v8::BeforeCompile:
2995 break; 2823 break;
2996 case v8::AfterCompile: 2824 case v8::AfterCompile:
2997 sendEventMessage = true; 2825 sendEventMessage = true;
2998 break; 2826 break;
2999 case v8::ScriptCollected: 2827 case v8::ScriptCollected:
3000 sendEventMessage = true; 2828 sendEventMessage = true;
3001 break; 2829 break;
3002 case v8::NewFunction: 2830 case v8::NewFunction:
3003 break; 2831 break;
3004 default: 2832 default:
3005 UNREACHABLE(); 2833 UNREACHABLE();
3006 } 2834 }
3007 2835
3008 // The debug command interrupt flag might have been set when the command was 2836 // The debug command interrupt flag might have been set when the command was
3009 // added. It should be enough to clear the flag only once while we are in the 2837 // added. It should be enough to clear the flag only once while we are in the
3010 // debugger. 2838 // debugger.
3011 ASSERT(isolate_->debug()->InDebugger()); 2839 ASSERT(in_debug_scope());
3012 isolate_->stack_guard()->ClearDebugCommand(); 2840 isolate_->stack_guard()->ClearDebugCommand();
3013 2841
3014 // Notify the debugger that a debug event has occurred unless auto continue is 2842 // Notify the debugger that a debug event has occurred unless auto continue is
3015 // active in which case no event is send. 2843 // active in which case no event is send.
3016 if (sendEventMessage) { 2844 if (sendEventMessage) {
3017 MessageImpl message = MessageImpl::NewEvent( 2845 MessageImpl message = MessageImpl::NewEvent(
3018 event, 2846 event,
3019 auto_continue, 2847 auto_continue,
3020 Handle<JSObject>::cast(exec_state), 2848 Handle<JSObject>::cast(exec_state),
3021 Handle<JSObject>::cast(event_data)); 2849 Handle<JSObject>::cast(event_data));
3022 InvokeMessageHandler(message); 2850 InvokeMessageHandler(message);
3023 } 2851 }
3024 2852
3025 // If auto continue don't make the event cause a break, but process messages 2853 // If auto continue don't make the event cause a break, but process messages
3026 // in the queue if any. For script collected events don't even process 2854 // in the queue if any. For script collected events don't even process
3027 // messages in the queue as the execution state might not be what is expected 2855 // messages in the queue as the execution state might not be what is expected
3028 // by the client. 2856 // by the client.
3029 if ((auto_continue && !HasCommands()) || event == v8::ScriptCollected) { 2857 if ((auto_continue && !has_commands()) || event == v8::ScriptCollected) {
3030 return; 2858 return;
3031 } 2859 }
3032 2860
3033 // DebugCommandProcessor goes here. 2861 // DebugCommandProcessor goes here.
3034 bool running = auto_continue; 2862 bool running = auto_continue;
3035 2863
3036 Handle<Object> cmd_processor_ctor = Object::GetProperty( 2864 Handle<Object> cmd_processor_ctor = Object::GetProperty(
3037 isolate_, exec_state, "debugCommandProcessor").ToHandleChecked(); 2865 isolate_, exec_state, "debugCommandProcessor").ToHandleChecked();
3038 Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) }; 2866 Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) };
3039 Handle<Object> cmd_processor = Execution::Call( 2867 Handle<Object> cmd_processor = Execution::Call(
3040 isolate_, cmd_processor_ctor, exec_state, 1, ctor_args).ToHandleChecked(); 2868 isolate_, cmd_processor_ctor, exec_state, 1, ctor_args).ToHandleChecked();
3041 Handle<JSFunction> process_debug_request = Handle<JSFunction>::cast( 2869 Handle<JSFunction> process_debug_request = Handle<JSFunction>::cast(
3042 Object::GetProperty( 2870 Object::GetProperty(
3043 isolate_, cmd_processor, "processDebugRequest").ToHandleChecked()); 2871 isolate_, cmd_processor, "processDebugRequest").ToHandleChecked());
3044 Handle<Object> is_running = Object::GetProperty( 2872 Handle<Object> is_running = Object::GetProperty(
3045 isolate_, cmd_processor, "isRunning").ToHandleChecked(); 2873 isolate_, cmd_processor, "isRunning").ToHandleChecked();
3046 2874
3047 // Process requests from the debugger. 2875 // Process requests from the debugger.
3048 do { 2876 do {
3049 // Wait for new command in the queue. 2877 // Wait for new command in the queue.
3050 command_received_.Wait(); 2878 command_received_.Wait();
3051 2879
3052 // Get the command from the queue. 2880 // Get the command from the queue.
3053 CommandMessage command = command_queue_.Get(); 2881 CommandMessage command = command_queue_.Get();
3054 isolate_->logger()->DebugTag( 2882 isolate_->logger()->DebugTag(
3055 "Got request from command queue, in interactive loop."); 2883 "Got request from command queue, in interactive loop.");
3056 if (!Debugger::is_active()) { 2884 if (!is_active()) {
3057 // Delete command text and user data. 2885 // Delete command text and user data.
3058 command.Dispose(); 2886 command.Dispose();
3059 return; 2887 return;
3060 } 2888 }
3061 2889
3062 Vector<const uc16> command_text( 2890 Vector<const uc16> command_text(
3063 const_cast<const uc16*>(command.text().start()), 2891 const_cast<const uc16*>(command.text().start()),
3064 command.text().length()); 2892 command.text().length());
3065 Handle<String> request_text = isolate_->factory()->NewStringFromTwoByte( 2893 Handle<String> request_text = isolate_->factory()->NewStringFromTwoByte(
3066 command_text).ToHandleChecked(); 2894 command_text).ToHandleChecked();
(...skipping 28 matching lines...) Expand all
3095 2923
3096 // Return the result. 2924 // Return the result.
3097 MessageImpl message = MessageImpl::NewResponse( 2925 MessageImpl message = MessageImpl::NewResponse(
3098 event, running, exec_state, event_data, answer, command.client_data()); 2926 event, running, exec_state, event_data, answer, command.client_data());
3099 InvokeMessageHandler(message); 2927 InvokeMessageHandler(message);
3100 command.Dispose(); 2928 command.Dispose();
3101 2929
3102 // Return from debug event processing if either the VM is put into the 2930 // Return from debug event processing if either the VM is put into the
3103 // running state (through a continue command) or auto continue is active 2931 // running state (through a continue command) or auto continue is active
3104 // and there are no more commands queued. 2932 // and there are no more commands queued.
3105 } while (!running || HasCommands()); 2933 } while (!running || has_commands());
3106 } 2934 }
3107 2935
3108 2936
3109 void Debugger::SetEventListener(Handle<Object> callback, 2937 void Debug::SetEventListener(Handle<Object> callback,
3110 Handle<Object> data) { 2938 Handle<Object> data) {
3111 GlobalHandles* global_handles = isolate_->global_handles(); 2939 GlobalHandles* global_handles = isolate_->global_handles();
3112 2940
3113 // Remove existing entry. 2941 // Remove existing entry.
3114 GlobalHandles::Destroy(event_listener_.location()); 2942 GlobalHandles::Destroy(event_listener_.location());
3115 event_listener_ = Handle<Object>(); 2943 event_listener_ = Handle<Object>();
3116 GlobalHandles::Destroy(event_listener_data_.location()); 2944 GlobalHandles::Destroy(event_listener_data_.location());
3117 event_listener_data_ = Handle<Object>(); 2945 event_listener_data_ = Handle<Object>();
3118 2946
3119 // Set new entry. 2947 // Set new entry.
3120 if (!callback->IsUndefined() && !callback->IsNull()) { 2948 if (!callback->IsUndefined() && !callback->IsNull()) {
3121 event_listener_ = global_handles->Create(*callback); 2949 event_listener_ = global_handles->Create(*callback);
3122 if (data.is_null()) data = isolate_->factory()->undefined_value(); 2950 if (data.is_null()) data = isolate_->factory()->undefined_value();
3123 event_listener_data_ = global_handles->Create(*data); 2951 event_listener_data_ = global_handles->Create(*data);
3124 } 2952 }
3125 2953
3126 UpdateState(); 2954 UpdateState();
3127 } 2955 }
3128 2956
3129 2957
3130 void Debugger::SetMessageHandler(v8::Debug::MessageHandler handler) { 2958 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
3131 message_handler_ = handler; 2959 message_handler_ = handler;
3132 UpdateState(); 2960 UpdateState();
3133 if (handler == NULL && isolate_->debug()->InDebugger()) { 2961 if (handler == NULL && in_debug_scope()) {
3134 // Send an empty command to the debugger if in a break to make JavaScript 2962 // Send an empty command to the debugger if in a break to make JavaScript
3135 // run again if the debugger is closed. 2963 // run again if the debugger is closed.
3136 EnqueueCommandMessage(Vector<const uint16_t>::empty()); 2964 EnqueueCommandMessage(Vector<const uint16_t>::empty());
3137 } 2965 }
3138 } 2966 }
3139 2967
3140 2968
3141 void Debugger::UpdateState() { 2969 void Debug::UpdateState() {
3142 bool activate = message_handler_ != NULL || 2970 is_active_ = message_handler_ != NULL || !event_listener_.is_null();
3143 !event_listener_.is_null() || 2971 if (is_active_ || in_debug_scope()) {
3144 isolate_->debug()->InDebugger();
3145 if (!is_active_ && activate) {
3146 // Note that the debug context could have already been loaded to 2972 // Note that the debug context could have already been loaded to
3147 // bootstrap test cases. 2973 // bootstrap test cases.
3148 isolate_->compilation_cache()->Disable(); 2974 isolate_->compilation_cache()->Disable();
3149 activate = isolate_->debug()->Load(); 2975 is_active_ = Load();
3150 } else if (is_active_ && !activate) { 2976 } else if (is_loaded()) {
3151 isolate_->compilation_cache()->Enable(); 2977 isolate_->compilation_cache()->Enable();
3152 isolate_->debug()->ClearAllBreakPoints(); 2978 ClearAllBreakPoints();
3153 isolate_->debug()->Unload(); 2979 Unload();
3154 } 2980 }
3155 is_active_ = activate;
3156 // At this point the debug context is loaded iff the debugger is active.
3157 ASSERT(isolate_->debug()->IsLoaded() == is_active_);
3158 } 2981 }
3159 2982
3160 2983
3161 // Calls the registered debug message handler. This callback is part of the 2984 // Calls the registered debug message handler. This callback is part of the
3162 // public API. 2985 // public API.
3163 void Debugger::InvokeMessageHandler(MessageImpl message) { 2986 void Debug::InvokeMessageHandler(MessageImpl message) {
3164 if (message_handler_ != NULL) message_handler_(message); 2987 if (message_handler_ != NULL) message_handler_(message);
3165 } 2988 }
3166 2989
3167 2990
3168 // Puts a command coming from the public API on the queue. Creates 2991 // Puts a command coming from the public API on the queue. Creates
3169 // a copy of the command string managed by the debugger. Up to this 2992 // a copy of the command string managed by the debugger. Up to this
3170 // point, the command data was managed by the API client. Called 2993 // point, the command data was managed by the API client. Called
3171 // by the API client thread. 2994 // by the API client thread.
3172 void Debugger::EnqueueCommandMessage(Vector<const uint16_t> command, 2995 void Debug::EnqueueCommandMessage(Vector<const uint16_t> command,
3173 v8::Debug::ClientData* client_data) { 2996 v8::Debug::ClientData* client_data) {
3174 // Need to cast away const. 2997 // Need to cast away const.
3175 CommandMessage message = CommandMessage::New( 2998 CommandMessage message = CommandMessage::New(
3176 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), 2999 Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
3177 command.length()), 3000 command.length()),
3178 client_data); 3001 client_data);
3179 isolate_->logger()->DebugTag("Put command on command_queue."); 3002 isolate_->logger()->DebugTag("Put command on command_queue.");
3180 command_queue_.Put(message); 3003 command_queue_.Put(message);
3181 command_received_.Signal(); 3004 command_received_.Signal();
3182 3005
3183 // Set the debug command break flag to have the command processed. 3006 // Set the debug command break flag to have the command processed.
3184 if (!isolate_->debug()->InDebugger()) { 3007 if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
3185 isolate_->stack_guard()->RequestDebugCommand();
3186 }
3187 } 3008 }
3188 3009
3189 3010
3190 bool Debugger::HasCommands() { 3011 void Debug::EnqueueDebugCommand(v8::Debug::ClientData* client_data) {
3191 return !command_queue_.IsEmpty();
3192 }
3193
3194
3195 void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) {
3196 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); 3012 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data);
3197 event_command_queue_.Put(message); 3013 event_command_queue_.Put(message);
3198 3014
3199 // Set the debug command break flag to have the command processed. 3015 // Set the debug command break flag to have the command processed.
3200 if (!isolate_->debug()->InDebugger()) { 3016 if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
3201 isolate_->stack_guard()->RequestDebugCommand();
3202 }
3203 } 3017 }
3204 3018
3205 3019
3206 MaybeHandle<Object> Debugger::Call(Handle<JSFunction> fun, 3020 MaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) {
3207 Handle<Object> data) { 3021 DebugScope debug_scope(this);
3208 // Enter the debugger. 3022 if (debug_scope.failed()) return isolate_->factory()->undefined_value();
3209 EnterDebugger debugger(isolate_);
3210 if (debugger.FailedToEnter()) {
3211 return isolate_->factory()->undefined_value();
3212 }
3213 3023
3214 // Create the execution state. 3024 // Create the execution state.
3215 Handle<Object> exec_state; 3025 Handle<Object> exec_state;
3216 if (!MakeExecutionState().ToHandle(&exec_state)) { 3026 if (!MakeExecutionState().ToHandle(&exec_state)) {
3217 return isolate_->factory()->undefined_value(); 3027 return isolate_->factory()->undefined_value();
3218 } 3028 }
3219 3029
3220 Handle<Object> argv[] = { exec_state, data }; 3030 Handle<Object> argv[] = { exec_state, data };
3221 return Execution::Call( 3031 return Execution::Call(
3222 isolate_, 3032 isolate_,
3223 fun, 3033 fun,
3224 Handle<Object>(isolate_->debug()->debug_context_->global_proxy(), 3034 Handle<Object>(debug_context()->global_proxy(), isolate_),
3225 isolate_),
3226 ARRAY_SIZE(argv), 3035 ARRAY_SIZE(argv),
3227 argv); 3036 argv);
3228 } 3037 }
3229 3038
3230 3039
3231 EnterDebugger::EnterDebugger(Isolate* isolate) 3040 void Debug::HandleDebugBreak() {
3232 : isolate_(isolate), 3041 // Ignore debug break during bootstrapping.
3233 prev_(isolate_->debug()->debugger_entry()), 3042 if (isolate_->bootstrapper()->IsActive()) return;
3234 save_(isolate_) { 3043 // Just continue if breaks are disabled.
3235 Debug* debug = isolate_->debug(); 3044 if (break_disabled_) return;
3045 // Ignore debug break if debugger is not active.
3046 if (!is_active()) return;
3236 3047
3048 StackLimitCheck check(isolate_);
3049 if (check.HasOverflowed()) return;
3050
3051 { JavaScriptFrameIterator it(isolate_);
3052 ASSERT(!it.done());
3053 Object* fun = it.frame()->function();
3054 if (fun && fun->IsJSFunction()) {
3055 // Don't stop in builtin functions.
3056 if (JSFunction::cast(fun)->IsBuiltin()) return;
3057 GlobalObject* global = JSFunction::cast(fun)->context()->global_object();
3058 // Don't stop in debugger functions.
3059 if (IsDebugGlobal(global)) return;
3060 }
3061 }
3062
3063 // Collect the break state before clearing the flags.
3064 bool debug_command_only = isolate_->stack_guard()->CheckDebugCommand() &&
3065 !isolate_->stack_guard()->CheckDebugBreak();
3066
3067 isolate_->stack_guard()->ClearDebugBreak();
3068
3069 ProcessDebugMessages(debug_command_only);
3070 }
3071
3072
3073 void Debug::ProcessDebugMessages(bool debug_command_only) {
3074 isolate_->stack_guard()->ClearDebugCommand();
3075
3076 StackLimitCheck check(isolate_);
3077 if (check.HasOverflowed()) return;
3078
3079 HandleScope scope(isolate_);
3080 DebugScope debug_scope(this);
3081 if (debug_scope.failed()) return;
3082
3083 // Notify the debug event listeners. Indicate auto continue if the break was
3084 // a debug command break.
3085 OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only);
3086 }
3087
3088
3089 DebugScope::DebugScope(Debug* debug) : debug_(debug),
3090 prev_(debug->debugger_entry()),
3091 save_(debug_->isolate_) {
3237 // Link recursive debugger entry. 3092 // Link recursive debugger entry.
3238 debug->set_debugger_entry(this); 3093 debug_->thread_local_.current_debug_scope_ = this;
3239 3094
3240 // Store the previous break id and frame id. 3095 // Store the previous break id and frame id.
3241 break_id_ = debug->break_id(); 3096 break_id_ = debug_->break_id();
3242 break_frame_id_ = debug->break_frame_id(); 3097 break_frame_id_ = debug_->break_frame_id();
3243 3098
3244 // Create the new break info. If there is no JavaScript frames there is no 3099 // Create the new break info. If there is no JavaScript frames there is no
3245 // break frame id. 3100 // break frame id.
3246 JavaScriptFrameIterator it(isolate_); 3101 JavaScriptFrameIterator it(isolate());
3247 has_js_frames_ = !it.done(); 3102 bool has_js_frames = !it.done();
3248 debug->NewBreak(has_js_frames_ ? it.frame()->id() : StackFrame::NO_ID); 3103 debug_->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id()
3104 : StackFrame::NO_ID;
3105 debug_->SetNextBreakId();
3249 3106
3250 isolate_->debugger()->UpdateState(); 3107 debug_->UpdateState();
3251 // Make sure that debugger is loaded and enter the debugger context. 3108 // Make sure that debugger is loaded and enter the debugger context.
3252 // The previous context is kept in save_. 3109 // The previous context is kept in save_.
3253 load_failed_ = !debug->IsLoaded(); 3110 failed_ = !debug_->is_loaded();
3254 if (!load_failed_) isolate_->set_context(*debug->debug_context()); 3111 if (!failed_) isolate()->set_context(*debug->debug_context());
3255 } 3112 }
3256 3113
3257 3114
3258 EnterDebugger::~EnterDebugger() { 3115 DebugScope::~DebugScope() {
3259 Debug* debug = isolate_->debug();
3260
3261 // Leaving this debugger entry. 3116 // Leaving this debugger entry.
3262 debug->set_debugger_entry(prev_); 3117 debug_->thread_local_.current_debug_scope_ = prev_;
3263 3118
3264 // Restore to the previous break state. 3119 // Restore to the previous break state.
3265 debug->SetBreak(break_frame_id_, break_id_); 3120 debug_->thread_local_.break_frame_id_ = break_frame_id_;
3121 debug_->thread_local_.break_id_ = break_id_;
3266 3122
3267 // Check for leaving the debugger. 3123 // Check for leaving the debugger.
3268 if (!load_failed_ && prev_ == NULL) { 3124 if (!failed_ && prev_ == NULL) {
3269 // Clear mirror cache when leaving the debugger. Skip this if there is a 3125 // Clear mirror cache when leaving the debugger. Skip this if there is a
3270 // pending exception as clearing the mirror cache calls back into 3126 // pending exception as clearing the mirror cache calls back into
3271 // JavaScript. This can happen if the v8::Debug::Call is used in which 3127 // JavaScript. This can happen if the v8::Debug::Call is used in which
3272 // case the exception should end up in the calling code. 3128 // case the exception should end up in the calling code.
3273 if (!isolate_->has_pending_exception()) { 3129 if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache();
3274 // Try to avoid any pending debug break breaking in the clear mirror
3275 // cache JavaScript code.
3276 if (isolate_->stack_guard()->CheckDebugBreak()) {
3277 debug->set_has_pending_interrupt(true);
3278 isolate_->stack_guard()->ClearDebugBreak();
3279 }
3280 debug->ClearMirrorCache();
3281 }
3282
3283 // Request debug break when leaving the last debugger entry
3284 // if one was recorded while debugging.
3285 if (debug->has_pending_interrupt()) {
3286 debug->set_has_pending_interrupt(false);
3287 isolate_->stack_guard()->RequestDebugBreak();
3288 }
3289 3130
3290 // If there are commands in the queue when leaving the debugger request 3131 // If there are commands in the queue when leaving the debugger request
3291 // that these commands are processed. 3132 // that these commands are processed.
3292 if (isolate_->debugger()->HasCommands()) { 3133 if (debug_->has_commands()) isolate()->stack_guard()->RequestDebugCommand();
3293 isolate_->stack_guard()->RequestDebugCommand();
3294 }
3295 } 3134 }
3296 3135
3297 isolate_->debugger()->UpdateState(); 3136 debug_->UpdateState();
3298 } 3137 }
3299 3138
3300 3139
3301 MessageImpl MessageImpl::NewEvent(DebugEvent event, 3140 MessageImpl MessageImpl::NewEvent(DebugEvent event,
3302 bool running, 3141 bool running,
3303 Handle<JSObject> exec_state, 3142 Handle<JSObject> exec_state,
3304 Handle<JSObject> event_data) { 3143 Handle<JSObject> event_data) {
3305 MessageImpl message(true, event, running, 3144 MessageImpl message(true, event, running,
3306 exec_state, event_data, Handle<String>(), NULL); 3145 exec_state, event_data, Handle<String>(), NULL);
3307 return message; 3146 return message;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
3457 } 3296 }
3458 3297
3459 3298
3460 CommandMessage::CommandMessage(const Vector<uint16_t>& text, 3299 CommandMessage::CommandMessage(const Vector<uint16_t>& text,
3461 v8::Debug::ClientData* data) 3300 v8::Debug::ClientData* data)
3462 : text_(text), 3301 : text_(text),
3463 client_data_(data) { 3302 client_data_(data) {
3464 } 3303 }
3465 3304
3466 3305
3467 CommandMessage::~CommandMessage() {
3468 }
3469
3470
3471 void CommandMessage::Dispose() { 3306 void CommandMessage::Dispose() {
3472 text_.Dispose(); 3307 text_.Dispose();
3473 delete client_data_; 3308 delete client_data_;
3474 client_data_ = NULL; 3309 client_data_ = NULL;
3475 } 3310 }
3476 3311
3477 3312
3478 CommandMessage CommandMessage::New(const Vector<uint16_t>& command, 3313 CommandMessage CommandMessage::New(const Vector<uint16_t>& command,
3479 v8::Debug::ClientData* data) { 3314 v8::Debug::ClientData* data) {
3480 return CommandMessage(command.Clone(), data); 3315 return CommandMessage(command.Clone(), data);
3481 } 3316 }
3482 3317
3483 3318
3484 CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0), 3319 CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
3485 size_(size) { 3320 size_(size) {
3486 messages_ = NewArray<CommandMessage>(size); 3321 messages_ = NewArray<CommandMessage>(size);
3487 } 3322 }
3488 3323
3489 3324
3490 CommandMessageQueue::~CommandMessageQueue() { 3325 CommandMessageQueue::~CommandMessageQueue() {
3491 while (!IsEmpty()) { 3326 while (!IsEmpty()) Get().Dispose();
3492 CommandMessage m = Get();
3493 m.Dispose();
3494 }
3495 DeleteArray(messages_); 3327 DeleteArray(messages_);
3496 } 3328 }
3497 3329
3498 3330
3499 CommandMessage CommandMessageQueue::Get() { 3331 CommandMessage CommandMessageQueue::Get() {
3500 ASSERT(!IsEmpty()); 3332 ASSERT(!IsEmpty());
3501 int result = start_; 3333 int result = start_;
3502 start_ = (start_ + 1) % size_; 3334 start_ = (start_ + 1) % size_;
3503 return messages_[result]; 3335 return messages_[result];
3504 } 3336 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3551 logger_->DebugEvent("Put", message.text()); 3383 logger_->DebugEvent("Put", message.text());
3552 } 3384 }
3553 3385
3554 3386
3555 void LockingCommandMessageQueue::Clear() { 3387 void LockingCommandMessageQueue::Clear() {
3556 LockGuard<Mutex> lock_guard(&mutex_); 3388 LockGuard<Mutex> lock_guard(&mutex_);
3557 queue_.Clear(); 3389 queue_.Clear();
3558 } 3390 }
3559 3391
3560 } } // namespace v8::internal 3392 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/execution.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698