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

Side by Side Diff: src/debug.cc

Issue 39124: Handle thread preemption in debugger (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/debug.h ('k') | src/execution.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 #endif 393 #endif
394 } 394 }
395 395
396 396
397 bool Debug::has_break_points_ = false; 397 bool Debug::has_break_points_ = false;
398 DebugInfoListNode* Debug::debug_info_list_ = NULL; 398 DebugInfoListNode* Debug::debug_info_list_ = NULL;
399 399
400 400
401 // Threading support. 401 // Threading support.
402 void Debug::ThreadInit() { 402 void Debug::ThreadInit() {
403 thread_local_.break_count_ = 0;
404 thread_local_.break_id_ = 0;
405 thread_local_.break_frame_id_ = StackFrame::NO_ID;
403 thread_local_.last_step_action_ = StepNone; 406 thread_local_.last_step_action_ = StepNone;
404 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; 407 thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
405 thread_local_.step_count_ = 0; 408 thread_local_.step_count_ = 0;
406 thread_local_.last_fp_ = 0; 409 thread_local_.last_fp_ = 0;
407 thread_local_.step_into_fp_ = 0; 410 thread_local_.step_into_fp_ = 0;
408 thread_local_.after_break_target_ = 0; 411 thread_local_.after_break_target_ = 0;
412 thread_local_.debugger_entry_ = NULL;
413 thread_local_.preemption_pending_ = false;
409 } 414 }
410 415
411 416
412 JSCallerSavedBuffer Debug::registers_; 417 JSCallerSavedBuffer Debug::registers_;
413 Debug::ThreadLocal Debug::thread_local_; 418 Debug::ThreadLocal Debug::thread_local_;
414 419
415 420
416 char* Debug::ArchiveDebug(char* storage) { 421 char* Debug::ArchiveDebug(char* storage) {
417 char* to = storage; 422 char* to = storage;
418 memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); 423 memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 609
605 // Get rid of all break points and related information. 610 // Get rid of all break points and related information.
606 ClearAllBreakPoints(); 611 ClearAllBreakPoints();
607 612
608 // Clear debugger context global handle. 613 // Clear debugger context global handle.
609 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location())); 614 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location()));
610 debug_context_ = Handle<Context>(); 615 debug_context_ = Handle<Context>();
611 } 616 }
612 617
613 618
619 // Set the flag indicating that preemption happened during debugging.
620 void Debug::PreemptionWhileInDebugger() {
621 ASSERT(InDebugger());
622 Debug::set_preemption_pending(true);
623 }
624
625
614 void Debug::Iterate(ObjectVisitor* v) { 626 void Debug::Iterate(ObjectVisitor* v) {
615 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_entry_))); 627 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_entry_)));
616 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_))); 628 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_)));
617 } 629 }
618 630
619 631
620 Object* Debug::Break(Arguments args) { 632 Object* Debug::Break(Arguments args) {
621 HandleScope scope; 633 HandleScope scope;
622 ASSERT(args.length() == 0); 634 ASSERT(args.length() == 0);
623 635
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 // Ignore check if break point object is not a JSObject. 748 // Ignore check if break point object is not a JSObject.
737 if (!break_point_object->IsJSObject()) return true; 749 if (!break_point_object->IsJSObject()) return true;
738 750
739 // Get the function CheckBreakPoint (defined in debug.js). 751 // Get the function CheckBreakPoint (defined in debug.js).
740 Handle<JSFunction> check_break_point = 752 Handle<JSFunction> check_break_point =
741 Handle<JSFunction>(JSFunction::cast( 753 Handle<JSFunction>(JSFunction::cast(
742 debug_context()->global()->GetProperty( 754 debug_context()->global()->GetProperty(
743 *Factory::LookupAsciiSymbol("IsBreakPointTriggered")))); 755 *Factory::LookupAsciiSymbol("IsBreakPointTriggered"))));
744 756
745 // Get the break id as an object. 757 // Get the break id as an object.
746 Handle<Object> break_id = Factory::NewNumberFromInt(Top::break_id()); 758 Handle<Object> break_id = Factory::NewNumberFromInt(Debug::break_id());
747 759
748 // Call HandleBreakPointx. 760 // Call HandleBreakPointx.
749 bool caught_exception = false; 761 bool caught_exception = false;
750 const int argc = 2; 762 const int argc = 2;
751 Object** argv[argc] = { 763 Object** argv[argc] = {
752 break_id.location(), 764 break_id.location(),
753 reinterpret_cast<Object**>(break_point_object.location()) 765 reinterpret_cast<Object**>(break_point_object.location())
754 }; 766 };
755 Handle<Object> result = Execution::TryCall(check_break_point, 767 Handle<Object> result = Execution::TryCall(check_break_point,
756 Top::builtins(), argc, argv, 768 Top::builtins(), argc, argv,
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS); 878 BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS);
867 while (!it.Done()) { 879 while (!it.Done()) {
868 it.SetOneShot(); 880 it.SetOneShot();
869 it.Next(); 881 it.Next();
870 } 882 }
871 } 883 }
872 884
873 885
874 void Debug::FloodHandlerWithOneShot() { 886 void Debug::FloodHandlerWithOneShot() {
875 // Iterate through the JavaScript stack looking for handlers. 887 // Iterate through the JavaScript stack looking for handlers.
876 StackFrame::Id id = Top::break_frame_id(); 888 StackFrame::Id id = break_frame_id();
877 if (id == StackFrame::NO_ID) { 889 if (id == StackFrame::NO_ID) {
878 // If there is no JavaScript stack don't do anything. 890 // If there is no JavaScript stack don't do anything.
879 return; 891 return;
880 } 892 }
881 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) { 893 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) {
882 JavaScriptFrame* frame = it.frame(); 894 JavaScriptFrame* frame = it.frame();
883 if (frame->HasHandler()) { 895 if (frame->HasHandler()) {
884 Handle<SharedFunctionInfo> shared = 896 Handle<SharedFunctionInfo> shared =
885 Handle<SharedFunctionInfo>( 897 Handle<SharedFunctionInfo>(
886 JSFunction::cast(frame->function())->shared()); 898 JSFunction::cast(frame->function())->shared());
(...skipping 19 matching lines...) Expand all
906 ASSERT(Debug::InDebugger()); 918 ASSERT(Debug::InDebugger());
907 919
908 // Remember this step action and count. 920 // Remember this step action and count.
909 thread_local_.last_step_action_ = step_action; 921 thread_local_.last_step_action_ = step_action;
910 thread_local_.step_count_ = step_count; 922 thread_local_.step_count_ = step_count;
911 923
912 // Get the frame where the execution has stopped and skip the debug frame if 924 // Get the frame where the execution has stopped and skip the debug frame if
913 // any. The debug frame will only be present if execution was stopped due to 925 // any. The debug frame will only be present if execution was stopped due to
914 // hitting a break point. In other situations (e.g. unhandled exception) the 926 // hitting a break point. In other situations (e.g. unhandled exception) the
915 // debug frame is not present. 927 // debug frame is not present.
916 StackFrame::Id id = Top::break_frame_id(); 928 StackFrame::Id id = break_frame_id();
917 if (id == StackFrame::NO_ID) { 929 if (id == StackFrame::NO_ID) {
918 // If there is no JavaScript stack don't do anything. 930 // If there is no JavaScript stack don't do anything.
919 return; 931 return;
920 } 932 }
921 JavaScriptFrameIterator frames_it(id); 933 JavaScriptFrameIterator frames_it(id);
922 JavaScriptFrame* frame = frames_it.frame(); 934 JavaScriptFrame* frame = frames_it.frame();
923 935
924 // First of all ensure there is one-shot break points in the top handler 936 // First of all ensure there is one-shot break points in the top handler
925 // if any. 937 // if any.
926 FloodHandlerWithOneShot(); 938 FloodHandlerWithOneShot();
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 BreakPointInfo::cast(debug_info->break_points()->get(i)); 1123 BreakPointInfo::cast(debug_info->break_points()->get(i));
1112 if (break_point_info->GetBreakPointCount() > 0) { 1124 if (break_point_info->GetBreakPointCount() > 0) {
1113 locations->set(count++, break_point_info->statement_position()); 1125 locations->set(count++, break_point_info->statement_position());
1114 } 1126 }
1115 } 1127 }
1116 } 1128 }
1117 return locations; 1129 return locations;
1118 } 1130 }
1119 1131
1120 1132
1133 void Debug::NewBreak(StackFrame::Id break_frame_id) {
1134 thread_local_.break_frame_id_ = break_frame_id;
1135 thread_local_.break_id_ = ++thread_local_.break_count_;
1136 }
1137
1138
1139 void Debug::SetBreak(StackFrame::Id break_frame_id, int break_id) {
1140 thread_local_.break_frame_id_ = break_frame_id;
1141 thread_local_.break_id_ = break_id;
1142 }
1143
1144
1121 // Handle stepping into a function. 1145 // Handle stepping into a function.
1122 void Debug::HandleStepIn(Handle<JSFunction> function, 1146 void Debug::HandleStepIn(Handle<JSFunction> function,
1123 Address fp, 1147 Address fp,
1124 bool is_constructor) { 1148 bool is_constructor) {
1125 // If the frame pointer is not supplied by the caller find it. 1149 // If the frame pointer is not supplied by the caller find it.
1126 if (fp == 0) { 1150 if (fp == 0) {
1127 StackFrameIterator it; 1151 StackFrameIterator it;
1128 it.Advance(); 1152 it.Advance();
1129 // For constructor functions skip another frame. 1153 // For constructor functions skip another frame.
1130 if (is_constructor) { 1154 if (is_constructor) {
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 Handle<Object> js_object = Execution::TryCall( 1398 Handle<Object> js_object = Execution::TryCall(
1375 Handle<JSFunction>::cast(constructor), 1399 Handle<JSFunction>::cast(constructor),
1376 Handle<JSObject>(Debug::debug_context()->global()), argc, argv, 1400 Handle<JSObject>(Debug::debug_context()->global()), argc, argv,
1377 caught_exception); 1401 caught_exception);
1378 return js_object; 1402 return js_object;
1379 } 1403 }
1380 1404
1381 1405
1382 Handle<Object> Debugger::MakeExecutionState(bool* caught_exception) { 1406 Handle<Object> Debugger::MakeExecutionState(bool* caught_exception) {
1383 // Create the execution state object. 1407 // Create the execution state object.
1384 Handle<Object> break_id = Factory::NewNumberFromInt(Top::break_id()); 1408 Handle<Object> break_id = Factory::NewNumberFromInt(Debug::break_id());
1385 const int argc = 1; 1409 const int argc = 1;
1386 Object** argv[argc] = { break_id.location() }; 1410 Object** argv[argc] = { break_id.location() };
1387 return MakeJSObject(CStrVector("MakeExecutionState"), 1411 return MakeJSObject(CStrVector("MakeExecutionState"),
1388 argc, argv, caught_exception); 1412 argc, argv, caught_exception);
1389 } 1413 }
1390 1414
1391 1415
1392 Handle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state, 1416 Handle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state,
1393 Handle<Object> break_points_hit, 1417 Handle<Object> break_points_hit,
1394 bool* caught_exception) { 1418 bool* caught_exception) {
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after
2119 } 2143 }
2120 2144
2121 2145
2122 void LockingMessageQueue::Clear() { 2146 void LockingMessageQueue::Clear() {
2123 ScopedLock sl(lock_); 2147 ScopedLock sl(lock_);
2124 queue_.Clear(); 2148 queue_.Clear();
2125 } 2149 }
2126 2150
2127 2151
2128 } } // namespace v8::internal 2152 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/execution.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698