Changeset 201990 in webkit
- Timestamp:
- Jun 13, 2016 8:53:42 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r201976 r201990 1 2016-06-13 Mark Lam <mark.lam@apple.com> 2 3 Add a mechanism for collecting LLINT stats. 4 https://bugs.webkit.org/show_bug.cgi?id=158668 5 6 Reviewed by Filip Pizlo. 7 8 This patch will add a mechanism for collecting the stats on LLINT opcode 9 execution counts. The changes made to enable this are: 10 11 1. Refactored how Options availability work so that we can add a new category: 12 Configurable (in addition to the pre-existing Normal and Restricted 13 availability). 14 Normal options - always available. 15 Restricted options - only available on debug builds. 16 Configurable options - depends on #define flag options. 17 18 This change is necessary so that: 19 a. we won't have to rebuild the world when we want to enable that #define flag 20 to make that Configurable option available. 21 b. when the #define flag is disabled, the option will be invisible to the user. 22 23 With this, we add our first configurable option, JSC_reportLLIntStats, which 24 is dependent on the ENABLE_LLINT_STATS flag. See next. 25 26 2. Added the ENABLE_LLINT_STATS flag in LLIntCommon.h. To enable LLINT stats 27 collection, we'll need to set this flag to a non-zero value, and rebuilding 28 the project. By design, this will only require a minimal set of files to 29 be rebuilt. 30 31 ENABLE_LLINT_STATS is 0 (i.e. disabled) by default. 32 33 3. Added a slow path callback to the LLINT's traceExecution() macro, to call 34 _llint_count_opcode(), which in turns counts the opcode. This callback will 35 only be built into the LLINT if ENABLE_LLINT_STATS is non-zero. 36 37 4. Added s_opcodeStatsArray to LLInt::Data. This is where the stats are 38 recorded and stored. 39 40 5. Added calls to LLInt::Data::dumpStats() in jsc.cpp and DumpRenderTree.mm 41 to dump the LLINT stats if enabled. If enabled, the LLINT stats will be 42 sorted and dumped (via dataLog) before the programs terminate. 43 44 * interpreter/Interpreter.h: 45 * jsc.cpp: 46 (main): 47 * llint/LLIntCommon.h: 48 * llint/LLIntData.cpp: 49 (JSC::LLInt::initialize): 50 (JSC::LLInt::Data::dumpStats): 51 * llint/LLIntData.h: 52 (JSC::LLInt::Data::opcodeStats): 53 * llint/LLIntOfflineAsmConfig.h: 54 * llint/LLIntSlowPaths.cpp: 55 (JSC::LLInt::llint_crash): 56 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 57 * llint/LLIntSlowPaths.h: 58 * llint/LowLevelInterpreter.asm: 59 * runtime/Options.cpp: 60 (JSC::parse): 61 (JSC::Options::isAvailable): 62 (JSC::overrideOptionWithHeuristic): 63 (JSC::scaleJITPolicy): 64 (JSC::Options::initialize): 65 (JSC::Options::setOptionWithoutAlias): 66 (JSC::Options::dumpAllOptions): 67 (JSC::Options::dumpOption): 68 * runtime/Options.h: 69 (JSC::Option::Option): 70 (JSC::Option::operator!=): 71 (JSC::Option::id): 72 1 73 2016-06-11 Mark Lam <mark.lam@apple.com> 2 74 -
trunk/Source/JavaScriptCore/interpreter/Interpreter.h
r201976 r201990 36 36 #include "JSObject.h" 37 37 #include "JSStack.h" 38 #include "LLIntData.h"39 38 #include "Opcode.h" 40 39 #include "SourceProvider.h" -
trunk/Source/JavaScriptCore/jsc.cpp
r201783 r201990 52 52 #include "JSString.h" 53 53 #include "JSWASMModule.h" 54 #include "LLIntData.h" 54 55 #include "ProfilerDatabase.h" 55 56 #include "SamplingProfiler.h" … … 1984 1985 if (Options::logHeapStatisticsAtExit()) 1985 1986 HeapStatistics::reportSuccess(); 1987 if (Options::reportLLIntStats()) 1988 LLInt::Data::dumpStats(); 1986 1989 1987 1990 #if PLATFORM(EFL) -
trunk/Source/JavaScriptCore/llint/LLIntCommon.h
r161356 r201990 1 1 /* 2 * Copyright (C) 2012 , 2013Apple Inc. All rights reserved.2 * Copyright (C) 2012-2013, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #define LLIntCommon_h 28 28 29 // Enables LLINT stats collection. 30 #define ENABLE_LLINT_STATS 0 31 29 32 // Print every instruction executed. 30 33 #define LLINT_EXECUTION_TRACING 0 -
trunk/Source/JavaScriptCore/llint/LLIntData.cpp
r201335 r201990 26 26 #include "config.h" 27 27 #include "LLIntData.h" 28 28 29 #include "BytecodeConventions.h" 29 30 #include "CodeBlock.h" … … 32 33 #include "JSScope.h" 33 34 #include "LLIntCLoop.h" 35 #include "LLIntCommon.h" 34 36 #include "MaxFrameExtentForSlowPathCall.h" 35 37 #include "Opcode.h" … … 44 46 Instruction* Data::s_exceptionInstructions = 0; 45 47 Opcode Data::s_opcodeMap[numOpcodeIDs] = { }; 48 OpcodeStatsArray* Data::s_opcodeStatsArray = nullptr; 46 49 47 50 #if ENABLE(JIT) … … 63 66 LLInt::getCodePtr(llint_throw_from_slow_path_trampoline); 64 67 #endif // ENABLE(JIT) 68 69 #if ENABLE(LLINT_STATS) 70 Data::s_opcodeStatsArray = new OpcodeStatsArray(); 71 unsigned i = 0; 72 for (auto& stats : *Data::s_opcodeStatsArray) 73 stats.id = static_cast<OpcodeID>(i++); 74 #endif 65 75 } 66 76 … … 218 228 #endif 219 229 230 void Data::dumpStats() 231 { 232 #if ENABLE(LLINT_STATS) 233 if (!Options::reportLLIntStats()) 234 return; 235 236 auto statsCopy = *s_opcodeStatsArray; 237 std::sort(statsCopy.begin(), statsCopy.end(), [] (OpcodeStats& a, OpcodeStats& b) -> bool { 238 return a.count > b.count; 239 }); 240 241 dataLog("Opcode stats:\n"); 242 unsigned i = 0; 243 for (auto& stats : statsCopy) { 244 if (stats.count) 245 dataLog(" [", i++, "]: fast:", stats.count, " ", opcodeNames[stats.id], "\n"); 246 } 247 #endif 248 } 249 250 220 251 } } // namespace JSC::LLInt -
trunk/Source/JavaScriptCore/llint/LLIntData.h
r170147 r201990 29 29 #include "JSCJSValue.h" 30 30 #include "Opcode.h" 31 #include <array> 31 32 32 33 namespace JSC { … … 43 44 namespace LLInt { 44 45 46 struct OpcodeStats { 47 OpcodeID id; 48 size_t count { 0 }; 49 }; 50 typedef std::array<OpcodeStats, numOpcodeIDs> OpcodeStatsArray; 51 45 52 class Data { 46 53 public: 54 47 55 static void performAssertions(VM&); 56 static OpcodeStats& opcodeStats(OpcodeID id) { return (*s_opcodeStatsArray)[id]; } 57 58 JS_EXPORT_PRIVATE static void dumpStats(); 48 59 49 60 private: 50 61 static Instruction* s_exceptionInstructions; 51 62 static Opcode s_opcodeMap[numOpcodeIDs]; 63 static OpcodeStatsArray* s_opcodeStatsArray; 52 64 53 65 friend void initialize(); -
trunk/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
r190129 r201990 156 156 #endif 157 157 158 #if ENABLE(LLINT_STATS) 159 #define OFFLINE_ASM_COLLECT_STATS 1 160 #else 161 #define OFFLINE_ASM_COLLECT_STATS 0 162 #endif 163 158 164 #if LLINT_EXECUTION_TRACING 159 165 #define OFFLINE_ASM_EXECUTION_TRACING 1 -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r201703 r201990 50 50 #include "JSWithScope.h" 51 51 #include "LLIntCommon.h" 52 #include "LLIntData.h" 52 53 #include "LLIntExceptions.h" 53 54 #include "LowLevelInterpreter.h" … … 1624 1625 } 1625 1626 1627 #if ENABLE(LLINT_STATS) 1628 1629 LLINT_SLOW_PATH_DECL(count_opcode) 1630 { 1631 OpcodeID opcodeID = exec->vm().interpreter->getOpcodeID(pc[0].u.opcode); 1632 Data::opcodeStats(opcodeID).count++; 1633 LLINT_END_IMPL(); 1634 } 1635 1636 #endif // ENABLE(LLINT_STATS) 1637 1626 1638 } } // namespace JSC::LLInt -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h
r201542 r201990 55 55 LLINT_SLOW_PATH_HIDDEN_DECL(trace); 56 56 LLINT_SLOW_PATH_HIDDEN_DECL(special_trace); 57 LLINT_SLOW_PATH_HIDDEN_DECL(count_opcode); 57 58 LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr); 58 59 LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr_function_for_call); -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r201542 r201990 727 727 728 728 macro traceExecution() 729 if COLLECT_STATS 730 callSlowPath(_llint_count_opcode) 731 end 729 732 if EXECUTION_TRACING 730 733 callSlowPath(_llint_trace) -
trunk/Source/JavaScriptCore/runtime/Options.cpp
r201848 r201990 27 27 #include "Options.h" 28 28 29 #include "LLIntCommon.h" 29 30 #include <algorithm> 30 31 #include <limits> … … 124 125 } 125 126 127 bool Options::isAvailable(Options::ID id, Options::Availability availability) 128 { 129 if (availability == Availability::Restricted) 130 return allowRestrictedOptions(); 131 ASSERT(availability == Availability::Configurable); 132 133 UNUSED_PARAM(id); 134 #if ENABLE(LLINT_STATS) 135 if (id == reportLLIntStatsID) 136 return true; 137 #endif 138 return false; 139 } 140 126 141 template<typename T> 127 bool overrideOptionWithHeuristic(T& variable, const char* name, Options::Availability availability) 128 { 129 bool isAvailable = (availability != Options::Availability::Restricted) || allowRestrictedOptions(); 142 bool overrideOptionWithHeuristic(T& variable, Options::ID id, const char* name, Options::Availability availability) 143 { 144 bool available = (availability == Options::Availability::Normal) 145 || Options::isAvailable(id, availability); 130 146 131 147 const char* stringValue = getenv(name); … … 133 149 return false; 134 150 135 if ( isAvailable && parse(stringValue, variable))151 if (available && parse(stringValue, variable)) 136 152 return true; 137 153 … … 259 275 260 276 struct OptionToScale { 261 Options:: OptionID id;277 Options::ID id; 262 278 int32_t minVal; 263 279 }; … … 407 423 #else // PLATFORM(COCOA) 408 424 #define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \ 409 overrideOptionWithHeuristic(name_(), "JSC_" #name_, Availability::availability_);425 overrideOptionWithHeuristic(name_(), name_##ID, "JSC_" #name_, Availability::availability_); 410 426 JSC_OPTIONS(FOR_EACH_OPTION) 411 427 #undef FOR_EACH_OPTION … … 574 590 if (strlen(#name_) == static_cast<size_t>(equalStr - arg) \ 575 591 && !strncmp(arg, #name_, equalStr - arg)) { \ 576 if (Availability::availability_ == Availability::Restricted && !allowRestrictedOptions()) \ 592 if (Availability::availability_ != Availability::Normal \ 593 && !isAvailable(name_##ID, Availability::availability_)) \ 577 594 return false; \ 578 595 type_ value; \ … … 668 685 if (separator && id) 669 686 builder.append(separator); 670 dumpOption(builder, level, static_cast< OptionID>(id), optionHeader, optionFooter, dumpDefaultsOption);687 dumpOption(builder, level, static_cast<ID>(id), optionHeader, optionFooter, dumpDefaultsOption); 671 688 } 672 689 } … … 684 701 } 685 702 686 void Options::dumpOption(StringBuilder& builder, DumpLevel level, Option ID id,703 void Options::dumpOption(StringBuilder& builder, DumpLevel level, Options::ID id, 687 704 const char* header, const char* footer, DumpDefaultsOption dumpDefaultsOption) 688 705 { … … 691 708 692 709 Option option(id); 693 if (option.availability() == Availability::Restricted && !allowRestrictedOptions()) 710 Availability availability = option.availability(); 711 if (availability != Availability::Normal && !isAvailable(id, availability)) 694 712 return; 695 713 -
trunk/Source/JavaScriptCore/runtime/Options.h
r201866 r201990 372 372 v(bool, dumpAirAfterAllocateStack, false, Normal, nullptr) \ 373 373 \ 374 v(bool, useSuperSampler, false, Normal, nullptr) 374 v(bool, useSuperSampler, false, Normal, nullptr) \ 375 \ 376 v(bool, reportLLIntStats, false, Configurable, "Reports LLInt statistics") 375 377 376 378 enum OptionEquivalence { … … 422 424 enum class Availability { 423 425 Normal = 0, 424 Restricted 426 Restricted, 427 Configurable 425 428 }; 426 429 … … 430 433 431 434 // Declare the option IDs: 432 enum OptionID {435 enum ID { 433 436 #define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \ 434 437 name_##ID, … … 470 473 JSC_OPTIONS(FOR_EACH_OPTION) 471 474 #undef FOR_EACH_OPTION 475 476 static bool isAvailable(ID, Availability); 472 477 473 478 private: … … 500 505 static void dumpAllOptions(StringBuilder&, DumpLevel, const char* title, 501 506 const char* separator, const char* optionHeader, const char* optionFooter, DumpDefaultsOption); 502 static void dumpOption(StringBuilder&, DumpLevel, OptionID,507 static void dumpOption(StringBuilder&, DumpLevel, ID, 503 508 const char* optionHeader, const char* optionFooter, DumpDefaultsOption); 504 509 … … 517 522 class Option { 518 523 public: 519 Option(Options:: OptionID id)524 Option(Options::ID id) 520 525 : m_id(id) 521 526 , m_entry(Options::s_options[m_id]) … … 528 533 bool operator!=(const Option& other) const { return !(*this == other); } 529 534 535 Options::ID id() const { return m_id; } 530 536 const char* name() const; 531 537 const char* description() const; … … 545 551 private: 546 552 // Only used for constructing default Options. 547 Option(Options:: OptionID id, Options::Entry& entry)553 Option(Options::ID id, Options::Entry& entry) 548 554 : m_id(id) 549 555 , m_entry(entry) … … 551 557 } 552 558 553 Options:: OptionID m_id;559 Options::ID m_id; 554 560 Options::Entry& m_entry; 555 561 }; -
trunk/Tools/ChangeLog
r201989 r201990 1 2016-06-13 Mark Lam <mark.lam@apple.com> 2 3 Add a mechanism for collecting LLINT stats. 4 https://bugs.webkit.org/show_bug.cgi?id=158668 5 6 Reviewed by Filip Pizlo. 7 8 * DumpRenderTree/mac/DumpRenderTree.mm: 9 (DumpRenderTreeMain): 10 1 11 2016-06-13 Romain Bellessort <romain.bellessort@crf.canon.fr> 2 12 -
trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm
r201981 r201990 58 58 #import <CoreFoundation/CoreFoundation.h> 59 59 #import <JavaScriptCore/HeapStatistics.h> 60 #import <JavaScriptCore/LLIntData.h> 60 61 #import <JavaScriptCore/Options.h> 61 62 #import <WebCore/Logging.h> … … 1443 1444 if (JSC::Options::logHeapStatisticsAtExit()) 1444 1445 JSC::HeapStatistics::reportSuccess(); 1446 if (JSC::Options::reportLLIntStats()) 1447 JSC::LLInt::Data::dumpStats(); 1445 1448 [pool release]; 1446 1449 returningFromMain = true;
Note: See TracChangeset
for help on using the changeset viewer.