Index: base/memory/discardable_memory_emulated.cc |
diff --git a/base/memory/discardable_memory_emulated.cc b/base/memory/discardable_memory_emulated.cc |
index f9097b186e1405897f2a85c17f52398f0e90a1ac..9820e2ea73842431f1ea32a1638c994c33c681d1 100644 |
--- a/base/memory/discardable_memory_emulated.cc |
+++ b/base/memory/discardable_memory_emulated.cc |
@@ -15,16 +15,31 @@ const size_t kEmulatedMemoryLimit = 512 * 1024 * 1024; |
const size_t kEmulatedSoftMemoryLimit = 32 * 1024 * 1024; |
const size_t kEmulatedHardMemoryLimitExpirationTimeMs = 1000; |
-struct SharedState { |
- SharedState() |
- : manager(kEmulatedMemoryLimit, |
- kEmulatedSoftMemoryLimit, |
- TimeDelta::FromMilliseconds( |
- kEmulatedHardMemoryLimitExpirationTimeMs)) {} |
- |
- internal::DiscardableMemoryManager manager; |
+// internal::DiscardableMemoryManager has an explicit constructor that takes |
+// a number of memory limit parameters. The LeakyLazyInstanceTraits doesn't |
+// handle the case. Thus, we need our own class here. |
+struct DiscardableMemoryManagerLazyInstanceTraits { |
+ // Leaky as discardable memory clients can use this after the exit handler |
+ // has been called. |
+ static const bool kRegisterOnExit = false; |
+#ifndef NDEBUG |
+ static const bool kAllowedToAccessOnNonjoinableThread = true; |
+#endif |
+ |
+ static internal::DiscardableMemoryManager* New(void* instance) { |
+ return new (instance) internal::DiscardableMemoryManager( |
+ kEmulatedMemoryLimit, |
+ kEmulatedSoftMemoryLimit, |
+ TimeDelta::FromMilliseconds(kEmulatedHardMemoryLimitExpirationTimeMs)); |
+ } |
+ static void Delete(internal::DiscardableMemoryManager* instance) { |
+ instance->~DiscardableMemoryManager(); |
+ } |
}; |
-LazyInstance<SharedState>::Leaky g_shared_state = LAZY_INSTANCE_INITIALIZER; |
+ |
+LazyInstance<internal::DiscardableMemoryManager, |
+ DiscardableMemoryManagerLazyInstanceTraits> |
+ g_manager = LAZY_INSTANCE_INITIALIZER; |
} // namespace |
@@ -33,29 +48,29 @@ namespace internal { |
DiscardableMemoryEmulated::DiscardableMemoryEmulated(size_t bytes) |
: bytes_(bytes), |
is_locked_(false) { |
- g_shared_state.Pointer()->manager.Register(this, bytes); |
+ g_manager.Pointer()->Register(this, bytes); |
} |
DiscardableMemoryEmulated::~DiscardableMemoryEmulated() { |
if (is_locked_) |
Unlock(); |
- g_shared_state.Pointer()->manager.Unregister(this); |
+ g_manager.Pointer()->Unregister(this); |
} |
// static |
bool DiscardableMemoryEmulated::ReduceMemoryUsage() { |
- return g_shared_state.Pointer()->manager.ReduceMemoryUsage(); |
+ return g_manager.Pointer()->ReduceMemoryUsage(); |
} |
// static |
void DiscardableMemoryEmulated::ReduceMemoryUsageUntilWithinLimit( |
size_t bytes) { |
- g_shared_state.Pointer()->manager.ReduceMemoryUsageUntilWithinLimit(bytes); |
+ g_manager.Pointer()->ReduceMemoryUsageUntilWithinLimit(bytes); |
} |
// static |
void DiscardableMemoryEmulated::PurgeForTesting() { |
- g_shared_state.Pointer()->manager.PurgeAll(); |
+ g_manager.Pointer()->PurgeAll(); |
} |
bool DiscardableMemoryEmulated::Initialize() { |
@@ -66,7 +81,7 @@ DiscardableMemoryLockStatus DiscardableMemoryEmulated::Lock() { |
DCHECK(!is_locked_); |
bool purged = false; |
- if (!g_shared_state.Pointer()->manager.AcquireLock(this, &purged)) |
+ if (!g_manager.Pointer()->AcquireLock(this, &purged)) |
return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED; |
is_locked_ = true; |
@@ -76,7 +91,7 @@ DiscardableMemoryLockStatus DiscardableMemoryEmulated::Lock() { |
void DiscardableMemoryEmulated::Unlock() { |
DCHECK(is_locked_); |
- g_shared_state.Pointer()->manager.ReleaseLock(this); |
+ g_manager.Pointer()->ReleaseLock(this); |
is_locked_ = false; |
} |