OLD | NEW |
---|---|
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 "src/debug/debug.h" | 5 #include "src/debug/debug.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
472 void Debug::ThreadInit() { | 472 void Debug::ThreadInit() { |
473 thread_local_.break_count_ = 0; | 473 thread_local_.break_count_ = 0; |
474 thread_local_.break_id_ = 0; | 474 thread_local_.break_id_ = 0; |
475 thread_local_.break_frame_id_ = StackFrame::NO_ID; | 475 thread_local_.break_frame_id_ = StackFrame::NO_ID; |
476 thread_local_.last_step_action_ = StepNone; | 476 thread_local_.last_step_action_ = StepNone; |
477 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; | 477 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; |
478 thread_local_.last_fp_ = 0; | 478 thread_local_.last_fp_ = 0; |
479 thread_local_.target_fp_ = 0; | 479 thread_local_.target_fp_ = 0; |
480 thread_local_.step_in_enabled_ = false; | 480 thread_local_.step_in_enabled_ = false; |
481 thread_local_.return_value_ = Handle<Object>(); | 481 thread_local_.return_value_ = Handle<Object>(); |
482 thread_local_.suspended_generator_ = nullptr; | |
482 // TODO(isolates): frames_are_dropped_? | 483 // TODO(isolates): frames_are_dropped_? |
483 base::NoBarrier_Store(&thread_local_.current_debug_scope_, | 484 base::NoBarrier_Store(&thread_local_.current_debug_scope_, |
484 static_cast<base::AtomicWord>(0)); | 485 static_cast<base::AtomicWord>(0)); |
485 } | 486 } |
486 | 487 |
487 | 488 |
488 char* Debug::ArchiveDebug(char* storage) { | 489 char* Debug::ArchiveDebug(char* storage) { |
489 char* to = storage; | 490 // Simply reset state. Don't archive anything. |
490 MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); | |
491 ThreadInit(); | 491 ThreadInit(); |
492 return storage + ArchiveSpacePerThread(); | 492 return storage + ArchiveSpacePerThread(); |
493 } | 493 } |
494 | 494 |
495 | 495 |
496 char* Debug::RestoreDebug(char* storage) { | 496 char* Debug::RestoreDebug(char* storage) { |
497 char* from = storage; | 497 // Simply reset state. Don't restore anything. |
498 MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); | 498 ThreadInit(); |
499 return storage + ArchiveSpacePerThread(); | 499 return storage + ArchiveSpacePerThread(); |
500 } | 500 } |
501 | 501 |
502 int Debug::ArchiveSpacePerThread() { return 0; } | |
502 | 503 |
503 int Debug::ArchiveSpacePerThread() { | 504 void Debug::Iterate(ObjectVisitor* v) { |
504 return sizeof(ThreadLocal); | 505 v->VisitPointer(&thread_local_.suspended_generator_); |
ulan
2016/06/03 09:33:50
Please guard it with
if (thread_local_.suspended_g
Yang
2016/06/03 11:48:11
Done.
| |
505 } | 506 } |
506 | 507 |
507 | |
508 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { | 508 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) { |
509 // Globalize the request debug info object and make it weak. | 509 // Globalize the request debug info object and make it weak. |
510 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); | 510 GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles(); |
511 debug_info_ = | 511 debug_info_ = |
512 Handle<DebugInfo>::cast(global_handles->Create(debug_info)).location(); | 512 Handle<DebugInfo>::cast(global_handles->Create(debug_info)).location(); |
513 } | 513 } |
514 | 514 |
515 | 515 |
516 DebugInfoListNode::~DebugInfoListNode() { | 516 DebugInfoListNode::~DebugInfoListNode() { |
517 if (debug_info_ == nullptr) return; | 517 if (debug_info_ == nullptr) return; |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
933 | 933 |
934 void Debug::PrepareStepIn(Handle<JSFunction> function) { | 934 void Debug::PrepareStepIn(Handle<JSFunction> function) { |
935 if (!is_active()) return; | 935 if (!is_active()) return; |
936 if (last_step_action() < StepIn) return; | 936 if (last_step_action() < StepIn) return; |
937 if (in_debug_scope()) return; | 937 if (in_debug_scope()) return; |
938 if (thread_local_.step_in_enabled_) { | 938 if (thread_local_.step_in_enabled_) { |
939 FloodWithOneShot(function); | 939 FloodWithOneShot(function); |
940 } | 940 } |
941 } | 941 } |
942 | 942 |
943 void Debug::PrepareStepInSuspendedGenerator() { | |
944 if (!is_active()) return; | |
945 if (in_debug_scope()) return; | |
946 DCHECK_NOT_NULL(thread_local_.suspended_generator_); | |
947 thread_local_.last_step_action_ = StepIn; | |
948 thread_local_.step_in_enabled_ = true; | |
949 Handle<JSFunction> function( | |
950 JSGeneratorObject::cast(thread_local_.suspended_generator_)->function()); | |
951 FloodWithOneShot(function); | |
952 thread_local_.suspended_generator_ = nullptr; | |
953 } | |
943 | 954 |
944 void Debug::PrepareStepOnThrow() { | 955 void Debug::PrepareStepOnThrow() { |
945 if (!is_active()) return; | 956 if (!is_active()) return; |
946 if (last_step_action() == StepNone) return; | 957 if (last_step_action() == StepNone) return; |
947 if (in_debug_scope()) return; | 958 if (in_debug_scope()) return; |
948 | 959 |
949 ClearOneShot(); | 960 ClearOneShot(); |
950 | 961 |
951 // Iterate through the JavaScript stack looking for handlers. | 962 // Iterate through the JavaScript stack looking for handlers. |
952 JavaScriptFrameIterator it(isolate_); | 963 JavaScriptFrameIterator it(isolate_); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1034 | 1045 |
1035 // Any step at a return is a step-out. | 1046 // Any step at a return is a step-out. |
1036 if (location.IsReturn()) step_action = StepOut; | 1047 if (location.IsReturn()) step_action = StepOut; |
1037 // A step-next at a tail call is a step-out. | 1048 // A step-next at a tail call is a step-out. |
1038 if (location.IsTailCall() && step_action == StepNext) step_action = StepOut; | 1049 if (location.IsTailCall() && step_action == StepNext) step_action = StepOut; |
1039 | 1050 |
1040 thread_local_.last_statement_position_ = | 1051 thread_local_.last_statement_position_ = |
1041 debug_info->abstract_code()->SourceStatementPosition( | 1052 debug_info->abstract_code()->SourceStatementPosition( |
1042 summary.code_offset()); | 1053 summary.code_offset()); |
1043 thread_local_.last_fp_ = frame->UnpaddedFP(); | 1054 thread_local_.last_fp_ = frame->UnpaddedFP(); |
1055 // No longer perform the current async step. | |
1056 thread_local_.suspended_generator_ = nullptr; | |
1044 | 1057 |
1045 switch (step_action) { | 1058 switch (step_action) { |
1046 case StepNone: | 1059 case StepNone: |
1047 UNREACHABLE(); | 1060 UNREACHABLE(); |
1048 break; | 1061 break; |
1049 case StepOut: | 1062 case StepOut: |
1050 // Advance to caller frame. | 1063 // Advance to caller frame. |
1051 frames_it.Advance(); | 1064 frames_it.Advance(); |
1052 // Skip native and extension functions on the stack. | 1065 // Skip native and extension functions on the stack. |
1053 while (!frames_it.done() && | 1066 while (!frames_it.done() && |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1378 } | 1391 } |
1379 | 1392 |
1380 // Update PCs on the stack to point to recompiled code. | 1393 // Update PCs on the stack to point to recompiled code. |
1381 RedirectActiveFunctions redirect_visitor(*shared); | 1394 RedirectActiveFunctions redirect_visitor(*shared); |
1382 redirect_visitor.VisitThread(isolate_, isolate_->thread_local_top()); | 1395 redirect_visitor.VisitThread(isolate_, isolate_->thread_local_top()); |
1383 isolate_->thread_manager()->IterateArchivedThreads(&redirect_visitor); | 1396 isolate_->thread_manager()->IterateArchivedThreads(&redirect_visitor); |
1384 | 1397 |
1385 return true; | 1398 return true; |
1386 } | 1399 } |
1387 | 1400 |
1401 void Debug::RecordAsyncFunction(Handle<JSGeneratorObject> generator_object) { | |
1402 if (last_step_action() <= StepOut) return; | |
1403 DCHECK_NULL(thread_local_.suspended_generator_); | |
1404 DCHECK(generator_object->function()->shared()->is_async()); | |
1405 thread_local_.suspended_generator_ = *generator_object; | |
1406 ClearStepping(); | |
1407 } | |
1388 | 1408 |
1389 class SharedFunctionInfoFinder { | 1409 class SharedFunctionInfoFinder { |
1390 public: | 1410 public: |
1391 explicit SharedFunctionInfoFinder(int target_position) | 1411 explicit SharedFunctionInfoFinder(int target_position) |
1392 : current_candidate_(NULL), | 1412 : current_candidate_(NULL), |
1393 current_candidate_closure_(NULL), | 1413 current_candidate_closure_(NULL), |
1394 current_start_position_(RelocInfo::kNoPosition), | 1414 current_start_position_(RelocInfo::kNoPosition), |
1395 target_position_(target_position) {} | 1415 target_position_(target_position) {} |
1396 | 1416 |
1397 void NewCandidate(SharedFunctionInfo* shared, JSFunction* closure = NULL) { | 1417 void NewCandidate(SharedFunctionInfo* shared, JSFunction* closure = NULL) { |
(...skipping 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2587 } | 2607 } |
2588 | 2608 |
2589 | 2609 |
2590 void LockingCommandMessageQueue::Clear() { | 2610 void LockingCommandMessageQueue::Clear() { |
2591 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 2611 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
2592 queue_.Clear(); | 2612 queue_.Clear(); |
2593 } | 2613 } |
2594 | 2614 |
2595 } // namespace internal | 2615 } // namespace internal |
2596 } // namespace v8 | 2616 } // namespace v8 |
OLD | NEW |