Commit 7ca17c22 authored by Yuzu Saijo's avatar Yuzu Saijo Committed by Commit Bot

Make BlinkLeakDetector hold the list of ResourceFetcher to stop keepalive loaders

This CL makes BlinkLeakDetector hold the list of all the ResourceFethcers so that the keepalive loaders, which may persist over page navigation, would be cancelled in PrepareForLeakDetection.

Change-Id: I3f7dffa5e549835b496d131fb95b71b5c3e7f035
Reviewed-on: https://chromium-review.googlesource.com/956651
Commit-Queue: Yuzu Saijo <yuzus@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarKeishi Hattori <keishi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543304}
parent a04e40f7
...@@ -182,6 +182,7 @@ ...@@ -182,6 +182,7 @@
#include "core/layout/LayoutEmbeddedContent.h" #include "core/layout/LayoutEmbeddedContent.h"
#include "core/layout/LayoutView.h" #include "core/layout/LayoutView.h"
#include "core/layout/TextAutosizer.h" #include "core/layout/TextAutosizer.h"
#include "core/leak_detector/BlinkLeakDetector.h"
#include "core/loader/CookieJar.h" #include "core/loader/CookieJar.h"
#include "core/loader/DocumentLoader.h" #include "core/loader/DocumentLoader.h"
#include "core/loader/FrameFetchContext.h" #include "core/loader/FrameFetchContext.h"
...@@ -690,6 +691,7 @@ Document::Document(const DocumentInit& initializer, ...@@ -690,6 +691,7 @@ Document::Document(const DocumentInit& initializer,
fetcher_ = FrameFetchContext::CreateFetcherFromDocument(this); fetcher_ = FrameFetchContext::CreateFetcherFromDocument(this);
} else { } else {
fetcher_ = ResourceFetcher::Create(nullptr); fetcher_ = ResourceFetcher::Create(nullptr);
BlinkLeakDetector::Instance().RegisterResourceFetcher(fetcher_);
} }
DCHECK(fetcher_); DCHECK(fetcher_);
......
...@@ -53,7 +53,7 @@ using PrepareForLeakDetectionCallback = ...@@ -53,7 +53,7 @@ using PrepareForLeakDetectionCallback =
using protocol::Response; using protocol::Response;
InspectorMemoryAgent::InspectorMemoryAgent(InspectedFrames* inspected_frames) InspectorMemoryAgent::InspectorMemoryAgent(InspectedFrames* inspected_frames)
: detector_(nullptr), callback_(nullptr), frames_(inspected_frames) {} : callback_(nullptr), frames_(inspected_frames) {}
InspectorMemoryAgent::~InspectorMemoryAgent() = default; InspectorMemoryAgent::~InspectorMemoryAgent() = default;
...@@ -71,16 +71,20 @@ Response InspectorMemoryAgent::getDOMCounters(int* documents, ...@@ -71,16 +71,20 @@ Response InspectorMemoryAgent::getDOMCounters(int* documents,
void InspectorMemoryAgent::prepareForLeakDetection( void InspectorMemoryAgent::prepareForLeakDetection(
std::unique_ptr<PrepareForLeakDetectionCallback> callback) { std::unique_ptr<PrepareForLeakDetectionCallback> callback) {
callback_ = std::move(callback); callback_ = std::move(callback);
detector_.reset(new BlinkLeakDetector(this));
detector_->PrepareForLeakDetection(frames_->Root()->Client()->GetWebFrame()); BlinkLeakDetector& detector = BlinkLeakDetector::Instance();
detector_->CollectGarbage(); detector.SetClient(this);
detector.PrepareForLeakDetection(frames_->Root()->Client()->GetWebFrame());
detector.CollectGarbage();
} }
void InspectorMemoryAgent::OnLeakDetectionComplete() { void InspectorMemoryAgent::OnLeakDetectionComplete() {
DCHECK(callback_); DCHECK(callback_);
callback_->sendSuccess(); callback_->sendSuccess();
callback_.reset(); callback_.reset();
detector_.reset();
// Reset the client for BlinkLeakDetector
BlinkLeakDetector::Instance().SetClient(nullptr);
} }
void InspectorMemoryAgent::Trace(blink::Visitor* visitor) { void InspectorMemoryAgent::Trace(blink::Visitor* visitor) {
......
...@@ -80,7 +80,6 @@ class CORE_EXPORT InspectorMemoryAgent final ...@@ -80,7 +80,6 @@ class CORE_EXPORT InspectorMemoryAgent final
std::unique_ptr<protocol::Memory::SamplingProfile> GetSamplingProfileById( std::unique_ptr<protocol::Memory::SamplingProfile> GetSamplingProfileById(
uint32_t id); uint32_t id);
std::unique_ptr<BlinkLeakDetector> detector_;
std::unique_ptr<PrepareForLeakDetectionCallback> callback_; std::unique_ptr<PrepareForLeakDetectionCallback> callback_;
Member<InspectedFrames> frames_; Member<InspectedFrames> frames_;
uint32_t profile_id_ = 0; uint32_t profile_id_ = 0;
......
...@@ -17,16 +17,22 @@ ...@@ -17,16 +17,22 @@
#include "platform/Timer.h" #include "platform/Timer.h"
#include "platform/bindings/V8PerIsolateData.h" #include "platform/bindings/V8PerIsolateData.h"
#include "platform/loader/fetch/MemoryCache.h" #include "platform/loader/fetch/MemoryCache.h"
#include "platform/loader/fetch/ResourceFetcher.h"
#include "public/platform/Platform.h" #include "public/platform/Platform.h"
namespace blink { namespace blink {
BlinkLeakDetector::BlinkLeakDetector(BlinkLeakDetectorClient* client) BlinkLeakDetector& BlinkLeakDetector::Instance() {
DEFINE_THREAD_SAFE_STATIC_LOCAL(BlinkLeakDetector, blink_leak_detector, ());
return blink_leak_detector;
}
BlinkLeakDetector::BlinkLeakDetector()
: delayed_gc_timer_(Platform::Current()->CurrentThread()->GetTaskRunner(), : delayed_gc_timer_(Platform::Current()->CurrentThread()->GetTaskRunner(),
this, this,
&BlinkLeakDetector::TimerFiredGC), &BlinkLeakDetector::TimerFiredGC),
number_of_gc_needed_(0), number_of_gc_needed_(0),
client_(client) {} client_(nullptr) {}
BlinkLeakDetector::~BlinkLeakDetector() = default; BlinkLeakDetector::~BlinkLeakDetector() = default;
...@@ -64,6 +70,10 @@ void BlinkLeakDetector::PrepareForLeakDetection(WebFrame* frame) { ...@@ -64,6 +70,10 @@ void BlinkLeakDetector::PrepareForLeakDetection(WebFrame* frame) {
// Clear lazily loaded style sheets. // Clear lazily loaded style sheets.
CSSDefaultStyleSheets::Instance().PrepareForLeakDetection(); CSSDefaultStyleSheets::Instance().PrepareForLeakDetection();
// Stop keepalive loaders that may persist after page navigation.
for (auto resource_fetcher : resource_fetchers_)
resource_fetcher->PrepareForLeakDetection();
} }
void BlinkLeakDetector::CollectGarbage() { void BlinkLeakDetector::CollectGarbage() {
...@@ -111,4 +121,13 @@ void BlinkLeakDetector::TimerFiredGC(TimerBase*) { ...@@ -111,4 +121,13 @@ void BlinkLeakDetector::TimerFiredGC(TimerBase*) {
// Note: Oilpan precise GC is scheduled at the end of the event loop. // Note: Oilpan precise GC is scheduled at the end of the event loop.
} }
void BlinkLeakDetector::SetClient(BlinkLeakDetectorClient* client) {
client_ = client;
}
void BlinkLeakDetector::RegisterResourceFetcher(ResourceFetcher* fetcher) {
DCHECK(IsMainThread());
resource_fetchers_.insert(fetcher);
}
} // namespace blink } // namespace blink
...@@ -12,24 +12,34 @@ namespace blink { ...@@ -12,24 +12,34 @@ namespace blink {
class BlinkLeakDetectorClient; class BlinkLeakDetectorClient;
class WebFrame; class WebFrame;
class ResourceFetcher;
// This class is responsible for stabilizing the detection results which are // This class is responsible for stabilizing the detection results which are
// InstanceCounter values by 1) preparing for leak detection and 2) operating // InstanceCounter values by 1) preparing for leak detection and 2) operating
// garbage collections before leak detection. // garbage collections before leak detection.
// This class is implemented as singleton, but there needs to be only one user
// at a time.
class CORE_EXPORT BlinkLeakDetector { class CORE_EXPORT BlinkLeakDetector {
public: public:
explicit BlinkLeakDetector(BlinkLeakDetectorClient*); static BlinkLeakDetector& Instance();
~BlinkLeakDetector(); ~BlinkLeakDetector();
void PrepareForLeakDetection(WebFrame*); void PrepareForLeakDetection(WebFrame*);
void CollectGarbage(); void CollectGarbage();
void SetClient(BlinkLeakDetectorClient*);
// This registration function needs to be called whenever ResourceFetcher is
// created (i.e. ResourceFetcher::Create is called).
void RegisterResourceFetcher(ResourceFetcher*);
private: private:
BlinkLeakDetector();
void TimerFiredGC(TimerBase*); void TimerFiredGC(TimerBase*);
TaskRunnerTimer<BlinkLeakDetector> delayed_gc_timer_; TaskRunnerTimer<BlinkLeakDetector> delayed_gc_timer_;
int number_of_gc_needed_; int number_of_gc_needed_;
BlinkLeakDetectorClient* client_; BlinkLeakDetectorClient* client_;
PersistentHeapHashSet<WeakMember<ResourceFetcher>> resource_fetchers_;
}; };
} // namespace blink } // namespace blink
......
...@@ -46,7 +46,7 @@ class WebLeakDetectorImpl final : public WebLeakDetector, ...@@ -46,7 +46,7 @@ class WebLeakDetectorImpl final : public WebLeakDetector,
public: public:
explicit WebLeakDetectorImpl(WebLeakDetectorClient* client) explicit WebLeakDetectorImpl(WebLeakDetectorClient* client)
: client_(client), detector_(nullptr) { : client_(client) {
DCHECK(client_); DCHECK(client_);
} }
...@@ -60,17 +60,17 @@ class WebLeakDetectorImpl final : public WebLeakDetector, ...@@ -60,17 +60,17 @@ class WebLeakDetectorImpl final : public WebLeakDetector,
private: private:
WebLeakDetectorClient* client_; WebLeakDetectorClient* client_;
std::unique_ptr<BlinkLeakDetector> detector_;
DISALLOW_COPY_AND_ASSIGN(WebLeakDetectorImpl); DISALLOW_COPY_AND_ASSIGN(WebLeakDetectorImpl);
}; };
void WebLeakDetectorImpl::PrepareForLeakDetection(WebFrame* frame) { void WebLeakDetectorImpl::PrepareForLeakDetection(WebFrame* frame) {
detector_.reset(new BlinkLeakDetector(this)); BlinkLeakDetector& detector = BlinkLeakDetector::Instance();
detector_->PrepareForLeakDetection(frame); detector.SetClient(this);
detector.PrepareForLeakDetection(frame);
} }
void WebLeakDetectorImpl::CollectGarbageAndReport() { void WebLeakDetectorImpl::CollectGarbageAndReport() {
detector_->CollectGarbage(); BlinkLeakDetector::Instance().CollectGarbage();
} }
void WebLeakDetectorImpl::OnLeakDetectionComplete() { void WebLeakDetectorImpl::OnLeakDetectionComplete() {
...@@ -101,7 +101,8 @@ void WebLeakDetectorImpl::OnLeakDetectionComplete() { ...@@ -101,7 +101,8 @@ void WebLeakDetectorImpl::OnLeakDetectionComplete() {
InstanceCounters::CounterValue(InstanceCounters::kUACSSResourceCounter); InstanceCounters::CounterValue(InstanceCounters::kUACSSResourceCounter);
client_->OnLeakDetectionComplete(result); client_->OnLeakDetectionComplete(result);
detector_.reset(); // Reset the client for BlinkLeakDetector
BlinkLeakDetector::Instance().SetClient(nullptr);
#ifndef NDEBUG #ifndef NDEBUG
showLiveDocumentInstances(); showLiveDocumentInstances();
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include "core/inspector/ConsoleMessage.h" #include "core/inspector/ConsoleMessage.h"
#include "core/inspector/IdentifiersFactory.h" #include "core/inspector/IdentifiersFactory.h"
#include "core/inspector/InspectorTraceEvents.h" #include "core/inspector/InspectorTraceEvents.h"
#include "core/leak_detector/BlinkLeakDetector.h"
#include "core/loader/DocumentLoader.h" #include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h" #include "core/loader/FrameLoader.h"
#include "core/loader/IdlenessDetector.h" #include "core/loader/IdlenessDetector.h"
...@@ -252,6 +253,7 @@ ResourceFetcher* FrameFetchContext::CreateFetcher(DocumentLoader* loader, ...@@ -252,6 +253,7 @@ ResourceFetcher* FrameFetchContext::CreateFetcher(DocumentLoader* loader,
Document* document) { Document* document) {
FrameFetchContext* context = new FrameFetchContext(loader, document); FrameFetchContext* context = new FrameFetchContext(loader, document);
ResourceFetcher* fetcher = ResourceFetcher::Create(context); ResourceFetcher* fetcher = ResourceFetcher::Create(context);
BlinkLeakDetector::Instance().RegisterResourceFetcher(fetcher);
if (loader && context->GetSettings()->GetSavePreviousDocumentResources() != if (loader && context->GetSettings()->GetSavePreviousDocumentResources() !=
SavePreviousDocumentResources::kNever) { SavePreviousDocumentResources::kNever) {
......
...@@ -1640,6 +1640,12 @@ void ResourceFetcher::EmulateLoadStartedForInspector( ...@@ -1640,6 +1640,12 @@ void ResourceFetcher::EmulateLoadStartedForInspector(
RequestLoadStarted(resource->Identifier(), resource, params, kUse); RequestLoadStarted(resource->Identifier(), resource, params, kUse);
} }
void ResourceFetcher::PrepareForLeakDetection() {
// Stop loaders including keepalive ones that may persist after page
// navigation and thus affect instance counters of leak detection.
StopFetchingIncludingKeepaliveLoaders();
}
void ResourceFetcher::StopFetchingInternal(StopFetchingTarget target) { void ResourceFetcher::StopFetchingInternal(StopFetchingTarget target) {
// TODO(toyoshim): May want to suspend scheduler while canceling loaders so // TODO(toyoshim): May want to suspend scheduler while canceling loaders so
// that the cancellations below do not awake unnecessary scheduling. // that the cancellations below do not awake unnecessary scheduling.
......
...@@ -171,6 +171,11 @@ class PLATFORM_EXPORT ResourceFetcher ...@@ -171,6 +171,11 @@ class PLATFORM_EXPORT ResourceFetcher
WebURLRequest::RequestContext, WebURLRequest::RequestContext,
const AtomicString& initiator_name); const AtomicString& initiator_name);
// This is called from leak detectors (Real-world leak detector & layout test
// leak detector) to clean up loaders after page navigation before instance
// counting.
void PrepareForLeakDetection();
private: private:
friend class ResourceCacheValidationSuppressor; friend class ResourceCacheValidationSuppressor;
enum class StopFetchingTarget { enum class StopFetchingTarget {
......
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