[JSC] JSRunLoopTimer::Manager should be small
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Apr 2019 18:33:45 +0000 (18:33 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Apr 2019 18:33:45 +0000 (18:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196425

Reviewed by Darin Adler.

Using very large Key or Value in HashMap potentially bloats memory since HashMap pre-allocates large size of
memory ((sizeof(Key) + sizeof(Value)) * N) for its backing storage's array. Using std::unique_ptr<> for JSRunLoopTimer's
PerVMData to keep HashMap's backing store size small.

* runtime/JSRunLoopTimer.cpp:
(JSC::JSRunLoopTimer::Manager::timerDidFire):
(JSC::JSRunLoopTimer::Manager::registerVM):
(JSC::JSRunLoopTimer::Manager::scheduleTimer):
(JSC::JSRunLoopTimer::Manager::cancelTimer):
(JSC::JSRunLoopTimer::Manager::timeUntilFire):
(JSC::JSRunLoopTimer::Manager::didChangeRunLoop):
* runtime/JSRunLoopTimer.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243702 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/JSRunLoopTimer.cpp
Source/JavaScriptCore/runtime/JSRunLoopTimer.h

index 4e2b24f..6cf9444 100644 (file)
@@ -1,3 +1,23 @@
+2019-04-01  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] JSRunLoopTimer::Manager should be small
+        https://bugs.webkit.org/show_bug.cgi?id=196425
+
+        Reviewed by Darin Adler.
+
+        Using very large Key or Value in HashMap potentially bloats memory since HashMap pre-allocates large size of
+        memory ((sizeof(Key) + sizeof(Value)) * N) for its backing storage's array. Using std::unique_ptr<> for JSRunLoopTimer's
+        PerVMData to keep HashMap's backing store size small.
+
+        * runtime/JSRunLoopTimer.cpp:
+        (JSC::JSRunLoopTimer::Manager::timerDidFire):
+        (JSC::JSRunLoopTimer::Manager::registerVM):
+        (JSC::JSRunLoopTimer::Manager::scheduleTimer):
+        (JSC::JSRunLoopTimer::Manager::cancelTimer):
+        (JSC::JSRunLoopTimer::Manager::timeUntilFire):
+        (JSC::JSRunLoopTimer::Manager::didChangeRunLoop):
+        * runtime/JSRunLoopTimer.h:
+
 2019-04-01  Stephan Szabo  <stephan.szabo@sony.com>
 
         [PlayStation] Add initialization for JSC shell for PlayStation port
index 2a78af8..1af0036 100644 (file)
@@ -121,7 +121,7 @@ void JSRunLoopTimer::Manager::timerDidFire()
 #endif
         EpochTime nowEpochTime = epochTime(0_s);
         for (auto& entry : m_mapping) {
-            PerVMData& data = entry.value;
+            PerVMData& data = *entry.value;
 #if USE(CF)
             if (data.runLoop.get() != currentRunLoop)
                 continue;
@@ -172,9 +172,9 @@ JSRunLoopTimer::Manager& JSRunLoopTimer::Manager::shared()
 
 void JSRunLoopTimer::Manager::registerVM(VM& vm)
 {
-    PerVMData data { *this };
+    auto data = std::make_unique<PerVMData>(*this);
 #if USE(CF)
-    data.setRunLoop(this, vm.runLoop());
+    data->setRunLoop(this, vm.runLoop());
 #endif
 
     auto locker = holdLock(m_lock);
@@ -199,7 +199,7 @@ void JSRunLoopTimer::Manager::scheduleTimer(JSRunLoopTimer& timer, Seconds delay
     auto iter = m_mapping.find(timer.m_apiLock);
     RELEASE_ASSERT(iter != m_mapping.end()); // We don't allow calling this after the VM dies.
 
-    PerVMData& data = iter->value;
+    PerVMData& data = *iter->value;
     EpochTime scheduleTime = fireEpochTime;
     bool found = false;
     for (auto& entry : data.timers) {
@@ -229,7 +229,7 @@ void JSRunLoopTimer::Manager::cancelTimer(JSRunLoopTimer& timer)
         return;
     }
 
-    PerVMData& data = iter->value;
+    PerVMData& data = *iter->value;
     EpochTime scheduleTime = epochTime(s_decade);
     for (unsigned i = 0; i < data.timers.size(); ++i) {
         {
@@ -261,7 +261,7 @@ Optional<Seconds> JSRunLoopTimer::Manager::timeUntilFire(JSRunLoopTimer& timer)
     auto iter = m_mapping.find(timer.m_apiLock);
     RELEASE_ASSERT(iter != m_mapping.end()); // We only allow this to be called with a live VM.
 
-    PerVMData& data = iter->value;
+    PerVMData& data = *iter->value;
     for (auto& entry : data.timers) {
         if (entry.first.ptr() == &timer) {
             EpochTime nowEpochTime = epochTime(0_s);
@@ -279,7 +279,7 @@ void JSRunLoopTimer::Manager::didChangeRunLoop(VM& vm, CFRunLoopRef newRunLoop)
     auto iter = m_mapping.find({ vm.apiLock() });
     RELEASE_ASSERT(iter != m_mapping.end());
 
-    PerVMData& data = iter->value;
+    PerVMData& data = *iter->value;
     data.setRunLoop(this, newRunLoop);
 }
 #endif
index 3626ab6..d03da29 100644 (file)
@@ -78,15 +78,11 @@ public:
         Lock m_lock;
 
         struct PerVMData {
-            PerVMData() = default;
 #if USE(CF)
             PerVMData(Manager&) { }
 #else
             PerVMData(Manager&);
 #endif
-            PerVMData(PerVMData&&) = default;
-            PerVMData& operator=(PerVMData&&) = default;
-
             ~PerVMData();
 
 #if USE(CF)
@@ -101,7 +97,7 @@ public:
             Vector<std::pair<Ref<JSRunLoopTimer>, EpochTime>> timers;
         };
 
-        HashMap<Ref<JSLock>, PerVMData> m_mapping;
+        HashMap<Ref<JSLock>, std::unique_ptr<PerVMData>> m_mapping;
     };
 
     JSRunLoopTimer(VM*);