Title: [201990] trunk
Revision
201990
Author
[email protected]
Date
2016-06-13 08:53:42 -0700 (Mon, 13 Jun 2016)

Log Message

Add a mechanism for collecting LLINT stats.
https://bugs.webkit.org/show_bug.cgi?id=158668

Reviewed by Filip Pizlo.

Source/_javascript_Core:

This patch will add a mechanism for collecting the stats on LLINT opcode
execution counts.  The changes made to enable this are:

1. Refactored how Options availability work so that we can add a new category:
   Configurable (in addition to the pre-existing Normal and Restricted
   availability).
       Normal options - always available.
       Restricted options - only available on debug builds.
       Configurable options - depends on #define flag options.

   This change is necessary so that:
   a. we won't have to rebuild the world when we want to enable that #define flag
      to make that Configurable option available.
   b. when the #define flag is disabled, the option will be invisible to the user.

   With this, we add our first configurable option, JSC_reportLLIntStats, which
   is dependent on the ENABLE_LLINT_STATS flag.  See next.

2. Added the ENABLE_LLINT_STATS flag in LLIntCommon.h.  To enable LLINT stats
   collection, we'll need to set this flag to a non-zero value, and rebuilding
   the project.  By design, this will only require a minimal set of files to
   be rebuilt.

   ENABLE_LLINT_STATS is 0 (i.e. disabled) by default.

3. Added a slow path callback to the LLINT's traceExecution() macro, to call
   _llint_count_opcode(), which in turns counts the opcode.  This callback will
   only be built into the LLINT if ENABLE_LLINT_STATS is non-zero.

4. Added s_opcodeStatsArray to LLInt::Data.  This is where the stats are
   recorded and stored.

5. Added calls to LLInt::Data::dumpStats() in jsc.cpp and DumpRenderTree.mm
   to dump the LLINT stats if enabled.  If enabled, the LLINT stats will be
   sorted and dumped (via dataLog) before the programs terminate.

* interpreter/Interpreter.h:
* jsc.cpp:
(main):
* llint/LLIntCommon.h:
* llint/LLIntData.cpp:
(JSC::LLInt::initialize):
(JSC::LLInt::Data::dumpStats):
* llint/LLIntData.h:
(JSC::LLInt::Data::opcodeStats):
* llint/LLIntOfflineAsmConfig.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::llint_crash):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* runtime/Options.cpp:
(JSC::parse):
(JSC::Options::isAvailable):
(JSC::overrideOptionWithHeuristic):
(JSC::scaleJITPolicy):
(JSC::Options::initialize):
(JSC::Options::setOptionWithoutAlias):
(JSC::Options::dumpAllOptions):
(JSC::Options::dumpOption):
* runtime/Options.h:
(JSC::Option::Option):
(JSC::Option::operator!=):
(JSC::Option::id):

Tools:

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

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (201989 => 201990)


--- trunk/Source/_javascript_Core/ChangeLog	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-06-13 15:53:42 UTC (rev 201990)
@@ -1,3 +1,75 @@
+2016-06-13  Mark Lam  <[email protected]>
+
+        Add a mechanism for collecting LLINT stats.
+        https://bugs.webkit.org/show_bug.cgi?id=158668
+
+        Reviewed by Filip Pizlo.
+
+        This patch will add a mechanism for collecting the stats on LLINT opcode
+        execution counts.  The changes made to enable this are:
+
+        1. Refactored how Options availability work so that we can add a new category:
+           Configurable (in addition to the pre-existing Normal and Restricted
+           availability).
+               Normal options - always available.
+               Restricted options - only available on debug builds.
+               Configurable options - depends on #define flag options.
+
+           This change is necessary so that:
+           a. we won't have to rebuild the world when we want to enable that #define flag
+              to make that Configurable option available.
+           b. when the #define flag is disabled, the option will be invisible to the user.
+
+           With this, we add our first configurable option, JSC_reportLLIntStats, which
+           is dependent on the ENABLE_LLINT_STATS flag.  See next.
+
+        2. Added the ENABLE_LLINT_STATS flag in LLIntCommon.h.  To enable LLINT stats
+           collection, we'll need to set this flag to a non-zero value, and rebuilding
+           the project.  By design, this will only require a minimal set of files to
+           be rebuilt.
+
+           ENABLE_LLINT_STATS is 0 (i.e. disabled) by default.
+
+        3. Added a slow path callback to the LLINT's traceExecution() macro, to call
+           _llint_count_opcode(), which in turns counts the opcode.  This callback will
+           only be built into the LLINT if ENABLE_LLINT_STATS is non-zero.
+
+        4. Added s_opcodeStatsArray to LLInt::Data.  This is where the stats are
+           recorded and stored.
+
+        5. Added calls to LLInt::Data::dumpStats() in jsc.cpp and DumpRenderTree.mm
+           to dump the LLINT stats if enabled.  If enabled, the LLINT stats will be
+           sorted and dumped (via dataLog) before the programs terminate.
+
+        * interpreter/Interpreter.h:
+        * jsc.cpp:
+        (main):
+        * llint/LLIntCommon.h:
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::initialize):
+        (JSC::LLInt::Data::dumpStats):
+        * llint/LLIntData.h:
+        (JSC::LLInt::Data::opcodeStats):
+        * llint/LLIntOfflineAsmConfig.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::llint_crash):
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+        * runtime/Options.cpp:
+        (JSC::parse):
+        (JSC::Options::isAvailable):
+        (JSC::overrideOptionWithHeuristic):
+        (JSC::scaleJITPolicy):
+        (JSC::Options::initialize):
+        (JSC::Options::setOptionWithoutAlias):
+        (JSC::Options::dumpAllOptions):
+        (JSC::Options::dumpOption):
+        * runtime/Options.h:
+        (JSC::Option::Option):
+        (JSC::Option::operator!=):
+        (JSC::Option::id):
+
 2016-06-11  Mark Lam  <[email protected]>
 
         Minimize the amount of memcpy done for allocating Error stacks.

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.h (201989 => 201990)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.h	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.h	2016-06-13 15:53:42 UTC (rev 201990)
@@ -35,7 +35,6 @@
 #include "JSCell.h"
 #include "JSObject.h"
 #include "JSStack.h"
-#include "LLIntData.h"
 #include "Opcode.h"
 #include "SourceProvider.h"
 #include "StackAlignment.h"

Modified: trunk/Source/_javascript_Core/jsc.cpp (201989 => 201990)


--- trunk/Source/_javascript_Core/jsc.cpp	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Source/_javascript_Core/jsc.cpp	2016-06-13 15:53:42 UTC (rev 201990)
@@ -51,6 +51,7 @@
 #include "JSProxy.h"
 #include "JSString.h"
 #include "JSWASMModule.h"
+#include "LLIntData.h"
 #include "ProfilerDatabase.h"
 #include "SamplingProfiler.h"
 #include "ShadowChicken.h"
@@ -1983,6 +1984,8 @@
     EXCEPT(res = 3)
     if (Options::logHeapStatisticsAtExit())
         HeapStatistics::reportSuccess();
+    if (Options::reportLLIntStats())
+        LLInt::Data::dumpStats();
 
 #if PLATFORM(EFL)
     ecore_shutdown();

Modified: trunk/Source/_javascript_Core/llint/LLIntCommon.h (201989 => 201990)


--- trunk/Source/_javascript_Core/llint/LLIntCommon.h	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Source/_javascript_Core/llint/LLIntCommon.h	2016-06-13 15:53:42 UTC (rev 201990)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2013, 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
@@ -26,6 +26,9 @@
 #ifndef LLIntCommon_h
 #define LLIntCommon_h
 
+// Enables LLINT stats collection.
+#define ENABLE_LLINT_STATS 0
+
 // Print every instruction executed.
 #define LLINT_EXECUTION_TRACING 0
 

Modified: trunk/Source/_javascript_Core/llint/LLIntData.cpp (201989 => 201990)


--- trunk/Source/_javascript_Core/llint/LLIntData.cpp	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Source/_javascript_Core/llint/LLIntData.cpp	2016-06-13 15:53:42 UTC (rev 201990)
@@ -25,12 +25,14 @@
 
 #include "config.h"
 #include "LLIntData.h"
+
 #include "BytecodeConventions.h"
 #include "CodeBlock.h"
 #include "CodeType.h"
 #include "Instruction.h"
 #include "JSScope.h"
 #include "LLIntCLoop.h"
+#include "LLIntCommon.h"
 #include "MaxFrameExtentForSlowPathCall.h"
 #include "Opcode.h"
 #include "PropertyOffset.h"
@@ -43,6 +45,7 @@
 
 Instruction* Data::s_exceptionInstructions = 0;
 Opcode Data::s_opcodeMap[numOpcodeIDs] = { };
+OpcodeStatsArray* Data::s_opcodeStatsArray = nullptr;
 
 #if ENABLE(JIT)
 extern "C" void llint_entry(void*);
@@ -62,6 +65,13 @@
         Data::s_exceptionInstructions[i].u.pointer =
             LLInt::getCodePtr(llint_throw_from_slow_path_trampoline);
 #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++);
+#endif
 }
 
 #if COMPILER(CLANG)
@@ -217,4 +227,25 @@
 #pragma clang diagnostic pop
 #endif
 
+void Data::dumpStats()
+{
+#if ENABLE(LLINT_STATS)
+    if (!Options::reportLLIntStats())
+        return;
+
+    auto statsCopy = *s_opcodeStatsArray;
+    std::sort(statsCopy.begin(), statsCopy.end(), [] (OpcodeStats& a, OpcodeStats& b) -> bool {
+        return a.count > b.count;
+    });
+    
+    dataLog("Opcode stats:\n");
+    unsigned i = 0;
+    for (auto& stats : statsCopy) {
+        if (stats.count)
+            dataLog("   [", i++, "]: fast:", stats.count, " ", opcodeNames[stats.id], "\n");
+    }
+#endif
+}
+
+
 } } // namespace JSC::LLInt

Modified: trunk/Source/_javascript_Core/llint/LLIntData.h (201989 => 201990)


--- trunk/Source/_javascript_Core/llint/LLIntData.h	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Source/_javascript_Core/llint/LLIntData.h	2016-06-13 15:53:42 UTC (rev 201990)
@@ -28,6 +28,7 @@
 
 #include "JSCJSValue.h"
 #include "Opcode.h"
+#include <array>
 
 namespace JSC {
 
@@ -42,13 +43,24 @@
 
 namespace LLInt {
 
+struct OpcodeStats {
+    OpcodeID id;
+    size_t count { 0 };
+};
+typedef std::array<OpcodeStats, numOpcodeIDs> OpcodeStatsArray;
+
 class Data {
 public:
+
     static void performAssertions(VM&);
+    static OpcodeStats& opcodeStats(OpcodeID id) { return (*s_opcodeStatsArray)[id]; }
 
+    JS_EXPORT_PRIVATE static void dumpStats();
+
 private:
     static Instruction* s_exceptionInstructions;
     static Opcode s_opcodeMap[numOpcodeIDs];
+    static OpcodeStatsArray* s_opcodeStatsArray;
 
     friend void initialize();
 

Modified: trunk/Source/_javascript_Core/llint/LLIntOfflineAsmConfig.h (201989 => 201990)


--- trunk/Source/_javascript_Core/llint/LLIntOfflineAsmConfig.h	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Source/_javascript_Core/llint/LLIntOfflineAsmConfig.h	2016-06-13 15:53:42 UTC (rev 201990)
@@ -155,6 +155,12 @@
 #define OFFLINE_ASM_BIG_ENDIAN 0
 #endif
 
+#if ENABLE(LLINT_STATS)
+#define OFFLINE_ASM_COLLECT_STATS 1
+#else
+#define OFFLINE_ASM_COLLECT_STATS 0
+#endif
+
 #if LLINT_EXECUTION_TRACING
 #define OFFLINE_ASM_EXECUTION_TRACING 1
 #else

Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (201989 => 201990)


--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2016-06-13 15:53:42 UTC (rev 201990)
@@ -49,6 +49,7 @@
 #include "JSString.h"
 #include "JSWithScope.h"
 #include "LLIntCommon.h"
+#include "LLIntData.h"
 #include "LLIntExceptions.h"
 #include "LowLevelInterpreter.h"
 #include "ObjectConstructor.h"
@@ -1623,4 +1624,15 @@
     CRASH();
 }
 
+#if ENABLE(LLINT_STATS)
+
+LLINT_SLOW_PATH_DECL(count_opcode)
+{
+    OpcodeID opcodeID = exec->vm().interpreter->getOpcodeID(pc[0].u.opcode);
+    Data::opcodeStats(opcodeID).count++;
+    LLINT_END_IMPL();
+}
+
+#endif // ENABLE(LLINT_STATS)
+
 } } // namespace JSC::LLInt

Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.h (201989 => 201990)


--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.h	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.h	2016-06-13 15:53:42 UTC (rev 201990)
@@ -54,6 +54,7 @@
 LLINT_SLOW_PATH_HIDDEN_DECL(trace_arityCheck_for_construct);
 LLINT_SLOW_PATH_HIDDEN_DECL(trace);
 LLINT_SLOW_PATH_HIDDEN_DECL(special_trace);
+LLINT_SLOW_PATH_HIDDEN_DECL(count_opcode);
 LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr);
 LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr_function_for_call);
 LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr_function_for_construct);

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm (201989 => 201990)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2016-06-13 15:53:42 UTC (rev 201990)
@@ -726,6 +726,9 @@
 end
 
 macro traceExecution()
+    if COLLECT_STATS
+        callSlowPath(_llint_count_opcode)
+    end
     if EXECUTION_TRACING
         callSlowPath(_llint_trace)
     end

Modified: trunk/Source/_javascript_Core/runtime/Options.cpp (201989 => 201990)


--- trunk/Source/_javascript_Core/runtime/Options.cpp	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Source/_javascript_Core/runtime/Options.cpp	2016-06-13 15:53:42 UTC (rev 201990)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "Options.h"
 
+#include "LLIntCommon.h"
 #include <algorithm>
 #include <limits>
 #include <math.h>
@@ -123,16 +124,31 @@
     return false;
 }
 
+bool Options::isAvailable(Options::ID id, Options::Availability availability)
+{
+    if (availability == Availability::Restricted)
+        return allowRestrictedOptions();
+    ASSERT(availability == Availability::Configurable);
+    
+    UNUSED_PARAM(id);
+#if ENABLE(LLINT_STATS)
+    if (id == reportLLIntStatsID)
+        return true;
+#endif
+    return false;
+}
+
 template<typename T>
-bool overrideOptionWithHeuristic(T& variable, const char* name, Options::Availability availability)
+bool overrideOptionWithHeuristic(T& variable, Options::ID id, const char* name, Options::Availability availability)
 {
-    bool isAvailable = (availability != Options::Availability::Restricted) || allowRestrictedOptions();
+    bool available = (availability == Options::Availability::Normal)
+        || Options::isAvailable(id, availability);
 
     const char* stringValue = getenv(name);
     if (!stringValue)
         return false;
     
-    if (isAvailable && parse(stringValue, variable))
+    if (available && parse(stringValue, variable))
         return true;
     
     fprintf(stderr, "WARNING: failed to parse %s=%s\n", name, stringValue);
@@ -258,7 +274,7 @@
         scaleFactor = 0.0;
 
     struct OptionToScale {
-        Options::OptionID id;
+        Options::ID id;
         int32_t minVal;
     };
 
@@ -406,7 +422,7 @@
                 CRASH();
 #else // PLATFORM(COCOA)
 #define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
-            overrideOptionWithHeuristic(name_(), "JSC_" #name_, Availability::availability_);
+            overrideOptionWithHeuristic(name_(), name_##ID, "JSC_" #name_, Availability::availability_);
             JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
 #endif // PLATFORM(COCOA)
@@ -573,7 +589,8 @@
 #define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
     if (strlen(#name_) == static_cast<size_t>(equalStr - arg)      \
         && !strncmp(arg, #name_, equalStr - arg)) {                \
-        if (Availability::availability_ == Availability::Restricted && !allowRestrictedOptions()) \
+        if (Availability::availability_ != Availability::Normal     \
+            && !isAvailable(name_##ID, Availability::availability_)) \
             return false;                                          \
         type_ value;                                               \
         value = (defaultValue_);                                   \
@@ -667,7 +684,7 @@
     for (int id = 0; id < numberOfOptions; id++) {
         if (separator && id)
             builder.append(separator);
-        dumpOption(builder, level, static_cast<OptionID>(id), optionHeader, optionFooter, dumpDefaultsOption);
+        dumpOption(builder, level, static_cast<ID>(id), optionHeader, optionFooter, dumpDefaultsOption);
     }
 }
 
@@ -683,14 +700,15 @@
     fprintf(stream, "%s", builder.toString().utf8().data());
 }
 
-void Options::dumpOption(StringBuilder& builder, DumpLevel level, OptionID id,
+void Options::dumpOption(StringBuilder& builder, DumpLevel level, Options::ID id,
     const char* header, const char* footer, DumpDefaultsOption dumpDefaultsOption)
 {
     if (id >= numberOfOptions)
         return; // Illegal option.
 
     Option option(id);
-    if (option.availability() == Availability::Restricted && !allowRestrictedOptions())
+    Availability availability = option.availability();
+    if (availability != Availability::Normal && !isAvailable(id, availability))
         return;
 
     bool wasOverridden = option.isOverridden();

Modified: trunk/Source/_javascript_Core/runtime/Options.h (201989 => 201990)


--- trunk/Source/_javascript_Core/runtime/Options.h	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Source/_javascript_Core/runtime/Options.h	2016-06-13 15:53:42 UTC (rev 201990)
@@ -371,7 +371,9 @@
     v(bool, dumpAirAsJSBeforeAllocateStack, false, Normal, nullptr) \
     v(bool, dumpAirAfterAllocateStack, false, Normal, nullptr) \
     \
-    v(bool, useSuperSampler, false, Normal, nullptr)
+    v(bool, useSuperSampler, false, Normal, nullptr) \
+    \
+    v(bool, reportLLIntStats, false, Configurable, "Reports LLInt statistics")
 
 enum OptionEquivalence {
     SameOption,
@@ -421,7 +423,8 @@
 
     enum class Availability {
         Normal = 0,
-        Restricted
+        Restricted,
+        Configurable
     };
 
     // This typedef is to allow us to eliminate the '_' in the field name in
@@ -429,7 +432,7 @@
     typedef int32_t int32;
 
     // Declare the option IDs:
-    enum OptionID {
+    enum ID {
 #define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
         name_##ID,
         JSC_OPTIONS(FOR_EACH_OPTION)
@@ -470,6 +473,8 @@
     JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
 
+    static bool isAvailable(ID, Availability);
+
 private:
     // For storing for an option value:
     union Entry {
@@ -499,7 +504,7 @@
     static void dumpOptionsIfNeeded();
     static void dumpAllOptions(StringBuilder&, DumpLevel, const char* title,
         const char* separator, const char* optionHeader, const char* optionFooter, DumpDefaultsOption);
-    static void dumpOption(StringBuilder&, DumpLevel, OptionID,
+    static void dumpOption(StringBuilder&, DumpLevel, ID,
         const char* optionHeader, const char* optionFooter, DumpDefaultsOption);
 
     static bool setOptionWithoutAlias(const char* arg);
@@ -516,7 +521,7 @@
 
 class Option {
 public:
-    Option(Options::OptionID id)
+    Option(Options::ID id)
         : m_id(id)
         , m_entry(Options::s_options[m_id])
     {
@@ -527,6 +532,7 @@
     bool operator==(const Option& other) const;
     bool operator!=(const Option& other) const { return !(*this == other); }
     
+    Options::ID id() const { return m_id; }
     const char* name() const;
     const char* description() const;
     Options::Type type() const;
@@ -544,13 +550,13 @@
     
 private:
     // Only used for constructing default Options.
-    Option(Options::OptionID id, Options::Entry& entry)
+    Option(Options::ID id, Options::Entry& entry)
         : m_id(id)
         , m_entry(entry)
     {
     }
     
-    Options::OptionID m_id;
+    Options::ID m_id;
     Options::Entry& m_entry;
 };
 

Modified: trunk/Tools/ChangeLog (201989 => 201990)


--- trunk/Tools/ChangeLog	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Tools/ChangeLog	2016-06-13 15:53:42 UTC (rev 201990)
@@ -1,3 +1,13 @@
+2016-06-13  Mark Lam  <[email protected]>
+
+        Add a mechanism for collecting LLINT stats.
+        https://bugs.webkit.org/show_bug.cgi?id=158668
+
+        Reviewed by Filip Pizlo.
+
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (DumpRenderTreeMain):
+
 2016-06-13  Romain Bellessort  <[email protected]>
 
         [GTK] Enabling Shadow DOM by default

Modified: trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm (201989 => 201990)


--- trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2016-06-13 14:10:18 UTC (rev 201989)
+++ trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2016-06-13 15:53:42 UTC (rev 201990)
@@ -57,6 +57,7 @@
 #import "WorkQueueItem.h"
 #import <CoreFoundation/CoreFoundation.h>
 #import <_javascript_Core/HeapStatistics.h>
+#import <_javascript_Core/LLIntData.h>
 #import <_javascript_Core/Options.h>
 #import <WebCore/Logging.h>
 #import <WebKit/DOMElement.h>
@@ -1442,6 +1443,8 @@
     [WebCoreStatistics emptyCache]; // Otherwise SVGImages trigger false positives for Frame/Node counts
     if (JSC::Options::logHeapStatisticsAtExit())
         JSC::HeapStatistics::reportSuccess();
+    if (JSC::Options::reportLLIntStats())
+        JSC::LLInt::Data::dumpStats();
     [pool release];
     returningFromMain = true;
     return 0;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to