Commit 576afe62 authored by Fernando Serboncini's avatar Fernando Serboncini Committed by Commit Bot

Allows MemoryCoordinator to clear thread-specific memory in-thread

GC-supporting WebThreads get to have global thread-specific memory
cleared.

A proper support would involve making MemoryCoordinatorClient thread
friendly as base's. But this is more than enough for current thread
memory cleaning.

Bug: 730692
Change-Id: I07685c2ef66325b82a02b76536166cfbada8911a
Reviewed-on: https://chromium-review.googlesource.com/533796
Commit-Queue: Fernando Serboncini <fserb@chromium.org>
Reviewed-by: default avatarJustin Novosad <junov@chromium.org>
Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Reviewed-by: default avatarKenichi Ishibashi <bashi@chromium.org>
Reviewed-by: default avatarTakashi Sakamoto <tasak@google.com>
Cr-Commit-Position: refs/heads/master@{#480866}
parent 2f2ac9ae
......@@ -5,10 +5,12 @@
#include "platform/MemoryCoordinator.h"
#include "base/sys_info.h"
#include "platform/fonts/FontCache.h"
#include "platform/WebTaskRunner.h"
#include "platform/fonts/FontGlobalContext.h"
#include "platform/graphics/ImageDecodingStore.h"
#include "platform/instrumentation/tracing/TraceEvent.h"
#include "platform/wtf/allocator/Partitions.h"
#include "public/platform/WebThread.h"
#if OS(ANDROID)
#include "base/android/sys_utils.h"
......@@ -64,6 +66,13 @@ MemoryCoordinator& MemoryCoordinator::Instance() {
return *external.Get();
}
void MemoryCoordinator::RegisterThread(WebThread* thread) {
MemoryCoordinator::Instance().web_threads_.insert(thread);
}
void MemoryCoordinator::UnregisterThread(WebThread* thread) {
MemoryCoordinator::Instance().web_threads_.erase(thread);
}
MemoryCoordinator::MemoryCoordinator() {}
......@@ -102,6 +111,15 @@ void MemoryCoordinator::OnPurgeMemory() {
// cache in purge+throttle.
ImageDecodingStore::Instance().Clear();
WTF::Partitions::DecommitFreeableMemory();
// Thread-specific data never issues a layout, so we are safe here.
for (auto thread : web_threads_) {
if (!thread->GetWebTaskRunner())
continue;
thread->GetWebTaskRunner()->PostTask(
FROM_HERE, WTF::Bind(MemoryCoordinator::ClearThreadSpecificMemory));
}
}
void MemoryCoordinator::ClearMemory() {
......@@ -109,7 +127,11 @@ void MemoryCoordinator::ClearMemory() {
// TODO(tasak|bashi): Make ImageDecodingStore and FontCache be
// MemoryCoordinatorClients rather than clearing caches here.
ImageDecodingStore::Instance().Clear();
FontCache::GetFontCache()->Invalidate();
FontGlobalContext::ClearMemory();
}
void MemoryCoordinator::ClearThreadSpecificMemory() {
FontGlobalContext::ClearMemory();
}
DEFINE_TRACE(MemoryCoordinator) {
......
......@@ -10,6 +10,7 @@
#include "platform/wtf/Noncopyable.h"
#include "public/platform/WebMemoryPressureLevel.h"
#include "public/platform/WebMemoryState.h"
#include "public/platform/WebThread.h"
namespace blink {
......@@ -29,7 +30,7 @@ class PLATFORM_EXPORT MemoryCoordinatorClient : public GarbageCollectedMixin {
// MemoryCoordinator listens to some events which could be opportunities
// for reducing memory consumption and notifies its clients.
class PLATFORM_EXPORT MemoryCoordinator final
: public GarbageCollected<MemoryCoordinator> {
: public GarbageCollectedFinalized<MemoryCoordinator> {
WTF_MAKE_NONCOPYABLE(MemoryCoordinator);
public:
......@@ -56,6 +57,9 @@ class PLATFORM_EXPORT MemoryCoordinator final
// the heap size.
static void Initialize();
static void RegisterThread(WebThread*);
static void UnregisterThread(WebThread*);
void RegisterClient(MemoryCoordinatorClient*);
void UnregisterClient(MemoryCoordinatorClient*);
......@@ -77,11 +81,13 @@ class PLATFORM_EXPORT MemoryCoordinator final
MemoryCoordinator();
void ClearMemory();
static void ClearThreadSpecificMemory();
static bool is_low_end_device_;
static int64_t physical_memory_mb_;
HeapHashSet<WeakMember<MemoryCoordinatorClient>> clients_;
HashSet<WebThread*> web_threads_;
};
} // namespace blink
......
......@@ -5,6 +5,7 @@
#include "platform/WebThreadSupportingGC.h"
#include <memory>
#include "platform/MemoryCoordinator.h"
#include "platform/heap/SafePoint.h"
#include "platform/scheduler/child/web_scheduler.h"
#include "platform/wtf/PtrUtil.h"
......@@ -36,11 +37,13 @@ WebThreadSupportingGC::WebThreadSupportingGC(const char* name,
owning_thread_ = Platform::Current()->CreateThread(name);
thread_ = owning_thread_.get();
}
MemoryCoordinator::RegisterThread(thread_);
}
WebThreadSupportingGC::~WebThreadSupportingGC() {
// WebThread's destructor blocks until all the tasks are processed.
owning_thread_.reset();
MemoryCoordinator::UnregisterThread(thread_);
}
void WebThreadSupportingGC::Initialize() {
......
......@@ -10,12 +10,22 @@
namespace blink {
FontGlobalContext& FontGlobalContext::Get() {
DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<FontGlobalContext>,
FontGlobalContext* FontGlobalContext::Get(CreateIfNeeded create_if_needed) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<FontGlobalContext*>,
font_persistent, ());
if (!*font_persistent && create_if_needed == kCreate) {
*font_persistent = new FontGlobalContext();
}
return *font_persistent;
}
FontGlobalContext::FontGlobalContext() {}
void FontGlobalContext::ClearMemory() {
if (!Get(kDoNotCreate))
return;
GetFontCache().Invalidate();
}
} // namespace blink
......@@ -11,15 +11,20 @@
namespace blink {
enum CreateIfNeeded { kDoNotCreate, kCreate };
// FontGlobalContext contains non-thread-safe, thread-specific data used for
// font formatting.
class PLATFORM_EXPORT FontGlobalContext {
WTF_MAKE_NONCOPYABLE(FontGlobalContext);
public:
static FontGlobalContext& Get();
static FontGlobalContext* Get(CreateIfNeeded = kCreate);
static inline FontCache& GetFontCache() { return Get()->font_cache; }
static inline FontCache& GetFontCache() { return Get().font_cache; }
// Called by MemoryCoordinator to clear memory.
static void ClearMemory();
private:
friend class WTF::ThreadSpecific<FontGlobalContext>;
......
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