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

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

Issue 2578923002: [inspector] async stacks for Promise.then calls... (Closed)
Patch Set: avoid calling functions Created 3 years, 11 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
« no previous file with comments | « src/inspector/v8-debugger.h ('k') | src/isolate.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 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"
11 #include "src/inspector/string-util.h" 11 #include "src/inspector/string-util.h"
12 #include "src/inspector/v8-debugger-agent-impl.h" 12 #include "src/inspector/v8-debugger-agent-impl.h"
13 #include "src/inspector/v8-inspector-impl.h" 13 #include "src/inspector/v8-inspector-impl.h"
14 #include "src/inspector/v8-internal-value-type.h" 14 #include "src/inspector/v8-internal-value-type.h"
15 #include "src/inspector/v8-stack-trace-impl.h" 15 #include "src/inspector/v8-stack-trace-impl.h"
16 #include "src/inspector/v8-value-copier.h" 16 #include "src/inspector/v8-value-copier.h"
17 17
18 #include "include/v8-util.h" 18 #include "include/v8-util.h"
19 19
20 namespace v8_inspector { 20 namespace v8_inspector {
21 21
22 namespace { 22 namespace {
23 static const char v8AsyncTaskEventEnqueue[] = "enqueue";
24 static const char v8AsyncTaskEventEnqueueRecurring[] = "enqueueRecurring";
25 static const char v8AsyncTaskEventWillHandle[] = "willHandle";
26 static const char v8AsyncTaskEventDidHandle[] = "didHandle";
27 static const char v8AsyncTaskEventCancel[] = "cancel";
28 23
29 // Based on DevTools frontend measurement, with asyncCallStackDepth = 4, 24 // Based on DevTools frontend measurement, with asyncCallStackDepth = 4,
30 // average async call stack tail requires ~1 Kb. Let's reserve ~ 128 Mb 25 // average async call stack tail requires ~1 Kb. Let's reserve ~ 128 Mb
31 // for async stacks. 26 // for async stacks.
32 static const int kMaxAsyncTaskStacks = 128 * 1024; 27 static const int kMaxAsyncTaskStacks = 128 * 1024;
33 28
34 inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) { 29 inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) {
35 return value ? v8::True(isolate) : v8::False(isolate); 30 return value ? v8::True(isolate) : v8::False(isolate);
36 } 31 }
37 32
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 .ToLocalChecked(); 523 .ToLocalChecked();
529 DCHECK(!getterValue.IsEmpty() && getterValue->IsFunction()); 524 DCHECK(!getterValue.IsEmpty() && getterValue->IsFunction());
530 return v8::Local<v8::Function>::Cast(getterValue) 525 return v8::Local<v8::Function>::Cast(getterValue)
531 ->Call(m_isolate->GetCurrentContext(), object, 0, nullptr) 526 ->Call(m_isolate->GetCurrentContext(), object, 0, nullptr)
532 .ToLocalChecked(); 527 .ToLocalChecked();
533 } 528 }
534 529
535 void V8Debugger::handleV8DebugEvent( 530 void V8Debugger::handleV8DebugEvent(
536 const v8::debug::EventDetails& eventDetails) { 531 const v8::debug::EventDetails& eventDetails) {
537 if (!enabled()) return; 532 if (!enabled()) return;
533 v8::HandleScope scope(m_isolate);
534
538 v8::DebugEvent event = eventDetails.GetEvent(); 535 v8::DebugEvent event = eventDetails.GetEvent();
539 if (event != v8::AsyncTaskEvent && event != v8::Break && 536 if (event != v8::AsyncTaskEvent && event != v8::Break &&
540 event != v8::Exception && event != v8::AfterCompile && 537 event != v8::Exception && event != v8::AfterCompile &&
541 event != v8::CompileError) 538 event != v8::CompileError)
542 return; 539 return;
543 540
544 v8::Local<v8::Context> eventContext = eventDetails.GetEventContext();
545 DCHECK(!eventContext.IsEmpty());
546
547 if (event == v8::AsyncTaskEvent) { 541 if (event == v8::AsyncTaskEvent) {
548 v8::HandleScope scope(m_isolate); 542 handleV8AsyncTaskEvent(eventDetails.GetEventData());
549 handleV8AsyncTaskEvent(eventContext, eventDetails.GetExecutionState(),
550 eventDetails.GetEventData());
551 return; 543 return;
552 } 544 }
553 545
546 v8::Local<v8::Context> eventContext = eventDetails.GetEventContext();
547 DCHECK(!eventContext.IsEmpty());
554 V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup( 548 V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup(
555 m_inspector->contextGroupId(eventContext)); 549 m_inspector->contextGroupId(eventContext));
556 if (!agent) return; 550 if (!agent) return;
557 551
558 v8::HandleScope scope(m_isolate);
559 if (event == v8::AfterCompile || event == v8::CompileError) { 552 if (event == v8::AfterCompile || event == v8::CompileError) {
560 v8::Context::Scope contextScope(debuggerContext()); 553 v8::Context::Scope contextScope(debuggerContext());
561 // Determine if the script is a wasm script. 554 // Determine if the script is a wasm script.
562 v8::Local<v8::Value> scriptMirror = 555 v8::Local<v8::Value> scriptMirror =
563 callInternalGetterFunction(eventDetails.GetEventData(), "script"); 556 callInternalGetterFunction(eventDetails.GetEventData(), "script");
564 DCHECK(scriptMirror->IsObject()); 557 DCHECK(scriptMirror->IsObject());
565 v8::Local<v8::Value> scriptWrapper = 558 v8::Local<v8::Value> scriptWrapper =
566 callInternalGetterFunction(scriptMirror.As<v8::Object>(), "value"); 559 callInternalGetterFunction(scriptMirror.As<v8::Object>(), "value");
567 DCHECK(scriptWrapper->IsObject()); 560 DCHECK(scriptWrapper->IsObject());
568 v8::Local<v8::debug::Script> script; 561 v8::Local<v8::debug::Script> script;
(...skipping 27 matching lines...) Expand all
596 v8::Local<v8::Value> hitBreakpoints; 589 v8::Local<v8::Value> hitBreakpoints;
597 if (!callDebuggerMethod("getBreakpointNumbers", 1, argv) 590 if (!callDebuggerMethod("getBreakpointNumbers", 1, argv)
598 .ToLocal(&hitBreakpoints)) 591 .ToLocal(&hitBreakpoints))
599 return; 592 return;
600 DCHECK(hitBreakpoints->IsArray()); 593 DCHECK(hitBreakpoints->IsArray());
601 handleProgramBreak(eventContext, eventDetails.GetExecutionState(), 594 handleProgramBreak(eventContext, eventDetails.GetExecutionState(),
602 v8::Local<v8::Value>(), hitBreakpoints.As<v8::Array>()); 595 v8::Local<v8::Value>(), hitBreakpoints.As<v8::Array>());
603 } 596 }
604 } 597 }
605 598
606 void V8Debugger::handleV8AsyncTaskEvent(v8::Local<v8::Context> context, 599 void V8Debugger::handleV8AsyncTaskEvent(v8::Local<v8::Object> eventData) {
607 v8::Local<v8::Object> executionState,
608 v8::Local<v8::Object> eventData) {
609 if (!m_maxAsyncCallStackDepth) return; 600 if (!m_maxAsyncCallStackDepth) return;
610 601
611 String16 type = toProtocolStringWithTypeCheck( 602 // TODO(kozyatinskiy): remove usage of current context as soon as async event
612 callInternalGetterFunction(eventData, "type")); 603 // is migrated to pure C++ API.
604 v8::debug::PromiseDebugActionType type =
605 static_cast<v8::debug::PromiseDebugActionType>(
606 eventData
607 ->Get(m_isolate->GetCurrentContext(),
608 toV8StringInternalized(m_isolate, "type_"))
609 .ToLocalChecked()
610 ->ToInteger(m_isolate->GetCurrentContext())
611 .ToLocalChecked()
612 ->Value());
613 String16 name = toProtocolStringWithTypeCheck( 613 String16 name = toProtocolStringWithTypeCheck(
614 callInternalGetterFunction(eventData, "name")); 614 eventData
615 int id = static_cast<int>(callInternalGetterFunction(eventData, "id") 615 ->Get(m_isolate->GetCurrentContext(),
616 ->ToInteger(context) 616 toV8StringInternalized(m_isolate, "name_"))
617 .ToLocalChecked());
618 int id = static_cast<int>(eventData
619 ->Get(m_isolate->GetCurrentContext(),
620 toV8StringInternalized(m_isolate, "id_"))
621 .ToLocalChecked()
622 ->ToInteger(m_isolate->GetCurrentContext())
617 .ToLocalChecked() 623 .ToLocalChecked()
618 ->Value()); 624 ->Value());
619 // Async task events from Promises are given misaligned pointers to prevent 625 // Async task events from Promises are given misaligned pointers to prevent
620 // from overlapping with other Blink task identifiers. There is a single 626 // from overlapping with other Blink task identifiers. There is a single
621 // namespace of such ids, managed by src/js/promise.js. 627 // namespace of such ids, managed by src/js/promise.js.
622 void* ptr = reinterpret_cast<void*>(id * 2 + 1); 628 void* ptr = reinterpret_cast<void*>(id * 2 + 1);
623 if (type == v8AsyncTaskEventEnqueue) 629 switch (type) {
624 asyncTaskScheduled(name, ptr, false); 630 case v8::debug::kDebugEnqueueRecurring:
625 else if (type == v8AsyncTaskEventEnqueueRecurring) 631 asyncTaskScheduled(name, ptr, true);
626 asyncTaskScheduled(name, ptr, true); 632 break;
627 else if (type == v8AsyncTaskEventWillHandle) 633 case v8::debug::kDebugCancel:
628 asyncTaskStarted(ptr); 634 asyncTaskCanceled(ptr);
629 else if (type == v8AsyncTaskEventDidHandle) 635 break;
630 asyncTaskFinished(ptr); 636 case v8::debug::kDebugWillHandle:
631 else if (type == v8AsyncTaskEventCancel) 637 asyncTaskStarted(ptr);
632 asyncTaskCanceled(ptr); 638 break;
633 else 639 case v8::debug::kDebugDidHandle:
634 UNREACHABLE(); 640 asyncTaskFinished(ptr);
641 break;
642 }
635 } 643 }
636 644
637 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() { 645 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() {
638 if (!m_currentStacks.size()) return nullptr; 646 if (!m_currentStacks.size()) return nullptr;
639 return m_currentStacks.back().get(); 647 return m_currentStacks.back().get();
640 } 648 }
641 649
642 void V8Debugger::compileDebuggerScript() { 650 void V8Debugger::compileDebuggerScript() {
643 if (!m_debuggerScript.IsEmpty()) { 651 if (!m_debuggerScript.IsEmpty()) {
644 UNREACHABLE(); 652 UNREACHABLE();
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 1010
1003 size_t stackSize = 1011 size_t stackSize =
1004 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; 1012 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1;
1005 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) 1013 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId))
1006 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; 1014 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
1007 1015
1008 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); 1016 return V8StackTraceImpl::capture(this, contextGroupId, stackSize);
1009 } 1017 }
1010 1018
1011 } // namespace v8_inspector 1019 } // namespace v8_inspector
OLDNEW
« no previous file with comments | « src/inspector/v8-debugger.h ('k') | src/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698