Changeset 251400 in webkit


Ignore:
Timestamp:
Oct 21, 2019 5:17:50 PM (4 years ago)
Author:
mark.lam@apple.com
Message:

Rolling out r251226: Causes a build speed regression.
https://bugs.webkit.org/show_bug.cgi?id=203219

Not reviewed.

Apparently, compilers aren't very fast at compiling constexpr function invocations.
Rolling this out while I rework the patch to not have this build speed regression.

  • API/glib/JSCOptions.cpp:

(jscOptionsSetValue):
(jscOptionsGetValue):
(jsc_options_foreach):
(jsc_options_get_option_group):

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Sources.txt:
  • runtime/JSCConfig.h:
  • runtime/OptionEntry.h: Copied from Source/JavaScriptCore/runtime/OptionEntry.h.
  • runtime/Options.cpp:

(JSC::Options::isAvailable):
(JSC::overrideOptionWithHeuristic):
(JSC::scaleJITPolicy):
(JSC::recomputeDependentOptions):
(JSC::Options::initialize):
(JSC::Options::setOptionWithoutAlias):
(JSC::Options::dumpAllOptions):
(JSC::Options::dumpOption):
(JSC::Option::dump const):
(JSC::Option::operator== const):
(JSC::optionTypeSpecificIndex): Deleted.
(JSC::Option::Option): Deleted.
(JSC::Option::defaultOption const): Deleted.

  • runtime/Options.h:

(JSC::Option::Option):
(JSC::Option::id const):
(JSC::Option::name const):
(JSC::Option::description const):
(JSC::Option::type const):
(JSC::Option::availability const):
(JSC::Option::isOverridden const):
(JSC::Option::defaultOption const):
(JSC::Option::boolVal):
(JSC::Option::unsignedVal):
(JSC::Option::doubleVal):
(JSC::Option::int32Val):
(JSC::Option::optionRangeVal):
(JSC::Option::optionStringVal):
(JSC::Option::gcLogLevelVal):
(JSC::Option::idIndex const): Deleted.
(JSC::optionTypeSpecificIndex): Deleted.

  • runtime/OptionsList.h:

(JSC::OptionRange::operator= ): Deleted.
(JSC::OptionRange::rangeString const): Deleted.
(JSC::countNumberOfJSCOptionsOfType): Deleted.

Location:
trunk/Source/JavaScriptCore
Files:
9 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/glib/JSCOptions.cpp

    r251226 r251400  
    169169#define SET_OPTION_VALUE(type_, name_, defaultValue_, availability_, description_) \
    170170    if (!g_strcmp0(#name_, option)) {                                   \
    171         OptionTypes::type_ valueToSet;                                  \
     171        OptionEntry::type_ valueToSet;                                  \
    172172        if (!valueFromGValue(value, valueToSet))                        \
    173173            return FALSE;                                               \
     
    187187#define GET_OPTION_VALUE(type_, name_, defaultValue_, availability_, description_) \
    188188    if (!g_strcmp0(#name_, option)) {                                   \
    189         OptionTypes::type_ valueToGet = Options::name_();               \
     189        OptionEntry::type_ valueToGet = Options::name_();               \
    190190        valueToGValue(valueToGet, value);                               \
    191191        return TRUE;                                                    \
     
    617617#define VISIT_OPTION(type_, name_, defaultValue_, availability_, description_) \
    618618    if (Options::Availability::availability_ == Options::Availability::Normal \
    619         || Options::isAvailable(OptionID::name_, Options::Availability::availability_)) { \
    620         OptionTypes::type_ defaultValue { };                            \
     619        || Options::isAvailable(Options::name_##ID, Options::Availability::availability_)) { \
     620        OptionEntry::type_ defaultValue { };                            \
    621621        auto optionType = jscOptionsType(defaultValue);                 \
    622622        if (function (#name_, optionType, description_, userData))      \
     
    667667#define REGISTER_OPTION(type_, name_, defaultValue_, availability_, description_) \
    668668    if (Options::Availability::availability_ == Options::Availability::Normal \
    669         || Options::isAvailable(OptionID::name_, Options::Availability::availability_)) { \
     669        || Options::isAvailable(Options::name_##ID, Options::Availability::availability_)) { \
    670670        GUniquePtr<char> name(g_strdup_printf("jsc-%s", #name_));       \
    671671        entries = g_array_set_size(entries, entries->len + 1); \
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r251226 r251400  
    921921    runtime/ObjectPrototype.h
    922922    runtime/Operations.h
     923    runtime/OptionEntry.h
    923924    runtime/Options.h
    924925    runtime/OptionsList.h
  • trunk/Source/JavaScriptCore/ChangeLog

    r251399 r251400  
     12019-10-21  Mark Lam  <mark.lam@apple.com>
     2
     3        Rolling out r251226: Causes a build speed regression.
     4        https://bugs.webkit.org/show_bug.cgi?id=203219
     5
     6        Not reviewed.
     7
     8        Apparently, compilers aren't very fast at compiling constexpr function invocations.
     9        Rolling this out while I rework the patch to not have this build speed regression.
     10
     11        * API/glib/JSCOptions.cpp:
     12        (jscOptionsSetValue):
     13        (jscOptionsGetValue):
     14        (jsc_options_foreach):
     15        (jsc_options_get_option_group):
     16        * CMakeLists.txt:
     17        * JavaScriptCore.xcodeproj/project.pbxproj:
     18        * Sources.txt:
     19        * runtime/JSCConfig.h:
     20        * runtime/OptionEntry.h: Copied from Source/JavaScriptCore/runtime/OptionEntry.h.
     21        * runtime/Options.cpp:
     22        (JSC::Options::isAvailable):
     23        (JSC::overrideOptionWithHeuristic):
     24        (JSC::scaleJITPolicy):
     25        (JSC::recomputeDependentOptions):
     26        (JSC::Options::initialize):
     27        (JSC::Options::setOptionWithoutAlias):
     28        (JSC::Options::dumpAllOptions):
     29        (JSC::Options::dumpOption):
     30        (JSC::Option::dump const):
     31        (JSC::Option::operator== const):
     32        (JSC::optionTypeSpecificIndex): Deleted.
     33        (JSC::Option::Option): Deleted.
     34        (JSC::Option::defaultOption const): Deleted.
     35        * runtime/Options.h:
     36        (JSC::Option::Option):
     37        (JSC::Option::id const):
     38        (JSC::Option::name const):
     39        (JSC::Option::description const):
     40        (JSC::Option::type const):
     41        (JSC::Option::availability const):
     42        (JSC::Option::isOverridden const):
     43        (JSC::Option::defaultOption const):
     44        (JSC::Option::boolVal):
     45        (JSC::Option::unsignedVal):
     46        (JSC::Option::doubleVal):
     47        (JSC::Option::int32Val):
     48        (JSC::Option::optionRangeVal):
     49        (JSC::Option::optionStringVal):
     50        (JSC::Option::gcLogLevelVal):
     51        (JSC::Option::idIndex const): Deleted.
     52        (JSC::optionTypeSpecificIndex): Deleted.
     53        * runtime/OptionsList.h:
     54        (JSC::OptionRange::operator= ): Deleted.
     55        (JSC::OptionRange::rangeString const): Deleted.
     56        (JSC::countNumberOfJSCOptionsOfType): Deleted.
     57
    1582019-10-21  Mark Lam  <mark.lam@apple.com>
    259
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r251226 r251400  
    18651865                FE1BD0251E72053800134BC9 /* HeapVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1BD0231E72052F00134BC9 /* HeapVerifier.h */; };
    18661866                FE1C0FFD1B193E9800B53FCA /* Exception.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1C0FFC1B193E9800B53FCA /* Exception.h */; settings = {ATTRIBUTES = (Private, ); }; };
    1867                 FE1D6D4523580E1F007A5C26 /* Options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE228EA1436AB2300196C48 /* Options.cpp */; };
    18681867                FE1E2C3F2240DD5800F6B729 /* MacroAssemblerARM64E.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1E2C3E2240D30B00F6B729 /* MacroAssemblerARM64E.h */; settings = {ATTRIBUTES = (Private, ); }; };
    18691868                FE1E2C402240DD6200F6B729 /* ARM64EAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1E2C3D2240D2F600F6B729 /* ARM64EAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    18741873                FE318FE01CAC982F00DFCC54 /* ECMAScriptSpecInternalFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = FE318FDE1CAC8C5300DFCC54 /* ECMAScriptSpecInternalFunctions.h */; };
    18751874                FE3422121D6B81C30032BE88 /* ThrowScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3422111D6B818C0032BE88 /* ThrowScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1875                FE3842322324D51B009DD445 /* OptionEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3842302324D51A009DD445 /* OptionEntry.h */; settings = {ATTRIBUTES = (Private, ); }; };
    18761876                FE3842332324D51B009DD445 /* OptionsList.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3842312324D51B009DD445 /* OptionsList.h */; settings = {ATTRIBUTES = (Private, ); }; };
    18771877                FE384EE61ADDB7AD0055DE2C /* JSDollarVM.h in Headers */ = {isa = PBXBuildFile; fileRef = FE384EE21ADDB7AD0055DE2C /* JSDollarVM.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    50745074                FE35C2FB21B1E6C7000F4CA8 /* OpcodeGroup.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = OpcodeGroup.rb; sourceTree = "<group>"; };
    50755075                FE35C2FC21B1E6C7000F4CA8 /* Metadata.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = Metadata.rb; sourceTree = "<group>"; };
     5076                FE3842302324D51A009DD445 /* OptionEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OptionEntry.h; sourceTree = "<group>"; };
    50765077                FE3842312324D51B009DD445 /* OptionsList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OptionsList.h; sourceTree = "<group>"; };
    50775078                FE384EE11ADDB7AD0055DE2C /* JSDollarVM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDollarVM.cpp; sourceTree = "<group>"; };
     
    73827383                                F692A8770255597D01FF60F7 /* Operations.cpp */,
    73837384                                F692A8780255597D01FF60F7 /* Operations.h */,
     7385                                FE3842302324D51A009DD445 /* OptionEntry.h */,
    73847386                                0FE228EA1436AB2300196C48 /* Options.cpp */,
    73857387                                0FE228EB1436AB2300196C48 /* Options.h */,
     
    99049906                                A70447EA17A0BD4600F5898E /* OperandsInlines.h in Headers */,
    99059907                                BC18C4480E16F5CD00B34460 /* Operations.h in Headers */,
     9908                                FE3842322324D51B009DD445 /* OptionEntry.h in Headers */,
    99069909                                0FE228ED1436AB2700196C48 /* Options.h in Headers */,
    99079910                                FE3842332324D51B009DD445 /* OptionsList.h in Headers */,
     
    1113211135                                536B315C1F71C5990037FC33 /* UnifiedSource88.cpp in Sources */,
    1113311136                                536B31621F71C5990037FC33 /* UnifiedSource89.cpp in Sources */,
    11134                                 FE1D6D4523580E1F007A5C26 /* Options.cpp in Sources */,
    1113511137                                536B31421F71C5990037FC33 /* UnifiedSource90.cpp in Sources */,
    1113611138                                536B31491F71C5990037FC33 /* UnifiedSource91.cpp in Sources */,
  • trunk/Source/JavaScriptCore/Sources.txt

    r251226 r251400  
    905905runtime/ObjectToStringAdaptiveStructureWatchpoint.cpp
    906906runtime/Operations.cpp
    907 runtime/Options.cpp @no-unify
     907runtime/Options.cpp
    908908runtime/ProgramExecutable.cpp
    909909runtime/PromiseDeferredTimer.cpp
  • trunk/Source/JavaScriptCore/runtime/JSCConfig.h

    r251226 r251400  
    2626#pragma once
    2727
     28#include "OptionEntry.h"
    2829#include "OptionsList.h"
    2930#include <wtf/StdLibExtras.h>
     
    3637#if CPU(ARM64) || PLATFORM(WATCHOS)
    3738constexpr size_t PageSize = 16 * KB;
    38 constexpr size_t ConfigSizeToProtect = 1 * PageSize;
    3939#else
    4040constexpr size_t PageSize = 4 * KB;
    41 constexpr size_t ConfigSizeToProtect = 1 * PageSize;
    4241#endif
     42
     43constexpr size_t ConfigSizeToProtect = 32 * KB;
    4344
    4445#if ENABLE(SEPARATED_WX_HEAP)
     
    8283#endif
    8384
    84             bool typeBoolOptions[NumberOfBoolOptions];
    85             bool typeBoolDefaultOptions[NumberOfBoolOptions];
    86 
    87             GCLogging::Level typeGCLogLevelOptions[NumberOfGCLogLevelOptions];
    88             GCLogging::Level typeGCLogLevelDefaultOptions[NumberOfGCLogLevelOptions];
    89 
    90             int32_t typeInt32Options[NumberOfInt32Options];
    91             int32_t typeInt32DefaultOptions[NumberOfInt32Options];
    92 
    93             unsigned typeUnsignedOptions[NumberOfUnsignedOptions];
    94             unsigned typeUnsignedDefaultOptions[NumberOfUnsignedOptions];
    95 
    96             double typeDoubleOptions[NumberOfDoubleOptions];
    97             double typeDoubleDefaultOptions[NumberOfDoubleOptions];
    98 
    99             size_t typeSizeOptions[NumberOfSizeOptions];
    100             size_t typeSizeDefaultOptions[NumberOfSizeOptions];
    101 
    102             const char* typeOptionStringOptions[NumberOfOptionStringOptions];
    103             const char* typeOptionStringDefaultOptions[NumberOfOptionStringOptions];
    104 
    105             OptionRange typeOptionRangeOptions[NumberOfOptionRangeOptions];
    106             OptionRange typeOptionRangeDefaultOptions[NumberOfOptionRangeOptions];
     85            OptionEntry options[NumberOfOptions];
     86            OptionEntry defaultOptions[NumberOfOptions];
    10787        };
    10888        char ensureSize[ConfigSizeToProtect];
  • trunk/Source/JavaScriptCore/runtime/Options.cpp

    r251276 r251400  
    133133}
    134134
    135 bool Options::isAvailable(OptionID id, Options::Availability availability)
     135bool Options::isAvailable(Options::ID id, Options::Availability availability)
    136136{
    137137    if (availability == Availability::Restricted)
     
    141141    UNUSED_PARAM(id);
    142142#if !defined(NDEBUG)
    143     if (id == OptionID::maxSingleAllocationSize)
     143    if (id == maxSingleAllocationSizeID)
    144144        return true;
    145145#endif
    146146#if OS(DARWIN)
    147     if (id == OptionID::useSigillCrashAnalyzer)
     147    if (id == useSigillCrashAnalyzerID)
    148148        return true;
    149149#endif
    150150#if ENABLE(ASSEMBLER) && OS(LINUX)
    151     if (id == OptionID::logJITCodeForPerf)
    152         return true;
    153 #endif
    154     if (id == OptionID::traceLLIntExecution)
     151    if (id == logJITCodeForPerfID)
     152        return true;
     153#endif
     154    if (id == traceLLIntExecutionID)
    155155        return !!LLINT_TRACING;
    156     if (id == OptionID::traceLLIntSlowPath)
     156    if (id == traceLLIntSlowPathID)
    157157        return !!LLINT_TRACING;
    158158    return false;
     
    160160
    161161template<typename T>
    162 bool overrideOptionWithHeuristic(T& variable, OptionID id, const char* name, Options::Availability availability)
     162bool overrideOptionWithHeuristic(T& variable, Options::ID id, const char* name, Options::Availability availability)
    163163{
    164164    bool available = (availability == Options::Availability::Normal)
     
    283283}
    284284
    285 // FIXME: This is a workaround for MSVC's inability to handle large sources.
    286 // Once the MSVC bug has been fixed, we can remove this snippet of code and
    287 // make its counterpart in Options.h unconditional.
    288 // See https://developercommunity.visualstudio.com/content/problem/653301/fatal-error-c1002-compiler-is-out-of-heap-space-in.html
    289 #if COMPILER(MSVC)
    290 
    291 template<OptionTypeID type, OptionID id>
    292 constexpr size_t optionTypeSpecificIndex()
    293 {
    294     size_t index = 0;
    295     index = 0; // MSVC (16.3.5) improperly optimizes away the inline initialization of index, so use an explicit assignment.
    296 
    297 #define COUNT_INDEX_AND_FIND_MATCH(type_, name_, defaultValue_, availability_, description_) \
    298     if (id == OptionID::name_) \
    299         return index; \
    300     if (type == OptionTypeID::type_) \
    301         index++;
    302 
    303     FOR_EACH_JSC_OPTION(COUNT_INDEX_AND_FIND_MATCH);
    304 #undef COUNT_INDEX_AND_FIND_MATCH
    305     return InvalidOptionIndex;
    306 }
    307 
    308 #define DEFINE_OPTION_ACCESSORS(type_, name_, defaultValue_, availability_, description_) \
    309     JS_EXPORT_PRIVATE OptionTypes::type_& Options::name_() \
    310     { \
    311         return g_jscConfig.type##type_##Options[optionTypeSpecificIndex<OptionTypeID::type_, OptionID::name_>()]; \
    312     }  \
    313     JS_EXPORT_PRIVATE OptionTypes::type_& Options::name_##Default() \
    314     { \
    315         return g_jscConfig.type##type_##DefaultOptions[optionTypeSpecificIndex<OptionTypeID::type_, OptionID::name_>()]; \
    316     }
    317     FOR_EACH_JSC_OPTION(DEFINE_OPTION_ACCESSORS)
    318 #undef DEFINE_OPTION_ACCESSORS
    319 
    320 #endif // COMPILER(MSVC)
    321 
    322285// Realize the names for each of the options:
    323 const Options::EntryInfo Options::s_optionsInfo[NumberOfOptions] = {
     286const Options::EntryInfo Options::s_optionsInfo[Options::numberOfOptions] = {
    324287#define FILL_OPTION_INFO(type_, name_, defaultValue_, availability_, description_) \
    325     { #name_, description_, OptionTypeID::type_, Availability::availability_, optionTypeSpecificIndex<OptionTypeID::type_, OptionID::name_>() },
     288    { #name_, description_, Options::Type::type_, Availability::availability_ },
    326289    FOR_EACH_JSC_OPTION(FILL_OPTION_INFO)
    327290#undef FILL_OPTION_INFO
     
    337300
    338301    struct OptionToScale {
    339         size_t index;
     302        Options::ID id;
    340303        int32_t minVal;
    341304    };
    342305
    343306    static const OptionToScale optionsToScale[] = {
    344         { optionTypeSpecificIndex<OptionTypeID::Int32, OptionID::thresholdForJITAfterWarmUp>(), 0 },
    345         { optionTypeSpecificIndex<OptionTypeID::Int32, OptionID::thresholdForJITSoon>(), 0 },
    346         { optionTypeSpecificIndex<OptionTypeID::Int32, OptionID::thresholdForOptimizeAfterWarmUp>(), 1 },
    347         { optionTypeSpecificIndex<OptionTypeID::Int32, OptionID::thresholdForOptimizeAfterLongWarmUp>(), 1 },
    348         { optionTypeSpecificIndex<OptionTypeID::Int32, OptionID::thresholdForOptimizeSoon>(), 1 },
    349         { optionTypeSpecificIndex<OptionTypeID::Int32, OptionID::thresholdForFTLOptimizeSoon>(), 2 },
    350         { optionTypeSpecificIndex<OptionTypeID::Int32, OptionID::thresholdForFTLOptimizeAfterWarmUp>(), 2 },
     307        { Options::thresholdForJITAfterWarmUpID, 0 },
     308        { Options::thresholdForJITSoonID, 0 },
     309        { Options::thresholdForOptimizeAfterWarmUpID, 1 },
     310        { Options::thresholdForOptimizeAfterLongWarmUpID, 1 },
     311        { Options::thresholdForOptimizeSoonID, 1 },
     312        { Options::thresholdForFTLOptimizeSoonID, 2 },
     313        { Options::thresholdForFTLOptimizeAfterWarmUpID, 2 }
    351314    };
    352315
    353     constexpr int numberOfOptionsToScale = sizeof(optionsToScale) / sizeof(OptionToScale);
     316    const int numberOfOptionsToScale = sizeof(optionsToScale) / sizeof(OptionToScale);
    354317    for (int i = 0; i < numberOfOptionsToScale; i++) {
    355         int32_t& optionValue = g_jscConfig.typeInt32Options[optionsToScale[i].index];
    356         optionValue *= scaleFactor;
    357         optionValue = std::max(optionValue, optionsToScale[i].minVal);
     318        Option option(optionsToScale[i].id);
     319        ASSERT(option.type() == Options::Type::Int32);
     320        option.int32Val() *= scaleFactor;
     321        option.int32Val() = std::max(option.int32Val(), optionsToScale[i].minVal);
    358322    }
    359323}
     
    478442        Options::collectContinuously() = false;
    479443
    480     if (Option(OptionID::jitPolicyScale).isOverridden())
     444    if (Option(Options::jitPolicyScaleID).isOverridden())
    481445        scaleJITPolicy();
    482446   
     
    559523#endif
    560524            // Initialize each of the options with their default values:
    561 #define INIT_OPTION(type_, name_, defaultValue_, availability_, description_) { \
    562                 auto value = defaultValue_; \
    563                 name_() = value; \
    564                 name_##Default() = value; \
    565             }
     525#define INIT_OPTION(type_, name_, defaultValue_, availability_, description_) \
     526            name_() = defaultValue_; \
     527            name_##Default() = defaultValue_;
    566528            FOR_EACH_JSC_OPTION(INIT_OPTION)
    567529#undef INIT_OPTION
     
    587549#else // PLATFORM(COCOA)
    588550#define OVERRIDE_OPTION_WITH_HEURISTICS(type_, name_, defaultValue_, availability_, description_) \
    589             overrideOptionWithHeuristic(name_(), OptionID::name_, "JSC_" #name_, Availability::availability_);
     551            overrideOptionWithHeuristic(name_(), name_##ID, "JSC_" #name_, Availability::availability_);
    590552            FOR_EACH_JSC_OPTION(OVERRIDE_OPTION_WITH_HEURISTICS)
    591553#undef OVERRIDE_OPTION_WITH_HEURISTICS
     
    766728    const char* valueStr = equalStr + 1;
    767729
    768     // For each option, check if the specified arg is a match. If so, set the arg
     730    // For each option, check if the specify arg is a match. If so, set the arg
    769731    // if the value makes sense. Otherwise, move on to checking the next option.
    770732#define SET_OPTION_IF_MATCH(type_, name_, defaultValue_, availability_, description_) \
    771733    if (strlen(#name_) == static_cast<size_t>(equalStr - arg)      \
    772734        && !strncmp(arg, #name_, equalStr - arg)) {                \
    773         if (Availability::availability_ != Availability::Normal    \
    774             && !isAvailable(OptionID::name_, Availability::availability_)) \
     735        if (Availability::availability_ != Availability::Normal     \
     736            && !isAvailable(name_##ID, Availability::availability_)) \
    775737            return false;                                          \
    776         OptionTypes::type_ value;                                  \
     738        OptionEntry::type_ value;                                  \
     739        value = (defaultValue_);                                   \
    777740        bool success = parse(valueStr, value);                     \
    778741        if (success) {                                             \
     
    854817    }
    855818
    856     for (size_t id = 0; id < NumberOfOptions; id++) {
     819    for (int id = 0; id < numberOfOptions; id++) {
    857820        if (separator && id)
    858821            builder.append(separator);
    859         dumpOption(builder, level, static_cast<OptionID>(id), optionHeader, optionFooter, dumpDefaultsOption);
     822        dumpOption(builder, level, static_cast<ID>(id), optionHeader, optionFooter, dumpDefaultsOption);
    860823    }
    861824}
     
    873836}
    874837
    875 void Options::dumpOption(StringBuilder& builder, DumpLevel level, OptionID id,
     838void Options::dumpOption(StringBuilder& builder, DumpLevel level, Options::ID id,
    876839    const char* header, const char* footer, DumpDefaultsOption dumpDefaultsOption)
    877840{
    878     if (static_cast<size_t>(id) >= NumberOfOptions)
     841    if (id >= numberOfOptions)
    879842        return; // Illegal option.
    880843
     
    918881}
    919882
    920 Option::Option(OptionID id)
    921     : m_id(id)
    922 {
    923     unsigned index = static_cast<unsigned>(m_id);
    924     unsigned typeSpecificIndex = Options::s_optionsInfo[index].typeSpecificIndex;
    925     OptionTypeID type = Options::s_optionsInfo[index].type;
    926 
    927     switch (type) {
    928 
    929 #define HANDLE_CASE(OptionType_, type_) \
    930     case OptionTypeID::OptionType_: \
    931         ASSERT(typeSpecificIndex < NumberOf##OptionType_##Options); \
    932         m_val##OptionType_ = g_jscConfig.type##OptionType_##Options[typeSpecificIndex]; \
     883void Option::dump(StringBuilder& builder) const
     884{
     885    switch (type()) {
     886    case Options::Type::Bool:
     887        builder.append(m_entry.valBool ? "true" : "false");
    933888        break;
    934 
    935     FOR_EACH_JSC_OPTION_TYPE(HANDLE_CASE)
    936 #undef HANDLE_CASE
    937     }
    938 }
    939 
    940 const Option Option::defaultOption() const
    941 {
    942     Option result;
    943     unsigned index = static_cast<unsigned>(m_id);
    944     unsigned typeSpecificIndex = Options::s_optionsInfo[index].typeSpecificIndex;
    945     OptionTypeID type = Options::s_optionsInfo[index].type;
    946 
    947     result.m_id = m_id;
    948     switch (type) {
    949 
    950 #define HANDLE_CASE(OptionType_, type_) \
    951     case OptionTypeID::OptionType_: \
    952         ASSERT(typeSpecificIndex < NumberOf##OptionType_##Options); \
    953         result.m_val##OptionType_ = g_jscConfig.type##OptionType_##DefaultOptions[typeSpecificIndex]; \
     889    case Options::Type::Unsigned:
     890        builder.appendNumber(m_entry.valUnsigned);
    954891        break;
    955 
    956     FOR_EACH_JSC_OPTION_TYPE(HANDLE_CASE)
    957 #undef HANDLE_CASE
    958     }
    959     return result;
    960 }
    961 
    962 void Option::dump(StringBuilder& builder) const
    963 {
    964     switch (type()) {
    965     case OptionTypeID::Bool:
    966         builder.append(m_valBool ? "true" : "false");
     892    case Options::Type::Size:
     893        builder.appendNumber(m_entry.valSize);
    967894        break;
    968     case OptionTypeID::Unsigned:
    969         builder.appendNumber(m_valUnsigned);
     895    case Options::Type::Double:
     896        builder.appendFixedPrecisionNumber(m_entry.valDouble);
    970897        break;
    971     case OptionTypeID::Size:
    972         builder.appendNumber(m_valSize);
     898    case Options::Type::Int32:
     899        builder.appendNumber(m_entry.valInt32);
    973900        break;
    974     case OptionTypeID::Double:
    975         builder.appendFixedPrecisionNumber(m_valDouble);
     901    case Options::Type::OptionRange:
     902        builder.append(m_entry.valOptionRange.rangeString());
    976903        break;
    977     case OptionTypeID::Int32:
    978         builder.appendNumber(m_valInt32);
    979         break;
    980     case OptionTypeID::OptionRange:
    981         builder.append(m_valOptionRange.rangeString());
    982         break;
    983     case OptionTypeID::OptionString: {
    984         const char* option = m_valOptionString;
     904    case Options::Type::OptionString: {
     905        const char* option = m_entry.valOptionString;
    985906        if (!option)
    986907            option = "";
     
    990911        break;
    991912    }
    992     case OptionTypeID::GCLogLevel: {
    993         builder.append(GCLogging::levelAsString(m_valGCLogLevel));
     913    case Options::Type::GCLogLevel: {
     914        builder.append(GCLogging::levelAsString(m_entry.valGCLogLevel));
    994915        break;
    995916    }
     
    1000921{
    1001922    switch (type()) {
    1002     case OptionTypeID::Bool:
    1003         return m_valBool == other.m_valBool;
    1004     case OptionTypeID::Unsigned:
    1005         return m_valUnsigned == other.m_valUnsigned;
    1006     case OptionTypeID::Size:
    1007         return m_valSize == other.m_valSize;
    1008     case OptionTypeID::Double:
    1009         return (m_valDouble == other.m_valDouble) || (std::isnan(m_valDouble) && std::isnan(other.m_valDouble));
    1010     case OptionTypeID::Int32:
    1011         return m_valInt32 == other.m_valInt32;
    1012     case OptionTypeID::OptionRange:
    1013         return m_valOptionRange.rangeString() == other.m_valOptionRange.rangeString();
    1014     case OptionTypeID::OptionString:
    1015         return (m_valOptionString == other.m_valOptionString)
    1016             || (m_valOptionString && other.m_valOptionString && !strcmp(m_valOptionString, other.m_valOptionString));
    1017     case OptionTypeID::GCLogLevel:
    1018         return m_valGCLogLevel == other.m_valGCLogLevel;
     923    case Options::Type::Bool:
     924        return m_entry.valBool == other.m_entry.valBool;
     925    case Options::Type::Unsigned:
     926        return m_entry.valUnsigned == other.m_entry.valUnsigned;
     927    case Options::Type::Size:
     928        return m_entry.valSize == other.m_entry.valSize;
     929    case Options::Type::Double:
     930        return (m_entry.valDouble == other.m_entry.valDouble) || (std::isnan(m_entry.valDouble) && std::isnan(other.m_entry.valDouble));
     931    case Options::Type::Int32:
     932        return m_entry.valInt32 == other.m_entry.valInt32;
     933    case Options::Type::OptionRange:
     934        return m_entry.valOptionRange.rangeString() == other.m_entry.valOptionRange.rangeString();
     935    case Options::Type::OptionString:
     936        return (m_entry.valOptionString == other.m_entry.valOptionString)
     937            || (m_entry.valOptionString && other.m_entry.valOptionString && !strcmp(m_entry.valOptionString, other.m_entry.valOptionString));
     938    case Options::Type::GCLogLevel:
     939        return m_entry.valGCLogLevel == other.m_entry.valGCLogLevel;
    1019940    }
    1020941    return false;
  • trunk/Source/JavaScriptCore/runtime/Options.h

    r251226 r251400  
    3030#include <stdint.h>
    3131#include <stdio.h>
     32#include <wtf/PrintStream.h>
    3233#include <wtf/StdLibExtras.h>
    3334
     
    5354class Options {
    5455public:
    55     enum class DumpLevel : uint8_t {
     56    enum class DumpLevel {
    5657        None = 0,
    5758        Overridden,
     
    6061    };
    6162
    62     enum class Availability : uint8_t {
     63    enum class Availability {
    6364        Normal = 0,
    6465        Restricted,
     
    6667    };
    6768
     69#define DECLARE_OPTION_ID(type_, name_, defaultValue_, availability_, description_) \
     70    name_##ID,
     71
     72    enum ID {
     73        FOR_EACH_JSC_OPTION(DECLARE_OPTION_ID)
     74        numberOfOptions
     75    };
     76#undef DECLARE_OPTION_ID
     77
     78    enum class Type {
     79        Bool,
     80        Unsigned,
     81        Double,
     82        Int32,
     83        Size,
     84        OptionRange,
     85        OptionString,
     86        GCLogLevel,
     87    };
     88
    6889    JS_EXPORT_PRIVATE static void initialize();
    6990
     
    81102    JS_EXPORT_PRIVATE static void ensureOptionsAreCoherent();
    82103
    83 // FIXME: This is a workaround for MSVC's inability to handle large sources.
    84 // See https://developercommunity.visualstudio.com/content/problem/653301/fatal-error-c1002-compiler-is-out-of-heap-space-in.html
    85 #if COMPILER(MSVC)
    86 #define OPTION_ACCESSOR_LINKAGE JS_EXPORT_PRIVATE
    87 #else
    88 #define OPTION_ACCESSOR_LINKAGE ALWAYS_INLINE
    89 #endif
    90 
    91104#define DECLARE_OPTION_ACCESSORS(type_, name_, defaultValue_, availability_, description_) \
    92     OPTION_ACCESSOR_LINKAGE static OptionTypes::type_& name_(); \
    93     OPTION_ACCESSOR_LINKAGE static OptionTypes::type_& name_##Default();
     105    ALWAYS_INLINE static OptionEntry::type_& name_() { return g_jscConfig.options[name_##ID].val##type_; }  \
     106    ALWAYS_INLINE static OptionEntry::type_& name_##Default() { return g_jscConfig.defaultOptions[name_##ID].val##type_; }
     107
    94108    FOR_EACH_JSC_OPTION(DECLARE_OPTION_ACCESSORS)
    95109#undef DECLARE_OPTION_ACCESSORS
    96110
    97     static bool isAvailable(OptionID, Availability);
     111    static bool isAvailable(ID, Availability);
    98112
    99113private:
     
    103117        const char* name;
    104118        const char* description;
    105         OptionTypeID type;
     119        Type type;
    106120        Availability availability;
    107         unsigned typeSpecificIndex;
    108121    };
    109122
     
    117130    static void dumpAllOptions(StringBuilder&, DumpLevel, const char* title,
    118131        const char* separator, const char* optionHeader, const char* optionFooter, DumpDefaultsOption);
    119     static void dumpOption(StringBuilder&, DumpLevel, OptionID,
     132    static void dumpOption(StringBuilder&, DumpLevel, ID,
    120133        const char* optionHeader, const char* optionFooter, DumpDefaultsOption);
    121134
     
    124137    static bool overrideAliasedOptionWithHeuristic(const char* name);
    125138
    126     static const EntryInfo s_optionsInfo[NumberOfOptions];
     139    static const EntryInfo s_optionsInfo[numberOfOptions];
    127140
    128141    friend class Option;
     
    131144class Option {
    132145public:
    133     Option(OptionID);
    134 
     146    Option(Options::ID id)
     147        : m_id(id)
     148        , m_entry(g_jscConfig.options[m_id])
     149    {
     150    }
     151   
    135152    void dump(StringBuilder&) const;
    136153
     
    138155    bool operator!=(const Option& other) const { return !(*this == other); }
    139156   
    140     OptionID id() const { return m_id; }
    141     const char* name() const { return Options::s_optionsInfo[idIndex()].name; }
    142     const char* description() const { return Options::s_optionsInfo[idIndex()].description; }
    143     OptionTypeID type() const { return Options::s_optionsInfo[idIndex()].type; }
    144     Options::Availability availability() const { return Options::s_optionsInfo[idIndex()].availability; }
    145     bool isOverridden() const { return *this != defaultOption(); }
     157    Options::ID id() const { return m_id; }
     158    const char* name() const;
     159    const char* description() const;
     160    Options::Type type() const;
     161    Options::Availability availability() const;
     162    bool isOverridden() const;
    146163    const Option defaultOption() const;
    147 
    148 #define DECLARE_ACCESSOR(OptionType_, type_) \
    149     type_ val##OptionType_() const { return m_val##OptionType_; }
    150     FOR_EACH_JSC_OPTION_TYPE(DECLARE_ACCESSOR)
    151 #undef DECLARE_ACCESSOR
    152 
     164   
     165    bool& boolVal();
     166    unsigned& unsignedVal();
     167    double& doubleVal();
     168    int32_t& int32Val();
     169    OptionRange optionRangeVal();
     170    const char* optionStringVal();
     171    GCLogging::Level& gcLogLevelVal();
     172   
    153173private:
    154     Option() { }
    155 
    156     size_t idIndex() const { return static_cast<size_t>(m_id); }
    157 
    158     OptionID m_id;
    159     union {
    160 
    161 #define DECLARE_MEMBER(OptionType_, type_) \
    162         type_ m_val##OptionType_;
    163     FOR_EACH_JSC_OPTION_TYPE(DECLARE_MEMBER)
    164 #undef DECLARE_MEMBER
    165 
    166     };
     174    // Only used for constructing default Options.
     175    Option(Options::ID id, OptionEntry& entry)
     176        : m_id(id)
     177        , m_entry(entry)
     178    {
     179    }
     180   
     181    Options::ID m_id;
     182    OptionEntry& m_entry;
    167183};
    168184
    169 // FIXME: This is a workaround for MSVC's inability to handle large sources.
    170 // Once the MSVC bug has been fixed, we can make the following unconditional and
    171 // remove its counterpart MSVC version in Options.cpp.
    172 // See https://developercommunity.visualstudio.com/content/problem/653301/fatal-error-c1002-compiler-is-out-of-heap-space-in.html
    173 #if !COMPILER(MSVC)
    174 
    175 template<OptionTypeID type, OptionID id>
    176 constexpr size_t optionTypeSpecificIndex()
    177 {
    178     size_t index = 0;
    179 #define COUNT_INDEX_AND_FIND_MATCH(type_, name_, defaultValue_, availability_, description_) \
    180     if (id == OptionID::name_) \
    181         return index; \
    182     if (type == OptionTypeID::type_) \
    183         index++;
    184 
    185     FOR_EACH_JSC_OPTION(COUNT_INDEX_AND_FIND_MATCH);
    186 #undef COUNT_INDEX_AND_FIND_MATCH
    187     return InvalidOptionIndex;
    188 }
    189 
    190 #define DEFINE_OPTION_ACCESSORS(type_, name_, defaultValue_, availability_, description_) \
    191     ALWAYS_INLINE OptionTypes::type_& Options::name_() \
    192     { \
    193         return g_jscConfig.type##type_##Options[optionTypeSpecificIndex<OptionTypeID::type_, OptionID::name_>()]; \
    194     }  \
    195     ALWAYS_INLINE OptionTypes::type_& Options::name_##Default() \
    196     { \
    197         return g_jscConfig.type##type_##DefaultOptions[optionTypeSpecificIndex<OptionTypeID::type_, OptionID::name_>()]; \
    198     }
    199     FOR_EACH_JSC_OPTION(DEFINE_OPTION_ACCESSORS)
    200 #undef DEFINE_OPTION_ACCESSORS
    201 
    202 #endif // !COMPILER(MSVC)
     185inline const char* Option::name() const
     186{
     187    return Options::s_optionsInfo[m_id].name;
     188}
     189
     190inline const char* Option::description() const
     191{
     192    return Options::s_optionsInfo[m_id].description;
     193}
     194
     195inline Options::Type Option::type() const
     196{
     197    return Options::s_optionsInfo[m_id].type;
     198}
     199
     200inline Options::Availability Option::availability() const
     201{
     202    return Options::s_optionsInfo[m_id].availability;
     203}
     204
     205inline bool Option::isOverridden() const
     206{
     207    return *this != defaultOption();
     208}
     209
     210inline const Option Option::defaultOption() const
     211{
     212    return Option(m_id, g_jscConfig.defaultOptions[m_id]);
     213}
     214
     215inline bool& Option::boolVal()
     216{
     217    return m_entry.valBool;
     218}
     219
     220inline unsigned& Option::unsignedVal()
     221{
     222    return m_entry.valUnsigned;
     223}
     224
     225inline double& Option::doubleVal()
     226{
     227    return m_entry.valDouble;
     228}
     229
     230inline int32_t& Option::int32Val()
     231{
     232    return m_entry.valInt32;
     233}
     234
     235inline OptionRange Option::optionRangeVal()
     236{
     237    return m_entry.valOptionRange;
     238}
     239
     240inline const char* Option::optionStringVal()
     241{
     242    return m_entry.valOptionString;
     243}
     244
     245inline GCLogging::Level& Option::gcLogLevelVal()
     246{
     247    return m_entry.valGCLogLevel;
     248}
    203249
    204250} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/OptionsList.h

    r251226 r251400  
    2626#pragma once
    2727
    28 #include "GCLogging.h"
    29 #include <wtf/PrintStream.h>
    30 
    3128namespace JSC {
    3229
     
    3532// The FOR_EACH_JSC_OPTION() macro below defines a list of all JSC options in use,
    3633// along with their types and default values. The options values are actually
    37 // realized as arrays of each of the OptionTypes in JSC::Config.
     34// realized as an array of OptionEntry elements in JSC::Config.
    3835//
    39 //     Options::initialize() will initialize the arrays of options values with
     36//     Options::initialize() will initialize the array of options values with
    4037// the defaults specified in FOR_EACH_JSC_OPTION() below. After that, the values can
    4138// be programmatically read and written to using an accessor method with the
     
    5855// values after the sanity checks (for your own testing), then you're liable to
    5956// ensure that the new values set are sane and reasonable for your own run.
    60 //
    61 // Any modifications to options must be done before the first VM is instantiate.
    62 // On instantiation of the first VM instance, the Options will be write protected
    63 // and cannot be modified thereafter.
    64 
    65 class OptionRange {
    66 private:
    67     enum RangeState { Uninitialized, InitError, Normal, Inverted };
    68 public:
    69     OptionRange& operator= (const int& rhs)
    70     { // Only needed for initialization
    71         if (!rhs) {
    72             m_state = Uninitialized;
    73             m_rangeString = 0;
    74             m_lowLimit = 0;
    75             m_highLimit = 0;
    76         }
    77         return *this;
    78     }
    79 
    80     bool init(const char*);
    81     bool isInRange(unsigned);
    82     const char* rangeString() const { return (m_state > InitError) ? m_rangeString : s_nullRangeStr; }
    83    
    84     void dump(PrintStream& out) const;
    85 
    86 private:
    87     static const char* const s_nullRangeStr;
    88 
    89     RangeState m_state;
    90     const char* m_rangeString;
    91     unsigned m_lowLimit;
    92     unsigned m_highLimit;
    93 };
    94 
    95 #define FOR_EACH_JSC_OPTION_TYPE(v) \
    96     v(Bool, bool) \
    97     v(Unsigned, unsigned) \
    98     v(Double, double) \
    99     v(Int32, int32_t) \
    100     v(Size, size_t) \
    101     v(OptionRange, OptionRange) \
    102     v(OptionString, const char*) \
    103     v(GCLogLevel, GCLogging::Level) \
    104 
    105 namespace OptionTypes {
    106 
    107 #define DECLARE_TYPES(OptionType_, type_) \
    108     using OptionType_ = type_;
    109     FOR_EACH_JSC_OPTION_TYPE(DECLARE_TYPES)
    110 #undef DECLARE_TYPES
    111 
    112 } // namespace OptionTypes
    113 
    114 enum class OptionTypeID : uint8_t {
    115 
    116 #define DECLARE_TYPEID(OptionType_, type_) \
    117     OptionType_,
    118     FOR_EACH_JSC_OPTION_TYPE(DECLARE_TYPEID)
    119 #undef DECLARE_TYPEID
    120 
    121 };
    12257
    12358#define FOR_EACH_JSC_OPTION(v)                                          \
     
    576511    v(maximumInliningCallerSize, maximumInliningCallerBytecodeCost, SameOption) \
    577512
    578 #define DECLARE_OPTION_ID(type_, name_, defaultValue_, availability_, description_) \
    579     name_,
    580 enum class OptionID : uint16_t {
    581     FOR_EACH_JSC_OPTION(DECLARE_OPTION_ID)
    582 };
    583 #undef DECLARE_OPTION_ID
    584 
    585 static constexpr size_t InvalidOptionIndex = std::numeric_limits<size_t>::max();
    586513
    587514constexpr size_t countNumberOfJSCOptions()
     
    596523constexpr size_t NumberOfOptions = countNumberOfJSCOptions();
    597524
    598 constexpr size_t countNumberOfJSCOptionsOfType(OptionTypeID type)
    599 {
    600     size_t count = 0;
    601 #define COUNT_OPTION(type_, name_, defaultValue_, availability_, description_) \
    602     if (type == OptionTypeID::type_) \
    603         count++;
    604     FOR_EACH_JSC_OPTION(COUNT_OPTION);
    605 #undef COUNT_OPTION
    606     return count;
    607 }
    608 
    609 constexpr size_t NumberOfBoolOptions = countNumberOfJSCOptionsOfType(OptionTypeID::Bool);
    610 constexpr size_t NumberOfUnsignedOptions = countNumberOfJSCOptionsOfType(OptionTypeID::Unsigned);
    611 constexpr size_t NumberOfDoubleOptions = countNumberOfJSCOptionsOfType(OptionTypeID::Double);
    612 constexpr size_t NumberOfInt32Options = countNumberOfJSCOptionsOfType(OptionTypeID::Int32);
    613 constexpr size_t NumberOfSizeOptions = countNumberOfJSCOptionsOfType(OptionTypeID::Size);
    614 constexpr size_t NumberOfOptionRangeOptions = countNumberOfJSCOptionsOfType(OptionTypeID::OptionRange);
    615 constexpr size_t NumberOfOptionStringOptions = countNumberOfJSCOptionsOfType(OptionTypeID::OptionString);
    616 constexpr size_t NumberOfGCLogLevelOptions = countNumberOfJSCOptionsOfType(OptionTypeID::GCLogLevel);
    617 
    618525} // namespace JSC
     526
Note: See TracChangeset for help on using the changeset viewer.