Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / core / inspector / PromiseTracker.cpp
blobeb7a4a04d75cde9739b684067d71d81edf434ddc
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.
5 #include "config.h"
6 #include "core/inspector/PromiseTracker.h"
8 #include "bindings/core/v8/ScriptCallStackFactory.h"
9 #include "bindings/core/v8/ScriptState.h"
10 #include "bindings/core/v8/ScriptValue.h"
11 #include "core/inspector/ScriptAsyncCallStack.h"
12 #include "wtf/CurrentTime.h"
13 #include "wtf/PassOwnPtr.h"
14 #include "wtf/WeakPtr.h"
16 using blink::TypeBuilder::Array;
17 using blink::TypeBuilder::Console::CallFrame;
18 using blink::TypeBuilder::Debugger::PromiseDetails;
20 namespace blink {
22 class PromiseTracker::PromiseWeakCallbackData final {
23 WTF_MAKE_NONCOPYABLE(PromiseWeakCallbackData);
24 public:
25 PromiseWeakCallbackData(PromiseTracker* tracker, int id)
26 #if ENABLE(OILPAN)
27 : m_tracker(tracker)
28 #else
29 : m_tracker(tracker->m_weakPtrFactory.createWeakPtr())
30 #endif
31 , m_id(id)
35 ~PromiseWeakCallbackData()
37 if (!m_tracker)
38 return;
39 RefPtr<PromiseDetails> promiseDetails = PromiseDetails::create().setId(m_id);
40 m_tracker->m_listener->didUpdatePromise(InspectorFrontend::Debugger::EventType::Gc, promiseDetails.release());
43 WeakPtrWillBeWeakPersistent<PromiseTracker> m_tracker;
44 int m_id;
47 PromiseTracker::IdToPromiseMapTraits::WeakCallbackDataType* PromiseTracker::IdToPromiseMapTraits::WeakCallbackParameter(MapType* map, int key, v8::Local<v8::Object>& value)
49 // This method is called when promise is added into the map, hence the map must be alive at this point. The tracker in turn must be alive too.
50 PromiseTracker* tracker = reinterpret_cast<PromiseTracker*>(reinterpret_cast<intptr_t>(map) - offsetof(PromiseTracker, m_idToPromise));
51 return new PromiseWeakCallbackData(tracker, key);
54 void PromiseTracker::IdToPromiseMapTraits::DisposeCallbackData(WeakCallbackDataType* callbackData)
56 delete callbackData;
59 void PromiseTracker::IdToPromiseMapTraits::DisposeWeak(const v8::WeakCallbackInfo<WeakCallbackDataType>& data)
61 delete data.GetParameter();
64 PromiseTracker::IdToPromiseMapTraits::MapType* PromiseTracker::IdToPromiseMapTraits::MapFromWeakCallbackInfo(const v8::WeakCallbackInfo<WeakCallbackDataType>& info)
66 return &info.GetParameter()->m_tracker->m_idToPromise;
69 int PromiseTracker::IdToPromiseMapTraits::KeyFromWeakCallbackInfo(const v8::WeakCallbackInfo<WeakCallbackDataType>& info)
71 return info.GetParameter()->m_id;
74 PromiseTracker::PromiseTracker(Listener* listener, v8::Isolate* isolate)
75 : m_circularSequentialId(0)
76 , m_isEnabled(false)
77 , m_captureStacks(false)
78 , m_listener(listener)
79 , m_isolate(isolate)
80 #if !ENABLE(OILPAN)
81 , m_weakPtrFactory(this)
82 #endif
83 , m_idToPromise(isolate)
85 clear();
88 PromiseTracker::~PromiseTracker()
92 DEFINE_TRACE(PromiseTracker)
94 #if ENABLE(OILPAN)
95 visitor->trace(m_listener);
96 #endif
99 void PromiseTracker::setEnabled(bool enabled, bool captureStacks)
101 m_isEnabled = enabled;
102 m_captureStacks = captureStacks;
103 if (!enabled)
104 clear();
107 void PromiseTracker::clear()
109 v8::HandleScope scope(m_isolate);
110 m_promiseToId.Reset(m_isolate, v8::NativeWeakMap::New(m_isolate));
111 m_idToPromise.Clear();
114 int PromiseTracker::circularSequentialId()
116 ++m_circularSequentialId;
117 if (m_circularSequentialId <= 0)
118 m_circularSequentialId = 1;
119 return m_circularSequentialId;
122 int PromiseTracker::promiseId(v8::Local<v8::Object> promise, bool* isNewPromise)
124 v8::HandleScope scope(m_isolate);
125 v8::Local<v8::NativeWeakMap> map = v8::Local<v8::NativeWeakMap>::New(m_isolate, m_promiseToId);
126 v8::Local<v8::Value> value = map->Get(promise);
127 if (value->IsInt32()) {
128 *isNewPromise = false;
129 return value.As<v8::Int32>()->Value();
131 *isNewPromise = true;
132 int id = circularSequentialId();
133 map->Set(promise, v8::Int32::New(m_isolate, id));
134 m_idToPromise.Set(id, promise);
135 return id;
138 void PromiseTracker::didReceiveV8PromiseEvent(ScriptState* scriptState, v8::Local<v8::Object> promise, v8::Local<v8::Value> parentPromise, int status)
140 ASSERT(isEnabled());
141 ASSERT(scriptState->contextIsValid());
143 bool isNewPromise = false;
144 int id = promiseId(promise, &isNewPromise);
146 ScriptState::Scope scope(scriptState);
147 InspectorFrontend::Debugger::EventType::Enum eventType = isNewPromise ? InspectorFrontend::Debugger::EventType::New : InspectorFrontend::Debugger::EventType::Update;
149 PromiseDetails::Status::Enum promiseStatus;
150 switch (status) {
151 case 0:
152 promiseStatus = PromiseDetails::Status::Pending;
153 break;
154 case 1:
155 promiseStatus = PromiseDetails::Status::Resolved;
156 break;
157 default:
158 promiseStatus = PromiseDetails::Status::Rejected;
160 RefPtr<PromiseDetails> promiseDetails = PromiseDetails::create().setId(id);
161 promiseDetails->setStatus(promiseStatus);
163 if (!parentPromise.IsEmpty() && parentPromise->IsObject()) {
164 v8::Local<v8::Object> handle = parentPromise->ToObject(scriptState->isolate());
165 bool parentIsNewPromise = false;
166 int parentPromiseId = promiseId(handle, &parentIsNewPromise);
167 promiseDetails->setParentId(parentPromiseId);
168 } else {
169 if (!status) {
170 if (isNewPromise) {
171 promiseDetails->setCreationTime(currentTimeMS());
172 RefPtrWillBeRawPtr<ScriptCallStack> stack = currentScriptCallStack(m_captureStacks ? ScriptCallStack::maxCallStackSizeToCapture : 1);
173 if (stack) {
174 if (stack->size()) {
175 promiseDetails->setCallFrame(stack->at(0).buildInspectorObject());
176 if (m_captureStacks)
177 promiseDetails->setCreationStack(stack->buildInspectorArray());
179 RefPtrWillBeRawPtr<ScriptAsyncCallStack> asyncCallStack = stack->asyncCallStack();
180 if (m_captureStacks && asyncCallStack)
181 promiseDetails->setAsyncCreationStack(asyncCallStack->buildInspectorObject());
184 } else {
185 promiseDetails->setSettlementTime(currentTimeMS());
186 if (m_captureStacks) {
187 RefPtrWillBeRawPtr<ScriptCallStack> stack = currentScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture);
188 if (stack) {
189 if (stack->size())
190 promiseDetails->setSettlementStack(stack->buildInspectorArray());
191 if (RefPtrWillBeRawPtr<ScriptAsyncCallStack> asyncCallStack = stack->asyncCallStack())
192 promiseDetails->setAsyncSettlementStack(asyncCallStack->buildInspectorObject());
198 m_listener->didUpdatePromise(eventType, promiseDetails.release());
201 ScriptValue PromiseTracker::promiseById(int promiseId)
203 ASSERT(isEnabled());
204 v8::HandleScope scope(m_isolate);
205 v8::Local<v8::Object> value = m_idToPromise.Get(promiseId);
206 if (value.IsEmpty())
207 return ScriptValue();
208 return ScriptValue(ScriptState::from(value->CreationContext()) , value);
211 } // namespace blink