Title: [202650] trunk
Revision
202650
Author
mark....@apple.com
Date
2016-06-29 15:00:02 -0700 (Wed, 29 Jun 2016)

Log Message

Add support for collecting cumulative LLINT stats via a JSC_llintStatsFile option.
https://bugs.webkit.org/show_bug.cgi?id=159274

Reviewed by Keith Miller.

Source/_javascript_Core:

* jsc.cpp:
(main):
* llint/LLIntData.cpp:
(JSC::LLInt::initialize):
(JSC::LLInt::Data::finalizeStats):
(JSC::LLInt::compareStats):
(JSC::LLInt::Data::dumpStats):
(JSC::LLInt::Data::ensureStats):
(JSC::LLInt::Data::loadStats):
(JSC::LLInt::Data::resetStats):
(JSC::LLInt::Data::saveStats):
* llint/LLIntData.h:
(JSC::LLInt::Data::opcodeStats):
* runtime/Options.cpp:
(JSC::Options::isAvailable):
(JSC::recomputeDependentOptions):
(JSC::Options::initialize):
* runtime/Options.h:

Tools:

* DumpRenderTree/mac/DumpRenderTree.mm:
(DumpRenderTreeMain):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (202649 => 202650)


--- trunk/Source/_javascript_Core/ChangeLog	2016-06-29 21:54:50 UTC (rev 202649)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-06-29 22:00:02 UTC (rev 202650)
@@ -1,3 +1,29 @@
+2016-06-29  Mark Lam  <mark....@apple.com>
+
+        Add support for collecting cumulative LLINT stats via a JSC_llintStatsFile option.
+        https://bugs.webkit.org/show_bug.cgi?id=159274
+
+        Reviewed by Keith Miller.
+
+        * jsc.cpp:
+        (main):
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::initialize):
+        (JSC::LLInt::Data::finalizeStats):
+        (JSC::LLInt::compareStats):
+        (JSC::LLInt::Data::dumpStats):
+        (JSC::LLInt::Data::ensureStats):
+        (JSC::LLInt::Data::loadStats):
+        (JSC::LLInt::Data::resetStats):
+        (JSC::LLInt::Data::saveStats):
+        * llint/LLIntData.h:
+        (JSC::LLInt::Data::opcodeStats):
+        * runtime/Options.cpp:
+        (JSC::Options::isAvailable):
+        (JSC::recomputeDependentOptions):
+        (JSC::Options::initialize):
+        * runtime/Options.h:
+
 2016-06-29  Saam barati  <sbar...@apple.com>
 
         Destructuring variable declaration is missing a validation of the syntax of a sub production when there is a rhs

Modified: trunk/Source/_javascript_Core/jsc.cpp (202649 => 202650)


--- trunk/Source/_javascript_Core/jsc.cpp	2016-06-29 21:54:50 UTC (rev 202649)
+++ trunk/Source/_javascript_Core/jsc.cpp	2016-06-29 22:00:02 UTC (rev 202650)
@@ -1985,7 +1985,7 @@
     if (Options::logHeapStatisticsAtExit())
         HeapStatistics::reportSuccess();
     if (Options::reportLLIntStats())
-        LLInt::Data::dumpStats();
+        LLInt::Data::finalizeStats();
 
 #if PLATFORM(EFL)
     ecore_shutdown();

Modified: trunk/Source/_javascript_Core/llint/LLIntData.cpp (202649 => 202650)


--- trunk/Source/_javascript_Core/llint/LLIntData.cpp	2016-06-29 21:54:50 UTC (rev 202649)
+++ trunk/Source/_javascript_Core/llint/LLIntData.cpp	2016-06-29 22:00:02 UTC (rev 202650)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #include "BytecodeConventions.h"
 #include "CodeBlock.h"
 #include "CodeType.h"
+#include "InitializeThreading.h"
 #include "Instruction.h"
 #include "JSScope.h"
 #include "LLIntCLoop.h"
@@ -38,6 +39,8 @@
 #include "PropertyOffset.h"
 #include "ShadowChicken.h"
 #include "WriteBarrier.h"
+#include <string>
+#include <wtf/NeverDestroyed.h>
 
 #define STATIC_ASSERT(cond) static_assert(cond, "LLInt assumes " #cond)
 
@@ -67,10 +70,7 @@
 #endif // ENABLE(JIT)
 
 #if ENABLE(LLINT_STATS)
-    Data::s_opcodeStatsArray = new OpcodeStatsArray();
-    unsigned i = 0;
-    for (auto& stats : *Data::s_opcodeStatsArray)
-        stats.id = static_cast<OpcodeID>(i++);
+    Data::ensureStats();
 #endif
 }
 
@@ -228,29 +228,136 @@
 #pragma clang diagnostic pop
 #endif
 
-void Data::dumpStats()
+void Data::finalizeStats()
 {
 #if ENABLE(LLINT_STATS)
     if (!Options::reportLLIntStats())
         return;
+    
+    if (Options::llintStatsFile())
+        saveStats();
+    
+    dumpStats();
+#endif
+}
 
+#if ENABLE(LLINT_STATS)
+static const bool verboseStats = false;
+
+static bool compareStats(const OpcodeStats& a, const OpcodeStats& b)
+{
+    if (a.count > b.count)
+        return true;
+    if (a.count < b.count)
+        return false;
+    return a.slowPathCount > b.slowPathCount;
+}
+
+void Data::dumpStats()
+{
+    ASSERT(Options::reportLLIntStats());
     auto statsCopy = *s_opcodeStatsArray;
-    std::sort(statsCopy.begin(), statsCopy.end(), [] (OpcodeStats& a, OpcodeStats& b) -> bool {
-        if (a.count > b.count)
-            return true;
-        if (a.count < b.count)
-            return false;
-        return a.slowPathCount > b.slowPathCount;
-    });
-    
+    std::sort(statsCopy.begin(), statsCopy.end(), compareStats);
+
     dataLog("Opcode stats:\n");
     unsigned i = 0;
     for (auto& stats : statsCopy) {
-        if (stats.count)
+        if (stats.count || stats.slowPathCount)
             dataLog("   [", i++, "]: fast:", stats.count, " slow:", stats.slowPathCount, " ", opcodeNames[stats.id], "\n");
     }
-#endif
 }
 
+void Data::ensureStats()
+{
+    static std::once_flag initializeOptionsOnceFlag;
+    std::call_once(initializeOptionsOnceFlag, [] {
+        s_opcodeStatsArray = new OpcodeStatsArray();
+        resetStats();
+    });
+}
 
+void Data::loadStats()
+{
+    static NeverDestroyed<std::string> installedStatsFile;
+    if (!Options::llintStatsFile() || !installedStatsFile.get().compare(Options::llintStatsFile()))
+        return;
+
+    Options::reportLLIntStats() = true; // Force stats collection.
+    installedStatsFile.get() = Options::llintStatsFile();
+
+    ensureStats();
+
+    const char* filename = Options::llintStatsFile();
+    FILE* file = fopen(filename, "r");
+    if (!file) {
+        dataLogF("Failed to open file %s. Did you add the file-read-write-data entitlement to WebProcess.sb?\n", filename);
+        return;
+    }
+
+    resetStats();
+
+    OpcodeStats loaded;
+    unsigned index;
+    char opcodeName[100];
+    while (fscanf(file, "[%u]: fast:%zu slow:%zu id:%u %s\n", &index, &loaded.count, &loaded.slowPathCount, &loaded.id, opcodeName) != EOF) {
+        if (verboseStats)
+            dataLogF("loaded [%u]: fast %zu slow %zu id:%u %s\n", index, loaded.count, loaded.slowPathCount, loaded.id, opcodeName);
+
+        OpcodeStats& stats = opcodeStats(loaded.id);
+        stats.count = loaded.count;
+        stats.slowPathCount = loaded.slowPathCount;
+    }
+
+    if (verboseStats) {
+        dataLogF("After loading from %s, ", filename);
+        dumpStats();
+    }
+
+    int result = fclose(file);
+    if (result)
+        dataLogF("Failed to close file %s: %s\n", filename, strerror(errno));
+}
+
+void Data::resetStats()
+{
+    unsigned i = 0;
+    for (auto& stats : *s_opcodeStatsArray) {
+        stats.id = static_cast<OpcodeID>(i++);
+        stats.count = 0;
+        stats.slowPathCount = 0;
+    }
+}
+
+void Data::saveStats()
+{
+    ASSERT(Options::reportLLIntStats() && Options::llintStatsFile());
+    const char* filename = Options::llintStatsFile();
+
+    FILE* file = fopen(filename, "w");
+    if (!file) {
+        dataLogF("Failed to open file %s. Did you add the file-read-write-data entitlement to WebProcess.sb?\n", filename);
+        return;
+    }
+
+    auto statsCopy = *s_opcodeStatsArray;
+    std::sort(statsCopy.begin(), statsCopy.end(), compareStats);
+
+    int index = 0;
+    for (auto& stats : statsCopy) {
+        if (!stats.count && !stats.slowPathCount)
+            break; // stats are sorted. If we encountered 0 counts, then there are no more non-zero counts.
+
+        if (verboseStats)
+            dataLogF("saved [%u]: fast:%zu slow:%zu id:%u %s\n", index, stats.count, stats.slowPathCount, stats.id, opcodeNames[stats.id]);
+
+        fprintf(file, "[%u]: fast:%zu slow:%zu id:%u %s\n", index, stats.count, stats.slowPathCount, stats.id, opcodeNames[stats.id]);
+        index++;
+    }
+
+    int result = fclose(file);
+    if (result)
+        dataLogF("Failed to close file %s: %s\n", filename, strerror(errno));
+}
+#endif
+
 } } // namespace JSC::LLInt

Modified: trunk/Source/_javascript_Core/llint/LLIntData.h (202649 => 202650)


--- trunk/Source/_javascript_Core/llint/LLIntData.h	2016-06-29 21:54:50 UTC (rev 202649)
+++ trunk/Source/_javascript_Core/llint/LLIntData.h	2016-06-29 22:00:02 UTC (rev 202650)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,9 +56,16 @@
     static void performAssertions(VM&);
     static OpcodeStats& opcodeStats(OpcodeID id) { return (*s_opcodeStatsArray)[id]; }
 
-    JS_EXPORT_PRIVATE static void dumpStats();
+    JS_EXPORT_PRIVATE static void finalizeStats();
 
+    static void dumpStats();
+    static void loadStats();
+
 private:
+    static void ensureStats();
+    static void resetStats();
+    static void saveStats();
+
     static Instruction* s_exceptionInstructions;
     static Opcode s_opcodeMap[numOpcodeIDs];
     static OpcodeStatsArray* s_opcodeStatsArray;

Modified: trunk/Source/_javascript_Core/runtime/Options.cpp (202649 => 202650)


--- trunk/Source/_javascript_Core/runtime/Options.cpp	2016-06-29 21:54:50 UTC (rev 202649)
+++ trunk/Source/_javascript_Core/runtime/Options.cpp	2016-06-29 22:00:02 UTC (rev 202650)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2012, 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2012, 2014-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,6 +27,7 @@
 #include "Options.h"
 
 #include "LLIntCommon.h"
+#include "LLIntData.h"
 #include <algorithm>
 #include <limits>
 #include <math.h>
@@ -132,7 +133,7 @@
     
     UNUSED_PARAM(id);
 #if ENABLE(LLINT_STATS)
-    if (id == reportLLIntStatsID)
+    if (id == reportLLIntStatsID || id == llintStatsFileID)
         return true;
 #endif
     return false;
@@ -389,6 +390,10 @@
     ASSERT((static_cast<int64_t>(Options::thresholdForOptimizeAfterLongWarmUp()) << Options::reoptimizationRetryCounterMax()) > 0);
     ASSERT((static_cast<int64_t>(Options::thresholdForOptimizeAfterLongWarmUp()) << Options::reoptimizationRetryCounterMax()) <= static_cast<int64_t>(std::numeric_limits<int32_t>::max()));
     ASSERT(Options::deferGCProbability() >= 0.0 && Options::deferGCProbability() <= 1.0);
+
+#if ENABLE(LLINT_STATS)
+    LLInt::Data::loadStats();
+#endif
 }
 
 void Options::initialize()
@@ -437,8 +442,6 @@
                 ; // Deconfuse editors that do auto indentation
 #endif
     
-            recomputeDependentOptions();
-
 #if USE(OPTIONS_FILE)
             {
                 const char* filename = OPTIONS_FILENAME;
@@ -464,6 +467,8 @@
             }
 #endif
 
+            recomputeDependentOptions();
+
             // Do range checks where needed and make corrections to the options:
             ASSERT(Options::thresholdForOptimizeAfterLongWarmUp() >= Options::thresholdForOptimizeAfterWarmUp());
             ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= Options::thresholdForOptimizeSoon());

Modified: trunk/Source/_javascript_Core/runtime/Options.h (202649 => 202650)


--- trunk/Source/_javascript_Core/runtime/Options.h	2016-06-29 21:54:50 UTC (rev 202649)
+++ trunk/Source/_javascript_Core/runtime/Options.h	2016-06-29 22:00:02 UTC (rev 202650)
@@ -375,7 +375,8 @@
     \
     v(bool, useSuperSampler, false, Normal, nullptr) \
     \
-    v(bool, reportLLIntStats, false, Configurable, "Reports LLInt statistics")
+    v(bool, reportLLIntStats, false, Configurable, "Reports LLInt statistics") \
+    v(optionString, llintStatsFile, nullptr, Configurable, "File to collect LLInt statistics in") \
 
 enum OptionEquivalence {
     SameOption,

Modified: trunk/Tools/ChangeLog (202649 => 202650)


--- trunk/Tools/ChangeLog	2016-06-29 21:54:50 UTC (rev 202649)
+++ trunk/Tools/ChangeLog	2016-06-29 22:00:02 UTC (rev 202650)
@@ -1,3 +1,13 @@
+2016-06-29  Mark Lam  <mark....@apple.com>
+
+        Add support for collecting cumulative LLINT stats via a JSC_llintStatsFile option.
+        https://bugs.webkit.org/show_bug.cgi?id=159274
+
+        Reviewed by Keith Miller.
+
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (DumpRenderTreeMain):
+
 2016-06-29  Alex Christensen  <achristen...@webkit.org>
 
         WKWebView should ask WKNavigationDelegate about bad ssl certificates

Modified: trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm (202649 => 202650)


--- trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2016-06-29 21:54:50 UTC (rev 202649)
+++ trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2016-06-29 22:00:02 UTC (rev 202650)
@@ -1444,7 +1444,7 @@
     if (JSC::Options::logHeapStatisticsAtExit())
         JSC::HeapStatistics::reportSuccess();
     if (JSC::Options::reportLLIntStats())
-        JSC::LLInt::Data::dumpStats();
+        JSC::LLInt::Data::finalizeStats();
     [pool release];
     returningFromMain = true;
     return 0;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to