WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-72960-20111214141316.patch (text/plain), 17.93 KB, created by
Andy Wingo
on 2011-12-14 05:13:18 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Andy Wingo
Created:
2011-12-14 05:13:18 PST
Size:
17.93 KB
patch
obsolete
>Subversion Revision: 102762 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 150c772144a2093efc68ad2a5125fc834fc84af2..02d489db94f007b334b0afeb44739288855c9a1a 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,29 @@ >+2011-11-29 Andy Wingo <wingo@igalia.com> >+ >+ Allow JSC heuristics to be set on the command-line >+ https://bugs.webkit.org/show_bug.cgi?id=72960 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * jsc.cpp: >+ (printDebugUsageStatement): >+ (printUsageStatement): >+ (parseArguments): Add --help-debug, which prints out heuristics >+ that can be set at runtime. >+ >+ * runtime/Options.cpp: >+ (JSC::Options::parse): >+ (JSC::Options::parseFlag): >+ (JSC::Options::parseCommandLineArg): >+ (JSC::Options::initializeOptions): >+ (JSC::Options::setFromEnvironment): >+ (JSC::Options::setOptionsFromEnvironment): >+ (JSC::Options::initializeOptions): Refactor the parser a bit to >+ share mechanism and use WTFString. >+ * runtime/Options.h: Add an "option-name" to all of the options, >+ currently used when parsing command-line arguments. Add an >+ interface to set options from command-line arguments. >+ > 2011-12-14 Andy Wingo <wingo@igalia.com> > > Ensure consistent heuristics >diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp >index 36d3f7a05a5fe1368b29fd5f8f1d5f9cb259e8d2..3ea48273996ff1850f87bd27ef1f546c2cd40689 100644 >--- a/Source/JavaScriptCore/jsc.cpp >+++ b/Source/JavaScriptCore/jsc.cpp >@@ -532,16 +532,30 @@ static void runInteractive(GlobalObject* globalObject) > printf("\n"); > } > >+static NO_RETURN void printDebugUsageStatement(JSGlobalData* globalData) >+{ >+ fprintf(stderr, "Available debugging options:\n"); >+#define PRINT(type, cname, default_val, optname) \ >+ fprintf(stderr, " --" optname "=" #type "\n"); \ >+ fprintf(stderr, " Default: " #default_val "\n"); >+ FOR_EACH_OPTION(PRINT) >+#undef PRINT >+ >+ cleanupGlobalData(globalData); >+ exit(EXIT_SUCCESS); >+} >+ > static NO_RETURN void printUsageStatement(JSGlobalData* globalData, bool help = false) > { > fprintf(stderr, "Usage: jsc [options] [files] [-- arguments]\n"); >- fprintf(stderr, " -d Dumps bytecode (debug builds only)\n"); >- fprintf(stderr, " -e Evaluate argument as script code\n"); >- fprintf(stderr, " -f Specifies a source file (deprecated)\n"); >- fprintf(stderr, " -h|--help Prints this help message\n"); >- fprintf(stderr, " -i Enables interactive mode (default if no files are specified)\n"); >+ fprintf(stderr, " -d Dumps bytecode (debug builds only)\n"); >+ fprintf(stderr, " -e Evaluate argument as script code\n"); >+ fprintf(stderr, " -f Specifies a source file (deprecated)\n"); >+ fprintf(stderr, " -h|--help Prints this help message\n"); >+ fprintf(stderr, " --help-debug Show additional debugging options\n"); >+ fprintf(stderr, " -i Enables interactive mode (default if no files are specified)\n"); > #if HAVE(SIGNAL_H) >- fprintf(stderr, " -s Installs signal handlers that exit on a crash (Unix platforms only)\n"); >+ fprintf(stderr, " -s Installs signal handlers that exit on a crash (Unix platforms only)\n"); > #endif > > cleanupGlobalData(globalData); >@@ -553,6 +567,24 @@ static void parseArguments(int argc, char** argv, CommandLine& options, JSGlobal > int i = 1; > for (; i < argc; ++i) { > const char* arg = argv[i]; >+ const char* next = (i < argc) ? argv[i+1] : 0; >+ >+ switch (Options::parseCommandLineArg(arg, next)) { >+ case Options::NoMatch: >+ break; >+ case Options::ConsumedOneArgument: >+ continue; >+ case Options::ConsumedTwoArguments: >+ i++; >+ continue; >+ case Options::MissingValue: >+ fprintf(stderr, "ERROR: Missing value for option %s.\n", arg); >+ exit(EXIT_FAILURE); >+ case Options::InvalidValue: >+ fprintf(stderr, "ERROR: Bad value for option %s.\n", arg); >+ exit(EXIT_FAILURE); >+ } >+ > if (!strcmp(arg, "-f")) { > if (++i == argc) > printUsageStatement(globalData); >@@ -588,6 +620,8 @@ static void parseArguments(int argc, char** argv, CommandLine& options, JSGlobal > } > if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) > printUsageStatement(globalData, true); >+ if (!strcmp(arg, "--help-debug")) >+ printDebugUsageStatement(globalData); > options.scripts.append(Script(true, argv[i])); > } > >diff --git a/Source/JavaScriptCore/runtime/Options.cpp b/Source/JavaScriptCore/runtime/Options.cpp >index b8ca1ec15fea3dbf8fac1bad17116284cb10500f..796b635eefcdc486ba5faed8d1fb023cdd6caad0 100644 >--- a/Source/JavaScriptCore/runtime/Options.cpp >+++ b/Source/JavaScriptCore/runtime/Options.cpp >@@ -27,24 +27,33 @@ > #include "Options.h" > > #include <limits> >+#include <wtf/text/WTFString.h> > #include <wtf/PageBlock.h> > > #if OS(DARWIN) && ENABLE(PARALLEL_GC) > #include <sys/sysctl.h> > #endif > >+// There is lots of conditional compilation going on here, and it is too hard to >+// track which static functions will be used or not. Instead, just trust the >+// compiler to not emit code for unused static functions. >+#if COMPILER(GCC) >+#define WTF_UNUSED __attribute((__unused__)) >+#else >+#define WTF_UNUSED >+#endif >+ > // Set to 1 to control the heuristics using environment variables. > #define ENABLE_RUN_TIME_HEURISTICS 0 > > #if ENABLE(RUN_TIME_HEURISTICS) > #include <stdio.h> > #include <stdlib.h> >-#include <wtf/StdLibExtras.h> > #endif > > namespace JSC { namespace Options { > >-#define DEFINE(type, cname, default_val) type cname; >+#define DEFINE(type, cname, default_val, optname) type cname; > FOR_EACH_OPTION(DEFINE) > #undef DEFINE > >@@ -82,48 +91,149 @@ static void ensureConsistency() > ASSERT((static_cast<int64_t>(executionCounterValueForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) >= static_cast<int64_t>(std::numeric_limits<int32_t>::min())); > } > >-#if ENABLE(RUN_TIME_HEURISTICS) >-static bool parse(const char* string, int32_t& value) >+static bool parse(bool& variable, String value) WTF_UNUSED; >+static bool parse(bool& variable, String value) >+{ >+ bool ok = true; >+ if (value == "true" || value == "1") >+ variable = true; >+ else if (value == "false" || value == "0") >+ variable = false; >+ else >+ ok = false; >+ return ok; >+} >+ >+static bool parse(unsigned& variable, String value) >+{ >+ bool ok = true; >+ unsigned t = value.toUInt(&ok); >+ if (ok) >+ variable = t; >+ return ok; >+} >+ >+static bool parse(int32_t& variable, String value) > { >- return sscanf(string, "%d", &value) == 1; >+ bool ok = true; >+ int32_t t = value.toInt(&ok); >+ if (ok) >+ variable = t; >+ return ok; > } > >-static bool parse(const char* string, unsigned& value) >+static bool parse(double& variable, String value) > { >- return sscanf(string, "%u", &value) == 1; >+ bool ok = true; >+ double t = value.toDouble(&ok); >+ if (ok) >+ variable = t; >+ return ok; > } > >-static bool parse(const char* string, double& value) >+static bool parseFlag(bool& variable, String option, const char *enable, const char *disable) WTF_UNUSED; >+static bool parseFlag(bool& variable, String option, const char *enable, const char *disable) >+{ >+ if (option == enable) >+ variable = true; >+ else if (option == disable) >+ variable = false; >+ else >+ return false; >+ return true; >+} >+static bool parseFlag(unsigned& variable, String option, const char *enable, const char *disable) >+{ >+ return false; >+} >+static bool parseFlag(int32_t& variable, String option, const char *enable, const char *disable) >+{ >+ return false; >+} >+static bool parseFlag(double& variable, String option, const char *enable, const char *disable) >+{ >+ return false; >+} >+ >+static const char *argPrefix = "--"; >+ >+OptionParseStatus parseCommandLineArg(const char *c_arg, const char *c_next) > { >- return sscanf(string, "%lf", &value) == 1; >+ String arg(c_arg); >+ >+ if (!arg.startsWith(argPrefix)) >+ return NoMatch; >+ >+ String option = arg.substring(strlen(argPrefix), arg.length()); >+ String value; >+ OptionParseStatus success, failure; >+ >+#define PARSE_FLAG(type, cname, default_val, optname) \ >+ if (parseFlag(cname, option, optname, "no-" optname)) { \ >+ ensureConsistency(); \ >+ return ConsumedOneArgument; \ >+ } >+ FOR_EACH_OPTION(PARSE_FLAG); >+#undef PARSE_FLAG >+ >+ size_t equalsPosition = option.find('='); >+ if (equalsPosition < option.length()) { >+ success = ConsumedOneArgument; >+ failure = InvalidValue; >+ value = option.substring(equalsPosition + 1, option.length()); >+ option = option.substring(0, equalsPosition); >+ } else if (c_next) { >+ success = ConsumedTwoArguments; >+ failure = InvalidValue; >+ value = c_next; >+ } else { >+ success = ConsumedOneArgument; >+ failure = MissingValue; >+ } >+ >+#define PARSE(type, cname, default_val, optname) \ >+ if (option == optname) { \ >+ if (parse(cname, value)) { \ >+ ensureConsistency(); \ >+ return success; \ >+ } \ >+ return failure; \ >+ } >+ FOR_EACH_OPTION(PARSE); >+#undef PARSE >+ >+ return NoMatch; > } > >-template<typename T, typename U> >-void setHeuristic(T& variable, const char* name, U value) >+template<typename T> >+void setFromEnvironment(T& variable, const char* name) > { >+#if ENABLE(RUN_TIME_HEURISTICS) > const char* stringValue = getenv(name); >- if (!stringValue) { >- variable = safeCast<T>(value); >+ if (!stringValue) > return; >- } >- >- if (parse(stringValue, variable)) >+ if (parse(variable, stringValue)) > return; >- > fprintf(stderr, "WARNING: failed to parse %s=%s\n", name, stringValue); >- variable = safeCast<T>(value); >-} >- >-#define SET(variable, value) setHeuristic(variable, "JSC_" #variable, value) >-#else >-#define SET(variable, value) variable = value > #endif >+} > >+static void setOptionsFromEnvironment() >+{ >+#define SET_FROM_ENV(type, cname, default_val, optname) \ >+ setFromEnvironment(cname, #cname); >+ FOR_EACH_OPTION(SET_FROM_ENV); >+#undef SET_FROM_ENV >+} >+ > void initializeOptions() > { >-#define INIT(type, cname, default_val) SET(cname, default_val); >- FOR_EACH_OPTION(INIT) >-#undef INIT >+#define INIT_DEFAULT(type, cname, default_val, optname) \ >+ cname = default_val; >+ FOR_EACH_OPTION(INIT_DEFAULT) >+#undef INIT_DEFAULT >+ >+ setOptionsFromEnvironment(); > > // Now we initialize heuristics whose defaults are not known at > // compile-time. >diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h >index 6c1fb09909c5365abfd48355b26caf526b1246eb..d5fc3850fed084f0e29ce15c5649db13a08ec17d 100644 >--- a/Source/JavaScriptCore/runtime/Options.h >+++ b/Source/JavaScriptCore/runtime/Options.h >@@ -37,59 +37,105 @@ namespace JSC { namespace Options { > // take slow case, for example for linking or caching. > > #define FOR_EACH_HEURISTIC(m) \ >- m(unsigned, maximumOptimizationCandidateInstructionCount, 1000) \ >+ m(unsigned, maximumOptimizationCandidateInstructionCount, 1000, \ >+ "maximum-optimization-candidate-instruction-count") \ > \ >- m(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 150) \ >- m(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 80) \ >+ m(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 150, \ >+ "maximum-function-for-call-inline-candidate-instruction-count") \ >+ m(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 80, \ >+ "maximum-function-for-construct-inline-candidate-instruction-count") \ > \ >- m(unsigned, maximumInliningDepth, 5) \ >+ m(unsigned, maximumInliningDepth, 5, \ >+ "maximum-inlining-depth") \ > \ >- m(int32_t, executionCounterValueForOptimizeAfterWarmUp, -1000) \ >- m(int32_t, executionCounterValueForOptimizeAfterLongWarmUp, -5000) \ >- m(int32_t, executionCounterValueForDontOptimizeAnytimeSoon, std::numeric_limits<int32_t>::min()) \ >- m(int32_t, executionCounterValueForOptimizeSoon, -1000) \ >- m(int32_t, executionCounterValueForOptimizeNextInvocation, 0) \ >+ m(int32_t, executionCounterValueForOptimizeAfterWarmUp, -1000, \ >+ "execution-counter-value-for-optimize-after-warm-up") \ >+ m(int32_t, executionCounterValueForOptimizeAfterLongWarmUp, -5000, \ >+ "execution-counter-value-for-optimize-after-long-warm-up") \ >+ m(int32_t, executionCounterValueForDontOptimizeAnytimeSoon, std::numeric_limits<int32_t>::min(), \ >+ "execution-counter-value-for-dont-optimize-anytime-soon") \ >+ m(int32_t, executionCounterValueForOptimizeSoon, -1000, \ >+ "execution-counter-value-for-optimize-soon") \ >+ m(int32_t, executionCounterValueForOptimizeNextInvocation, 0, \ >+ "execution-counter-value-for-optimize-next-invocation") \ > \ >- m(int32_t, executionCounterIncrementForLoop, 1) \ >- m(int32_t, executionCounterIncrementForReturn, 15) \ >+ m(int32_t, executionCounterIncrementForLoop, 1, \ >+ "execution-counter-increment-for-loop") \ >+ m(int32_t, executionCounterIncrementForReturn, 15, \ >+ "execution-counter-increment-for-return") \ > \ >- m(unsigned, desiredSpeculativeSuccessFailRatio, 6) \ >+ m(unsigned, desiredSpeculativeSuccessFailRatio, 6, \ >+ "desired-speculative-success-fail-ratio") \ > \ >- m(double, likelyToTakeSlowCaseThreshold, 0.15) \ >- m(double, couldTakeSlowCaseThreshold, 0.05) \ >- m(unsigned, likelyToTakeSlowCaseMinimumCount, 100) \ >- m(unsigned, couldTakeSlowCaseMinimumCount, 10) \ >+ m(double, likelyToTakeSlowCaseThreshold, 0.15, \ >+ "likely-to-take-slow-case-threshold") \ >+ m(double, couldTakeSlowCaseThreshold, 0.05, \ >+ "could-take-slow-case-threshold") \ >+ m(unsigned, likelyToTakeSlowCaseMinimumCount, 100, \ >+ "likely-to-take-slow-case-minimum-count") \ >+ m(unsigned, couldTakeSlowCaseMinimumCount, 10, \ >+ "could-take-slow-case-minimum-count") \ > \ >- m(double, osrExitProminenceForFrequentExitSite, 0.3) \ >+ m(double, osrExitProminenceForFrequentExitSite, 0.3, \ >+ "osr-exit-prominence-for-frequent-exit-site") \ > \ >- m(unsigned, largeFailCountThresholdBase, 20) \ >- m(unsigned, largeFailCountThresholdBaseForLoop, 1) \ >+ m(unsigned, largeFailCountThresholdBase, 20, \ >+ "large-fail-count-threshold-base") \ >+ m(unsigned, largeFailCountThresholdBaseForLoop, 1, \ >+ "large-fail-count-threshold-base-for-loop") \ > \ >- m(unsigned, reoptimizationRetryCounterMax, 30) \ >- m(unsigned, reoptimizationRetryCounterStep, 1) \ >+ m(unsigned, reoptimizationRetryCounterMax, 30, \ >+ "reoptimization-retry-counter-max") \ >+ m(unsigned, reoptimizationRetryCounterStep, 1, \ >+ "reoptimization-retry-counter-step") \ > \ >- m(unsigned, minimumOptimizationDelay, 1) \ >- m(unsigned, maximumOptimizationDelay, 5) \ >- m(double, desiredProfileLivenessRate, 0.75) \ >- m(double, desiredProfileFullnessRate, 0.35) \ >+ m(unsigned, minimumOptimizationDelay, 1, \ >+ "minimum-optimization-delay") \ >+ m(unsigned, maximumOptimizationDelay, 5, \ >+ "maximum-optimization-delay") \ >+ m(double, desiredProfileLivenessRate, 0.75, \ >+ "desired-profile-liveness-rate") \ >+ m(double, desiredProfileFullnessRate, 0.35, \ >+ "desired-profile-fullness-rate") \ > \ >- m(double, doubleVoteRatioForDoubleFormat, 2) \ >+ m(double, doubleVoteRatioForDoubleFormat, 2, \ >+ "double-vote-ratio-for-double-format") \ > \ >- m(unsigned, minimumNumberOfScansBetweenRebalance, 10000) \ >- m(unsigned, gcMarkStackSegmentSize, 0) \ >- m(unsigned, minimumNumberOfCellsToKeep, 10) \ >- m(unsigned, maximumNumberOfSharedSegments, 3) \ >- m(unsigned, sharedStackWakeupThreshold, 1) \ >- m(unsigned, numberOfGCMarkers, 0) \ >- m(unsigned, opaqueRootMergeThreshold, 1000) >+ m(unsigned, minimumNumberOfScansBetweenRebalance, 10000, \ >+ "minimum-number-of-scans-between-rebalance") \ >+ m(unsigned, gcMarkStackSegmentSize, 0, \ >+ "gc-mark-stack-segment-size") \ >+ m(unsigned, minimumNumberOfCellsToKeep, 10, \ >+ "minimum-number-of-cells-to-keep") \ >+ m(unsigned, maximumNumberOfSharedSegments, 3, \ >+ "maximum-number-of-shared-segments") \ >+ m(unsigned, sharedStackWakeupThreshold, 1, \ >+ "shared-stack-wakeup-threshold") \ >+ m(unsigned, numberOfGCMarkers, 0, \ >+ "number-of-gc-markers") \ >+ m(unsigned, opaqueRootMergeThreshold, 1000, \ >+ "opaque-root-merge-threshold") > > #define FOR_EACH_OPTION(m) \ > FOR_EACH_HEURISTIC(m) > >-#define DECLARE(type, cname, default_val) extern type cname; >+#define DECLARE(type, cname, default_val, optname) extern type cname; > FOR_EACH_OPTION(DECLARE) > #undef DECLARE > >+enum OptionParseStatus { >+ NoMatch, >+ ConsumedOneArgument, >+ ConsumedTwoArguments, >+ MissingValue, >+ InvalidValue >+}; >+ >+// Set a JSC run-time option from a command-line argument. Both `--foo bar' and >+// `--foo=bar' forms are supported. >+// >+OptionParseStatus parseCommandLineArg(const char *arg, const char *next); >+ > void initializeOptions(); > > } } // namespace JSC::Options
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 72960
:
116230
|
116231
|
116616
|
116988
| 119206