Add extra information to dumpJITMemory
https://bugs.webkit.org/show_bug.cgi?id=197998

Reviewed by Saam Barati.

Source/JavaScriptCore:

Add ktrace events around the memory dump and mach_absolute_time to link the
events with the entries in the dump. Additionally, add a background queue
to flush on a configurable interval, since the atexit callback does not work
in every situation.

* jit/ExecutableAllocator.cpp:
(JSC::dumpJITMemory):
* runtime/Options.h:

Source/WTF:

Add a new trace point code for JSC::dumpJITMemory

* wtf/SystemTracing.h:

Tools:

Add description for the new dumpJITMemory trace point code.

* Tracing/SystemTracePoints.plist:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@245499 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 1851c98..547bd52 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,19 @@
+2019-05-18  Tadeu Zagallo  <tzagallo@apple.com>
+
+        Add extra information to dumpJITMemory
+        https://bugs.webkit.org/show_bug.cgi?id=197998
+
+        Reviewed by Saam Barati.
+
+        Add ktrace events around the memory dump and mach_absolute_time to link the
+        events with the entries in the dump. Additionally, add a background queue
+        to flush on a configurable interval, since the atexit callback does not work
+        in every situation.
+
+        * jit/ExecutableAllocator.cpp:
+        (JSC::dumpJITMemory):
+        * runtime/Options.h:
+
 2019-05-17  Justin Michaud  <justin_michaud@apple.com>
 
         [WASM-References] Add support for Anyref in parameters and return types, Ref.null and Ref.is_null for Anyref values.
diff --git a/Source/JavaScriptCore/jit/ExecutableAllocator.cpp b/Source/JavaScriptCore/jit/ExecutableAllocator.cpp
index 7230cb7..4be4b26 100644
--- a/Source/JavaScriptCore/jit/ExecutableAllocator.cpp
+++ b/Source/JavaScriptCore/jit/ExecutableAllocator.cpp
@@ -33,8 +33,11 @@
 #include "JSCInlines.h"
 #include <wtf/MetaAllocator.h>
 #include <wtf/PageReservation.h>
+#include <wtf/SystemTracing.h>
+#include <wtf/WorkQueue.h>
 
 #if OS(DARWIN)
+#include <mach/mach_time.h>
 #include <sys/mman.h>
 #endif
 
@@ -559,39 +562,61 @@
     static uint8_t* buffer;
     static constexpr size_t bufferSize = fixedExecutableMemoryPoolSize;
     static size_t offset = 0;
-    static auto flush = [] {
+    static Lock dumpJITMemoryLock;
+    static bool needsToFlush = false;
+    static auto flush = [](const AbstractLocker&) {
         if (fd == -1) {
             fd = open(Options::dumpJITMemoryPath(), O_CREAT | O_TRUNC | O_APPEND | O_WRONLY | O_EXLOCK | O_NONBLOCK, 0666);
             RELEASE_ASSERT(fd != -1);
         }
         write(fd, buffer, offset);
         offset = 0;
+        needsToFlush = false;
     };
 
-    static Lock dumpJITMemoryLock;
     static std::once_flag once;
+    static LazyNeverDestroyed<Ref<WorkQueue>> flushQueue;
     std::call_once(once, [] {
         buffer = bitwise_cast<uint8_t*>(malloc(bufferSize));
+        flushQueue.construct(WorkQueue::create("jsc.dumpJITMemory.queue", WorkQueue::Type::Serial, WorkQueue::QOS::Background));
         std::atexit([] {
             LockHolder locker(dumpJITMemoryLock);
-            flush();
+            flush(locker);
             close(fd);
+            fd = -1;
         });
     });
 
-    static auto write = [](const void* src, size_t size) {
+    static auto enqueueFlush = [](const AbstractLocker&) {
+        if (needsToFlush)
+            return;
+
+        needsToFlush = true;
+        flushQueue.get()->dispatchAfter(Seconds(Options::dumpJITMemoryFlushInterval()), [] {
+            LockHolder locker(dumpJITMemoryLock);
+            if (!needsToFlush)
+                return;
+            flush(locker);
+        });
+    };
+
+    static auto write = [](const AbstractLocker& locker, const void* src, size_t size) {
         if (UNLIKELY(offset + size > bufferSize))
-            flush();
+            flush(locker);
         memcpy(buffer + offset, src, size);
         offset += size;
+        enqueueFlush(locker);
     };
 
     LockHolder locker(dumpJITMemoryLock);
+    uint64_t time = mach_absolute_time();
     uint64_t dst64 = bitwise_cast<uintptr_t>(dst);
-    write(&dst64, sizeof(dst64));
     uint64_t size64 = size;
-    write(&size64, sizeof(size64));
-    write(src, size);
+    TraceScope(DumpJITMemoryStart, DumpJITMemoryStop, time, dst64, size64);
+    write(locker, &time, sizeof(time));
+    write(locker, &dst64, sizeof(dst64));
+    write(locker, &size64, sizeof(size64));
+    write(locker, src, size);
 #else
     UNUSED_PARAM(dst);
     UNUSED_PARAM(src);
diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h
index f32fa6e..6f223be 100644
--- a/Source/JavaScriptCore/runtime/Options.h
+++ b/Source/JavaScriptCore/runtime/Options.h
@@ -519,6 +519,7 @@
     v(bool, validateAbstractInterpreterState, false, Restricted, nullptr) \
     v(double, validateAbstractInterpreterStateProbability, 0.5, Normal, nullptr) \
     v(optionString, dumpJITMemoryPath, nullptr, Restricted, nullptr) \
+    v(double, dumpJITMemoryFlushInterval, 10, Restricted, "Maximum time in between flushes of the JIT memory dump in seconds.") \
 
 
 enum OptionEquivalence {
diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog
index e63fa88..0ccc8bb 100644
--- a/Source/WTF/ChangeLog
+++ b/Source/WTF/ChangeLog
@@ -1,3 +1,14 @@
+2019-05-18  Tadeu Zagallo  <tzagallo@apple.com>
+
+        Add extra information to dumpJITMemory
+        https://bugs.webkit.org/show_bug.cgi?id=197998
+
+        Reviewed by Saam Barati.
+
+        Add a new trace point code for JSC::dumpJITMemory
+
+        * wtf/SystemTracing.h:
+
 2019-05-17  Don Olmstead  <don.olmstead@sony.com>
 
         [CMake] Use builtin FindICU
diff --git a/Source/WTF/wtf/SystemTracing.h b/Source/WTF/wtf/SystemTracing.h
index bcce0f9..75fdea9 100644
--- a/Source/WTF/wtf/SystemTracing.h
+++ b/Source/WTF/wtf/SystemTracing.h
@@ -47,6 +47,8 @@
     WebAssemblyCompileEnd,
     WebAssemblyExecuteStart,
     WebAssemblyExecuteEnd,
+    DumpJITMemoryStart,
+    DumpJITMemoryStop,
 
     WebCoreRange = 5000,
     MainResourceLoadDidStartProvisional,
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index 20f2f23..d2b62fb 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,14 @@
+2019-05-18  Tadeu Zagallo  <tzagallo@apple.com>
+
+        Add extra information to dumpJITMemory
+        https://bugs.webkit.org/show_bug.cgi?id=197998
+
+        Reviewed by Saam Barati.
+
+        Add description for the new dumpJITMemory trace point code.
+
+        * Tracing/SystemTracePoints.plist:
+
 2019-05-17  Justin Michaud  <justin_michaud@apple.com>
 
         [WASM-References] Add support for Anyref in parameters and return types, Ref.null and Ref.is_null for Anyref values.
diff --git a/Tools/Tracing/SystemTracePoints.plist b/Tools/Tracing/SystemTracePoints.plist
index c140e91..ad28156 100644
--- a/Tools/Tracing/SystemTracePoints.plist
+++ b/Tools/Tracing/SystemTracePoints.plist
@@ -45,6 +45,18 @@
              </dict>
              <dict>
                  <key>Name</key>
+                 <string>Dump JIT Memory</string>
+                 <key>Type</key>
+                 <string>Interval</string>
+                 <key>Component</key>
+                 <string>47</string>
+                 <key>CodeBegin</key>
+                 <string>2507</string>
+                 <key>CodeEnd</key>
+                 <string>2508</string>
+             </dict>
+             <dict>
+                 <key>Name</key>
                  <string>Main Resource Load</string>
                  <key>Type</key>
                  <string>Interval</string>