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

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

Issue 2723273002: [inspector] introduced Debugger.scheduleStepIntoAsync (Closed)
Patch Set: fixed 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,
632 bool createdByUser) {
631 // Async task events from Promises are given misaligned pointers to prevent 633 // Async task events from Promises are given misaligned pointers to prevent
632 // from overlapping with other Blink task identifiers. There is a single 634 // from overlapping with other Blink task identifiers. There is a single
633 // namespace of such ids, managed by src/js/promise.js. 635 // namespace of such ids, managed by src/js/promise.js.
634 void* ptr = reinterpret_cast<void*>(id * 2 + 1); 636 void* ptr = reinterpret_cast<void*>(id * 2 + 1);
637 void* parentPtr =
638 parentId ? reinterpret_cast<void*>(parentId * 2 + 1) : nullptr;
639 handleAsyncTaskStepping(context, type, ptr, parentPtr, createdByUser);
640 if (!m_maxAsyncCallStackDepth) return;
635 switch (type) { 641 switch (type) {
636 case v8::debug::kDebugPromiseCreated: 642 case v8::debug::kDebugPromiseCreated:
637 asyncTaskCreated( 643 asyncTaskCreated(ptr, parentPtr);
638 ptr, parentId ? reinterpret_cast<void*>(parentId * 2 + 1) : nullptr);
639 break; 644 break;
640 case v8::debug::kDebugEnqueueAsyncFunction: 645 case v8::debug::kDebugEnqueueAsyncFunction:
641 asyncTaskScheduled("async function", ptr, true); 646 asyncTaskScheduled("async function", ptr, true);
642 break; 647 break;
643 case v8::debug::kDebugEnqueuePromiseResolve: 648 case v8::debug::kDebugEnqueuePromiseResolve:
644 asyncTaskScheduled("Promise.resolve", ptr, true); 649 asyncTaskScheduled("Promise.resolve", ptr, true);
645 break; 650 break;
646 case v8::debug::kDebugEnqueuePromiseReject: 651 case v8::debug::kDebugEnqueuePromiseReject:
647 asyncTaskScheduled("Promise.reject", ptr, true); 652 asyncTaskScheduled("Promise.reject", ptr, true);
648 break; 653 break;
649 case v8::debug::kDebugPromiseCollected: 654 case v8::debug::kDebugPromiseCollected:
650 asyncTaskCanceled(ptr); 655 asyncTaskCanceled(ptr);
651 break; 656 break;
652 case v8::debug::kDebugWillHandle: 657 case v8::debug::kDebugWillHandle:
653 asyncTaskStarted(ptr); 658 asyncTaskStarted(ptr);
654 break; 659 break;
655 case v8::debug::kDebugDidHandle: 660 case v8::debug::kDebugDidHandle:
656 asyncTaskFinished(ptr); 661 asyncTaskFinished(ptr);
657 break; 662 break;
658 } 663 }
659 } 664 }
660 665
666 void V8Debugger::handleAsyncTaskStepping(v8::Local<v8::Context> context,
667 v8::debug::PromiseDebugActionType type,
668 void* task, void* parentTask,
669 bool createdByUser) {
670 bool isScheduledTask = task == m_taskWithScheduledBreak;
671 if (type == v8::debug::kDebugPromiseCollected) {
672 if (isScheduledTask) m_taskWithScheduledBreak = nullptr;
673 return;
674 }
675 if (type == v8::debug::kDebugPromiseCreated && !parentTask) return;
676
677 DCHECK(!context.IsEmpty());
678 int contextGroupId = m_inspector->contextGroupId(context);
679 V8DebuggerAgentImpl* agent =
680 m_inspector->enabledDebuggerAgentForGroup(contextGroupId);
681 if (!agent) return;
682 if (createdByUser && type == v8::debug::kDebugPromiseCreated) {
683 if (agent->shouldBreakInScheduledAsyncTask()) {
684 m_taskWithScheduledBreak = task;
685 }
dgozman 2017/03/03 19:47:06 return;
kozy 2017/03/03 23:14:02 Done.
686 } else if (isScheduledTask && type == v8::debug::kDebugWillHandle) {
687 agent->schedulePauseOnNextStatement(
688 protocol::Debugger::Paused::ReasonEnum::Other, nullptr);
689 } else if (isScheduledTask) {
dgozman 2017/03/03 19:47:06 return;
kozy 2017/03/03 23:14:02 Done.
690 DCHECK(type == v8::debug::kDebugDidHandle);
691 agent->cancelPauseOnNextStatement();
dgozman 2017/03/03 19:47:06 Would that interfere with stepping? Should we even
kozy 2017/03/03 23:14:02 Should not interfere with traditional stepping and
692 m_taskWithScheduledBreak = nullptr;
693 }
694 }
695
661 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() { 696 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() {
662 if (!m_currentStacks.size()) return nullptr; 697 if (!m_currentStacks.size()) return nullptr;
663 return m_currentStacks.back().get(); 698 return m_currentStacks.back().get();
664 } 699 }
665 700
666 void V8Debugger::compileDebuggerScript() { 701 void V8Debugger::compileDebuggerScript() {
667 if (!m_debuggerScript.IsEmpty()) { 702 if (!m_debuggerScript.IsEmpty()) {
668 UNREACHABLE(); 703 UNREACHABLE();
669 return; 704 return;
670 } 705 }
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 createDataProperty(context, properties, properties->Length(), 830 createDataProperty(context, properties, properties->Length(),
796 toV8StringInternalized(m_isolate, "[[Scopes]]")); 831 toV8StringInternalized(m_isolate, "[[Scopes]]"));
797 createDataProperty(context, properties, properties->Length(), scopes); 832 createDataProperty(context, properties, properties->Length(), scopes);
798 } 833 }
799 } 834 }
800 return properties; 835 return properties;
801 } 836 }
802 837
803 std::unique_ptr<V8StackTraceImpl> V8Debugger::createStackTrace( 838 std::unique_ptr<V8StackTraceImpl> V8Debugger::createStackTrace(
804 v8::Local<v8::StackTrace> stackTrace) { 839 v8::Local<v8::StackTrace> stackTrace) {
805 int contextGroupId = 840 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); 841 V8StackTraceImpl::maxCallStackSizeToCapture);
811 } 842 }
812 843
813 void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) { 844 void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) {
814 if (depth <= 0) 845 if (depth <= 0)
815 m_maxAsyncCallStackDepthMap.erase(agent); 846 m_maxAsyncCallStackDepthMap.erase(agent);
816 else 847 else
817 m_maxAsyncCallStackDepthMap[agent] = depth; 848 m_maxAsyncCallStackDepthMap[agent] = depth;
818 849
819 int maxAsyncCallStackDepth = 0; 850 int maxAsyncCallStackDepth = 0;
(...skipping 16 matching lines...) Expand all
836 if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) { 867 if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) {
837 void* taskToRemove = m_idToTask.begin()->second; 868 void* taskToRemove = m_idToTask.begin()->second;
838 asyncTaskCanceled(taskToRemove); 869 asyncTaskCanceled(taskToRemove);
839 } 870 }
840 } 871 }
841 872
842 void V8Debugger::asyncTaskCreated(void* task, void* parentTask) { 873 void V8Debugger::asyncTaskCreated(void* task, void* parentTask) {
843 if (!m_maxAsyncCallStackDepth) return; 874 if (!m_maxAsyncCallStackDepth) return;
844 if (parentTask) m_parentTask[task] = parentTask; 875 if (parentTask) m_parentTask[task] = parentTask;
845 v8::HandleScope scope(m_isolate); 876 v8::HandleScope scope(m_isolate);
846 // We don't need to pass context group id here because we gets this callback 877 // We don't need to pass context group id here because we get this callback
847 // from V8 for promise events only. 878 // from V8 for promise events only.
848 // Passing one as maxStackSize forces no async chain for the new stack and 879 // Passing one as maxStackSize forces no async chain for the new stack and
849 // allows us to not grow exponentially. 880 // allows us to not grow exponentially.
850 std::unique_ptr<V8StackTraceImpl> creationStack = 881 std::unique_ptr<V8StackTraceImpl> creationStack =
851 V8StackTraceImpl::capture(this, 0, 1, String16()); 882 V8StackTraceImpl::capture(this, 0, 1, String16());
852 if (creationStack && !creationStack->isEmpty()) { 883 if (creationStack && !creationStack->isEmpty()) {
853 m_asyncTaskCreationStacks[task] = std::move(creationStack); 884 m_asyncTaskCreationStacks[task] = std::move(creationStack);
854 registerAsyncTaskIfNeeded(task); 885 registerAsyncTaskIfNeeded(task);
855 } 886 }
856 } 887 }
857 888
858 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, 889 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task,
859 bool recurring) { 890 bool recurring) {
860 if (!m_maxAsyncCallStackDepth) return; 891 if (!m_maxAsyncCallStackDepth) return;
861 asyncTaskScheduled(toString16(taskName), task, recurring); 892 asyncTaskScheduled(toString16(taskName), task, recurring);
862 } 893 }
863 894
864 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, 895 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task,
865 bool recurring) { 896 bool recurring) {
866 if (!m_maxAsyncCallStackDepth) return; 897 if (!m_maxAsyncCallStackDepth) return;
867 v8::HandleScope scope(m_isolate); 898 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( 899 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture(
873 this, contextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture, 900 this, currentContextGroupId(),
874 taskName); 901 V8StackTraceImpl::maxCallStackSizeToCapture, taskName);
875 if (chain) { 902 if (chain) {
876 m_asyncTaskStacks[task] = std::move(chain); 903 m_asyncTaskStacks[task] = std::move(chain);
877 if (recurring) m_recurringTasks.insert(task); 904 if (recurring) m_recurringTasks.insert(task);
878 registerAsyncTaskIfNeeded(task); 905 registerAsyncTaskIfNeeded(task);
879 } 906 }
880 } 907 }
881 908
882 void V8Debugger::asyncTaskCanceled(void* task) { 909 void V8Debugger::asyncTaskCanceled(void* task) {
883 if (!m_maxAsyncCallStackDepth) return; 910 if (!m_maxAsyncCallStackDepth) return;
884 m_asyncTaskStacks.erase(task); 911 m_asyncTaskStacks.erase(task);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 void V8Debugger::unmuteScriptParsedEvents() { 974 void V8Debugger::unmuteScriptParsedEvents() {
948 --m_ignoreScriptParsedEventsCounter; 975 --m_ignoreScriptParsedEventsCounter;
949 DCHECK_GE(m_ignoreScriptParsedEventsCounter, 0); 976 DCHECK_GE(m_ignoreScriptParsedEventsCounter, 0);
950 } 977 }
951 978
952 std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace( 979 std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace(
953 bool fullStack) { 980 bool fullStack) {
954 if (!m_isolate->InContext()) return nullptr; 981 if (!m_isolate->InContext()) return nullptr;
955 982
956 v8::HandleScope handles(m_isolate); 983 v8::HandleScope handles(m_isolate);
957 int contextGroupId = 984 int contextGroupId = currentContextGroupId();
958 m_inspector->contextGroupId(m_isolate->GetCurrentContext());
959 if (!contextGroupId) return nullptr; 985 if (!contextGroupId) return nullptr;
960 986
961 size_t stackSize = 987 size_t stackSize =
962 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; 988 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1;
963 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) 989 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId))
964 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; 990 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
965 991
966 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); 992 return V8StackTraceImpl::capture(this, contextGroupId, stackSize);
967 } 993 }
968 994
995 int V8Debugger::currentContextGroupId() {
996 if (!m_isolate->InContext()) return 0;
997 return m_inspector->contextGroupId(m_isolate->GetCurrentContext());
998 }
999
969 } // namespace v8_inspector 1000 } // namespace v8_inspector
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698