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

Side by Side Diff: src/inspector/v8-debugger.cc

Issue 2723273002: [inspector] introduced Debugger.scheduleStepIntoAsync (Closed)
Patch Set: override current scheduled step into async if presented Created 3 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
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/inspector/v8-debugger.h" 5 #include "src/inspector/v8-debugger.h"
6 6
7 #include "src/inspector/debugger-script.h" 7 #include "src/inspector/debugger-script.h"
8 #include "src/inspector/inspected-context.h" 8 #include "src/inspector/inspected-context.h"
9 #include "src/inspector/protocol/Protocol.h" 9 #include "src/inspector/protocol/Protocol.h"
10 #include "src/inspector/script-breakpoint.h" 10 #include "src/inspector/script-breakpoint.h"
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 compileDebuggerScript(); 187 compileDebuggerScript();
188 } 188 }
189 189
190 void V8Debugger::disable() { 190 void V8Debugger::disable() {
191 if (--m_enableCount) return; 191 if (--m_enableCount) return;
192 DCHECK(enabled()); 192 DCHECK(enabled());
193 clearBreakpoints(); 193 clearBreakpoints();
194 m_debuggerScript.Reset(); 194 m_debuggerScript.Reset();
195 m_debuggerContext.Reset(); 195 m_debuggerContext.Reset();
196 allAsyncTasksCanceled(); 196 allAsyncTasksCanceled();
197 m_taskWithScheduledBreak = nullptr;
197 m_wasmTranslation.Clear(); 198 m_wasmTranslation.Clear();
198 v8::debug::SetDebugDelegate(m_isolate, nullptr); 199 v8::debug::SetDebugDelegate(m_isolate, nullptr);
199 v8::debug::SetOutOfMemoryCallback(m_isolate, nullptr, nullptr); 200 v8::debug::SetOutOfMemoryCallback(m_isolate, nullptr, nullptr);
200 m_isolate->RestoreOriginalHeapLimit(); 201 m_isolate->RestoreOriginalHeapLimit();
201 } 202 }
202 203
203 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); } 204 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); }
204 205
205 void V8Debugger::getCompiledScripts( 206 void V8Debugger::getCompiledScripts(
206 int contextGroupId, 207 int contextGroupId,
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 619
619 bool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script, 620 bool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script,
620 const v8::debug::Location& start, 621 const v8::debug::Location& start,
621 const v8::debug::Location& end) { 622 const v8::debug::Location& end) {
622 V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script); 623 V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script);
623 if (!agent) return false; 624 if (!agent) return false;
624 return agent->isFunctionBlackboxed(String16::fromInteger(script->Id()), start, 625 return agent->isFunctionBlackboxed(String16::fromInteger(script->Id()), start,
625 end); 626 end);
626 } 627 }
627 628
628 void V8Debugger::PromiseEventOccurred(v8::debug::PromiseDebugActionType type, 629 void V8Debugger::PromiseEventOccurred(v8::Local<v8::Context> context,
629 int id, int parentId) { 630 v8::debug::PromiseDebugActionType type,
630 if (!m_maxAsyncCallStackDepth) return; 631 int id, int parentId, bool breakable) {
dgozman 2017/03/01 23:03:57 Do we really need this?
kozy 2017/03/02 00:53:03 Yes, but we could make it better and called create
631 // Async task events from Promises are given misaligned pointers to prevent 632 // Async task events from Promises are given misaligned pointers to prevent
632 // from overlapping with other Blink task identifiers. There is a single 633 // from overlapping with other Blink task identifiers. There is a single
633 // namespace of such ids, managed by src/js/promise.js. 634 // namespace of such ids, managed by src/js/promise.js.
634 void* ptr = reinterpret_cast<void*>(id * 2 + 1); 635 void* ptr = reinterpret_cast<void*>(id * 2 + 1);
636 void* parentPtr =
637 parentId ? reinterpret_cast<void*>(parentId * 2 + 1) : nullptr;
638 if ((breakable && type == v8::debug::kDebugPromiseCreated && parentPtr) ||
dgozman 2017/03/01 23:03:57 Let's move checks inside of stepping method.
kozy 2017/03/02 00:53:03 Done.
639 type == v8::debug::kDebugWillHandle ||
640 type == v8::debug::kDebugDidHandle ||
641 type == v8::debug::kDebugPromiseCollected) {
642 steppingOnPromiseEvent(context, type, ptr);
643 }
644 if (!m_maxAsyncCallStackDepth) return;
635 switch (type) { 645 switch (type) {
636 case v8::debug::kDebugPromiseCreated: 646 case v8::debug::kDebugPromiseCreated:
637 asyncTaskCreated( 647 asyncTaskCreated(ptr, parentPtr);
638 ptr, parentId ? reinterpret_cast<void*>(parentId * 2 + 1) : nullptr);
639 break; 648 break;
640 case v8::debug::kDebugEnqueueAsyncFunction: 649 case v8::debug::kDebugEnqueueAsyncFunction:
641 asyncTaskScheduled("async function", ptr, true); 650 asyncTaskScheduled("async function", ptr, true);
642 break; 651 break;
643 case v8::debug::kDebugEnqueuePromiseResolve: 652 case v8::debug::kDebugEnqueuePromiseResolve:
644 asyncTaskScheduled("Promise.resolve", ptr, true); 653 asyncTaskScheduled("Promise.resolve", ptr, true);
645 break; 654 break;
646 case v8::debug::kDebugEnqueuePromiseReject: 655 case v8::debug::kDebugEnqueuePromiseReject:
647 asyncTaskScheduled("Promise.reject", ptr, true); 656 asyncTaskScheduled("Promise.reject", ptr, true);
648 break; 657 break;
649 case v8::debug::kDebugPromiseCollected: 658 case v8::debug::kDebugPromiseCollected:
650 asyncTaskCanceled(ptr); 659 asyncTaskCanceled(ptr);
651 break; 660 break;
652 case v8::debug::kDebugWillHandle: 661 case v8::debug::kDebugWillHandle:
653 asyncTaskStarted(ptr); 662 asyncTaskStarted(ptr);
654 break; 663 break;
655 case v8::debug::kDebugDidHandle: 664 case v8::debug::kDebugDidHandle:
656 asyncTaskFinished(ptr); 665 asyncTaskFinished(ptr);
657 break; 666 break;
658 } 667 }
659 } 668 }
660 669
670 void V8Debugger::steppingOnPromiseEvent(v8::Local<v8::Context> context,
dgozman 2017/03/01 23:03:57 handleAsyncTaskStepping
kozy 2017/03/02 00:53:03 Done.
671 v8::debug::PromiseDebugActionType type,
672 void* task) {
673 if (type == v8::debug::kDebugPromiseCollected) {
674 if (task == m_taskWithScheduledBreak) m_taskWithScheduledBreak = nullptr;
675 return;
676 }
677 DCHECK(!context.IsEmpty());
678 v8::Context::Scope contextScope(context);
679 V8DebuggerAgentImpl* agent =
680 m_inspector->enabledDebuggerAgentForGroup(currentContextGroupId());
681 if (!agent) return;
682 if (type == v8::debug::kDebugPromiseCreated) {
683 if (!agent->isStepIntoAsyncScheduled()) return;
684 m_taskWithScheduledBreak = task;
685 agent->stepIntoAsyncWasScheduled();
dgozman 2017/03/01 23:03:57 if (agent->shouldBreakInScheduledAsyncTask()) m_
kozy 2017/03/02 00:53:03 Done.
686 return;
687 }
688 if (m_taskWithScheduledBreak != task) return;
689 if (type == v8::debug::kDebugWillHandle) {
690 agent->schedulePauseOnNextStatement(
691 protocol::Debugger::Paused::ReasonEnum::Other, nullptr);
692 } else {
dgozman 2017/03/01 23:03:57 DCHECK(type == didHandle)
kozy 2017/03/02 00:53:03 Done.
693 agent->cancelPauseOnNextStatement();
694 m_taskWithScheduledBreak = nullptr;
695 }
696 }
697
661 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() { 698 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() {
662 if (!m_currentStacks.size()) return nullptr; 699 if (!m_currentStacks.size()) return nullptr;
663 return m_currentStacks.back().get(); 700 return m_currentStacks.back().get();
664 } 701 }
665 702
666 void V8Debugger::compileDebuggerScript() { 703 void V8Debugger::compileDebuggerScript() {
667 if (!m_debuggerScript.IsEmpty()) { 704 if (!m_debuggerScript.IsEmpty()) {
668 UNREACHABLE(); 705 UNREACHABLE();
669 return; 706 return;
670 } 707 }
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 createDataProperty(context, properties, properties->Length(), 832 createDataProperty(context, properties, properties->Length(),
796 toV8StringInternalized(m_isolate, "[[Scopes]]")); 833 toV8StringInternalized(m_isolate, "[[Scopes]]"));
797 createDataProperty(context, properties, properties->Length(), scopes); 834 createDataProperty(context, properties, properties->Length(), scopes);
798 } 835 }
799 } 836 }
800 return properties; 837 return properties;
801 } 838 }
802 839
803 std::unique_ptr<V8StackTraceImpl> V8Debugger::createStackTrace( 840 std::unique_ptr<V8StackTraceImpl> V8Debugger::createStackTrace(
804 v8::Local<v8::StackTrace> stackTrace) { 841 v8::Local<v8::StackTrace> stackTrace) {
805 int contextGroupId = 842 return V8StackTraceImpl::create(this, currentContextGroupId(), stackTrace,
806 m_isolate->InContext()
807 ? m_inspector->contextGroupId(m_isolate->GetCurrentContext())
808 : 0;
809 return V8StackTraceImpl::create(this, contextGroupId, stackTrace,
810 V8StackTraceImpl::maxCallStackSizeToCapture); 843 V8StackTraceImpl::maxCallStackSizeToCapture);
811 } 844 }
812 845
813 void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) { 846 void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) {
814 if (depth <= 0) 847 if (depth <= 0)
815 m_maxAsyncCallStackDepthMap.erase(agent); 848 m_maxAsyncCallStackDepthMap.erase(agent);
816 else 849 else
817 m_maxAsyncCallStackDepthMap[agent] = depth; 850 m_maxAsyncCallStackDepthMap[agent] = depth;
818 851
819 int maxAsyncCallStackDepth = 0; 852 int maxAsyncCallStackDepth = 0;
(...skipping 16 matching lines...) Expand all
836 if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) { 869 if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) {
837 void* taskToRemove = m_idToTask.begin()->second; 870 void* taskToRemove = m_idToTask.begin()->second;
838 asyncTaskCanceled(taskToRemove); 871 asyncTaskCanceled(taskToRemove);
839 } 872 }
840 } 873 }
841 874
842 void V8Debugger::asyncTaskCreated(void* task, void* parentTask) { 875 void V8Debugger::asyncTaskCreated(void* task, void* parentTask) {
843 if (!m_maxAsyncCallStackDepth) return; 876 if (!m_maxAsyncCallStackDepth) return;
844 if (parentTask) m_parentTask[task] = parentTask; 877 if (parentTask) m_parentTask[task] = parentTask;
845 v8::HandleScope scope(m_isolate); 878 v8::HandleScope scope(m_isolate);
846 // We don't need to pass context group id here because we gets this callback 879 // We don't need to pass context group id here because we get this callback
847 // from V8 for promise events only. 880 // from V8 for promise events only.
848 // Passing one as maxStackSize forces no async chain for the new stack and 881 // Passing one as maxStackSize forces no async chain for the new stack and
849 // allows us to not grow exponentially. 882 // allows us to not grow exponentially.
850 std::unique_ptr<V8StackTraceImpl> creationStack = 883 std::unique_ptr<V8StackTraceImpl> creationStack =
851 V8StackTraceImpl::capture(this, 0, 1, String16()); 884 V8StackTraceImpl::capture(this, 0, 1, String16());
852 if (creationStack && !creationStack->isEmpty()) { 885 if (creationStack && !creationStack->isEmpty()) {
853 m_asyncTaskCreationStacks[task] = std::move(creationStack); 886 m_asyncTaskCreationStacks[task] = std::move(creationStack);
854 registerAsyncTaskIfNeeded(task); 887 registerAsyncTaskIfNeeded(task);
855 } 888 }
856 } 889 }
857 890
858 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, 891 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task,
859 bool recurring) { 892 bool recurring) {
860 if (!m_maxAsyncCallStackDepth) return; 893 if (!m_maxAsyncCallStackDepth) return;
861 asyncTaskScheduled(toString16(taskName), task, recurring); 894 asyncTaskScheduled(toString16(taskName), task, recurring);
862 } 895 }
863 896
864 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, 897 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task,
865 bool recurring) { 898 bool recurring) {
866 if (!m_maxAsyncCallStackDepth) return; 899 if (!m_maxAsyncCallStackDepth) return;
867 v8::HandleScope scope(m_isolate); 900 v8::HandleScope scope(m_isolate);
868 int contextGroupId =
869 m_isolate->InContext()
870 ? m_inspector->contextGroupId(m_isolate->GetCurrentContext())
871 : 0;
872 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture( 901 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture(
873 this, contextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture, 902 this, currentContextGroupId(),
874 taskName); 903 V8StackTraceImpl::maxCallStackSizeToCapture, taskName);
875 if (chain) { 904 if (chain) {
876 m_asyncTaskStacks[task] = std::move(chain); 905 m_asyncTaskStacks[task] = std::move(chain);
877 if (recurring) m_recurringTasks.insert(task); 906 if (recurring) m_recurringTasks.insert(task);
878 registerAsyncTaskIfNeeded(task); 907 registerAsyncTaskIfNeeded(task);
879 } 908 }
880 } 909 }
881 910
882 void V8Debugger::asyncTaskCanceled(void* task) { 911 void V8Debugger::asyncTaskCanceled(void* task) {
883 if (!m_maxAsyncCallStackDepth) return; 912 if (!m_maxAsyncCallStackDepth) return;
884 m_asyncTaskStacks.erase(task); 913 m_asyncTaskStacks.erase(task);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 void V8Debugger::unmuteScriptParsedEvents() { 976 void V8Debugger::unmuteScriptParsedEvents() {
948 --m_ignoreScriptParsedEventsCounter; 977 --m_ignoreScriptParsedEventsCounter;
949 DCHECK_GE(m_ignoreScriptParsedEventsCounter, 0); 978 DCHECK_GE(m_ignoreScriptParsedEventsCounter, 0);
950 } 979 }
951 980
952 std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace( 981 std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace(
953 bool fullStack) { 982 bool fullStack) {
954 if (!m_isolate->InContext()) return nullptr; 983 if (!m_isolate->InContext()) return nullptr;
955 984
956 v8::HandleScope handles(m_isolate); 985 v8::HandleScope handles(m_isolate);
957 int contextGroupId = 986 int contextGroupId = currentContextGroupId();
958 m_inspector->contextGroupId(m_isolate->GetCurrentContext());
959 if (!contextGroupId) return nullptr; 987 if (!contextGroupId) return nullptr;
960 988
961 size_t stackSize = 989 size_t stackSize =
962 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; 990 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1;
963 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) 991 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId))
964 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; 992 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
965 993
966 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); 994 return V8StackTraceImpl::capture(this, contextGroupId, stackSize);
967 } 995 }
968 996
997 int V8Debugger::currentContextGroupId() {
998 if (!m_isolate->InContext()) return 0;
999 return m_inspector->contextGroupId(m_isolate->GetCurrentContext());
1000 }
1001
969 } // namespace v8_inspector 1002 } // namespace v8_inspector
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698