Changeset 182304 in webkit


Ignore:
Timestamp:
Apr 2, 2015 8:46:39 PM (9 years ago)
Author:
mark.lam@apple.com
Message:

Enhance ability to dump JSC Options.
<https://webkit.org/b/143357>

Reviewed by Benjamin Poulain.

Some enhancements to how the JSC options work:

  1. Add a JSC_showOptions option which take values: 0 = None, 1 = Overridden only, 2 = All, 3 = Verbose.

The default is 0 (None). This dumps nothing.
With the Overridden setting, at VM initialization time, we will dump all
option values that have been changed from their default.
With the All setting, at VM initialization time, we will dump all option values.
With the Verbose setting, at VM initialization time, we will dump all option
values along with their descriptions (if available).

  1. We now store a copy of the default option values.

We later use this for comparison to tell if an option has been overridden, and
print the default value for reference. As a result, we no longer need the
didOverride flag since we can compute whether the option is overridden at any time.

  1. Added description strings to some options to be printed when JSC_showOptions=3 (Verbose).

This will come in handy later when we want to rename some of the options to more sane
names that are easier to remember. For example, we can change
Options::dfgFunctionWhitelistFile() to Options::dfgWhiteList(), and
Options::slowPathAllocsBetweenGCs() to Options::forcedGcRate(). With the availability
of the description, we can afford to use shorter and less descriptive option names,
but they will be easier to remember and use for day to day debugging work.

In this patch, I did not change the names of any of the options yet. I only added
description strings for options that I know about, and where I think the option name
isn't already descriptive enough.

  1. Also deleted some unused code.
  • jsc.cpp:

(CommandLine::parseArguments):

  • runtime/Options.cpp:

(JSC::Options::initialize):
(JSC::Options::setOption):
(JSC::Options::dumpAllOptions):
(JSC::Options::dumpOption):
(JSC::Options::Option::dump):
(JSC::Options::Option::operator==):

  • runtime/Options.h:

(JSC::OptionRange::rangeString):
(JSC::Options::Option::Option):
(JSC::Options::Option::operator!=):

Location:
trunk/Source/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r182297 r182304  
     12015-04-02  Mark Lam  <mark.lam@apple.com>
     2
     3        Enhance ability to dump JSC Options.
     4        <https://webkit.org/b/143357>
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        Some enhancements to how the JSC options work:
     9
     10        1. Add a JSC_showOptions option which take values: 0 = None, 1 = Overridden only,
     11           2 = All, 3 = Verbose.
     12
     13           The default is 0 (None).  This dumps nothing.
     14           With the Overridden setting, at VM initialization time, we will dump all
     15           option values that have been changed from their default.
     16           With the All setting, at VM initialization time, we will dump all option values.
     17           With the Verbose setting, at VM initialization time, we will dump all option
     18           values along with their descriptions (if available).
     19
     20        2. We now store a copy of the default option values.
     21
     22           We later use this for comparison to tell if an option has been overridden, and
     23           print the default value for reference.  As a result, we no longer need the
     24           didOverride flag since we can compute whether the option is overridden at any time.
     25
     26        3. Added description strings to some options to be printed when JSC_showOptions=3 (Verbose).
     27
     28           This will come in handy later when we want to rename some of the options to more sane
     29           names that are easier to remember.  For example, we can change
     30           Options::dfgFunctionWhitelistFile() to Options::dfgWhiteList(), and
     31           Options::slowPathAllocsBetweenGCs() to Options::forcedGcRate().  With the availability
     32           of the description, we can afford to use shorter and less descriptive option names,
     33           but they will be easier to remember and use for day to day debugging work.
     34
     35           In this patch, I did not change the names of any of the options yet.  I only added
     36           description strings for options that I know about, and where I think the option name
     37           isn't already descriptive enough.
     38
     39        4. Also deleted some unused code.
     40
     41        * jsc.cpp:
     42        (CommandLine::parseArguments):
     43        * runtime/Options.cpp:
     44        (JSC::Options::initialize):
     45        (JSC::Options::setOption):
     46        (JSC::Options::dumpAllOptions):
     47        (JSC::Options::dumpOption):
     48        (JSC::Options::Option::dump):
     49        (JSC::Options::Option::operator==):
     50        * runtime/Options.h:
     51        (JSC::OptionRange::rangeString):
     52        (JSC::Options::Option::Option):
     53        (JSC::Options::Option::operator!=):
     54
    1552015-04-02  Geoffrey Garen  <ggaren@apple.com>
    256
  • trunk/Source/JavaScriptCore/jsc.cpp

    r182205 r182304  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2012, 2013, 2015 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2004-2008, 2012-2013, 2015 Apple Inc. All rights reserved.
    44 *  Copyright (C) 2006 Bjoern Graf (bjoern.graf@gmail.com)
    55 *
     
    14631463
    14641464    if (needToDumpOptions)
    1465         JSC::Options::dumpAllOptions(stderr);
     1465        JSC::Options::dumpAllOptions(JSC::Options::DumpLevel::Verbose, "All JSC runtime options:", stderr);
    14661466    if (needToExit)
    14671467        jscExit(EXIT_SUCCESS);
  • trunk/Source/JavaScriptCore/runtime/Options.cpp

    r174473 r182304  
    11/*
    2  * Copyright (C) 2011, 2012, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2012, 2014-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    202202
    203203Options::Entry Options::s_options[Options::numberOfOptions];
     204Options::Entry Options::s_defaultOptions[Options::numberOfOptions];
    204205
    205206// Realize the names for each of the options:
    206207const Options::EntryInfo Options::s_optionsInfo[Options::numberOfOptions] = {
    207 #define FOR_EACH_OPTION(type_, name_, defaultValue_) \
    208     { #name_, Options::type_##Type },
     208#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
     209    { #name_, description_, Options::type_##Type },
    209210    JSC_OPTIONS(FOR_EACH_OPTION)
    210211#undef FOR_EACH_OPTION
     
    271272{
    272273    // Initialize each of the options with their default values:
    273 #define FOR_EACH_OPTION(type_, name_, defaultValue_) \
    274     name_() = defaultValue_;
     274#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
     275    name_() = defaultValue_; \
     276    name_##Default() = defaultValue_;
    275277    JSC_OPTIONS(FOR_EACH_OPTION)
    276278#undef FOR_EACH_OPTION
     
    279281    // The evn var should be the name of the option prefixed with
    280282    // "JSC_".
    281 #define FOR_EACH_OPTION(type_, name_, defaultValue_) \
    282     if (overrideOptionWithHeuristic(name_(), "JSC_" #name_)) \
    283         s_options[OPT_##name_].didOverride = true;
     283#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
     284    overrideOptionWithHeuristic(name_(), "JSC_" #name_);
    284285    JSC_OPTIONS(FOR_EACH_OPTION)
    285286#undef FOR_EACH_OPTION
     
    295296    ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= Options::thresholdForOptimizeSoon());
    296297    ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= 0);
     298
     299    if (Options::showOptions()) {
     300        DumpLevel level = static_cast<DumpLevel>(Options::showOptions());
     301        if (level > DumpLevel::Verbose)
     302            level = DumpLevel::Verbose;
     303
     304        const char* title = nullptr;
     305        switch (level) {
     306        case DumpLevel::None:
     307            break;
     308        case DumpLevel::Overridden:
     309            title = "Overridden JSC options:";
     310            break;
     311        case DumpLevel::All:
     312            title = "All JSC options:";
     313            break;
     314        case DumpLevel::Verbose:
     315            title = "All JSC options with descriptions:";
     316            break;
     317        }
     318        dumpAllOptions(level, title);
     319    }
    297320}
    298321
     
    311334    // For each option, check if the specify arg is a match. If so, set the arg
    312335    // if the value makes sense. Otherwise, move on to checking the next option.
    313 #define FOR_EACH_OPTION(type_, name_, defaultValue_)    \
     336#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
    314337    if (!strncmp(arg, #name_, equalStr - arg)) {        \
    315338        type_ value;                                    \
     
    318341        if (success) {                                  \
    319342            name_() = value;                            \
    320             s_options[OPT_##name_].didOverride = true;  \
    321343            recomputeDependentOptions();                \
    322344            return true;                                \
     
    331353}
    332354
    333 void Options::dumpAllOptions(FILE* stream)
    334 {
    335     fprintf(stream, "JSC runtime options:\n");
     355void Options::dumpAllOptions(DumpLevel level, const char* title, FILE* stream)
     356{
     357    if (title)
     358        fprintf(stream, "%s\n", title);
    336359    for (int id = 0; id < numberOfOptions; id++)
    337         dumpOption(static_cast<OptionID>(id), stream, "   ", "\n");
    338 }
    339 
    340 void Options::dumpOption(OptionID id, FILE* stream, const char* header, const char* footer)
     360        dumpOption(level, static_cast<OptionID>(id), stream, "   ", "\n");
     361}
     362
     363void Options::dumpOption(DumpLevel level, OptionID id, FILE* stream, const char* header, const char* footer)
    341364{
    342365    if (id >= numberOfOptions)
    343366        return; // Illegal option.
    344367
     368    EntryType type = s_optionsInfo[id].type;
     369    Option option(type, s_options[id]);
     370    Option defaultOption(type, s_defaultOptions[id]);
     371
     372    bool wasOverridden = (option != defaultOption);
     373    bool needsDescription = (level == DumpLevel::Verbose && s_optionsInfo[id].description);
     374
     375    if (level == DumpLevel::Overridden && !wasOverridden)
     376        return;
     377
    345378    fprintf(stream, "%s%s: ", header, s_optionsInfo[id].name);
    346     switch (s_optionsInfo[id].type) {
     379    option.dump(stream);
     380
     381    if (wasOverridden) {
     382        fprintf(stream, " (default: ");
     383        defaultOption.dump(stream);
     384        fprintf(stream, ")");
     385    }
     386
     387    if (needsDescription)
     388        fprintf(stream, "\n%s   - %s", header, s_optionsInfo[id].description);
     389
     390    fprintf(stream, "%s", footer);
     391}
     392
     393void Options::Option::dump(FILE* stream) const
     394{
     395    switch (m_type) {
    347396    case boolType:
    348         fprintf(stream, "%s", s_options[id].u.boolVal?"true":"false");
     397        fprintf(stream, "%s", m_entry.boolVal ? "true" : "false");
    349398        break;
    350399    case unsignedType:
    351         fprintf(stream, "%u", s_options[id].u.unsignedVal);
     400        fprintf(stream, "%u", m_entry.unsignedVal);
    352401        break;
    353402    case doubleType:
    354         fprintf(stream, "%lf", s_options[id].u.doubleVal);
     403        fprintf(stream, "%lf", m_entry.doubleVal);
    355404        break;
    356405    case int32Type:
    357         fprintf(stream, "%d", s_options[id].u.int32Val);
     406        fprintf(stream, "%d", m_entry.int32Val);
    358407        break;
    359408    case optionRangeType:
    360         fprintf(stream, "%s", s_options[id].u.optionRangeVal.rangeString());
     409        fprintf(stream, "%s", m_entry.optionRangeVal.rangeString());
    361410        break;
    362411    case optionStringType: {
    363         const char* option = s_options[id].u.optionStringVal;
     412        const char* option = m_entry.optionStringVal;
    364413        if (!option)
    365414            option = "";
     
    368417    }
    369418    case gcLogLevelType: {
    370         fprintf(stream, "%s", GCLogging::levelAsString(s_options[id].u.gcLogLevelVal));
    371         break;
    372     }
    373     }
    374     fprintf(stream, "%s", footer);
     419        fprintf(stream, "%s", GCLogging::levelAsString(m_entry.gcLogLevelVal));
     420        break;
     421    }
     422    }
     423}
     424
     425bool Options::Option::operator==(const Options::Option& other) const
     426{
     427    switch (m_type) {
     428    case boolType:
     429        return m_entry.boolVal == other.m_entry.boolVal;
     430    case unsignedType:
     431        return m_entry.unsignedVal == other.m_entry.unsignedVal;
     432    case doubleType:
     433        return (m_entry.doubleVal == other.m_entry.doubleVal) || (isnan(m_entry.doubleVal) && isnan(other.m_entry.doubleVal));
     434    case int32Type:
     435        return m_entry.int32Val == other.m_entry.int32Val;
     436    case optionRangeType:
     437        return m_entry.optionRangeVal.rangeString() == other.m_entry.optionRangeVal.rangeString();
     438    case optionStringType:
     439        return (m_entry.optionStringVal == other.m_entry.optionStringVal)
     440            || (m_entry.optionStringVal && other.m_entry.optionStringVal && !strcmp(m_entry.optionStringVal, other.m_entry.optionStringVal));
     441    case gcLogLevelType:
     442        return m_entry.gcLogLevelVal == other.m_entry.gcLogLevelVal;
     443    }
     444    return false;
    375445}
    376446
  • trunk/Source/JavaScriptCore/runtime/Options.h

    r182294 r182304  
    8080    bool init(const char*);
    8181    bool isInRange(unsigned);
    82     const char* rangeString() { return (m_state > InitError) ? m_rangeString : "<null>"; }
     82    const char* rangeString() const { return (m_state > InitError) ? m_rangeString : "<null>"; }
    8383
    8484private:
     
    9393
    9494#define JSC_OPTIONS(v) \
    95     v(bool, useLLInt,  true) \
    96     v(bool, useJIT,    true) \
    97     v(bool, useDFGJIT, true) \
    98     v(bool, useRegExpJIT, true) \
    99     \
    100     v(bool, reportMustSucceedExecutableAllocations, false) \
    101     \
    102     v(unsigned, maxPerThreadStackUsage, 4 * MB) \
    103     v(unsigned, reservedZoneSize, 128 * KB) \
    104     v(unsigned, errorModeReservedZoneSize, 64 * KB) \
    105     \
    106     v(bool, crashIfCantAllocateJITMemory, false) \
    107     \
    108     v(bool, forceDFGCodeBlockLiveness, false) \
    109     v(bool, forceICFailure, false) \
    110     \
    111     v(bool, dumpGeneratedBytecodes, false) \
    112     v(bool, dumpBytecodeLivenessResults, false) \
    113     v(bool, validateBytecode, false) \
    114     v(bool, forceDebuggerBytecodeGeneration, false) \
    115     v(bool, forceProfilerBytecodeGeneration, false) \
    116     \
    117     v(bool, enableFunctionDotArguments, true) \
     95    v(unsigned, showOptions, 0, "shows JSC options (0 = None, 1 = Overridden only, 2 = All, 3 = Verbose)") \
     96    \
     97    v(bool, useLLInt,  true, "allows the LLINT to be used if true") \
     98    v(bool, useJIT,    true, "allows the baseline JIT to be used if true") \
     99    v(bool, useDFGJIT, true, "allows the DFG JIT to be used if true") \
     100    v(bool, useRegExpJIT, true, "allows the RegExp JIT to be used if true") \
     101    \
     102    v(bool, reportMustSucceedExecutableAllocations, false, nullptr) \
     103    \
     104    v(unsigned, maxPerThreadStackUsage, 4 * MB, nullptr) \
     105    v(unsigned, reservedZoneSize, 128 * KB, nullptr) \
     106    v(unsigned, errorModeReservedZoneSize, 64 * KB, nullptr) \
     107    \
     108    v(bool, crashIfCantAllocateJITMemory, false, nullptr) \
     109    \
     110    v(bool, forceDFGCodeBlockLiveness, false, nullptr) \
     111    v(bool, forceICFailure, false, nullptr) \
     112    \
     113    v(bool, dumpGeneratedBytecodes, false, nullptr) \
     114    v(bool, dumpBytecodeLivenessResults, false, nullptr) \
     115    v(bool, validateBytecode, false, nullptr) \
     116    v(bool, forceDebuggerBytecodeGeneration, false, nullptr) \
     117    v(bool, forceProfilerBytecodeGeneration, false, nullptr) \
     118    \
     119    v(bool, enableFunctionDotArguments, true, nullptr) \
    118120    \
    119121    /* showDisassembly implies showDFGDisassembly. */ \
    120     v(bool, showDisassembly, false) \
    121     v(bool, asyncDisassembly, false) \
    122     v(bool, showDFGDisassembly, false) \
    123     v(bool, showFTLDisassembly, false) \
    124     v(bool, showAllDFGNodes, false) \
    125     v(optionRange, bytecodeRangeToDFGCompile, 0) \
    126     v(optionString, dfgFunctionWhitelistFile, nullptr) \
    127     v(bool, dumpSourceAtDFGTime, false) \
    128     v(bool, dumpBytecodeAtDFGTime, false) \
    129     v(bool, dumpGraphAfterParsing, false) \
    130     v(bool, dumpGraphAtEachPhase, false) \
    131     v(bool, verboseDFGByteCodeParsing, false) \
    132     v(bool, verboseCompilation, false) \
    133     v(bool, verboseFTLCompilation, false) \
    134     v(bool, logCompilationChanges, false) \
    135     v(bool, printEachOSRExit, false) \
    136     v(bool, validateGraph, false) \
    137     v(bool, validateGraphAtEachPhase, false) \
    138     v(bool, verboseValidationFailure, false) \
    139     v(bool, verboseOSR, false) \
    140     v(bool, verboseFTLOSRExit, false) \
    141     v(bool, verboseCallLink, false) \
    142     v(bool, verboseCompilationQueue, false) \
    143     v(bool, reportCompileTimes, false) \
    144     v(bool, reportFTLCompileTimes, false) \
    145     v(bool, verboseCFA, false) \
    146     v(bool, verboseFTLToJSThunk, false) \
    147     v(bool, verboseFTLFailure, false) \
    148     v(bool, alwaysComputeHash, false) \
    149     v(bool, testTheFTL, false) \
    150     v(bool, verboseSanitizeStack, false) \
    151     v(bool, alwaysDoFullCollection, false) \
    152     v(bool, eagerlyUpdateTopCallFrame, false) \
    153     \
    154     v(bool, enableOSREntryToDFG, true) \
    155     v(bool, enableOSREntryToFTL, true) \
    156     \
    157     v(bool, useFTLJIT, true) \
    158     v(bool, useFTLTBAA, true) \
    159     v(bool, enableLLVMFastISel, false) \
    160     v(bool, useLLVMSmallCodeModel, false) \
    161     v(bool, dumpLLVMIR, false) \
    162     v(bool, validateFTLOSRExitLiveness, false) \
    163     v(bool, llvmAlwaysFailsBeforeCompile, false) \
    164     v(bool, llvmAlwaysFailsBeforeLink, false) \
    165     v(bool, llvmSimpleOpt, true) \
    166     v(unsigned, llvmBackendOptimizationLevel, 2) \
    167     v(unsigned, llvmOptimizationLevel, 2) \
    168     v(unsigned, llvmSizeLevel, 0) \
    169     v(unsigned, llvmMaxStackSize, 128 * KB) \
    170     v(bool, llvmDisallowAVX, true) \
    171     v(bool, ftlCrashes, false) /* fool-proof way of checking that you ended up in the FTL. ;-) */\
    172     v(bool, clobberAllRegsInFTLICSlowPath, !ASSERT_DISABLED) \
    173     v(bool, assumeAllRegsInFTLICAreLive, false) \
    174     v(bool, enableAccessInlining, true) \
    175     v(bool, enablePolyvariantDevirtualization, true) \
    176     v(bool, enablePolymorphicAccessInlining, true) \
    177     v(bool, enablePolymorphicCallInlining, true) \
    178     v(unsigned, maxPolymorphicCallVariantListSize, 15) \
    179     v(unsigned, maxPolymorphicCallVariantListSizeForTopTier, 5) \
    180     v(unsigned, maxPolymorphicCallVariantsForInlining, 5) \
    181     v(unsigned, frequentCallThreshold, 2) \
    182     v(double, minimumCallToKnownRate, 0.51) \
    183     v(bool, optimizeNativeCalls, false) \
    184     v(bool, enableObjectAllocationSinking, true) \
    185     \
    186     v(bool, enableConcurrentJIT, true) \
    187     v(unsigned, numberOfDFGCompilerThreads, computeNumberOfWorkerThreads(2, 2) - 1) \
    188     v(unsigned, numberOfFTLCompilerThreads, computeNumberOfWorkerThreads(8, 2) - 1) \
    189     v(int32, priorityDeltaOfDFGCompilerThreads, computePriorityDeltaOfWorkerThreads(-1, 0)) \
    190     v(int32, priorityDeltaOfFTLCompilerThreads, computePriorityDeltaOfWorkerThreads(-2, 0)) \
    191     \
    192     v(bool, enableProfiler, false) \
    193     \
    194     v(bool, forceUDis86Disassembler, false) \
    195     v(bool, forceLLVMDisassembler, false) \
    196     \
    197     v(bool, enableArchitectureSpecificOptimizations, true) \
    198     \
    199     v(bool, breakOnThrow, false) \
    200     \
    201     v(unsigned, maximumOptimizationCandidateInstructionCount, 100000) \
    202     \
    203     v(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 180) \
    204     v(unsigned, maximumFunctionForClosureCallInlineCandidateInstructionCount, 100) \
    205     v(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 100) \
    206     \
    207     v(unsigned, maximumFTLCandidateInstructionCount, 20000) \
     122    v(bool, showDisassembly, false, "dumps disassembly of all JIT compiled code upon compilation") \
     123    v(bool, asyncDisassembly, false, nullptr) \
     124    v(bool, showDFGDisassembly, false, "dumps disassembly of DFG function upon compilation") \
     125    v(bool, showFTLDisassembly, false, "dumps disassembly of FTL function upon compilation") \
     126    v(bool, showAllDFGNodes, false, nullptr) \
     127    v(optionRange, bytecodeRangeToDFGCompile, 0, "bytecode size range to allow DFG compilation on, e.g. 1:100") \
     128    v(optionString, dfgFunctionWhitelistFile, nullptr, "file with list of function signatures to allow DFG compilation on") \
     129    v(bool, dumpSourceAtDFGTime, false, "dumps source code of JS function being DFG compiled") \
     130    v(bool, dumpBytecodeAtDFGTime, false, "dumps bytecode of JS function being DFG compiled") \
     131    v(bool, dumpGraphAfterParsing, false, nullptr) \
     132    v(bool, dumpGraphAtEachPhase, false, nullptr) \
     133    v(bool, verboseDFGByteCodeParsing, false, nullptr) \
     134    v(bool, verboseCompilation, false, nullptr) \
     135    v(bool, verboseFTLCompilation, false, nullptr) \
     136    v(bool, logCompilationChanges, false, nullptr) \
     137    v(bool, printEachOSRExit, false, nullptr) \
     138    v(bool, validateGraph, false, nullptr) \
     139    v(bool, validateGraphAtEachPhase, false, nullptr) \
     140    v(bool, verboseValidationFailure, false, nullptr) \
     141    v(bool, verboseOSR, false, nullptr) \
     142    v(bool, verboseFTLOSRExit, false, nullptr) \
     143    v(bool, verboseCallLink, false, nullptr) \
     144    v(bool, verboseCompilationQueue, false, nullptr) \
     145    v(bool, reportCompileTimes, false, "dumps JS function signature and the time it took to compile") \
     146    v(bool, reportFTLCompileTimes, false, "dumps JS function signature and the time it took to FTL compile") \
     147    v(bool, verboseCFA, false, nullptr) \
     148    v(bool, verboseFTLToJSThunk, false, nullptr) \
     149    v(bool, verboseFTLFailure, false, nullptr) \
     150    v(bool, alwaysComputeHash, false, nullptr) \
     151    v(bool, testTheFTL, false, nullptr) \
     152    v(bool, verboseSanitizeStack, false, nullptr) \
     153    v(bool, alwaysDoFullCollection, false, nullptr) \
     154    v(bool, eagerlyUpdateTopCallFrame, false, nullptr) \
     155    \
     156    v(bool, enableOSREntryToDFG, true, nullptr) \
     157    v(bool, enableOSREntryToFTL, true, nullptr) \
     158    \
     159    v(bool, useFTLJIT, true, "allows the FTL JIT to be used if true") \
     160    v(bool, useFTLTBAA, true, nullptr) \
     161    v(bool, enableLLVMFastISel, false, nullptr) \
     162    v(bool, useLLVMSmallCodeModel, false, nullptr) \
     163    v(bool, dumpLLVMIR, false, nullptr) \
     164    v(bool, validateFTLOSRExitLiveness, false, nullptr) \
     165    v(bool, llvmAlwaysFailsBeforeCompile, false, nullptr) \
     166    v(bool, llvmAlwaysFailsBeforeLink, false, nullptr) \
     167    v(bool, llvmSimpleOpt, true, nullptr) \
     168    v(unsigned, llvmBackendOptimizationLevel, 2, nullptr) \
     169    v(unsigned, llvmOptimizationLevel, 2, nullptr) \
     170    v(unsigned, llvmSizeLevel, 0, nullptr) \
     171    v(unsigned, llvmMaxStackSize, 128 * KB, nullptr) \
     172    v(bool, llvmDisallowAVX, true, nullptr) \
     173    v(bool, ftlCrashes, false, nullptr) /* fool-proof way of checking that you ended up in the FTL. ;-) */\
     174    v(bool, clobberAllRegsInFTLICSlowPath, !ASSERT_DISABLED, nullptr) \
     175    v(bool, assumeAllRegsInFTLICAreLive, false, nullptr) \
     176    v(bool, enableAccessInlining, true, nullptr) \
     177    v(bool, enablePolyvariantDevirtualization, true, nullptr) \
     178    v(bool, enablePolymorphicAccessInlining, true, nullptr) \
     179    v(bool, enablePolymorphicCallInlining, true, nullptr) \
     180    v(unsigned, maxPolymorphicCallVariantListSize, 15, nullptr) \
     181    v(unsigned, maxPolymorphicCallVariantListSizeForTopTier, 5, nullptr) \
     182    v(unsigned, maxPolymorphicCallVariantsForInlining, 5, nullptr) \
     183    v(unsigned, frequentCallThreshold, 2, nullptr) \
     184    v(double, minimumCallToKnownRate, 0.51, nullptr) \
     185    v(bool, optimizeNativeCalls, false, nullptr) \
     186    v(bool, enableObjectAllocationSinking, true, nullptr) \
     187    \
     188    v(bool, enableConcurrentJIT, true, "allows the DFG / FTL compilation in threads other than the executing JS thread") \
     189    v(unsigned, numberOfDFGCompilerThreads, computeNumberOfWorkerThreads(2, 2) - 1, nullptr) \
     190    v(unsigned, numberOfFTLCompilerThreads, computeNumberOfWorkerThreads(8, 2) - 1, nullptr) \
     191    v(int32, priorityDeltaOfDFGCompilerThreads, computePriorityDeltaOfWorkerThreads(-1, 0), nullptr) \
     192    v(int32, priorityDeltaOfFTLCompilerThreads, computePriorityDeltaOfWorkerThreads(-2, 0), nullptr) \
     193    \
     194    v(bool, enableProfiler, false, nullptr) \
     195    \
     196    v(bool, forceUDis86Disassembler, false, nullptr) \
     197    v(bool, forceLLVMDisassembler, false, nullptr) \
     198    \
     199    v(bool, enableArchitectureSpecificOptimizations, true, nullptr) \
     200    \
     201    v(bool, breakOnThrow, false, nullptr) \
     202    \
     203    v(unsigned, maximumOptimizationCandidateInstructionCount, 100000, nullptr) \
     204    \
     205    v(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 180, nullptr) \
     206    v(unsigned, maximumFunctionForClosureCallInlineCandidateInstructionCount, 100, nullptr) \
     207    v(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 100, nullptr) \
     208    \
     209    v(unsigned, maximumFTLCandidateInstructionCount, 20000, nullptr) \
    208210    \
    209211    /* Depth of inline stack, so 1 = no inlining, 2 = one level, etc. */ \
    210     v(unsigned, maximumInliningDepth, 5) \
    211     v(unsigned, maximumInliningRecursion, 2) \
    212     \
    213     v(unsigned, maximumLLVMInstructionCountForNativeInlining, 80) \
     212    v(unsigned, maximumInliningDepth, 5, "maximum allowed inlining depth.  Depth of 1 means no inlining") \
     213    v(unsigned, maximumInliningRecursion, 2, nullptr) \
     214    \
     215    v(unsigned, maximumLLVMInstructionCountForNativeInlining, 80, nullptr) \
    214216    \
    215217    /* Maximum size of a caller for enabling inlining. This is purely to protect us */\
    216218    /* from super long compiles that take a lot of memory. */\
    217     v(unsigned, maximumInliningCallerSize, 10000) \
    218     \
    219     v(unsigned, maximumVarargsForInlining, 100) \
    220     \
    221     v(bool, enablePolyvariantCallInlining, true) \
    222     v(bool, enablePolyvariantByIdInlining, true) \
    223     \
    224     v(unsigned, maximumBinaryStringSwitchCaseLength, 50) \
    225     v(unsigned, maximumBinaryStringSwitchTotalLength, 2000) \
    226     \
    227     v(int32, thresholdForJITAfterWarmUp, 500) \
    228     v(int32, thresholdForJITSoon, 100) \
    229     \
    230     v(int32, thresholdForOptimizeAfterWarmUp, 1000) \
    231     v(int32, thresholdForOptimizeAfterLongWarmUp, 1000) \
    232     v(int32, thresholdForOptimizeSoon, 1000) \
    233     v(int32, executionCounterIncrementForLoop, 1) \
    234     v(int32, executionCounterIncrementForEntry, 15) \
    235     \
    236     v(int32, thresholdForFTLOptimizeAfterWarmUp, 100000) \
    237     v(int32, thresholdForFTLOptimizeSoon, 1000) \
    238     v(int32, ftlTierUpCounterIncrementForLoop, 1) \
    239     v(int32, ftlTierUpCounterIncrementForReturn, 15) \
    240     v(unsigned, ftlOSREntryFailureCountForReoptimization, 15) \
    241     v(unsigned, ftlOSREntryRetryThreshold, 100) \
    242     \
    243     v(int32, evalThresholdMultiplier, 10) \
    244     v(unsigned, maximumEvalCacheableSourceLength, 256) \
    245     \
    246     v(bool, randomizeExecutionCountsBetweenCheckpoints, false) \
    247     v(int32, maximumExecutionCountsBetweenCheckpointsForBaseline, 1000) \
    248     v(int32, maximumExecutionCountsBetweenCheckpointsForUpperTiers, 50000) \
    249     \
    250     v(unsigned, likelyToTakeSlowCaseMinimumCount, 20) \
    251     v(unsigned, couldTakeSlowCaseMinimumCount, 10) \
    252     \
    253     v(unsigned, osrExitCountForReoptimization, 100) \
    254     v(unsigned, osrExitCountForReoptimizationFromLoop, 5) \
    255     \
    256     v(unsigned, reoptimizationRetryCounterMax, 0)  \
    257     \
    258     v(unsigned, minimumOptimizationDelay, 1) \
    259     v(unsigned, maximumOptimizationDelay, 5) \
    260     v(double, desiredProfileLivenessRate, 0.75) \
    261     v(double, desiredProfileFullnessRate, 0.35) \
    262     \
    263     v(double, doubleVoteRatioForDoubleFormat, 2) \
    264     v(double, structureCheckVoteRatioForHoisting, 1) \
    265     v(double, checkArrayVoteRatioForHoisting, 1) \
    266     \
    267     v(unsigned, minimumNumberOfScansBetweenRebalance, 100) \
    268     v(unsigned, numberOfGCMarkers, computeNumberOfGCMarkers(7)) \
    269     v(unsigned, opaqueRootMergeThreshold, 1000) \
    270     v(double, minHeapUtilization, 0.8) \
    271     v(double, minCopiedBlockUtilization, 0.9) \
    272     v(double, minMarkedBlockUtilization, 0.9) \
    273     v(unsigned, slowPathAllocsBetweenGCs, 0) \
    274     \
    275     v(double, percentCPUPerMBForFullTimer, 0.0003125) \
    276     v(double, percentCPUPerMBForEdenTimer, 0.0025) \
    277     v(double, collectionTimerMaxPercentCPU, 0.05) \
    278     \
    279     v(bool, forceWeakRandomSeed, false) \
    280     v(unsigned, forcedWeakRandomSeed, 0) \
    281     \
    282     v(bool, useZombieMode, false) \
    283     v(bool, objectsAreImmortal, false) \
    284     v(bool, showObjectStatistics, false) \
    285     \
    286     v(gcLogLevel, logGC, GCLogging::None) \
    287     v(bool, disableGC, false) \
    288     v(unsigned, gcMaxHeapSize, 0) \
    289     v(bool, recordGCPauseTimes, false) \
    290     v(bool, logHeapStatisticsAtExit, false) \
    291     v(bool, enableTypeProfiler, false) \
    292     v(bool, enableControlFlowProfiler, false) \
    293     \
    294     v(bool, verifyHeap, false) \
    295     v(unsigned, numberOfGCCyclesToRecordForVerification, 3) \
    296     \
    297     v(bool, enableExceptionFuzz, false) \
    298     v(unsigned, fireExceptionFuzzAt, 0) \
    299     \
    300     v(bool, enableExecutableAllocationFuzz, false) \
    301     v(unsigned, fireExecutableAllocationFuzzAt, 0) \
    302     v(unsigned, fireExecutableAllocationFuzzAtOrAfter, 0) \
    303     v(bool, verboseExecutableAllocationFuzz, false)
     219    v(unsigned, maximumInliningCallerSize, 10000, nullptr) \
     220    \
     221    v(unsigned, maximumVarargsForInlining, 100, nullptr) \
     222    \
     223    v(bool, enablePolyvariantCallInlining, true, nullptr) \
     224    v(bool, enablePolyvariantByIdInlining, true, nullptr) \
     225    \
     226    v(unsigned, maximumBinaryStringSwitchCaseLength, 50, nullptr) \
     227    v(unsigned, maximumBinaryStringSwitchTotalLength, 2000, nullptr) \
     228    \
     229    v(int32, thresholdForJITAfterWarmUp, 500, nullptr) \
     230    v(int32, thresholdForJITSoon, 100, nullptr) \
     231    \
     232    v(int32, thresholdForOptimizeAfterWarmUp, 1000, nullptr) \
     233    v(int32, thresholdForOptimizeAfterLongWarmUp, 1000, nullptr) \
     234    v(int32, thresholdForOptimizeSoon, 1000, nullptr) \
     235    v(int32, executionCounterIncrementForLoop, 1, nullptr) \
     236    v(int32, executionCounterIncrementForEntry, 15, nullptr) \
     237    \
     238    v(int32, thresholdForFTLOptimizeAfterWarmUp, 100000, nullptr) \
     239    v(int32, thresholdForFTLOptimizeSoon, 1000, nullptr) \
     240    v(int32, ftlTierUpCounterIncrementForLoop, 1, nullptr) \
     241    v(int32, ftlTierUpCounterIncrementForReturn, 15, nullptr) \
     242    v(unsigned, ftlOSREntryFailureCountForReoptimization, 15, nullptr) \
     243    v(unsigned, ftlOSREntryRetryThreshold, 100, nullptr) \
     244    \
     245    v(int32, evalThresholdMultiplier, 10, nullptr) \
     246    v(unsigned, maximumEvalCacheableSourceLength, 256, nullptr) \
     247    \
     248    v(bool, randomizeExecutionCountsBetweenCheckpoints, false, nullptr) \
     249    v(int32, maximumExecutionCountsBetweenCheckpointsForBaseline, 1000, nullptr) \
     250    v(int32, maximumExecutionCountsBetweenCheckpointsForUpperTiers, 50000, nullptr) \
     251    \
     252    v(unsigned, likelyToTakeSlowCaseMinimumCount, 20, nullptr) \
     253    v(unsigned, couldTakeSlowCaseMinimumCount, 10, nullptr) \
     254    \
     255    v(unsigned, osrExitCountForReoptimization, 100, nullptr) \
     256    v(unsigned, osrExitCountForReoptimizationFromLoop, 5, nullptr) \
     257    \
     258    v(unsigned, reoptimizationRetryCounterMax, 0, nullptr)  \
     259    \
     260    v(unsigned, minimumOptimizationDelay, 1, nullptr) \
     261    v(unsigned, maximumOptimizationDelay, 5, nullptr) \
     262    v(double, desiredProfileLivenessRate, 0.75, nullptr) \
     263    v(double, desiredProfileFullnessRate, 0.35, nullptr) \
     264    \
     265    v(double, doubleVoteRatioForDoubleFormat, 2, nullptr) \
     266    v(double, structureCheckVoteRatioForHoisting, 1, nullptr) \
     267    v(double, checkArrayVoteRatioForHoisting, 1, nullptr) \
     268    \
     269    v(unsigned, minimumNumberOfScansBetweenRebalance, 100, nullptr) \
     270    v(unsigned, numberOfGCMarkers, computeNumberOfGCMarkers(7), nullptr) \
     271    v(unsigned, opaqueRootMergeThreshold, 1000, nullptr) \
     272    v(double, minHeapUtilization, 0.8, nullptr) \
     273    v(double, minCopiedBlockUtilization, 0.9, nullptr) \
     274    v(double, minMarkedBlockUtilization, 0.9, nullptr) \
     275    v(unsigned, slowPathAllocsBetweenGCs, 0, "force a GC on every Nth slow path alloc, where N is specified by this option") \
     276    \
     277    v(double, percentCPUPerMBForFullTimer, 0.0003125, nullptr) \
     278    v(double, percentCPUPerMBForEdenTimer, 0.0025, nullptr) \
     279    v(double, collectionTimerMaxPercentCPU, 0.05, nullptr) \
     280    \
     281    v(bool, forceWeakRandomSeed, false, nullptr) \
     282    v(unsigned, forcedWeakRandomSeed, 0, nullptr) \
     283    \
     284    v(bool, useZombieMode, false, "debugging option to scribble over dead objects with 0xdeadbeef") \
     285    v(bool, objectsAreImmortal, false, "debugging option to keep all objects alive forever") \
     286    v(bool, showObjectStatistics, false, nullptr) \
     287    \
     288    v(gcLogLevel, logGC, GCLogging::None, "debugging option to log GC activity (0 = None, 1 = Basic, 2 = Verbose)") \
     289    v(bool, disableGC, false, nullptr) \
     290    v(unsigned, gcMaxHeapSize, 0, nullptr) \
     291    v(bool, recordGCPauseTimes, false, nullptr) \
     292    v(bool, logHeapStatisticsAtExit, false, nullptr) \
     293    v(bool, enableTypeProfiler, false, nullptr) \
     294    v(bool, enableControlFlowProfiler, false, nullptr) \
     295    \
     296    v(bool, verifyHeap, false, nullptr) \
     297    v(unsigned, numberOfGCCyclesToRecordForVerification, 3, nullptr) \
     298    \
     299    v(bool, enableExceptionFuzz, false, nullptr) \
     300    v(unsigned, fireExceptionFuzzAt, 0, nullptr) \
     301    \
     302    v(bool, enableExecutableAllocationFuzz, false, nullptr) \
     303    v(unsigned, fireExecutableAllocationFuzzAt, 0, nullptr) \
     304    v(unsigned, fireExecutableAllocationFuzzAtOrAfter, 0, nullptr) \
     305    v(bool, verboseExecutableAllocationFuzz, false, nullptr)
    304306
    305307class Options {
    306308public:
     309    enum class DumpLevel {
     310        None = 0,
     311        Overridden,
     312        All,
     313        Verbose
     314    };
     315   
    307316    // This typedef is to allow us to eliminate the '_' in the field name in
    308317    // union inside Entry. This is needed to keep the style checker happy.
     
    311320    // Declare the option IDs:
    312321    enum OptionID {
    313 #define FOR_EACH_OPTION(type_, name_, defaultValue_) \
     322#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
    314323        OPT_##name_,
    315324        JSC_OPTIONS(FOR_EACH_OPTION)
     
    324333    // (no spaces allowed) and set the specified option if appropriate.
    325334    JS_EXPORT_PRIVATE static bool setOption(const char* arg);
    326     JS_EXPORT_PRIVATE static void dumpAllOptions(FILE* stream = stdout);
    327     static void dumpOption(OptionID id, FILE* stream = stdout, const char* header = "", const char* footer = "");
     335    JS_EXPORT_PRIVATE static void dumpAllOptions(DumpLevel, const char* title = nullptr, FILE* stream = stdout);
     336    static void dumpOption(DumpLevel, OptionID, FILE* stream = stdout, const char* header = "", const char* footer = "");
    328337
    329338    // Declare accessors for each option:
    330 #define FOR_EACH_OPTION(type_, name_, defaultValue_) \
    331     ALWAYS_INLINE static type_& name_() { return s_options[OPT_##name_].u.type_##Val; } \
    332     static bool name_##WasOverridden() { return s_options[OPT_##name_].didOverride; }
     339#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
     340    ALWAYS_INLINE static type_& name_() { return s_options[OPT_##name_].type_##Val; } \
     341    ALWAYS_INLINE static type_& name_##Default() { return s_defaultOptions[OPT_##name_].type_##Val; }
    333342
    334343    JSC_OPTIONS(FOR_EACH_OPTION)
     
    347356
    348357    // For storing for an option value:
    349     struct Entry {
    350         union {
    351             bool boolVal;
    352             unsigned unsignedVal;
    353             double doubleVal;
    354             int32 int32Val;
    355             OptionRange optionRangeVal;
    356             const char* optionStringVal;
    357             GCLogging::Level gcLogLevelVal;
    358         } u;
    359         bool didOverride;
     358    union Entry {
     359        bool boolVal;
     360        unsigned unsignedVal;
     361        double doubleVal;
     362        int32 int32Val;
     363        OptionRange optionRangeVal;
     364        const char* optionStringVal;
     365        GCLogging::Level gcLogLevelVal;
     366    };
     367
     368    class Option {
     369    public:
     370        Option(EntryType type, Entry& entry)
     371            : m_type(type)
     372            , m_entry(entry)
     373        {
     374        }
     375
     376        void dump(FILE*) const;
     377        bool operator==(const Option& other) const;
     378        bool operator!=(const Option& other) const { return !(*this == other); }
     379
     380    private:
     381        EntryType m_type;
     382        Entry& m_entry;
    360383    };
    361384
     
    363386    struct EntryInfo {
    364387        const char* name;
     388        const char* description;
    365389        EntryType type;
    366390    };
    367391
    368392    Options();
    369 
    370     // Declare the options:
    371 #define FOR_EACH_OPTION(type_, name_, defaultValue_) \
    372     type_ m_##name_;
    373     JSC_OPTIONS(FOR_EACH_OPTION)
    374 #undef FOR_EACH_OPTION
    375393
    376394    // Declare the singleton instance of the options store:
    377395    JS_EXPORTDATA static Entry s_options[numberOfOptions];
     396    static Entry s_defaultOptions[numberOfOptions];
    378397    static const EntryInfo s_optionsInfo[numberOfOptions];
    379398};
Note: See TracChangeset for help on using the changeset viewer.