Commit 46f7b628 authored by keishi@chromium.org's avatar keishi@chromium.org

Oilpan: Prepare moving AsyncCallStackTracker to Oilpan

BUG=340522

Review URL: https://codereview.chromium.org/422273002

git-svn-id: svn://svn.chromium.org/blink/trunk@180088 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 8f844b42
......@@ -33,7 +33,6 @@
#include "bindings/core/v8/V8Binding.h"
#include "bindings/core/v8/V8RecursionScope.h"
#include "core/dom/ContextLifecycleObserver.h"
#include "core/dom/ExecutionContext.h"
#include "core/dom/ExecutionContextTask.h"
#include "core/events/Event.h"
......@@ -56,48 +55,36 @@ static const char enqueueMutationRecordName[] = "Mutation";
namespace blink {
class AsyncCallStackTracker::ExecutionContextData FINAL : public ContextLifecycleObserver {
WTF_MAKE_FAST_ALLOCATED;
public:
ExecutionContextData(AsyncCallStackTracker* tracker, ExecutionContext* executionContext)
: ContextLifecycleObserver(executionContext)
, m_circularSequentialID(0)
, m_tracker(tracker)
{
}
virtual void contextDestroyed() OVERRIDE
{
ASSERT(executionContext());
ExecutionContextData* self = m_tracker->m_executionContextDataMap.take(executionContext());
ASSERT(self == this);
ContextLifecycleObserver::contextDestroyed();
delete self;
}
void AsyncCallStackTracker::ExecutionContextData::contextDestroyed()
{
ASSERT(executionContext());
OwnPtrWillBeRawPtr<ExecutionContextData> self = m_tracker->m_executionContextDataMap.take(executionContext());
ASSERT(self == this);
ContextLifecycleObserver::contextDestroyed();
}
int circularSequentialID()
{
++m_circularSequentialID;
if (m_circularSequentialID <= 0)
m_circularSequentialID = 1;
return m_circularSequentialID;
}
int AsyncCallStackTracker::ExecutionContextData::circularSequentialID()
{
++m_circularSequentialID;
if (m_circularSequentialID <= 0)
m_circularSequentialID = 1;
return m_circularSequentialID;
}
private:
int m_circularSequentialID;
public:
AsyncCallStackTracker* m_tracker;
HashSet<int> m_intervalTimerIds;
HashMap<int, RefPtr<AsyncCallChain> > m_timerCallChains;
HashMap<int, RefPtr<AsyncCallChain> > m_animationFrameCallChains;
HashMap<Event*, RefPtr<AsyncCallChain> > m_eventCallChains;
HashMap<EventTarget*, RefPtr<AsyncCallChain> > m_xhrCallChains;
HashMap<MutationObserver*, RefPtr<AsyncCallChain> > m_mutationObserverCallChains;
HashMap<ExecutionContextTask*, RefPtr<AsyncCallChain> > m_executionContextTaskCallChains;
HashMap<String, RefPtr<AsyncCallChain> > m_v8AsyncTaskCallChains;
HashMap<int, RefPtr<AsyncCallChain> > m_asyncOperationCallChains;
};
void AsyncCallStackTracker::ExecutionContextData::trace(Visitor* visitor)
{
visitor->trace(m_tracker);
#if ENABLE(OILPAN)
visitor->trace(m_timerCallChains);
visitor->trace(m_animationFrameCallChains);
visitor->trace(m_eventCallChains);
visitor->trace(m_xhrCallChains);
visitor->trace(m_mutationObserverCallChains);
visitor->trace(m_executionContextTaskCallChains);
visitor->trace(m_v8AsyncTaskCallChains);
visitor->trace(m_asyncOperationCallChains);
#endif
}
static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget)
{
......@@ -109,6 +96,11 @@ static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget)
return 0;
}
void AsyncCallStackTracker::AsyncCallChain::trace(Visitor* visitor)
{
visitor->trace(m_callStacks);
}
AsyncCallStackTracker::AsyncCallStack::AsyncCallStack(const String& description, const ScriptValue& callFrames)
: m_description(description)
, m_callFrames(callFrames)
......@@ -411,19 +403,19 @@ void AsyncCallStackTracker::didFireAsyncCall()
clearCurrentAsyncCallChain();
}
PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createAsyncCallChain(const String& description, const ScriptValue& callFrames)
PassRefPtrWillBeRawPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createAsyncCallChain(const String& description, const ScriptValue& callFrames)
{
if (callFrames.isEmpty()) {
ASSERT(m_currentAsyncCallChain);
return m_currentAsyncCallChain; // Propogate async call stack chain.
}
RefPtr<AsyncCallChain> chain = adoptRef(m_currentAsyncCallChain ? new AsyncCallStackTracker::AsyncCallChain(*m_currentAsyncCallChain) : new AsyncCallStackTracker::AsyncCallChain());
RefPtrWillBeRawPtr<AsyncCallChain> chain = adoptRefWillBeNoop(m_currentAsyncCallChain ? new AsyncCallStackTracker::AsyncCallChain(*m_currentAsyncCallChain) : new AsyncCallStackTracker::AsyncCallChain());
ensureMaxAsyncCallChainDepth(chain.get(), m_maxAsyncCallStackDepth - 1);
chain->m_callStacks.prepend(adoptRef(new AsyncCallStackTracker::AsyncCallStack(description, callFrames)));
chain->m_callStacks.prepend(adoptRefWillBeNoop(new AsyncCallStackTracker::AsyncCallStack(description, callFrames)));
return chain.release();
}
void AsyncCallStackTracker::setCurrentAsyncCallChain(ExecutionContext* context, PassRefPtr<AsyncCallChain> chain)
void AsyncCallStackTracker::setCurrentAsyncCallChain(ExecutionContext* context, PassRefPtrWillBeRawPtr<AsyncCallChain> chain)
{
if (chain && !V8RecursionScope::recursionLevel(toIsolate(context))) {
// Current AsyncCallChain corresponds to the bottommost JS call frame.
......@@ -459,8 +451,8 @@ AsyncCallStackTracker::ExecutionContextData* AsyncCallStackTracker::createContex
{
ExecutionContextData* data = m_executionContextDataMap.get(context);
if (!data) {
data = new AsyncCallStackTracker::ExecutionContextData(this, context);
m_executionContextDataMap.set(context, data);
data = m_executionContextDataMap.set(context, adoptPtrWillBeNoop(new AsyncCallStackTracker::ExecutionContextData(this, context)))
.storedValue->value.get();
}
return data;
}
......@@ -469,10 +461,15 @@ void AsyncCallStackTracker::clear()
{
m_currentAsyncCallChain.clear();
m_nestedAsyncCallCount = 0;
ExecutionContextDataMap copy;
m_executionContextDataMap.swap(copy);
for (ExecutionContextDataMap::const_iterator it = copy.begin(); it != copy.end(); ++it)
delete it->value;
m_executionContextDataMap.clear();
}
void AsyncCallStackTracker::trace(Visitor* visitor)
{
visitor->trace(m_currentAsyncCallChain);
#if ENABLE(OILPAN)
visitor->trace(m_executionContextDataMap);
#endif
}
} // namespace blink
......@@ -32,6 +32,7 @@
#define AsyncCallStackTracker_h
#include "bindings/core/v8/ScriptValue.h"
#include "core/dom/ContextLifecycleObserver.h"
#include "wtf/Deque.h"
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
......@@ -49,13 +50,14 @@ class ExecutionContextTask;
class MutationObserver;
class XMLHttpRequest;
class AsyncCallStackTracker {
class AsyncCallStackTracker FINAL : public NoBaseWillBeGarbageCollectedFinalized<AsyncCallStackTracker> {
WTF_MAKE_NONCOPYABLE(AsyncCallStackTracker);
public:
class AsyncCallStack : public RefCounted<AsyncCallStack> {
class AsyncCallStack FINAL : public RefCountedWillBeGarbageCollectedFinalized<AsyncCallStack> {
public:
AsyncCallStack(const String&, const ScriptValue&);
~AsyncCallStack();
void trace(Visitor*) { }
String description() const { return m_description; }
ScriptValue callFrames() const { return m_callFrames; }
private:
......@@ -63,18 +65,51 @@ public:
ScriptValue m_callFrames;
};
typedef Deque<RefPtr<AsyncCallStack>, 4> AsyncCallStackVector;
typedef WillBeHeapDeque<RefPtrWillBeMember<AsyncCallStack>, 4> AsyncCallStackVector;
class AsyncCallChain : public RefCounted<AsyncCallChain> {
class AsyncCallChain FINAL : public RefCountedWillBeGarbageCollected<AsyncCallChain> {
public:
AsyncCallChain() { }
AsyncCallChain(const AsyncCallChain& t) : m_callStacks(t.m_callStacks) { }
AsyncCallStackVector callStacks() const { return m_callStacks; }
void trace(Visitor*);
private:
friend class AsyncCallStackTracker;
AsyncCallStackVector m_callStacks;
};
class ExecutionContextData FINAL : public NoBaseWillBeGarbageCollectedFinalized<ExecutionContextData>, public ContextLifecycleObserver {
WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
ExecutionContextData(AsyncCallStackTracker* tracker, ExecutionContext* executionContext)
: ContextLifecycleObserver(executionContext)
, m_circularSequentialID(0)
, m_tracker(tracker)
{
}
virtual void contextDestroyed() OVERRIDE;
int circularSequentialID();
void trace(Visitor*);
private:
int m_circularSequentialID;
public:
RawPtrWillBeMember<AsyncCallStackTracker> m_tracker;
HashSet<int> m_intervalTimerIds;
WillBeHeapHashMap<int, RefPtrWillBeMember<AsyncCallChain> > m_timerCallChains;
WillBeHeapHashMap<int, RefPtrWillBeMember<AsyncCallChain> > m_animationFrameCallChains;
WillBeHeapHashMap<RawPtrWillBeMember<Event>, RefPtrWillBeMember<AsyncCallChain> > m_eventCallChains;
WillBeHeapHashMap<RawPtrWillBeMember<EventTarget>, RefPtrWillBeMember<AsyncCallChain> > m_xhrCallChains;
WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, RefPtrWillBeMember<AsyncCallChain> > m_mutationObserverCallChains;
WillBeHeapHashMap<ExecutionContextTask*, RefPtrWillBeMember<AsyncCallChain> > m_executionContextTaskCallChains;
WillBeHeapHashMap<String, RefPtrWillBeMember<AsyncCallChain> > m_v8AsyncTaskCallChains;
WillBeHeapHashMap<int, RefPtrWillBeMember<AsyncCallChain> > m_asyncOperationCallChains;
};
AsyncCallStackTracker();
bool isEnabled() const { return m_maxAsyncCallStackDepth; }
......@@ -115,22 +150,23 @@ public:
void didFireAsyncCall();
void clear();
void trace(Visitor*);
private:
void willHandleXHREvent(XMLHttpRequest*, Event*);
PassRefPtr<AsyncCallChain> createAsyncCallChain(const String& description, const ScriptValue& callFrames);
void setCurrentAsyncCallChain(ExecutionContext*, PassRefPtr<AsyncCallChain>);
PassRefPtrWillBeRawPtr<AsyncCallChain> createAsyncCallChain(const String& description, const ScriptValue& callFrames);
void setCurrentAsyncCallChain(ExecutionContext*, PassRefPtrWillBeRawPtr<AsyncCallChain>);
void clearCurrentAsyncCallChain();
static void ensureMaxAsyncCallChainDepth(AsyncCallChain*, unsigned);
bool validateCallFrames(const ScriptValue& callFrames);
class ExecutionContextData;
ExecutionContextData* createContextDataIfNeeded(ExecutionContext*);
unsigned m_maxAsyncCallStackDepth;
RefPtr<AsyncCallChain> m_currentAsyncCallChain;
RefPtrWillBeMember<AsyncCallChain> m_currentAsyncCallChain;
unsigned m_nestedAsyncCallCount;
typedef HashMap<ExecutionContext*, ExecutionContextData*> ExecutionContextDataMap;
typedef WillBeHeapHashMap<RawPtrWillBeMember<ExecutionContext>, OwnPtrWillBeMember<ExecutionContextData> > ExecutionContextDataMap;
ExecutionContextDataMap m_executionContextDataMap;
};
......
......@@ -238,6 +238,7 @@ private:
PassRefPtrWillBeRawPtr<JavaScriptCallFrame> topCallFrameSkipUnknownSources();
String scriptURL(JavaScriptCallFrame*);
AsyncCallStackTracker& asyncCallStackTracker() { return *m_asyncCallStackTracker; };
typedef HashMap<String, Script> ScriptsMap;
typedef HashMap<String, Vector<String> > BreakpointIdToDebugServerBreakpointIdsMap;
......@@ -263,7 +264,7 @@ private:
int m_minFrameCountForSkip;
bool m_skipAllPauses;
OwnPtr<ScriptRegexp> m_cachedSkipStackRegExp;
AsyncCallStackTracker m_asyncCallStackTracker;
OwnPtrWillBeMember<AsyncCallStackTracker> m_asyncCallStackTracker;
};
} // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment