Index: webkit/glue/webkitplatformsupport_impl.cc |
diff --git a/webkit/glue/webkitplatformsupport_impl.cc b/webkit/glue/webkitplatformsupport_impl.cc |
index 7b7ab157875b2f29e8c8bed55605ed95fdf579c7..016ae05493ef6df1dff4cadfbe7c652522f77ce5 100644 |
--- a/webkit/glue/webkitplatformsupport_impl.cc |
+++ b/webkit/glue/webkitplatformsupport_impl.cc |
@@ -12,6 +12,10 @@ |
#include <vector> |
+#if defined(OS_ANDROID) |
+#include <sys/system_properties.h> |
+#endif |
+ |
#include "base/bind.h" |
#include "base/debug/trace_event.h" |
#include "base/memory/singleton.h" |
@@ -112,6 +116,59 @@ class MemoryUsageCache { |
base::Lock lock_; |
}; |
+#if defined(OS_ANDROID) |
+// A simple class to cache the heap size of the device. |
+class DalvikHeapSize { |
darin (slow to review)
2012/05/09 14:57:35
it seems like this should be factored out into a s
ulan
2012/05/09 17:33:27
Done.
|
+ public: |
+ // Retrieves the Singleton. |
+ static DalvikHeapSize* GetInstance() { |
+ return Singleton<DalvikHeapSize>::get(); |
+ } |
+ |
+ DalvikHeapSize() : heap_size_mb_(0) { |
+ char heap_size_str[PROP_VALUE_MAX]; |
+ __system_property_get("dalvik.vm.heapsize", heap_size_str); |
+ heap_size_mb_ = ParseHeapSize(std::string(heap_size_str)); |
+ } |
+ |
+ ~DalvikHeapSize() {} |
+ |
+ int HeapSizeMB() const { return heap_size_mb_; } |
+ |
+ private: |
+ int ParseHeapSize(const std::string& str) const { |
+ const int64 KB = 1024; |
+ const int64 MB = 1024 * KB; |
+ const int64 GB = 1024 * MB; |
+ CHECK_GT(str.size(), 0u); |
+ int64 factor = 1; |
+ size_t length = str.size(); |
+ if (str[length - 1] == 'k') { |
+ factor = KB; |
+ length--; |
+ } else if (str[length - 1] == 'm') { |
+ factor = MB; |
+ length--; |
+ } else if (str[length - 1] == 'g') { |
+ factor = GB; |
+ length--; |
+ } else { |
+ CHECK('0' <= str[length - 1] && str[length - 1] <= '9'); |
+ } |
+ int64 result = 0; |
+ bool parsed = base::StringToInt64(str.substr(0, length), &result); |
+ CHECK(parsed); |
+ result = result * factor / MB; |
+ // dalvik.vm.heapsize property is writable by user, |
+ // truncate it to reasonable value to avoid overflows later. |
+ result = std::min<int64>(std::max<int64>(32, result), 1024); |
+ return static_cast<int>(result); |
+ } |
+ |
+ int heap_size_mb_; |
+}; |
+#endif |
+ |
} // anonymous namespace |
namespace webkit_glue { |
@@ -620,8 +677,8 @@ WebKit::WebString WebKitPlatformSupportImpl::signedPublicKeyAndChallengeString( |
return WebKit::WebString(""); |
} |
-#if defined(OS_LINUX) |
-static size_t memoryUsageMBLinux() { |
+#if defined(OS_LINUX) || defined(OS_ANDROID) |
+static size_t memoryUsageMB() { |
struct mallinfo minfo = mallinfo(); |
uint64_t mem_usage = |
#if defined(USE_TCMALLOC) |
@@ -635,10 +692,8 @@ static size_t memoryUsageMBLinux() { |
v8::V8::GetHeapStatistics(&stat); |
return mem_usage + (static_cast<uint64_t>(stat.total_heap_size()) >> 20); |
} |
-#endif |
- |
-#if defined(OS_MACOSX) |
-static size_t memoryUsageMBMac() { |
+#elif defined(OS_MACOSX) |
+static size_t memoryUsageMB() { |
using base::ProcessMetrics; |
static ProcessMetrics* process_metrics = |
// The default port provider is sufficient to get data for the current |
@@ -648,10 +703,8 @@ static size_t memoryUsageMBMac() { |
DCHECK(process_metrics); |
return process_metrics->GetWorkingSetSize() >> 20; |
} |
-#endif |
- |
-#if !defined(OS_LINUX) && !defined(OS_MACOSX) |
-static size_t memoryUsageMBGeneric() { |
+#else |
+static size_t memoryUsageMB() { |
using base::ProcessMetrics; |
static ProcessMetrics* process_metrics = |
ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle()); |
@@ -667,14 +720,7 @@ static size_t getMemoryUsageMB(bool bypass_cache) { |
mem_usage_cache_singleton->IsCachedValueValid(¤t_mem_usage)) |
return current_mem_usage; |
- current_mem_usage = |
-#if defined(OS_LINUX) |
- memoryUsageMBLinux(); |
-#elif defined(OS_MACOSX) |
- memoryUsageMBMac(); |
-#else |
- memoryUsageMBGeneric(); |
-#endif |
+ current_mem_usage = memoryUsageMB(); |
mem_usage_cache_singleton->SetMemoryValue(current_mem_usage); |
return current_mem_usage; |
} |
@@ -687,6 +733,28 @@ size_t WebKitPlatformSupportImpl::actualMemoryUsageMB() { |
return getMemoryUsageMB(true); |
} |
+#if defined(OS_ANDROID) |
+size_t WebKitPlatformSupportImpl::lowMemoryUsageMB() { |
+ // If memory usage is below this threshold, do not bother forcing GC. |
+ // Allow us to use up to our memory class value before V8's GC kicks in. |
+ // These values have been determined by experimentation. |
+ DalvikHeapSize* heap_size_singleton = DalvikHeapSize::GetInstance(); |
+ return heap_size_singleton->HeapSizeMB() / 4; |
+} |
+ |
+size_t WebKitPlatformSupportImpl::highMemoryUsageMB() { |
+ // If memory usage is above this threshold, force GC more aggressively. |
+ return lowMemoryUsageMB() * 2; |
+} |
+ |
+size_t WebKitPlatformSupportImpl::highUsageDeltaMB() { |
darin (slow to review)
2012/05/09 14:57:35
nit: this function name seems a little strange. s
ulan
2012/05/09 17:33:27
The name is already fixed on WebKit side. Added ex
|
+ // Threshold of delta of memory usage growth (vs. last working set estimate) |
+ // to force GC when memory usage is high. |
+ // Avoid constant V8 GC when memory usage equals to working set estimate. |
+ return lowMemoryUsageMB() / 2; |
+} |
+#endif |
+ |
void WebKitPlatformSupportImpl::SuspendSharedTimer() { |
++shared_timer_suspended_; |
} |