Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(113)

Side by Side Diff: Source/bindings/core/v8/ScriptPromiseResolver.cpp

Issue 1233173002: Have ScriptPromiseResolver on the Oilpan heap always. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: keepAliveWhilePending() comment Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "bindings/core/v8/ScriptPromiseResolver.h" 6 #include "bindings/core/v8/ScriptPromiseResolver.h"
7 7
8 #include "bindings/core/v8/V8RecursionScope.h" 8 #include "bindings/core/v8/V8RecursionScope.h"
9 #include "platform/LifecycleObserver.h" 9 #include "platform/LifecycleObserver.h"
10 10
11 namespace blink { 11 namespace blink {
12 12
13 ScriptPromiseResolver::ScriptPromiseResolver(ScriptState* scriptState) 13 ScriptPromiseResolver::ScriptPromiseResolver(ScriptState* scriptState)
14 : ActiveDOMObject(scriptState->executionContext()) 14 : ActiveDOMObject(scriptState->executionContext())
15 , m_state(Pending) 15 , m_state(Pending)
16 , m_scriptState(scriptState) 16 , m_scriptState(scriptState)
17 , m_mode(Default)
18 , m_timer(this, &ScriptPromiseResolver::onTimerFired) 17 , m_timer(this, &ScriptPromiseResolver::onTimerFired)
19 , m_resolver(scriptState) 18 , m_resolver(scriptState)
20 #if ENABLE(ASSERT) 19 #if ENABLE(ASSERT)
21 , m_isPromiseCalled(false) 20 , m_isPromiseCalled(false)
22 #endif 21 #endif
23 { 22 {
24 if (executionContext()->activeDOMObjectsAreStopped()) { 23 if (executionContext()->activeDOMObjectsAreStopped()) {
25 m_state = ResolvedOrRejected; 24 m_state = ResolvedOrRejected;
26 m_resolver.clear(); 25 m_resolver.clear();
27 } 26 }
(...skipping 11 matching lines...) Expand all
39 } 38 }
40 39
41 void ScriptPromiseResolver::stop() 40 void ScriptPromiseResolver::stop()
42 { 41 {
43 m_timer.stop(); 42 m_timer.stop();
44 clear(); 43 clear();
45 } 44 }
46 45
47 void ScriptPromiseResolver::keepAliveWhilePending() 46 void ScriptPromiseResolver::keepAliveWhilePending()
48 { 47 {
49 if (m_state == ResolvedOrRejected || m_mode == KeepAliveWhilePending) 48 // keepAliveWhilePending() will be called twice if the resolver
49 // is created in a suspended execution context and the resolver
50 // is then resolved/rejected while in that suspended state.
51 if (m_state == ResolvedOrRejected || m_keepAlive)
50 return; 52 return;
51 53
52 // Keep |this| while the promise is Pending. 54 // Keep |this| around while the promise is Pending;
53 // deref() will be called in clear(). 55 // see clear() for the dual operation.
54 m_mode = KeepAliveWhilePending; 56 m_keepAlive = this;
55 ref();
56 } 57 }
57 58
58 void ScriptPromiseResolver::onTimerFired(Timer<ScriptPromiseResolver>*) 59 void ScriptPromiseResolver::onTimerFired(Timer<ScriptPromiseResolver>*)
59 { 60 {
60 ASSERT(m_state == Resolving || m_state == Rejecting); 61 ASSERT(m_state == Resolving || m_state == Rejecting);
61 ScriptState::Scope scope(m_scriptState.get()); 62 ScriptState::Scope scope(m_scriptState.get());
62 resolveOrRejectImmediately(); 63 resolveOrRejectImmediately();
63 } 64 }
64 65
65 void ScriptPromiseResolver::resolveOrRejectImmediately() 66 void ScriptPromiseResolver::resolveOrRejectImmediately()
66 { 67 {
67 ASSERT(!executionContext()->activeDOMObjectsAreStopped()); 68 ASSERT(!executionContext()->activeDOMObjectsAreStopped());
68 ASSERT(!executionContext()->activeDOMObjectsAreSuspended()); 69 ASSERT(!executionContext()->activeDOMObjectsAreSuspended());
69 { 70 {
70 if (m_state == Resolving) { 71 if (m_state == Resolving) {
71 m_resolver.resolve(m_value.newLocal(m_scriptState->isolate())); 72 m_resolver.resolve(m_value.newLocal(m_scriptState->isolate()));
72 } else { 73 } else {
73 ASSERT(m_state == Rejecting); 74 ASSERT(m_state == Rejecting);
74 m_resolver.reject(m_value.newLocal(m_scriptState->isolate())); 75 m_resolver.reject(m_value.newLocal(m_scriptState->isolate()));
75 } 76 }
76 } 77 }
77 clear(); 78 clear();
78 } 79 }
79 80
80 void ScriptPromiseResolver::clear() 81 void ScriptPromiseResolver::clear()
81 { 82 {
82 if (m_state == ResolvedOrRejected) 83 if (m_state == ResolvedOrRejected)
83 return; 84 return;
84 ResolutionState state = m_state;
85 m_state = ResolvedOrRejected; 85 m_state = ResolvedOrRejected;
86 m_resolver.clear(); 86 m_resolver.clear();
87 m_value.clear(); 87 m_value.clear();
88 if (m_mode == KeepAliveWhilePending) { 88 m_keepAlive.clear();
89 // |ref| was called in |keepAliveWhilePending|.
90 deref();
91 }
92 // |this| may be deleted here, but it is safe to check |state| because
93 // it doesn't depend on |this|. When |this| is deleted, |state| can't be
94 // |Resolving| nor |Rejecting| and hence |this->deref()| can't be executed.
95 if (state == Resolving || state == Rejecting) {
96 // |ref| was called in |resolveOrReject|.
97 deref();
98 }
99 } 89 }
100 90
101 DEFINE_TRACE(ScriptPromiseResolver) 91 DEFINE_TRACE(ScriptPromiseResolver)
102 { 92 {
103 ActiveDOMObject::trace(visitor); 93 ActiveDOMObject::trace(visitor);
104 } 94 }
105 95
106 } // namespace blink 96 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698