Index: content/renderer/render_thread_impl_browsertest.cc |
diff --git a/content/renderer/render_thread_impl_browsertest.cc b/content/renderer/render_thread_impl_browsertest.cc |
index f5a0d1d7f7df750f26ae6beba93868d40690dcfd..099da86004b9445a39a15722927633423d1a2274 100644 |
--- a/content/renderer/render_thread_impl_browsertest.cc |
+++ b/content/renderer/render_thread_impl_browsertest.cc |
@@ -3,6 +3,8 @@ |
// found in the LICENSE file. |
#include "base/command_line.h" |
+#include "base/memory/discardable_memory.h" |
+#include "base/memory/scoped_vector.h" |
#include "content/public/browser/content_browser_client.h" |
#include "content/public/common/content_client.h" |
#include "content/public/common/content_switches.h" |
@@ -70,5 +72,63 @@ TEST_F(RenderThreadImplBrowserTest, |
base::Bind(&CheckRenderThreadInputHandlerManager, thread)); |
} |
+// Checks that emulated discardable memory is discarded when the last widget |
+// is hidden. |
+// Disabled under LeakSanitizer due to memory leaks. |
+#if defined(LEAK_SANITIZER) |
+#define MAYBE_EmulatedDiscardableMemoryDiscardedWhenWidgetsHidden \ |
+ DISABLED_EmulatedDiscardableMemoryDiscardedWhenWidgetsHidden |
+#else |
+#define MAYBE_EmulatedDiscardableMemoryDiscardedWhenWidgetsHidden \ |
+ EmulatedDiscardableMemoryDiscardedWhenWidgetsHidden |
+#endif |
+TEST_F(RenderThreadImplBrowserTest, |
+ MAYBE_EmulatedDiscardableMemoryDiscardedWhenWidgetsHidden) { |
+ ContentClient content_client; |
+ ContentBrowserClient content_browser_client; |
+ ContentRendererClient content_renderer_client; |
+ SetContentClient(&content_client); |
+ SetBrowserClientForTesting(&content_browser_client); |
+ SetRendererClientForTesting(&content_renderer_client); |
+ base::MessageLoopForIO message_loop_; |
+ |
+ std::string channel_id = |
+ IPC::Channel::GenerateVerifiedChannelID(std::string()); |
+ DummyListener dummy_listener; |
+ scoped_ptr<IPC::Channel> channel( |
+ IPC::Channel::CreateServer(channel_id, &dummy_listener)); |
+ ASSERT_TRUE(channel->Connect()); |
+ |
+ scoped_ptr<MockRenderProcess> mock_process(new MockRenderProcess); |
+ // Owned by mock_process. |
+ RenderThreadImpl* thread = new RenderThreadImpl(channel_id); |
+ thread->EnsureWebKitInitialized(); |
+ thread->WidgetCreated(); |
+ |
+ // Allocate 128MB of discardable memory. |
+ ScopedVector<base::DiscardableMemory> discardable_memory; |
+ for (int i = 0; i < 32; ++i) { |
+ discardable_memory.push_back( |
+ base::DiscardableMemory::CreateLockedMemoryWithType( |
+ base::DISCARDABLE_MEMORY_TYPE_EMULATED, 4 * 1024 * 1024).release()); |
+ ASSERT_TRUE(discardable_memory.back()); |
+ discardable_memory.back()->Unlock(); |
+ } |
+ |
+ // Hide all widgets. |
+ thread->WidgetHidden(); |
+ |
+ // Count how much memory is left, should be at most one block. |
+ int blocks_left = 0; |
+ for (auto iter = discardable_memory.begin(); iter != discardable_memory.end(); |
+ ++iter) { |
+ if ((*iter)->Lock() == base::DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS) |
+ ++blocks_left; |
+ } |
+ EXPECT_LE(blocks_left, 1); |
+ |
+ thread->WidgetDestroyed(); |
+} |
+ |
} // namespace |
} // namespace content |