#include <array>
#endif // BUILDFLAG(IS_WIN)
+#if BUILDFLAG(IS_TIZEN_TV)
+#include <stdio.h>
+#include "base/logging.h"
+namespace {
+static void DumpMemoryUsage() {
+ FILE* fd;
+ char buff[256];
+ fd = fopen("/proc/self/vd_memstat", "r");
+ if (!fd) {
+ LOG(ERROR) << "can't open /proc/self/vd_memstat ";
+ return;
+ }
+ if (fgets(buff, sizeof(buff), fd))
+ LOG(WARNING) << buff;
+ if (fgets(buff, sizeof(buff), fd))
+ LOG(WARNING) << buff;
+ if (fgets(buff, sizeof(buff), fd))
+ LOG(WARNING) << buff;
+ fclose(fd);
+}
+} // namespace
+#endif
+
namespace partition_alloc {
size_t g_oom_size = 0U;
#else
size_t tmp_size = size;
internal::base::debug::Alias(&tmp_size);
-
+#if BUILDFLAG(IS_TIZEN_TV)
+ DumpMemoryUsage();
+ LOG(WARNING) << "OOM size:" << size;
+#endif
// Note: Don't add anything that may allocate here. Depending on the
// allocator, this may be called from within the allocator (e.g. with
// PartitionAlloc), and would deadlock as our locks are not recursive.
#if BUILDFLAG(IS_TIZEN)
if (0 != ret)
- LOG(ERROR) << "Failed to close file descriptor! fd=" << fd;
+ LOG(ERROR) << "Failed to close file descriptor! fd=" << fd
+ << " errmsg:" << strerror(errno);
#else
PCHECK(0 == ret);
#endif
MAP_SHARED, handle.fd, checked_cast<off_t>(offset));
if (address == MAP_FAILED) {
+#if BUILDFLAG(IS_TIZEN_TV)
+ LOG(ERROR) << "mmap " << handle.fd << " failed. errmsg:" << strerror(errno)
+ << " size:" << size << " offset:" << offset;
+#endif
DPLOG(ERROR) << "mmap " << handle.fd << " failed";
return absl::nullopt;
}
}
void PlatformSharedMemoryMapper::Unmap(span<uint8_t> mapping) {
- if (munmap(mapping.data(), mapping.size()) < 0)
+ if (munmap(mapping.data(), mapping.size()) < 0) {
+#if BUILDFLAG(IS_TIZEN_TV)
+ LOG(ERROR) << "munmap failed. errmsg:" << strerror(errno)
+ << " size:" << mapping.size();
+#endif
DPLOG(ERROR) << "munmap";
+ }
}
} // namespace base
extern "C" void __llvm_profile_set_file_object(FILE* File, int EnableMerge);
#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "third_party/blink/renderer/controller/memory_usage_monitor.h"
+#endif
+
namespace content {
namespace {
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_TIZEN_TV)
void ChildThreadImpl::OnMemoryPressureFromBrowserReceived(
base::MemoryPressureListener::MemoryPressureLevel level) {
+ blink::MemoryUsage mem_usage =
+ blink::MemoryUsageMonitor::Instance().GetCurrentMemoryUsage();
+ LOG(ERROR) << mem_usage;
+
TRACE_EVENT0("v8", "ChildThreadImpl::OnMemoryPressureFromBrowserReceived");
// Generate no memory pressure signals when --single-process is specified.
// Because we expect a signal for the browser process has been already
// map offset + buffer_size here but this can be avoided using MapAt().
size_t map_size = offset_ + buffer_size;
shared_memory_mapping_ = shared_memory_region_.MapAt(0, map_size);
- if (!shared_memory_mapping_.IsValid())
+ if (!shared_memory_mapping_.IsValid()) {
+#if BUILDFLAG(IS_TIZEN_TV)
+ LOG(WARNING) << "shared_memory_mapping_ is invalid!!! OOM map_size:"
+ << map_size;
+#endif
base::TerminateBecauseOutOfMemory(map_size);
+ }
}
return true;
}
constexpr base::TimeDelta kPingInterval = base::Seconds(1);
}
+constexpr int MB = 1024 * 1024;
+std::ostream& operator<<(std::ostream& out, const MemoryUsage& memory_usage) {
+ return out << "v8_bytes:" << memory_usage.v8_bytes / MB
+ << "MB partition_alloc_bytes:"
+ << memory_usage.partition_alloc_bytes / MB
+ << "MB blink_gc_bytes:" << memory_usage.blink_gc_bytes / MB
+ << "MB private_footprint_bytes:"
+ << memory_usage.private_footprint_bytes / MB
+ << "MB swap_bytes:" << memory_usage.swap_bytes / MB
+ << "MB vm_size_bytes:" << memory_usage.vm_size_bytes / MB
+ << "MB peak_resident_bytes:"
+ << memory_usage.peak_resident_bytes / MB << "MB";
+}
+
MemoryUsageMonitor::MemoryUsageMonitor() {
MainThreadScheduler* scheduler =
Thread::MainThread()->Scheduler()->ToMainThreadScheduler();
double peak_resident_bytes = std::numeric_limits<double>::quiet_NaN();
};
+std::ostream& operator<<(std::ostream& out, const MemoryUsage& memory_usage);
+
// Periodically checks the memory usage and notifies its observers. Monitoring
// automatically starts/stops depending on whether an observer exists.
class CONTROLLER_EXPORT MemoryUsageMonitor {