Add total counts to sampling profiler dump
https://bugs.webkit.org/show_bug.cgi?id=218666

Reviewed by Yusuke Suzuki.

This is nice for computing the approximate percentage of total time in a function.

* runtime/SamplingProfiler.cpp:
(JSC::SamplingProfiler::reportTopFunctions):
(JSC::SamplingProfiler::reportTopBytecodes):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@269597 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/runtime/SamplingProfiler.cpp b/Source/JavaScriptCore/runtime/SamplingProfiler.cpp
index 295a261..ce8fce9 100644
--- a/Source/JavaScriptCore/runtime/SamplingProfiler.cpp
+++ b/Source/JavaScriptCore/runtime/SamplingProfiler.cpp
@@ -1023,7 +1023,7 @@
         processUnverifiedStackTraces(locker);
     }
 
-
+    size_t totalSamples = 0;
     HashMap<String, size_t> functionCounts;
     for (StackTrace& stackTrace : m_stackTraces) {
         if (!stackTrace.frames.size())
@@ -1039,6 +1039,7 @@
             hash = "<nil>"_s;
         String frameDescription = makeString(frame.displayName(m_vm), '#', hash, ':', frame.sourceID());
         functionCounts.add(frameDescription, 0).iterator->value++;
+        totalSamples++;
     }
 
     auto takeMax = [&] () -> std::pair<String, size_t> {
@@ -1056,14 +1057,14 @@
     };
 
     if (Options::samplingProfilerTopFunctionsCount()) {
-        out.print("\n\nSampling rate: ", m_timingInterval.microseconds(), " microseconds\n");
-        out.print("Top functions as <numSamples  'functionName#hash:sourceID'>\n");
+        out.println("\n\nSampling rate: ", m_timingInterval.microseconds(), " microseconds. Total samples: ", totalSamples);
+        out.println("Top functions as <numSamples  'functionName#hash:sourceID'>");
         for (size_t i = 0; i < Options::samplingProfilerTopFunctionsCount(); i++) {
             auto pair = takeMax();
             if (pair.first.isEmpty())
                 break;
             out.printf("%6zu ", pair.second);
-            out.print("   '", pair.first, "'\n");
+            out.println("   '", pair.first, "'");
         }
     }
 }
@@ -1083,6 +1084,7 @@
         processUnverifiedStackTraces(locker);
     }
 
+    size_t totalSamples = 0;
     HashMap<String, size_t> bytecodeCounts;
     for (StackTrace& stackTrace : m_stackTraces) {
         if (!stackTrace.frames.size())
@@ -1119,6 +1121,7 @@
                 machineLocation->second->inferredName().data(), descriptionForLocation(machineLocation->first, WTF::nullopt));
         }
         bytecodeCounts.add(frameDescription, 0).iterator->value++;
+        totalSamples++;
     }
 
     auto takeMax = [&] () -> std::pair<String, size_t> {
@@ -1136,14 +1139,14 @@
     };
 
     if (Options::samplingProfilerTopBytecodesCount()) {
-        out.print("\n\nSampling rate: ", m_timingInterval.microseconds(), " microseconds\n");
-        out.print("Hottest bytecodes as <numSamples   'functionName#hash:JITType:bytecodeIndex'>\n");
+        out.println("\n\nSampling rate: ", m_timingInterval.microseconds(), " microseconds. Total samples: ", totalSamples);
+        out.println("Hottest bytecodes as <numSamples   'functionName#hash:JITType:bytecodeIndex'>");
         for (size_t i = 0; i < Options::samplingProfilerTopBytecodesCount(); i++) {
             auto pair = takeMax();
             if (pair.first.isEmpty())
                 break;
             out.printf("%6zu ", pair.second);
-            out.print("   '", pair.first, "'\n");
+            out.println("   '", pair.first, "'");
         }
     }
 }