Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "config.h" | |
| 6 #include "core/inspector/PromiseTracker.h" | |
| 7 | |
| 8 #include "bindings/core/v8/ScriptCallStackFactory.h" | |
| 9 #include "bindings/core/v8/ScriptState.h" | |
| 10 | |
| 11 namespace blink { | |
| 12 | |
| 13 struct PromiseTracker::PromiseDataWrapper { | |
|
aandrey
2014/08/04 16:58:47
wrap into an anonymous namespace
Alexandra Mikhaylova
2014/08/06 13:28:39
How can it be compliant with the private method Pr
| |
| 14 WTF_MAKE_NONCOPYABLE(PromiseDataWrapper); | |
| 15 public: | |
| 16 PromiseDataWrapper(WeakPtr<PromiseData> data) | |
| 17 : m_data(data) | |
| 18 { | |
| 19 } | |
| 20 | |
| 21 WeakPtr<PromiseData> m_data; | |
| 22 | |
| 23 static void didRemovePromise(const v8::WeakCallbackData<v8::Object, PromiseD ataWrapper>& data) | |
| 24 { | |
| 25 OwnPtr<PromiseDataWrapper> wrapper = adoptPtr(data.GetParameter()); | |
| 26 WeakPtr<PromiseData> promiseData = wrapper->m_data; | |
| 27 if (!(promiseData.get() && promiseData->m_promiseTracker->isEnabled())) | |
|
aandrey
2014/08/04 16:58:48
if (!promiseData)
return;
PromiseTracker* trac
Alexandra Mikhaylova
2014/08/06 13:28:39
Done.
| |
| 28 return; | |
| 29 | |
| 30 promiseData->m_promiseTracker->didRemovePromise(promiseData->m_scriptSta te.get(), promiseData->m_promise); | |
| 31 } | |
| 32 }; | |
| 33 | |
| 34 PromiseTracker::PromiseData::PromiseData(const ScopedPersistent<v8::Object>& pro mise, const ScopedPersistent<v8::Object>& parentPromise, int status, ScriptState * scriptState, PromiseTracker* tracker, bool captureStack) | |
| 35 : m_scriptState(scriptState) | |
| 36 , m_promiseTracker(tracker) | |
| 37 , m_promise(scriptState->isolate(), promise.newLocal(scriptState->isolate()) ) | |
|
aandrey
2014/08/04 16:58:48
make copy constructor on ScopedPersistent
Alexandra Mikhaylova
2014/08/06 13:28:39
Switched back to v8::Handle instead.
| |
| 38 , m_parentPromise(scriptState->isolate(), parentPromise.newLocal(scriptState ->isolate())) | |
| 39 , m_status(status) | |
| 40 , m_weakPtrFactory(this) | |
| 41 { | |
| 42 if (captureStack) { | |
| 43 v8::Isolate* isolate = scriptState->isolate(); | |
| 44 v8::Handle<v8::StackTrace> stackTrace(v8::StackTrace::CurrentStackTrace( isolate, 1)); | |
| 45 RefPtrWillBeRawPtr<ScriptCallStack> stack = createScriptCallStack(stackT race, 1, isolate); | |
| 46 if (stack->size()) | |
| 47 m_callFrame = stack->at(0); | |
| 48 } | |
| 49 PromiseDataWrapper* wrapper = new PromiseDataWrapper(m_weakPtrFactory.create WeakPtr()); | |
| 50 m_promise.setWeak(wrapper, &PromiseTracker::PromiseDataWrapper::didRemovePro mise); | |
| 51 } | |
| 52 | |
| 53 void PromiseTracker::enable() | |
| 54 { | |
| 55 m_isEnabled = true; | |
| 56 } | |
| 57 | |
| 58 void PromiseTracker::disable() | |
| 59 { | |
| 60 m_isEnabled = false; | |
| 61 clear(); | |
| 62 } | |
| 63 | |
| 64 void PromiseTracker::clear() | |
| 65 { | |
| 66 m_promiseDataMap.clear(); | |
| 67 } | |
| 68 | |
| 69 PromiseTracker::PromiseDataVector* PromiseTracker::promiseVector(ScriptState* sc riptState, const ScopedPersistent<v8::Object>& promise) | |
| 70 { | |
| 71 ASSERT(isEnabled()); | |
| 72 | |
| 73 int promiseHash = promise.newLocal(scriptState->isolate())->GetIdentityHash( ); | |
| 74 PromiseDataMap::iterator it = m_promiseDataMap.find(promiseHash); | |
| 75 if (it != m_promiseDataMap.end()) | |
| 76 return &it->value; | |
| 77 return &m_promiseDataMap.add(promiseHash, PromiseDataVector()).storedValue-> value; | |
| 78 } | |
| 79 | |
| 80 void PromiseTracker::didReceiveV8PromiseEvent(ScriptState* scriptState, const Sc opedPersistent<v8::Object>& promise, const ScopedPersistent<v8::Object>& parentP romise, int status) | |
| 81 { | |
| 82 ASSERT(isEnabled()); | |
| 83 | |
| 84 if (status != 0) { | |
| 85 didUpdatePromiseStatus(scriptState, promise, status); | |
| 86 } else if (!parentPromise.isEmpty()) { | |
| 87 didUpdatePromiseParent(scriptState, promise, parentPromise); | |
| 88 } else { | |
| 89 didCreatePromise(scriptState, promise); | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 void PromiseTracker::didCreatePromise(ScriptState* scriptState, const ScopedPers istent<v8::Object>& promise) | |
| 94 { | |
| 95 PromiseDataVector* vector = promiseVector(scriptState, promise); | |
| 96 vector->append(adoptRef(new PromiseData(promise, ScopedPersistent<v8::Object >(), 0, scriptState, this, true))); | |
| 97 } | |
| 98 | |
| 99 void PromiseTracker::didUpdatePromiseParent(ScriptState* scriptState, const Scop edPersistent<v8::Object>& promise, const ScopedPersistent<v8::Object>& parentPro mise) | |
| 100 { | |
| 101 PromiseDataVector* vector = promiseVector(scriptState, promise); | |
| 102 bool found = false; | |
| 103 for (size_t index = 0; index < vector->size(); ++index) { | |
| 104 RefPtr<PromiseData> data = (*vector)[index]; | |
|
aandrey
2014/08/04 16:58:48
vector->at(index)
Alexandra Mikhaylova
2014/08/06 13:28:39
Done.
| |
| 105 if (data->m_promise == promise) { | |
| 106 found = true; | |
| 107 v8::Isolate* isolate = scriptState->isolate(); | |
| 108 data->m_parentPromise.set(isolate, parentPromise.newLocal(isolate)); | |
|
aandrey
2014/08/04 16:58:48
should be no newLocal() call
Alexandra Mikhaylova
2014/08/06 13:28:39
Done.
| |
| 109 break; | |
| 110 } | |
| 111 } | |
| 112 if (!found) | |
| 113 vector->append(adoptRef(new PromiseData(promise, parentPromise, 0, scrip tState, this))); | |
| 114 } | |
| 115 | |
| 116 void PromiseTracker::didUpdatePromiseStatus(ScriptState* scriptState, const Scop edPersistent<v8::Object>& promise, int status) | |
| 117 { | |
| 118 PromiseDataVector* vector = promiseVector(scriptState, promise); | |
| 119 bool found = false; | |
| 120 for (size_t index = 0; index < vector->size(); ++index) { | |
| 121 RefPtr<PromiseData> data = (*vector)[index]; | |
| 122 if (data->m_promise == promise) { | |
| 123 found = true; | |
| 124 data->m_status = status; | |
| 125 break; | |
| 126 } | |
| 127 } | |
| 128 if (!found) | |
| 129 vector->append(adoptRef(new PromiseData(promise, ScopedPersistent<v8::Ob ject>(), status, scriptState, this))); | |
| 130 } | |
| 131 | |
| 132 void PromiseTracker::didRemovePromise(ScriptState* scriptState, ScopedPersistent <v8::Object>& promise) | |
| 133 { | |
| 134 ASSERT(isEnabled()); | |
| 135 | |
| 136 int promiseHash = promise.newLocal(scriptState->isolate())->GetIdentityHash( ); | |
|
aandrey
2014/08/04 16:58:48
we can remove m_scriptState if we cache the identi
Alexandra Mikhaylova
2014/08/06 13:28:39
Done.
| |
| 137 | |
| 138 PromiseDataVector* vector = promiseVector(scriptState, promise); | |
| 139 ASSERT(vector->size() >= 1); | |
| 140 bool found = false; | |
| 141 for (size_t index = 0; index < vector->size(); ++index) { | |
| 142 RefPtr<PromiseData> data = (*vector)[index]; | |
| 143 if (data->m_promise == promise) { | |
| 144 found = true; | |
| 145 vector->remove(index); | |
|
aandrey
2014/08/04 16:58:48
too much code duplication
| |
| 146 break; | |
| 147 } | |
| 148 } | |
| 149 if (vector->size() == 0) | |
| 150 m_promiseDataMap.remove(promiseHash); | |
| 151 } | |
| 152 | |
| 153 } // namespace blink | |
| OLD | NEW |