Chromium Code Reviews| Index: src/inspector/v8-stack-trace-impl.cc |
| diff --git a/src/inspector/v8-stack-trace-impl.cc b/src/inspector/v8-stack-trace-impl.cc |
| index 962a00a773ded450312a8c5005601178c0773f76..0875de7c852225bf04d23b52e6db62407cc102ac 100644 |
| --- a/src/inspector/v8-stack-trace-impl.cc |
| +++ b/src/inspector/v8-stack-trace-impl.cc |
| @@ -141,16 +141,34 @@ std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::create( |
| maxAsyncCallChainDepth = 1; |
| } |
| - // Only the top stack in the chain may be empty, so ensure that second stack |
| - // is non-empty (it's the top of appended chain). |
| - if (asyncCallChain && asyncCallChain->isEmpty()) |
| + // Only the top stack in the chain may be empty and doesn't contain creation |
| + // stack , so ensure that second stack is non-empty (it's the top of appended |
| + // chain). |
| + if (asyncCallChain && asyncCallChain->isEmpty() && |
| + !asyncCallChain->m_creation) { |
| asyncCallChain = asyncCallChain->m_parent.get(); |
| + } |
| + |
| + // When async call chain is empty but doesn't contain useful schedule stack |
| + // and parent async call chain contains creationg stack but doesn't |
| + // synchronous we can merge them together. |
| + // e.g. Promise ThenableJob. |
| + if (asyncCallChain && asyncCallChain->isEmpty() && asyncCallChain->m_parent) { |
|
dgozman
2017/01/24 23:57:44
Let's move this logic to setCreationStack to avoid
kozy
2017/01/25 00:45:43
Done.
|
| + if (asyncCallChain->m_creation && asyncCallChain->isEmpty() && |
| + !asyncCallChain->m_parent->m_creation && |
| + asyncCallChain->m_description == |
| + asyncCallChain->m_parent->m_description) { |
| + asyncCallChain->m_parent->m_creation = |
| + std::move(asyncCallChain->m_creation); |
| + asyncCallChain = asyncCallChain->m_parent.get(); |
| + } |
| + } |
| if (stackTrace.IsEmpty() && !asyncCallChain) return nullptr; |
| std::unique_ptr<V8StackTraceImpl> result(new V8StackTraceImpl( |
| contextGroupId, description, frames, |
| - asyncCallChain ? asyncCallChain->cloneImpl() : nullptr)); |
| + asyncCallChain ? asyncCallChain->cloneImpl() : nullptr, nullptr)); |
| // Crop to not exceed maxAsyncCallChainDepth. |
| V8StackTraceImpl* deepest = result.get(); |
| @@ -182,24 +200,27 @@ std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::cloneImpl() { |
| std::vector<Frame> framesCopy(m_frames); |
| return std::unique_ptr<V8StackTraceImpl>( |
| new V8StackTraceImpl(m_contextGroupId, m_description, framesCopy, |
| - m_parent ? m_parent->cloneImpl() : nullptr)); |
| + m_parent ? m_parent->cloneImpl() : nullptr, |
| + m_creation ? m_creation->cloneImpl() : nullptr)); |
| } |
| std::unique_ptr<V8StackTrace> V8StackTraceImpl::clone() { |
| std::vector<Frame> frames; |
| for (size_t i = 0; i < m_frames.size(); i++) |
| frames.push_back(m_frames.at(i).clone()); |
| - return std::unique_ptr<V8StackTraceImpl>( |
| - new V8StackTraceImpl(m_contextGroupId, m_description, frames, nullptr)); |
| + return std::unique_ptr<V8StackTraceImpl>(new V8StackTraceImpl( |
| + m_contextGroupId, m_description, frames, nullptr, nullptr)); |
| } |
| V8StackTraceImpl::V8StackTraceImpl(int contextGroupId, |
| const String16& description, |
| std::vector<Frame>& frames, |
| - std::unique_ptr<V8StackTraceImpl> parent) |
| + std::unique_ptr<V8StackTraceImpl> parent, |
| + std::unique_ptr<V8StackTraceImpl> creation) |
| : m_contextGroupId(contextGroupId), |
| m_description(description), |
| - m_parent(std::move(parent)) { |
| + m_parent(std::move(parent)), |
| + m_creation(std::move(creation)) { |
| m_frames.swap(frames); |
| } |
| @@ -243,6 +264,10 @@ V8StackTraceImpl::buildInspectorObjectImpl() const { |
| .build(); |
| if (!m_description.isEmpty()) stackTrace->setDescription(m_description); |
| if (m_parent) stackTrace->setParent(m_parent->buildInspectorObjectImpl()); |
| + if (m_creation && m_creation->m_frames.size()) { |
| + stackTrace->setPromiseCreationFrame( |
| + m_creation->m_frames[0].buildInspectorObject()); |
| + } |
| return stackTrace; |
| } |