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

Side by Side Diff: src/debug.cc

Issue 435003: Patch for allowing several V8 instances in process:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years 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/disasm.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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 reloc_iterator_->next(); 496 reloc_iterator_->next();
497 reloc_iterator_original_->next(); 497 reloc_iterator_original_->next();
498 #ifdef DEBUG 498 #ifdef DEBUG
499 ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); 499 ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done());
500 if (!reloc_iterator_->done()) { 500 if (!reloc_iterator_->done()) {
501 ASSERT(rmode() == original_rmode()); 501 ASSERT(rmode() == original_rmode());
502 } 502 }
503 #endif 503 #endif
504 } 504 }
505 505
506 506 DebugData::DebugData()
507 bool Debug::has_break_points_ = false; 507 :has_break_points_(false),
508 ScriptCache* Debug::script_cache_ = NULL; 508 script_cache_(NULL),
509 DebugInfoListNode* Debug::debug_info_list_ = NULL; 509 debug_info_list_(NULL),
510 510 disable_break_(false),
511 break_on_exception_(false),
512 break_on_uncaught_exception_(true),
513 debug_context_(Handle<Context>()),
514 debug_break_return_(NULL) {
515 }
511 516
512 // Threading support. 517 // Threading support.
513 void Debug::ThreadInit() { 518 void Debug::ThreadInit() {
514 thread_local_.break_count_ = 0; 519 ThreadLocal& thread_local = v8_context()->debug_data_.thread_local_;
515 thread_local_.break_id_ = 0; 520 thread_local.break_count_ = 0;
516 thread_local_.break_frame_id_ = StackFrame::NO_ID; 521 thread_local.break_id_ = 0;
517 thread_local_.last_step_action_ = StepNone; 522 thread_local.break_frame_id_ = StackFrame::NO_ID;
518 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; 523 thread_local.last_step_action_ = StepNone;
519 thread_local_.step_count_ = 0; 524 thread_local.last_statement_position_ = RelocInfo::kNoPosition;
520 thread_local_.last_fp_ = 0; 525 thread_local.step_count_ = 0;
521 thread_local_.step_into_fp_ = 0; 526 thread_local.last_fp_ = 0;
522 thread_local_.step_out_fp_ = 0; 527 thread_local.step_into_fp_ = 0;
523 thread_local_.after_break_target_ = 0; 528 thread_local.step_out_fp_ = 0;
524 thread_local_.debugger_entry_ = NULL; 529 thread_local.after_break_target_ = 0;
525 thread_local_.pending_interrupts_ = 0; 530 thread_local.debugger_entry_ = NULL;
531 thread_local.pending_interrupts_ = 0;
526 } 532 }
527 533
528
529 JSCallerSavedBuffer Debug::registers_;
530 Debug::ThreadLocal Debug::thread_local_;
531
532
533 char* Debug::ArchiveDebug(char* storage) { 534 char* Debug::ArchiveDebug(char* storage) {
534 char* to = storage; 535 char* to = storage;
535 memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); 536 DebugData& data = v8_context()->debug_data_;
537 memcpy(to, reinterpret_cast<char*>(&data.thread_local_),
538 sizeof(ThreadLocal));
536 to += sizeof(ThreadLocal); 539 to += sizeof(ThreadLocal);
537 memcpy(to, reinterpret_cast<char*>(&registers_), sizeof(registers_)); 540 memcpy(to, reinterpret_cast<char*>(&data.registers_),
541 sizeof(JSCallerSavedBuffer));
538 ThreadInit(); 542 ThreadInit();
539 ASSERT(to <= storage + ArchiveSpacePerThread()); 543 ASSERT(to <= storage + ArchiveSpacePerThread());
540 return storage + ArchiveSpacePerThread(); 544 return storage + ArchiveSpacePerThread();
541 } 545 }
542 546
543 547
544 char* Debug::RestoreDebug(char* storage) { 548 char* Debug::RestoreDebug(char* storage) {
545 char* from = storage; 549 char* from = storage;
546 memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); 550 DebugData& data = v8_context()->debug_data_;
551 memcpy(reinterpret_cast<char*>(&data.thread_local_), from,
552 sizeof(ThreadLocal));
547 from += sizeof(ThreadLocal); 553 from += sizeof(ThreadLocal);
548 memcpy(reinterpret_cast<char*>(&registers_), from, sizeof(registers_)); 554 memcpy(reinterpret_cast<char*>(&data.registers_), from,
555 sizeof(JSCallerSavedBuffer));
549 ASSERT(from <= storage + ArchiveSpacePerThread()); 556 ASSERT(from <= storage + ArchiveSpacePerThread());
550 return storage + ArchiveSpacePerThread(); 557 return storage + ArchiveSpacePerThread();
551 } 558 }
552 559
553 560
554 int Debug::ArchiveSpacePerThread() { 561 int Debug::ArchiveSpacePerThread() {
555 return sizeof(ThreadLocal) + sizeof(registers_); 562 return sizeof(ThreadLocal) + sizeof(JSCallerSavedBuffer);
556 } 563 }
557 564
558
559 // Default break enabled.
560 bool Debug::disable_break_ = false;
561
562 // Default call debugger on uncaught exception.
563 bool Debug::break_on_exception_ = false;
564 bool Debug::break_on_uncaught_exception_ = true;
565
566 Handle<Context> Debug::debug_context_ = Handle<Context>();
567 Code* Debug::debug_break_return_ = NULL;
568
569
570 void ScriptCache::Add(Handle<Script> script) { 565 void ScriptCache::Add(Handle<Script> script) {
571 // Create an entry in the hash map for the script. 566 // Create an entry in the hash map for the script.
572 int id = Smi::cast(script->id())->value(); 567 int id = Smi::cast(script->id())->value();
573 HashMap::Entry* entry = 568 HashMap::Entry* entry =
574 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true); 569 HashMap::Lookup(reinterpret_cast<void*>(id), Hash(id), true);
575 if (entry->value != NULL) { 570 if (entry->value != NULL) {
576 ASSERT(*script == *reinterpret_cast<Script**>(entry->value)); 571 ASSERT(*script == *reinterpret_cast<Script**>(entry->value));
577 return; 572 return;
578 } 573 }
579 574
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 632
638 // Clear the weak handle. 633 // Clear the weak handle.
639 obj.Dispose(); 634 obj.Dispose();
640 obj.Clear(); 635 obj.Clear();
641 } 636 }
642 637
643 638
644 void Debug::Setup(bool create_heap_objects) { 639 void Debug::Setup(bool create_heap_objects) {
645 ThreadInit(); 640 ThreadInit();
646 if (create_heap_objects) { 641 if (create_heap_objects) {
642 DebugData& data = v8_context()->debug_data_;
647 // Get code to handle debug break on return. 643 // Get code to handle debug break on return.
648 debug_break_return_ = 644 data.debug_break_return_ =
649 Builtins::builtin(Builtins::Return_DebugBreak); 645 Builtins::builtin(Builtins::Return_DebugBreak);
650 ASSERT(debug_break_return_->IsCode()); 646 ASSERT(data.debug_break_return_->IsCode());
651 } 647 }
652 } 648 }
653 649
654 650
655 void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) { 651 void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) {
656 DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data); 652 DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data);
657 RemoveDebugInfo(node->debug_info()); 653 RemoveDebugInfo(node->debug_info());
658 #ifdef DEBUG 654 #ifdef DEBUG
659 node = Debug::debug_info_list_; 655 node = v8_context()->debug_data_.debug_info_list_;
660 while (node != NULL) { 656 while (node != NULL) {
661 ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data)); 657 ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data));
662 node = node->next(); 658 node = node->next();
663 } 659 }
664 #endif 660 #endif
665 } 661 }
666 662
667 663
668 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { 664 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
669 // Globalize the request debug info object and make it weak. 665 // Globalize the request debug info object and make it weak.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 Debugger::set_compiling_natives(false); 765 Debugger::set_compiling_natives(false);
770 766
771 // Make sure we mark the debugger as not loading before we might 767 // Make sure we mark the debugger as not loading before we might
772 // return. 768 // return.
773 Debugger::set_loading_debugger(false); 769 Debugger::set_loading_debugger(false);
774 770
775 // Check for caught exceptions. 771 // Check for caught exceptions.
776 if (caught_exception) return false; 772 if (caught_exception) return false;
777 773
778 // Debugger loaded. 774 // Debugger loaded.
779 debug_context_ = Handle<Context>::cast(GlobalHandles::Create(*context)); 775 v8_context()->debug_data_.debug_context_ =
776 Handle<Context>::cast(GlobalHandles::Create(*context));
780 777
781 return true; 778 return true;
782 } 779 }
783 780
784 781
785 void Debug::Unload() { 782 void Debug::Unload() {
786 // Return debugger is not loaded. 783 // Return debugger is not loaded.
787 if (!IsLoaded()) { 784 if (!IsLoaded()) {
788 return; 785 return;
789 } 786 }
790 787
791 // Clear the script cache. 788 // Clear the script cache.
792 DestroyScriptCache(); 789 DestroyScriptCache();
793 790
791 DebugData& data = v8_context()->debug_data_;
794 // Clear debugger context global handle. 792 // Clear debugger context global handle.
795 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location())); 793 GlobalHandles::Destroy(
796 debug_context_ = Handle<Context>(); 794 reinterpret_cast<Object**>(data.debug_context_.location()));
795 data.debug_context_ = Handle<Context>();
797 } 796 }
798 797
799 798
800 // Set the flag indicating that preemption happened during debugging. 799 // Set the flag indicating that preemption happened during debugging.
801 void Debug::PreemptionWhileInDebugger() { 800 void Debug::PreemptionWhileInDebugger() {
802 ASSERT(InDebugger()); 801 ASSERT(InDebugger());
803 Debug::set_interrupts_pending(PREEMPT); 802 Debug::set_interrupts_pending(PREEMPT);
804 } 803 }
805 804
806 805
807 void Debug::Iterate(ObjectVisitor* v) { 806 void Debug::Iterate(ObjectVisitor* v) {
808 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_))); 807 v->VisitPointer(bit_cast<Object**, Code**>(
808 &(v8_context()->debug_data_.debug_break_return_)));
809 } 809 }
810 810
811 811
812 Object* Debug::Break(Arguments args) { 812 Object* Debug::Break(Arguments args) {
813 HandleScope scope; 813 HandleScope scope;
814 ASSERT(args.length() == 0); 814 ASSERT(args.length() == 0);
815 815
816 // Get the top-most JavaScript frame. 816 // Get the top-most JavaScript frame.
817 JavaScriptFrameIterator it; 817 JavaScriptFrameIterator it;
818 JavaScriptFrame* frame = it.frame(); 818 JavaScriptFrame* frame = it.frame();
(...skipping 15 matching lines...) Expand all
834 834
835 // Get the debug info (create it if it does not exist). 835 // Get the debug info (create it if it does not exist).
836 Handle<SharedFunctionInfo> shared = 836 Handle<SharedFunctionInfo> shared =
837 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); 837 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
838 Handle<DebugInfo> debug_info = GetDebugInfo(shared); 838 Handle<DebugInfo> debug_info = GetDebugInfo(shared);
839 839
840 // Find the break point where execution has stopped. 840 // Find the break point where execution has stopped.
841 BreakLocationIterator break_location_iterator(debug_info, 841 BreakLocationIterator break_location_iterator(debug_info,
842 ALL_BREAK_LOCATIONS); 842 ALL_BREAK_LOCATIONS);
843 break_location_iterator.FindBreakLocationFromAddress(frame->pc()); 843 break_location_iterator.FindBreakLocationFromAddress(frame->pc());
844 ThreadLocal& thread_local = v8_context()->debug_data_.thread_local_;
844 845
845 // Check whether step next reached a new statement. 846 // Check whether step next reached a new statement.
846 if (!StepNextContinue(&break_location_iterator, frame)) { 847 if (!StepNextContinue(&break_location_iterator, frame)) {
847 // Decrease steps left if performing multiple steps. 848 // Decrease steps left if performing multiple steps.
848 if (thread_local_.step_count_ > 0) { 849 if (thread_local.step_count_ > 0) {
849 thread_local_.step_count_--; 850 thread_local.step_count_--;
850 } 851 }
851 } 852 }
852 853
853 // If there is one or more real break points check whether any of these are 854 // If there is one or more real break points check whether any of these are
854 // triggered. 855 // triggered.
855 Handle<Object> break_points_hit(Heap::undefined_value()); 856 Handle<Object> break_points_hit(Heap::undefined_value());
856 if (break_location_iterator.HasBreakPoint()) { 857 if (break_location_iterator.HasBreakPoint()) {
857 Handle<Object> break_point_objects = 858 Handle<Object> break_point_objects =
858 Handle<Object>(break_location_iterator.BreakPointObjects()); 859 Handle<Object>(break_location_iterator.BreakPointObjects());
859 break_points_hit = CheckBreakPoints(break_point_objects); 860 break_points_hit = CheckBreakPoints(break_point_objects);
860 } 861 }
861 862
862 // If step out is active skip everything until the frame where we need to step 863 // If step out is active skip everything until the frame where we need to step
863 // out to is reached, unless real breakpoint is hit. 864 // out to is reached, unless real breakpoint is hit.
864 if (Debug::StepOutActive() && frame->fp() != Debug::step_out_fp() && 865 if (Debug::StepOutActive() && frame->fp() != Debug::step_out_fp() &&
865 break_points_hit->IsUndefined() ) { 866 break_points_hit->IsUndefined() ) {
866 // Step count should always be 0 for StepOut. 867 // Step count should always be 0 for StepOut.
867 ASSERT(thread_local_.step_count_ == 0); 868 ASSERT(thread_local.step_count_ == 0);
868 } else if (!break_points_hit->IsUndefined() || 869 } else if (!break_points_hit->IsUndefined() ||
869 (thread_local_.last_step_action_ != StepNone && 870 (thread_local.last_step_action_ != StepNone &&
870 thread_local_.step_count_ == 0)) { 871 thread_local.step_count_ == 0)) {
871 // Notify debugger if a real break point is triggered or if performing 872 // Notify debugger if a real break point is triggered or if performing
872 // single stepping with no more steps to perform. Otherwise do another step. 873 // single stepping with no more steps to perform. Otherwise do another step.
873 874
874 // Clear all current stepping setup. 875 // Clear all current stepping setup.
875 ClearStepping(); 876 ClearStepping();
876 877
877 // Notify the debug event listeners. 878 // Notify the debug event listeners.
878 Debugger::OnDebugBreak(break_points_hit, false); 879 Debugger::OnDebugBreak(break_points_hit, false);
879 } else if (thread_local_.last_step_action_ != StepNone) { 880 } else if (thread_local.last_step_action_ != StepNone) {
880 // Hold on to last step action as it is cleared by the call to 881 // Hold on to last step action as it is cleared by the call to
881 // ClearStepping. 882 // ClearStepping.
882 StepAction step_action = thread_local_.last_step_action_; 883 StepAction step_action = thread_local.last_step_action_;
883 int step_count = thread_local_.step_count_; 884 int step_count = thread_local.step_count_;
884 885
885 // Clear all current stepping setup. 886 // Clear all current stepping setup.
886 ClearStepping(); 887 ClearStepping();
887 888
888 // Set up for the remaining steps. 889 // Set up for the remaining steps.
889 PrepareStep(step_action, step_count); 890 PrepareStep(step_action, step_count);
890 } 891 }
891 892
892 // Install jump to the call address which was overwritten. 893 // Install jump to the call address which was overwritten.
893 SetAfterBreakTarget(frame); 894 SetAfterBreakTarget(frame);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 it.SetBreakPoint(break_point_object); 1000 it.SetBreakPoint(break_point_object);
1000 1001
1001 // At least one active break point now. 1002 // At least one active break point now.
1002 ASSERT(debug_info->GetBreakPointCount() > 0); 1003 ASSERT(debug_info->GetBreakPointCount() > 0);
1003 } 1004 }
1004 1005
1005 1006
1006 void Debug::ClearBreakPoint(Handle<Object> break_point_object) { 1007 void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
1007 HandleScope scope; 1008 HandleScope scope;
1008 1009
1009 DebugInfoListNode* node = debug_info_list_; 1010 DebugData& data = v8_context()->debug_data_;
1011 DebugInfoListNode* node = data.debug_info_list_;
1010 while (node != NULL) { 1012 while (node != NULL) {
1011 Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(), 1013 Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(),
1012 break_point_object); 1014 break_point_object);
1013 if (!result->IsUndefined()) { 1015 if (!result->IsUndefined()) {
1014 // Get information in the break point. 1016 // Get information in the break point.
1015 BreakPointInfo* break_point_info = BreakPointInfo::cast(result); 1017 BreakPointInfo* break_point_info = BreakPointInfo::cast(result);
1016 Handle<DebugInfo> debug_info = node->debug_info(); 1018 Handle<DebugInfo> debug_info = node->debug_info();
1017 Handle<SharedFunctionInfo> shared(debug_info->shared()); 1019 Handle<SharedFunctionInfo> shared(debug_info->shared());
1018 int source_position = break_point_info->statement_position()->value(); 1020 int source_position = break_point_info->statement_position()->value();
1019 1021
(...skipping 12 matching lines...) Expand all
1032 } 1034 }
1033 1035
1034 return; 1036 return;
1035 } 1037 }
1036 node = node->next(); 1038 node = node->next();
1037 } 1039 }
1038 } 1040 }
1039 1041
1040 1042
1041 void Debug::ClearAllBreakPoints() { 1043 void Debug::ClearAllBreakPoints() {
1042 DebugInfoListNode* node = debug_info_list_; 1044 DebugData& data = v8_context()->debug_data_;
1045 DebugInfoListNode* node = data.debug_info_list_;
1043 while (node != NULL) { 1046 while (node != NULL) {
1044 // Remove all debug break code. 1047 // Remove all debug break code.
1045 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); 1048 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
1046 it.ClearAllDebugBreak(); 1049 it.ClearAllDebugBreak();
1047 node = node->next(); 1050 node = node->next();
1048 } 1051 }
1049 1052
1050 // Remove all debug info. 1053 // Remove all debug info.
1051 while (debug_info_list_ != NULL) { 1054 while (data.debug_info_list_ != NULL) {
1052 RemoveDebugInfo(debug_info_list_->debug_info()); 1055 RemoveDebugInfo(data.debug_info_list_->debug_info());
1053 } 1056 }
1054 } 1057 }
1055 1058
1056 1059
1057 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) { 1060 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) {
1058 // Make sure the function has setup the debug info. 1061 // Make sure the function has setup the debug info.
1059 if (!EnsureDebugInfo(shared)) { 1062 if (!EnsureDebugInfo(shared)) {
1060 // Return if we failed to retrieve the debug info. 1063 // Return if we failed to retrieve the debug info.
1061 return; 1064 return;
1062 } 1065 }
(...skipping 22 matching lines...) Expand all
1085 JSFunction::cast(frame->function())->shared()); 1088 JSFunction::cast(frame->function())->shared());
1086 // Flood the function with the catch block with break points 1089 // Flood the function with the catch block with break points
1087 FloodWithOneShot(shared); 1090 FloodWithOneShot(shared);
1088 return; 1091 return;
1089 } 1092 }
1090 } 1093 }
1091 } 1094 }
1092 1095
1093 1096
1094 void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) { 1097 void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) {
1098 DebugData& data = v8_context()->debug_data_;
1095 if (type == BreakUncaughtException) { 1099 if (type == BreakUncaughtException) {
1096 break_on_uncaught_exception_ = enable; 1100 data.break_on_uncaught_exception_ = enable;
1097 } else { 1101 } else {
1098 break_on_exception_ = enable; 1102 data.break_on_exception_ = enable;
1099 } 1103 }
1100 } 1104 }
1101 1105
1102 1106
1103 void Debug::PrepareStep(StepAction step_action, int step_count) { 1107 void Debug::PrepareStep(StepAction step_action, int step_count) {
1104 HandleScope scope; 1108 HandleScope scope;
1105 ASSERT(Debug::InDebugger()); 1109 ASSERT(Debug::InDebugger());
1110 ThreadLocal& thread_local = v8_context()->debug_data_.thread_local_;
1106 1111
1107 // Remember this step action and count. 1112 // Remember this step action and count.
1108 thread_local_.last_step_action_ = step_action; 1113 thread_local.last_step_action_ = step_action;
1109 if (step_action == StepOut) { 1114 if (step_action == StepOut) {
1110 // For step out target frame will be found on the stack so there is no need 1115 // For step out target frame will be found on the stack so there is no need
1111 // to set step counter for it. It's expected to always be 0 for StepOut. 1116 // to set step counter for it. It's expected to always be 0 for StepOut.
1112 thread_local_.step_count_ = 0; 1117 thread_local.step_count_ = 0;
1113 } else { 1118 } else {
1114 thread_local_.step_count_ = step_count; 1119 thread_local.step_count_ = step_count;
1115 } 1120 }
1116 1121
1117 // Get the frame where the execution has stopped and skip the debug frame if 1122 // Get the frame where the execution has stopped and skip the debug frame if
1118 // any. The debug frame will only be present if execution was stopped due to 1123 // any. The debug frame will only be present if execution was stopped due to
1119 // hitting a break point. In other situations (e.g. unhandled exception) the 1124 // hitting a break point. In other situations (e.g. unhandled exception) the
1120 // debug frame is not present. 1125 // debug frame is not present.
1121 StackFrame::Id id = break_frame_id(); 1126 StackFrame::Id id = break_frame_id();
1122 if (id == StackFrame::NO_ID) { 1127 if (id == StackFrame::NO_ID) {
1123 // If there is no JavaScript stack don't do anything. 1128 // If there is no JavaScript stack don't do anything.
1124 return; 1129 return;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 } 1221 }
1217 } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) || 1222 } else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) ||
1218 !call_function_stub.is_null()) 1223 !call_function_stub.is_null())
1219 || step_action == StepNext || step_action == StepMin) { 1224 || step_action == StepNext || step_action == StepMin) {
1220 // Step next or step min. 1225 // Step next or step min.
1221 1226
1222 // Fill the current function with one-shot break points. 1227 // Fill the current function with one-shot break points.
1223 FloodWithOneShot(shared); 1228 FloodWithOneShot(shared);
1224 1229
1225 // Remember source position and frame to handle step next. 1230 // Remember source position and frame to handle step next.
1226 thread_local_.last_statement_position_ = 1231 thread_local.last_statement_position_ =
1227 debug_info->code()->SourceStatementPosition(frame->pc()); 1232 debug_info->code()->SourceStatementPosition(frame->pc());
1228 thread_local_.last_fp_ = frame->fp(); 1233 thread_local.last_fp_ = frame->fp();
1229 } else { 1234 } else {
1230 // If it's CallFunction stub ensure target function is compiled and flood 1235 // If it's CallFunction stub ensure target function is compiled and flood
1231 // it with one shot breakpoints. 1236 // it with one shot breakpoints.
1232 if (!call_function_stub.is_null()) { 1237 if (!call_function_stub.is_null()) {
1233 // Find out number of arguments from the stub minor key. 1238 // Find out number of arguments from the stub minor key.
1234 // Reverse lookup required as the minor key cannot be retrieved 1239 // Reverse lookup required as the minor key cannot be retrieved
1235 // from the code object. 1240 // from the code object.
1236 Handle<Object> obj( 1241 Handle<Object> obj(
1237 Heap::code_stubs()->SlowReverseLookup(*call_function_stub)); 1242 Heap::code_stubs()->SlowReverseLookup(*call_function_stub));
1238 ASSERT(*obj != Heap::undefined_value()); 1243 ASSERT(*obj != Heap::undefined_value());
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 // a call target as the function called might be a native function for 1275 // a call target as the function called might be a native function for
1271 // which step in will not stop. It also prepares for stepping in 1276 // which step in will not stop. It also prepares for stepping in
1272 // getters/setters. 1277 // getters/setters.
1273 FloodWithOneShot(shared); 1278 FloodWithOneShot(shared);
1274 1279
1275 if (is_load_or_store) { 1280 if (is_load_or_store) {
1276 // Remember source position and frame to handle step in getter/setter. If 1281 // Remember source position and frame to handle step in getter/setter. If
1277 // there is a custom getter/setter it will be handled in 1282 // there is a custom getter/setter it will be handled in
1278 // Object::Get/SetPropertyWithCallback, otherwise the step action will be 1283 // Object::Get/SetPropertyWithCallback, otherwise the step action will be
1279 // propagated on the next Debug::Break. 1284 // propagated on the next Debug::Break.
1280 thread_local_.last_statement_position_ = 1285 thread_local.last_statement_position_ =
1281 debug_info->code()->SourceStatementPosition(frame->pc()); 1286 debug_info->code()->SourceStatementPosition(frame->pc());
1282 thread_local_.last_fp_ = frame->fp(); 1287 thread_local.last_fp_ = frame->fp();
1283 } 1288 }
1284 1289
1285 // Step in or Step in min 1290 // Step in or Step in min
1286 it.PrepareStepIn(); 1291 it.PrepareStepIn();
1287 ActivateStepIn(frame); 1292 ActivateStepIn(frame);
1288 } 1293 }
1289 } 1294 }
1290 1295
1291 1296
1292 // Check whether the current debug break should be reported to the debugger. It 1297 // Check whether the current debug break should be reported to the debugger. It
1293 // is used to have step next and step in only report break back to the debugger 1298 // is used to have step next and step in only report break back to the debugger
1294 // if on a different frame or in a different statement. In some situations 1299 // if on a different frame or in a different statement. In some situations
1295 // there will be several break points in the same statement when the code is 1300 // there will be several break points in the same statement when the code is
1296 // flooded with one-shot break points. This function helps to perform several 1301 // flooded with one-shot break points. This function helps to perform several
1297 // steps before reporting break back to the debugger. 1302 // steps before reporting break back to the debugger.
1298 bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator, 1303 bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator,
1299 JavaScriptFrame* frame) { 1304 JavaScriptFrame* frame) {
1305 ThreadLocal& thread_local = v8_context()->debug_data_.thread_local_;
1300 // If the step last action was step next or step in make sure that a new 1306 // If the step last action was step next or step in make sure that a new
1301 // statement is hit. 1307 // statement is hit.
1302 if (thread_local_.last_step_action_ == StepNext || 1308 if (thread_local.last_step_action_ == StepNext ||
1303 thread_local_.last_step_action_ == StepIn) { 1309 thread_local.last_step_action_ == StepIn) {
1304 // Never continue if returning from function. 1310 // Never continue if returning from function.
1305 if (break_location_iterator->IsExit()) return false; 1311 if (break_location_iterator->IsExit()) return false;
1306 1312
1307 // Continue if we are still on the same frame and in the same statement. 1313 // Continue if we are still on the same frame and in the same statement.
1308 int current_statement_position = 1314 int current_statement_position =
1309 break_location_iterator->code()->SourceStatementPosition(frame->pc()); 1315 break_location_iterator->code()->SourceStatementPosition(frame->pc());
1310 return thread_local_.last_fp_ == frame->fp() && 1316 return thread_local.last_fp_ == frame->fp() &&
1311 thread_local_.last_statement_position_ == current_statement_position; 1317 thread_local.last_statement_position_ == current_statement_position;
1312 } 1318 }
1313 1319
1314 // No step next action - don't continue. 1320 // No step next action - don't continue.
1315 return false; 1321 return false;
1316 } 1322 }
1317 1323
1318 1324
1319 // Check whether the code object at the specified address is a debug break code 1325 // Check whether the code object at the specified address is a debug break code
1320 // object. 1326 // object.
1321 bool Debug::IsDebugBreak(Address addr) { 1327 bool Debug::IsDebugBreak(Address addr) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 if (break_point_info->GetBreakPointCount() > 0) { 1408 if (break_point_info->GetBreakPointCount() > 0) {
1403 locations->set(count++, break_point_info->statement_position()); 1409 locations->set(count++, break_point_info->statement_position());
1404 } 1410 }
1405 } 1411 }
1406 } 1412 }
1407 return locations; 1413 return locations;
1408 } 1414 }
1409 1415
1410 1416
1411 void Debug::NewBreak(StackFrame::Id break_frame_id) { 1417 void Debug::NewBreak(StackFrame::Id break_frame_id) {
1412 thread_local_.break_frame_id_ = break_frame_id; 1418 ThreadLocal& thread_local = v8_context()->debug_data_.thread_local_;
1413 thread_local_.break_id_ = ++thread_local_.break_count_; 1419 thread_local.break_frame_id_ = break_frame_id;
1420 thread_local.break_id_ = ++thread_local.break_count_;
1414 } 1421 }
1415 1422
1416 1423
1417 void Debug::SetBreak(StackFrame::Id break_frame_id, int break_id) { 1424 void Debug::SetBreak(StackFrame::Id break_frame_id, int break_id) {
1418 thread_local_.break_frame_id_ = break_frame_id; 1425 ThreadLocal& thread_local = v8_context()->debug_data_.thread_local_;
1419 thread_local_.break_id_ = break_id; 1426 thread_local.break_frame_id_ = break_frame_id;
1427 thread_local.break_id_ = break_id;
1420 } 1428 }
1421 1429
1422 1430
1423 // Handle stepping into a function. 1431 // Handle stepping into a function.
1424 void Debug::HandleStepIn(Handle<JSFunction> function, 1432 void Debug::HandleStepIn(Handle<JSFunction> function,
1425 Handle<Object> holder, 1433 Handle<Object> holder,
1426 Address fp, 1434 Address fp,
1427 bool is_constructor) { 1435 bool is_constructor) {
1428 // If the frame pointer is not supplied by the caller find it. 1436 // If the frame pointer is not supplied by the caller find it.
1429 if (fp == 0) { 1437 if (fp == 0) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 1473
1466 1474
1467 void Debug::ClearStepping() { 1475 void Debug::ClearStepping() {
1468 // Clear the various stepping setup. 1476 // Clear the various stepping setup.
1469 ClearOneShot(); 1477 ClearOneShot();
1470 ClearStepIn(); 1478 ClearStepIn();
1471 ClearStepOut(); 1479 ClearStepOut();
1472 ClearStepNext(); 1480 ClearStepNext();
1473 1481
1474 // Clear multiple step counter. 1482 // Clear multiple step counter.
1475 thread_local_.step_count_ = 0; 1483 v8_context()->debug_data_.thread_local_.step_count_ = 0;
1476 } 1484 }
1477 1485
1478 // Clears all the one-shot break points that are currently set. Normally this 1486 // Clears all the one-shot break points that are currently set. Normally this
1479 // function is called each time a break point is hit as one shot break points 1487 // function is called each time a break point is hit as one shot break points
1480 // are used to support stepping. 1488 // are used to support stepping.
1481 void Debug::ClearOneShot() { 1489 void Debug::ClearOneShot() {
1482 // The current implementation just runs through all the breakpoints. When the 1490 // The current implementation just runs through all the breakpoints. When the
1483 // last break point for a function is removed that function is automatically 1491 // last break point for a function is removed that function is automatically
1484 // removed from the list. 1492 // removed from the list.
1485 1493
1486 DebugInfoListNode* node = debug_info_list_; 1494 DebugInfoListNode* node = v8_context()->debug_data_.debug_info_list_;
1487 while (node != NULL) { 1495 while (node != NULL) {
1488 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); 1496 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
1489 while (!it.Done()) { 1497 while (!it.Done()) {
1490 it.ClearOneShot(); 1498 it.ClearOneShot();
1491 it.Next(); 1499 it.Next();
1492 } 1500 }
1493 node = node->next(); 1501 node = node->next();
1494 } 1502 }
1495 } 1503 }
1496 1504
1497 1505
1498 void Debug::ActivateStepIn(StackFrame* frame) { 1506 void Debug::ActivateStepIn(StackFrame* frame) {
1499 ASSERT(!StepOutActive()); 1507 ASSERT(!StepOutActive());
1500 thread_local_.step_into_fp_ = frame->fp(); 1508 v8_context()->debug_data_.thread_local_.step_into_fp_ = frame->fp();
1501 } 1509 }
1502 1510
1503 1511
1504 void Debug::ClearStepIn() { 1512 void Debug::ClearStepIn() {
1505 thread_local_.step_into_fp_ = 0; 1513 v8_context()->debug_data_.thread_local_.step_into_fp_ = 0;
1506 } 1514 }
1507 1515
1508 1516
1509 void Debug::ActivateStepOut(StackFrame* frame) { 1517 void Debug::ActivateStepOut(StackFrame* frame) {
1510 ASSERT(!StepInActive()); 1518 ASSERT(!StepInActive());
1511 thread_local_.step_out_fp_ = frame->fp(); 1519 v8_context()->debug_data_.thread_local_.step_out_fp_ = frame->fp();
1512 } 1520 }
1513 1521
1514 1522
1515 void Debug::ClearStepOut() { 1523 void Debug::ClearStepOut() {
1516 thread_local_.step_out_fp_ = 0; 1524 v8_context()->debug_data_.thread_local_.step_out_fp_ = 0;
1517 } 1525 }
1518 1526
1519 1527
1520 void Debug::ClearStepNext() { 1528 void Debug::ClearStepNext() {
1521 thread_local_.last_step_action_ = StepNone; 1529 ThreadLocal& thread_local = v8_context()->debug_data_.thread_local_;
1522 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; 1530 thread_local.last_step_action_ = StepNone;
1523 thread_local_.last_fp_ = 0; 1531 thread_local.last_statement_position_ = RelocInfo::kNoPosition;
1532 thread_local.last_fp_ = 0;
1524 } 1533 }
1525 1534
1526 1535
1527 bool Debug::EnsureCompiled(Handle<SharedFunctionInfo> shared) { 1536 bool Debug::EnsureCompiled(Handle<SharedFunctionInfo> shared) {
1528 if (shared->is_compiled()) return true; 1537 if (shared->is_compiled()) return true;
1529 return CompileLazyShared(shared, CLEAR_EXCEPTION, 0); 1538 return CompileLazyShared(shared, CLEAR_EXCEPTION, 0);
1530 } 1539 }
1531 1540
1532 1541
1533 // Ensures the debug information is present for shared. 1542 // Ensures the debug information is present for shared.
1534 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) { 1543 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) {
1535 // Return if we already have the debug info for shared. 1544 // Return if we already have the debug info for shared.
1536 if (HasDebugInfo(shared)) return true; 1545 if (HasDebugInfo(shared)) return true;
1537 1546
1538 // Ensure shared in compiled. Return false if this failed. 1547 // Ensure shared in compiled. Return false if this failed.
1539 if (!EnsureCompiled(shared)) return false; 1548 if (!EnsureCompiled(shared)) return false;
1540 1549
1541 // Create the debug info object. 1550 // Create the debug info object.
1542 Handle<DebugInfo> debug_info = Factory::NewDebugInfo(shared); 1551 Handle<DebugInfo> debug_info = Factory::NewDebugInfo(shared);
1543 1552
1544 // Add debug info to the list. 1553 // Add debug info to the list.
1545 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); 1554 DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
1546 node->set_next(debug_info_list_); 1555 DebugData& data = v8_context()->debug_data_;
1547 debug_info_list_ = node; 1556 node->set_next(data.debug_info_list_);
1557 data.debug_info_list_ = node;
1548 1558
1549 // Now there is at least one break point. 1559 // Now there is at least one break point.
1550 has_break_points_ = true; 1560 data.has_break_points_ = true;
1551 1561
1552 return true; 1562 return true;
1553 } 1563 }
1554 1564
1555 1565
1556 void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) { 1566 void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) {
1557 ASSERT(debug_info_list_ != NULL); 1567 DebugData& data = v8_context()->debug_data_;
1568 ASSERT(data.debug_info_list_ != NULL);
1558 // Run through the debug info objects to find this one and remove it. 1569 // Run through the debug info objects to find this one and remove it.
1559 DebugInfoListNode* prev = NULL; 1570 DebugInfoListNode* prev = NULL;
1560 DebugInfoListNode* current = debug_info_list_; 1571 DebugInfoListNode* current = data.debug_info_list_;
1561 while (current != NULL) { 1572 while (current != NULL) {
1562 if (*current->debug_info() == *debug_info) { 1573 if (*current->debug_info() == *debug_info) {
1563 // Unlink from list. If prev is NULL we are looking at the first element. 1574 // Unlink from list. If prev is NULL we are looking at the first element.
1564 if (prev == NULL) { 1575 if (prev == NULL) {
1565 debug_info_list_ = current->next(); 1576 data.debug_info_list_ = current->next();
1566 } else { 1577 } else {
1567 prev->set_next(current->next()); 1578 prev->set_next(current->next());
1568 } 1579 }
1569 current->debug_info()->shared()->set_debug_info(Heap::undefined_value()); 1580 current->debug_info()->shared()->set_debug_info(Heap::undefined_value());
1570 delete current; 1581 delete current;
1571 1582
1572 // If there are no more debug info objects there are not more break 1583 // If there are no more debug info objects there are not more break
1573 // points. 1584 // points.
1574 has_break_points_ = debug_info_list_ != NULL; 1585 data.has_break_points_ = data.debug_info_list_ != NULL;
1575 1586
1576 return; 1587 return;
1577 } 1588 }
1578 // Move to next in list. 1589 // Move to next in list.
1579 prev = current; 1590 prev = current;
1580 current = current->next(); 1591 current = current->next();
1581 } 1592 }
1582 UNREACHABLE(); 1593 UNREACHABLE();
1583 } 1594 }
1584 1595
(...skipping 28 matching lines...) Expand all
1613 RelocIterator it(debug_info->code()); 1624 RelocIterator it(debug_info->code());
1614 while (!it.done()) { 1625 while (!it.done()) {
1615 if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) { 1626 if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
1616 at_js_return = (it.rinfo()->pc() == 1627 at_js_return = (it.rinfo()->pc() ==
1617 addr - Assembler::kPatchReturnSequenceAddressOffset); 1628 addr - Assembler::kPatchReturnSequenceAddressOffset);
1618 break_at_js_return_active = it.rinfo()->IsPatchedReturnSequence(); 1629 break_at_js_return_active = it.rinfo()->IsPatchedReturnSequence();
1619 } 1630 }
1620 it.next(); 1631 it.next();
1621 } 1632 }
1622 1633
1634 ThreadLocal& thread_local = v8_context()->debug_data_.thread_local_;
1623 // Handle the jump to continue execution after break point depending on the 1635 // Handle the jump to continue execution after break point depending on the
1624 // break location. 1636 // break location.
1625 if (at_js_return) { 1637 if (at_js_return) {
1626 // If the break point as return is still active jump to the corresponding 1638 // If the break point as return is still active jump to the corresponding
1627 // place in the original code. If not the break point was removed during 1639 // place in the original code. If not the break point was removed during
1628 // break point processing. 1640 // break point processing.
1629 if (break_at_js_return_active) { 1641 if (break_at_js_return_active) {
1630 addr += original_code->instruction_start() - code->instruction_start(); 1642 addr += original_code->instruction_start() - code->instruction_start();
1631 } 1643 }
1632 1644
1633 // Move back to where the call instruction sequence started. 1645 // Move back to where the call instruction sequence started.
1634 thread_local_.after_break_target_ = 1646 thread_local.after_break_target_ =
1635 addr - Assembler::kPatchReturnSequenceAddressOffset; 1647 addr - Assembler::kPatchReturnSequenceAddressOffset;
1636 } else { 1648 } else {
1637 // Check if there still is a debug break call at the target address. If the 1649 // Check if there still is a debug break call at the target address. If the
1638 // break point has been removed it will have disappeared. If it have 1650 // break point has been removed it will have disappeared. If it have
1639 // disappeared don't try to look in the original code as the running code 1651 // disappeared don't try to look in the original code as the running code
1640 // will have the right address. This takes care of the case where the last 1652 // will have the right address. This takes care of the case where the last
1641 // break point is removed from the function and therefore no "original code" 1653 // break point is removed from the function and therefore no "original code"
1642 // is available. If the debug break call is still there find the address in 1654 // is available. If the debug break call is still there find the address in
1643 // the original code. 1655 // the original code.
1644 if (IsDebugBreak(Assembler::target_address_at(addr))) { 1656 if (IsDebugBreak(Assembler::target_address_at(addr))) {
1645 // If the break point is still there find the call address which was 1657 // If the break point is still there find the call address which was
1646 // overwritten in the original code by the call to DebugBreakXXX. 1658 // overwritten in the original code by the call to DebugBreakXXX.
1647 1659
1648 // Find the corresponding address in the original code. 1660 // Find the corresponding address in the original code.
1649 addr += original_code->instruction_start() - code->instruction_start(); 1661 addr += original_code->instruction_start() - code->instruction_start();
1650 } 1662 }
1651 1663
1652 // Install jump to the call address in the original code. This will be the 1664 // Install jump to the call address in the original code. This will be the
1653 // call which was overwritten by the call to DebugBreakXXX. 1665 // call which was overwritten by the call to DebugBreakXXX.
1654 thread_local_.after_break_target_ = Assembler::target_address_at(addr); 1666 thread_local.after_break_target_ = Assembler::target_address_at(addr);
1655 } 1667 }
1656 } 1668 }
1657 1669
1658 1670
1659 bool Debug::IsDebugGlobal(GlobalObject* global) { 1671 bool Debug::IsDebugGlobal(GlobalObject* global) {
1660 return IsLoaded() && global == Debug::debug_context()->global(); 1672 return IsLoaded() && global == Debug::debug_context()->global();
1661 } 1673 }
1662 1674
1663 1675
1664 void Debug::ClearMirrorCache() { 1676 void Debug::ClearMirrorCache() {
(...skipping 15 matching lines...) Expand all
1680 1692
1681 void Debug::CreateScriptCache() { 1693 void Debug::CreateScriptCache() {
1682 HandleScope scope; 1694 HandleScope scope;
1683 1695
1684 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets 1696 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
1685 // rid of all the cached script wrappers and the second gets rid of the 1697 // rid of all the cached script wrappers and the second gets rid of the
1686 // scripts which is no longer referenced. 1698 // scripts which is no longer referenced.
1687 Heap::CollectAllGarbage(false); 1699 Heap::CollectAllGarbage(false);
1688 Heap::CollectAllGarbage(false); 1700 Heap::CollectAllGarbage(false);
1689 1701
1690 ASSERT(script_cache_ == NULL); 1702 DebugData& data = v8_context()->debug_data_;
1691 script_cache_ = new ScriptCache(); 1703 ASSERT(data.script_cache_ == NULL);
1704 data.script_cache_ = new ScriptCache();
1692 1705
1693 // Scan heap for Script objects. 1706 // Scan heap for Script objects.
1694 int count = 0; 1707 int count = 0;
1695 HeapIterator iterator; 1708 HeapIterator iterator;
1696 while (iterator.has_next()) { 1709 while (iterator.has_next()) {
1697 HeapObject* obj = iterator.next(); 1710 HeapObject* obj = iterator.next();
1698 ASSERT(obj != NULL); 1711 ASSERT(obj != NULL);
1699 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { 1712 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
1700 script_cache_->Add(Handle<Script>(Script::cast(obj))); 1713 data.script_cache_->Add(Handle<Script>(Script::cast(obj)));
1701 count++; 1714 count++;
1702 } 1715 }
1703 } 1716 }
1704 } 1717 }
1705 1718
1706 1719
1707 void Debug::DestroyScriptCache() { 1720 void Debug::DestroyScriptCache() {
1721 DebugData& data = v8_context()->debug_data_;
1708 // Get rid of the script cache if it was created. 1722 // Get rid of the script cache if it was created.
1709 if (script_cache_ != NULL) { 1723 if (data.script_cache_ != NULL) {
1710 delete script_cache_; 1724 delete data.script_cache_;
1711 script_cache_ = NULL; 1725 data.script_cache_ = NULL;
1712 } 1726 }
1713 } 1727 }
1714 1728
1715 1729
1716 void Debug::AddScriptToScriptCache(Handle<Script> script) { 1730 void Debug::AddScriptToScriptCache(Handle<Script> script) {
1717 if (script_cache_ != NULL) { 1731 DebugData& data = v8_context()->debug_data_;
1718 script_cache_->Add(script); 1732 if (data.script_cache_ != NULL) {
1733 data.script_cache_->Add(script);
1719 } 1734 }
1720 } 1735 }
1721 1736
1722 1737
1723 Handle<FixedArray> Debug::GetLoadedScripts() { 1738 Handle<FixedArray> Debug::GetLoadedScripts() {
1739 DebugData& data = v8_context()->debug_data_;
1724 // Create and fill the script cache when the loaded scripts is requested for 1740 // Create and fill the script cache when the loaded scripts is requested for
1725 // the first time. 1741 // the first time.
1726 if (script_cache_ == NULL) { 1742 if (data.script_cache_ == NULL) {
1727 CreateScriptCache(); 1743 CreateScriptCache();
1728 } 1744 }
1729 1745
1730 // If the script cache is not active just return an empty array. 1746 // If the script cache is not active just return an empty array.
1731 ASSERT(script_cache_ != NULL); 1747 ASSERT(data.script_cache_ != NULL);
1732 if (script_cache_ == NULL) { 1748 if (data.script_cache_ == NULL) {
1733 Factory::NewFixedArray(0); 1749 Factory::NewFixedArray(0);
1734 } 1750 }
1735 1751
1736 // Perform GC to get unreferenced scripts evicted from the cache before 1752 // Perform GC to get unreferenced scripts evicted from the cache before
1737 // returning the content. 1753 // returning the content.
1738 Heap::CollectAllGarbage(false); 1754 Heap::CollectAllGarbage(false);
1739 1755
1740 // Get the scripts from the cache. 1756 // Get the scripts from the cache.
1741 return script_cache_->GetScripts(); 1757 return data.script_cache_->GetScripts();
1742 } 1758 }
1743 1759
1744 1760
1745 void Debug::AfterGarbageCollection() { 1761 void Debug::AfterGarbageCollection() {
1762 DebugData& data = v8_context()->debug_data_;
1746 // Generate events for collected scripts. 1763 // Generate events for collected scripts.
1747 if (script_cache_ != NULL) { 1764 if (data.script_cache_ != NULL) {
1748 script_cache_->ProcessCollectedScripts(); 1765 data.script_cache_->ProcessCollectedScripts();
1749 } 1766 }
1750 } 1767 }
1751 1768
1752 1769 DebuggerData::DebuggerData()
1753 Mutex* Debugger::debugger_access_ = OS::CreateMutex(); 1770 :debugger_access_(OS::CreateMutex()),
1754 Handle<Object> Debugger::event_listener_ = Handle<Object>(); 1771 event_listener_(Handle<Object>()),
1755 Handle<Object> Debugger::event_listener_data_ = Handle<Object>(); 1772 event_listener_data_(Handle<Object>()),
1756 bool Debugger::compiling_natives_ = false; 1773 compiling_natives_(false),
1757 bool Debugger::is_loading_debugger_ = false; 1774 is_loading_debugger_(false),
1758 bool Debugger::never_unload_debugger_ = false; 1775 never_unload_debugger_(false),
1759 v8::Debug::MessageHandler2 Debugger::message_handler_ = NULL; 1776 message_handler_(NULL),
1760 bool Debugger::debugger_unload_pending_ = false; 1777 debugger_unload_pending_(false),
1761 v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL; 1778 host_dispatch_handler_(NULL),
1762 v8::Debug::DebugMessageDispatchHandler 1779 host_dispatch_micros_(100 * 1000),
1763 Debugger::debug_message_dispatch_handler_ = NULL; 1780 agent_(NULL),
1764 int Debugger::host_dispatch_micros_ = 100 * 1000; 1781 command_queue_(kQueueInitialSize),
1765 DebuggerAgent* Debugger::agent_ = NULL; 1782 command_received_(OS::CreateSemaphore(0)) {
1766 LockingCommandMessageQueue Debugger::command_queue_(kQueueInitialSize); 1783 }
1767 Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0);
1768
1769 1784
1770 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, 1785 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name,
1771 int argc, Object*** argv, 1786 int argc, Object*** argv,
1772 bool* caught_exception) { 1787 bool* caught_exception) {
1773 ASSERT(Top::context() == *Debug::debug_context()); 1788 ASSERT(Top::context() == *Debug::debug_context());
1774 1789
1775 // Create the execution state object. 1790 // Create the execution state object.
1776 Handle<String> constructor_str = Factory::LookupSymbol(constructor_name); 1791 Handle<String> constructor_str = Factory::LookupSymbol(constructor_name);
1777 Handle<Object> constructor(Top::global()->GetProperty(*constructor_str)); 1792 Handle<Object> constructor(Top::global()->GetProperty(*constructor_str));
1778 ASSERT(constructor->IsJSFunction()); 1793 ASSERT(constructor->IsJSFunction());
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
2100 if (!auto_continue) { 2115 if (!auto_continue) {
2101 Debug::clear_interrupt_pending(DEBUGBREAK); 2116 Debug::clear_interrupt_pending(DEBUGBREAK);
2102 } 2117 }
2103 2118
2104 // Create the execution state. 2119 // Create the execution state.
2105 bool caught_exception = false; 2120 bool caught_exception = false;
2106 Handle<Object> exec_state = MakeExecutionState(&caught_exception); 2121 Handle<Object> exec_state = MakeExecutionState(&caught_exception);
2107 if (caught_exception) { 2122 if (caught_exception) {
2108 return; 2123 return;
2109 } 2124 }
2125
2126 DebuggerData& data = v8_context()->debugger_data_;
2110 // First notify the message handler if any. 2127 // First notify the message handler if any.
2111 if (message_handler_ != NULL) { 2128 if (data.message_handler_ != NULL) {
2112 NotifyMessageHandler(event, 2129 NotifyMessageHandler(event,
2113 Handle<JSObject>::cast(exec_state), 2130 Handle<JSObject>::cast(exec_state),
2114 event_data, 2131 event_data,
2115 auto_continue); 2132 auto_continue);
2116 } 2133 }
2117 // Notify registered debug event listener. This can be either a C or a 2134 // Notify registered debug event listener. This can be either a C or a
2118 // JavaScript function. 2135 // JavaScript function.
2119 if (!event_listener_.is_null()) { 2136 if (!data.event_listener_.is_null()) {
2120 if (event_listener_->IsProxy()) { 2137 if (data.event_listener_->IsProxy()) {
2121 // C debug event listener. 2138 // C debug event listener.
2122 Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_)); 2139 Handle<Proxy> callback_obj(Handle<Proxy>::cast(data.event_listener_));
2123 v8::Debug::EventCallback callback = 2140 v8::Debug::EventCallback callback =
2124 FUNCTION_CAST<v8::Debug::EventCallback>(callback_obj->proxy()); 2141 FUNCTION_CAST<v8::Debug::EventCallback>(callback_obj->proxy());
2125 callback(event, 2142 callback(event,
2126 v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)), 2143 v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)),
2127 v8::Utils::ToLocal(event_data), 2144 v8::Utils::ToLocal(event_data),
2128 v8::Utils::ToLocal(Handle<Object>::cast(event_listener_data_))); 2145 v8::Utils::ToLocal(Handle<Object>::cast(
2146 data.event_listener_data_)));
2129 } else { 2147 } else {
2130 // JavaScript debug event listener. 2148 // JavaScript debug event listener.
2131 ASSERT(event_listener_->IsJSFunction()); 2149 ASSERT(data.event_listener_->IsJSFunction());
2132 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_)); 2150 Handle<JSFunction> fun(Handle<JSFunction>::cast(data.event_listener_));
2133 2151
2134 // Invoke the JavaScript debug event listener. 2152 // Invoke the JavaScript debug event listener.
2135 const int argc = 4; 2153 const int argc = 4;
2136 Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(), 2154 Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(),
2137 exec_state.location(), 2155 exec_state.location(),
2138 Handle<Object>::cast(event_data).location(), 2156 Handle<Object>::cast(event_data).location(),
2139 event_listener_data_.location() }; 2157 data.event_listener_data_.location() };
2140 Handle<Object> result = Execution::TryCall(fun, Top::global(), 2158 Handle<Object> result = Execution::TryCall(fun, Top::global(),
2141 argc, argv, &caught_exception); 2159 argc, argv, &caught_exception);
2142 // Silently ignore exceptions from debug event listeners. 2160 // Silently ignore exceptions from debug event listeners.
2143 } 2161 }
2144 } 2162 }
2145 } 2163 }
2146 2164
2147 2165
2148 void Debugger::UnloadDebugger() { 2166 void Debugger::UnloadDebugger() {
2149 // Make sure that there are no breakpoints left. 2167 // Make sure that there are no breakpoints left.
2150 Debug::ClearAllBreakPoints(); 2168 Debug::ClearAllBreakPoints();
2151 2169
2170 DebuggerData& data = v8_context()->debugger_data_;
2152 // Unload the debugger if feasible. 2171 // Unload the debugger if feasible.
2153 if (!never_unload_debugger_) { 2172 if (!data.never_unload_debugger_) {
2154 Debug::Unload(); 2173 Debug::Unload();
2155 } 2174 }
2156 2175
2157 // Clear the flag indicating that the debugger should be unloaded. 2176 // Clear the flag indicating that the debugger should be unloaded.
2158 debugger_unload_pending_ = false; 2177 data.debugger_unload_pending_ = false;
2159 } 2178 }
2160 2179
2161 2180
2162 void Debugger::NotifyMessageHandler(v8::DebugEvent event, 2181 void Debugger::NotifyMessageHandler(v8::DebugEvent event,
2163 Handle<JSObject> exec_state, 2182 Handle<JSObject> exec_state,
2164 Handle<JSObject> event_data, 2183 Handle<JSObject> event_data,
2165 bool auto_continue) { 2184 bool auto_continue) {
2166 HandleScope scope; 2185 HandleScope scope;
2167 2186
2168 if (!Debug::Load()) return; 2187 if (!Debug::Load()) return;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2232 static const int kArgc = 1; 2251 static const int kArgc = 1;
2233 v8::Handle<Value> argv[kArgc] = { running }; 2252 v8::Handle<Value> argv[kArgc] = { running };
2234 cmd_processor = v8::Object::Cast(*fun->Call(api_exec_state, kArgc, argv)); 2253 cmd_processor = v8::Object::Cast(*fun->Call(api_exec_state, kArgc, argv));
2235 if (try_catch.HasCaught()) { 2254 if (try_catch.HasCaught()) {
2236 PrintLn(try_catch.Exception()); 2255 PrintLn(try_catch.Exception());
2237 return; 2256 return;
2238 } 2257 }
2239 } 2258 }
2240 2259
2241 bool running = auto_continue; 2260 bool running = auto_continue;
2261 DebuggerData& data = v8_context()->debugger_data_;
2242 2262
2243 // Process requests from the debugger. 2263 // Process requests from the debugger.
2244 while (true) { 2264 while (true) {
2245 // Wait for new command in the queue. 2265 // Wait for new command in the queue.
2246 if (Debugger::host_dispatch_handler_) { 2266 if (data.host_dispatch_handler_) {
2247 // In case there is a host dispatch - do periodic dispatches. 2267 // In case there is a host dispatch - do periodic dispatches.
2248 if (!command_received_->Wait(host_dispatch_micros_)) { 2268 if (!data.command_received_->Wait(data.host_dispatch_micros_)) {
2249 // Timout expired, do the dispatch. 2269 // Timout expired, do the dispatch.
2250 Debugger::host_dispatch_handler_(); 2270 data.host_dispatch_handler_();
2251 continue; 2271 continue;
2252 } 2272 }
2253 } else { 2273 } else {
2254 // In case there is no host dispatch - just wait. 2274 // In case there is no host dispatch - just wait.
2255 command_received_->Wait(); 2275 data.command_received_->Wait();
2256 } 2276 }
2257 2277
2258 // Get the command from the queue. 2278 // Get the command from the queue.
2259 CommandMessage command = command_queue_.Get(); 2279 CommandMessage command = data.command_queue_.Get();
2260 Logger::DebugTag("Got request from command queue, in interactive loop."); 2280 Logger::DebugTag("Got request from command queue, in interactive loop.");
2261 if (!Debugger::IsDebuggerActive()) { 2281 if (!Debugger::IsDebuggerActive()) {
2262 // Delete command text and user data. 2282 // Delete command text and user data.
2263 command.Dispose(); 2283 command.Dispose();
2264 return; 2284 return;
2265 } 2285 }
2266 2286
2267 // Invoke JavaScript to process the debug request. 2287 // Invoke JavaScript to process the debug request.
2268 v8::Local<v8::String> fun_name; 2288 v8::Local<v8::String> fun_name;
2269 v8::Local<v8::Function> fun; 2289 v8::Local<v8::Function> fun;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2326 return; 2346 return;
2327 } 2347 }
2328 } 2348 }
2329 } 2349 }
2330 2350
2331 2351
2332 void Debugger::SetEventListener(Handle<Object> callback, 2352 void Debugger::SetEventListener(Handle<Object> callback,
2333 Handle<Object> data) { 2353 Handle<Object> data) {
2334 HandleScope scope; 2354 HandleScope scope;
2335 2355
2356 DebuggerData& debugger_data = v8_context()->debugger_data_;
2357
2336 // Clear the global handles for the event listener and the event listener data 2358 // Clear the global handles for the event listener and the event listener data
2337 // object. 2359 // object.
2338 if (!event_listener_.is_null()) { 2360 if (!debugger_data.event_listener_.is_null()) {
2339 GlobalHandles::Destroy( 2361 GlobalHandles::Destroy(
2340 reinterpret_cast<Object**>(event_listener_.location())); 2362 reinterpret_cast<Object**>(debugger_data.event_listener_.location()));
2341 event_listener_ = Handle<Object>(); 2363 debugger_data.event_listener_ = Handle<Object>();
2342 } 2364 }
2343 if (!event_listener_data_.is_null()) { 2365 if (!debugger_data.event_listener_data_.is_null()) {
2344 GlobalHandles::Destroy( 2366 GlobalHandles::Destroy(reinterpret_cast<Object**>(
2345 reinterpret_cast<Object**>(event_listener_data_.location())); 2367 debugger_data.event_listener_data_.location()));
2346 event_listener_data_ = Handle<Object>(); 2368 debugger_data.event_listener_data_ = Handle<Object>();
2347 } 2369 }
2348 2370
2349 // If there is a new debug event listener register it together with its data 2371 // If there is a new debug event listener register it together with its data
2350 // object. 2372 // object.
2351 if (!callback->IsUndefined() && !callback->IsNull()) { 2373 if (!callback->IsUndefined() && !callback->IsNull()) {
2352 event_listener_ = Handle<Object>::cast(GlobalHandles::Create(*callback)); 2374 debugger_data.event_listener_ =
2375 Handle<Object>::cast(GlobalHandles::Create(*callback));
2353 if (data.is_null()) { 2376 if (data.is_null()) {
2354 data = Factory::undefined_value(); 2377 data = Factory::undefined_value();
2355 } 2378 }
2356 event_listener_data_ = Handle<Object>::cast(GlobalHandles::Create(*data)); 2379 debugger_data.event_listener_data_ =
2380 Handle<Object>::cast(GlobalHandles::Create(*data));
2357 } 2381 }
2358 2382
2359 ListenersChanged(); 2383 ListenersChanged();
2360 } 2384 }
2361 2385
2362 2386
2363 void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) { 2387 void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) {
2364 ScopedLock with(debugger_access_); 2388 DebuggerData& data = v8_context()->debugger_data_;
2389 ScopedLock with(data.debugger_access_);
2365 2390
2366 message_handler_ = handler; 2391 data.message_handler_ = handler;
2367 ListenersChanged(); 2392 ListenersChanged();
2368 if (handler == NULL) { 2393 if (handler == NULL) {
2369 // Send an empty command to the debugger if in a break to make JavaScript 2394 // Send an empty command to the debugger if in a break to make JavaScript
2370 // run again if the debugger is closed. 2395 // run again if the debugger is closed.
2371 if (Debug::InDebugger()) { 2396 if (Debug::InDebugger()) {
2372 ProcessCommand(Vector<const uint16_t>::empty()); 2397 ProcessCommand(Vector<const uint16_t>::empty());
2373 } 2398 }
2374 } 2399 }
2375 } 2400 }
2376 2401
2377 2402
2378 void Debugger::ListenersChanged() { 2403 void Debugger::ListenersChanged() {
2379 if (IsDebuggerActive()) { 2404 if (IsDebuggerActive()) {
2380 // Disable the compilation cache when the debugger is active. 2405 // Disable the compilation cache when the debugger is active.
2381 CompilationCache::Disable(); 2406 CompilationCache::Disable();
2382 } else { 2407 } else {
2383 CompilationCache::Enable(); 2408 CompilationCache::Enable();
2384 2409
2385 // Unload the debugger if event listener and message handler cleared. 2410 // Unload the debugger if event listener and message handler cleared.
2386 if (Debug::InDebugger()) { 2411 if (Debug::InDebugger()) {
2387 // If we are in debugger set the flag to unload the debugger when last 2412 // If we are in debugger set the flag to unload the debugger when last
2388 // EnterDebugger on the current stack is destroyed. 2413 // EnterDebugger on the current stack is destroyed.
2389 debugger_unload_pending_ = true; 2414 v8_context()->debugger_data_.debugger_unload_pending_ = true;
2390 } else { 2415 } else {
2391 UnloadDebugger(); 2416 UnloadDebugger();
2392 } 2417 }
2393 } 2418 }
2394 } 2419 }
2395 2420
2396 2421
2397 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, 2422 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
2398 int period) { 2423 int period) {
2399 host_dispatch_handler_ = handler; 2424 DebuggerData& data = v8_context()->debugger_data_;
2400 host_dispatch_micros_ = period * 1000; 2425 data.host_dispatch_handler_ = handler;
2426 data.host_dispatch_micros_ = period * 1000;
2401 } 2427 }
2402 2428
2403 2429
2404 void Debugger::SetDebugMessageDispatchHandler( 2430 void Debugger::SetDebugMessageDispatchHandler(
2405 v8::Debug::DebugMessageDispatchHandler handler) { 2431 v8::Debug::DebugMessageDispatchHandler handler) {
2406 debug_message_dispatch_handler_ = handler; 2432 v8_context()->debugger_data_.debug_message_dispatch_handler_ = handler;
2407 } 2433 }
2408 2434
2409 2435
2410 // Calls the registered debug message handler. This callback is part of the 2436 // Calls the registered debug message handler. This callback is part of the
2411 // public API. 2437 // public API.
2412 void Debugger::InvokeMessageHandler(MessageImpl message) { 2438 void Debugger::InvokeMessageHandler(MessageImpl message) {
2413 ScopedLock with(debugger_access_); 2439 DebuggerData& data = v8_context()->debugger_data_;
2440 ScopedLock with(data.debugger_access_);
2414 2441
2415 if (message_handler_ != NULL) { 2442 if (data.message_handler_ != NULL) {
2416 message_handler_(message); 2443 data.message_handler_(message);
2417 } 2444 }
2418 } 2445 }
2419 2446
2420 2447
2421 // Puts a command coming from the public API on the queue. Creates 2448 // Puts a command coming from the public API on the queue. Creates
2422 // a copy of the command string managed by the debugger. Up to this 2449 // a copy of the command string managed by the debugger. Up to this
2423 // point, the command data was managed by the API client. Called 2450 // point, the command data was managed by the API client. Called
2424 // by the API client thread. 2451 // by the API client thread.
2425 void Debugger::ProcessCommand(Vector<const uint16_t> command, 2452 void Debugger::ProcessCommand(Vector<const uint16_t> command,
2426 v8::Debug::ClientData* client_data) { 2453 v8::Debug::ClientData* client_data) {
2427 // Need to cast away const. 2454 // Need to cast away const.
2428 CommandMessage message = CommandMessage::New( 2455 CommandMessage message = CommandMessage::New(
2429 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), 2456 Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
2430 command.length()), 2457 command.length()),
2431 client_data); 2458 client_data);
2432 Logger::DebugTag("Put command on command_queue."); 2459 Logger::DebugTag("Put command on command_queue.");
2433 command_queue_.Put(message); 2460 DebuggerData& data = v8_context()->debugger_data_;
2434 command_received_->Signal(); 2461 data.command_queue_.Put(message);
2462 data.command_received_->Signal();
2435 2463
2436 // Set the debug command break flag to have the command processed. 2464 // Set the debug command break flag to have the command processed.
2437 if (!Debug::InDebugger()) { 2465 if (!Debug::InDebugger()) {
2438 StackGuard::DebugCommand(); 2466 StackGuard::DebugCommand();
2439 } 2467 }
2440 2468
2441 if (Debugger::debug_message_dispatch_handler_ != NULL) { 2469 if (data.debug_message_dispatch_handler_ != NULL) {
2442 Debugger::debug_message_dispatch_handler_(); 2470 data.debug_message_dispatch_handler_();
2443 } 2471 }
2444 } 2472 }
2445 2473
2446 2474
2447 bool Debugger::HasCommands() { 2475 bool Debugger::HasCommands() {
2448 return !command_queue_.IsEmpty(); 2476 return !v8_context()->debugger_data_.command_queue_.IsEmpty();
2449 } 2477 }
2450 2478
2451 2479
2452 bool Debugger::IsDebuggerActive() { 2480 bool Debugger::IsDebuggerActive() {
2453 ScopedLock with(debugger_access_); 2481 DebuggerData& data = v8_context()->debugger_data_;
2482 ScopedLock with(data.debugger_access_);
2454 2483
2455 return message_handler_ != NULL || !event_listener_.is_null(); 2484 return data.message_handler_ != NULL || !data.event_listener_.is_null();
2456 } 2485 }
2457 2486
2458 2487
2459 Handle<Object> Debugger::Call(Handle<JSFunction> fun, 2488 Handle<Object> Debugger::Call(Handle<JSFunction> fun,
2460 Handle<Object> data, 2489 Handle<Object> data,
2461 bool* pending_exception) { 2490 bool* pending_exception) {
2462 // When calling functions in the debugger prevent it from beeing unloaded. 2491 // When calling functions in the debugger prevent it from beeing unloaded.
2463 Debugger::never_unload_debugger_ = true; 2492 v8_context()->debugger_data_.never_unload_debugger_ = true;
2464 2493
2465 // Enter the debugger. 2494 // Enter the debugger.
2466 EnterDebugger debugger; 2495 EnterDebugger debugger;
2467 if (debugger.FailedToEnter() || !debugger.HasJavaScriptFrames()) { 2496 if (debugger.FailedToEnter() || !debugger.HasJavaScriptFrames()) {
2468 return Factory::undefined_value(); 2497 return Factory::undefined_value();
2469 } 2498 }
2470 2499
2471 // Create the execution state. 2500 // Create the execution state.
2472 bool caught_exception = false; 2501 bool caught_exception = false;
2473 Handle<Object> exec_state = MakeExecutionState(&caught_exception); 2502 Handle<Object> exec_state = MakeExecutionState(&caught_exception);
2474 if (caught_exception) { 2503 if (caught_exception) {
2475 return Factory::undefined_value(); 2504 return Factory::undefined_value();
2476 } 2505 }
2477 2506
2478 static const int kArgc = 2; 2507 static const int kArgc = 2;
2479 Object** argv[kArgc] = { exec_state.location(), data.location() }; 2508 Object** argv[kArgc] = { exec_state.location(), data.location() };
2480 Handle<Object> result = Execution::Call(fun, Factory::undefined_value(), 2509 Handle<Object> result = Execution::Call(fun, Factory::undefined_value(),
2481 kArgc, argv, pending_exception); 2510 kArgc, argv, pending_exception);
2482 return result; 2511 return result;
2483 } 2512 }
2484 2513
2485 2514
2486 bool Debugger::StartAgent(const char* name, int port) { 2515 bool Debugger::StartAgent(const char* name, int port) {
2487 if (Socket::Setup()) { 2516 if (Socket::Setup()) {
2488 agent_ = new DebuggerAgent(name, port); 2517 DebuggerData& data = v8_context()->debugger_data_;
2489 agent_->Start(); 2518 data.agent_ = new DebuggerAgent(name, port);
2519 data.agent_->Start();
2490 return true; 2520 return true;
2491 } 2521 }
2492 2522
2493 return false; 2523 return false;
2494 } 2524 }
2495 2525
2496 2526
2497 void Debugger::StopAgent() { 2527 void Debugger::StopAgent() {
2498 if (agent_ != NULL) { 2528 DebuggerData& data = v8_context()->debugger_data_;
2499 agent_->Shutdown(); 2529 if (data.agent_ != NULL) {
2500 agent_->Join(); 2530 data.agent_->Shutdown();
2501 delete agent_; 2531 data.agent_->Join();
2502 agent_ = NULL; 2532 delete data.agent_;
2533 data.agent_ = NULL;
2503 } 2534 }
2504 } 2535 }
2505 2536
2506 2537
2507 void Debugger::WaitForAgent() { 2538 void Debugger::WaitForAgent() {
2508 if (agent_ != NULL) 2539 DebuggerData& data = v8_context()->debugger_data_;
2509 agent_->WaitUntilListening(); 2540 if (data.agent_ != NULL)
2541 data.agent_->WaitUntilListening();
2510 } 2542 }
2511 2543
2512 MessageImpl MessageImpl::NewEvent(DebugEvent event, 2544 MessageImpl MessageImpl::NewEvent(DebugEvent event,
2513 bool running, 2545 bool running,
2514 Handle<JSObject> exec_state, 2546 Handle<JSObject> exec_state,
2515 Handle<JSObject> event_data) { 2547 Handle<JSObject> event_data) {
2516 MessageImpl message(true, event, running, 2548 MessageImpl message(true, event, running,
2517 exec_state, event_data, Handle<String>(), NULL); 2549 exec_state, event_data, Handle<String>(), NULL);
2518 return message; 2550 return message;
2519 } 2551 }
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
2725 2757
2726 2758
2727 void LockingCommandMessageQueue::Clear() { 2759 void LockingCommandMessageQueue::Clear() {
2728 ScopedLock sl(lock_); 2760 ScopedLock sl(lock_);
2729 queue_.Clear(); 2761 queue_.Clear();
2730 } 2762 }
2731 2763
2732 #endif // ENABLE_DEBUGGER_SUPPORT 2764 #endif // ENABLE_DEBUGGER_SUPPORT
2733 2765
2734 } } // namespace v8::internal 2766 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/disasm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698