| Index: third_party/WebKit/Source/core/fetch/Resource.cpp
|
| diff --git a/third_party/WebKit/Source/core/fetch/Resource.cpp b/third_party/WebKit/Source/core/fetch/Resource.cpp
|
| index a88e43c79f3cd47a0321c0f9c034fee86bcf72e2..52b4cf5c160cc96b1beb0269ed89b86856872ad6 100644
|
| --- a/third_party/WebKit/Source/core/fetch/Resource.cpp
|
| +++ b/third_party/WebKit/Source/core/fetch/Resource.cpp
|
| @@ -28,7 +28,7 @@
|
| #include "core/fetch/FetchInitiatorTypeNames.h"
|
| #include "core/fetch/MemoryCache.h"
|
| #include "core/fetch/ResourceClient.h"
|
| -#include "core/fetch/ResourceClientOrObserverWalker.h"
|
| +#include "core/fetch/ResourceClientWalker.h"
|
| #include "core/fetch/ResourceLoader.h"
|
| #include "core/inspector/InstanceCounters.h"
|
| #include "platform/Histogram.h"
|
| @@ -308,6 +308,7 @@ Resource::Resource(const ResourceRequest& request, Type type, const ResourceLoad
|
| , m_needsSynchronousCacheHit(false)
|
| , m_linkPreload(false)
|
| , m_isRevalidating(false)
|
| + , m_isAlive(false)
|
| , m_options(options)
|
| , m_responseTimestamp(currentTime())
|
| , m_cancelTimer(this, &Resource::cancelTimerFired)
|
| @@ -331,6 +332,9 @@ DEFINE_TRACE(Resource)
|
| {
|
| visitor->trace(m_loader);
|
| visitor->trace(m_cacheHandler);
|
| + visitor->trace(m_clients);
|
| + visitor->trace(m_clientsAwaitingCallback);
|
| + visitor->trace(m_finishedClients);
|
| MemoryCoordinatorClient::trace(visitor);
|
| }
|
|
|
| @@ -677,8 +681,10 @@ void Resource::willAddClientOrObserver(PreloadReferencePolicy policy)
|
| preloadDiscoveryHistogram.count(timeSinceDiscovery);
|
| }
|
| }
|
| - if (!hasClientsOrObservers())
|
| + if (!hasClientsOrObservers()) {
|
| + m_isAlive = true;
|
| memoryCache()->makeLive(this);
|
| + }
|
| }
|
|
|
| void Resource::addClient(ResourceClient* client, PreloadReferencePolicy policy)
|
| @@ -704,7 +710,9 @@ void Resource::addClient(ResourceClient* client, PreloadReferencePolicy policy)
|
|
|
| void Resource::removeClient(ResourceClient* client)
|
| {
|
| - ASSERT(hasClient(client));
|
| + // This code may be called in a pre-finalizer, where weak members in the
|
| + // HashCountedSet are already swept out.
|
| +
|
| if (m_finishedClients.contains(client))
|
| m_finishedClients.remove(client);
|
| else if (m_clientsAwaitingCallback.contains(client))
|
| @@ -716,12 +724,12 @@ void Resource::removeClient(ResourceClient* client)
|
| ResourceCallback::callbackHandler().cancel(this);
|
|
|
| didRemoveClientOrObserver();
|
| - // This object may be dead here.
|
| }
|
|
|
| void Resource::didRemoveClientOrObserver()
|
| {
|
| - if (!hasClientsOrObservers()) {
|
| + if (!hasClientsOrObservers() && m_isAlive) {
|
| + m_isAlive = false;
|
| memoryCache()->makeDead(this);
|
| allClientsAndObserversRemoved();
|
|
|
| @@ -792,7 +800,7 @@ void Resource::finishPendingClients()
|
|
|
| // Handle case (1) by saving a list of clients to notify. A separate list also ensure
|
| // a client is either in m_clients or m_clientsAwaitingCallback.
|
| - Vector<ResourceClient*> clientsToNotify;
|
| + HeapVector<Member<ResourceClient>> clientsToNotify;
|
| copyToVector(m_clientsAwaitingCallback, clientsToNotify);
|
|
|
| for (const auto& client : clientsToNotify) {
|
|
|