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