<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[194591] trunk/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/194591">194591</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2016-01-05 11:12:05 -0800 (Tue, 05 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add support for aliasing JSC Options.
https://bugs.webkit.org/show_bug.cgi?id=152551

Reviewed by Filip Pizlo.

This allows us to use old options names as well.  This is for the benefit of
third party tools which may have been built to rely on those old options.  The
old option names will be mapped to the current option names in setOption().

For some options, the old option name specifies the inverse boolean value of the
current option name.  setOption() will take care of inverting the value before
applying it to the option.

* jsc.cpp:
(CommandLine::parseArguments):
- Switch to dumping only overridden options here.  Verbose dumping is too much
  for common usage.
* runtime/Options.cpp:
(JSC::overrideOptionWithHeuristic):
(JSC::Options::overrideAliasedOptionWithHeuristic):
(JSC::computeNumberOfWorkerThreads):
(JSC::Options::initialize):
(JSC::Options::setOptionWithoutAlias):
(JSC::invertBoolOptionValue):
(JSC::Options::setAliasedOption):
(JSC::Options::setOption):
(JSC::Options::dumpAllOptions):
- String.ascii() converts newline characters to '?', and this was messing up the
  printing of the options.  Switched to using String.utf8() instead.
(JSC::Options::dumpOption):
* runtime/Options.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionscpp">trunk/Source/JavaScriptCore/runtime/Options.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (194590 => 194591)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-01-05 19:03:07 UTC (rev 194590)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-01-05 19:12:05 UTC (rev 194591)
</span><span class="lines">@@ -1,5 +1,39 @@
</span><del>-2015-12-24  Mark Lam  &lt;mark.lam@apple.com&gt;
</del><ins>+2016-01-05  Mark Lam  &lt;mark.lam@apple.com&gt;
</ins><span class="cx"> 
</span><ins>+        Add support for aliasing JSC Options.
+        https://bugs.webkit.org/show_bug.cgi?id=152551
+
+        Reviewed by Filip Pizlo.
+
+        This allows us to use old options names as well.  This is for the benefit of
+        third party tools which may have been built to rely on those old options.  The
+        old option names will be mapped to the current option names in setOption().
+
+        For some options, the old option name specifies the inverse boolean value of the
+        current option name.  setOption() will take care of inverting the value before
+        applying it to the option.
+
+        * jsc.cpp:
+        (CommandLine::parseArguments):
+        - Switch to dumping only overridden options here.  Verbose dumping is too much
+          for common usage.
+        * runtime/Options.cpp:
+        (JSC::overrideOptionWithHeuristic):
+        (JSC::Options::overrideAliasedOptionWithHeuristic):
+        (JSC::computeNumberOfWorkerThreads):
+        (JSC::Options::initialize):
+        (JSC::Options::setOptionWithoutAlias):
+        (JSC::invertBoolOptionValue):
+        (JSC::Options::setAliasedOption):
+        (JSC::Options::setOption):
+        (JSC::Options::dumpAllOptions):
+        - String.ascii() converts newline characters to '?', and this was messing up the
+          printing of the options.  Switched to using String.utf8() instead.
+        (JSC::Options::dumpOption):
+        * runtime/Options.h:
+
+2016-01-05  Mark Lam  &lt;mark.lam@apple.com&gt;
+
</ins><span class="cx">         Add validation of JSC options to catch typos.
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=152549
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (194590 => 194591)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2016-01-05 19:03:07 UTC (rev 194590)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2016-01-05 19:12:05 UTC (rev 194591)
</span><span class="lines">@@ -1984,7 +1984,7 @@
</span><span class="cx">         m_arguments.append(argv[i]);
</span><span class="cx"> 
</span><span class="cx">     if (needToDumpOptions)
</span><del>-        JSC::Options::dumpAllOptions(stderr, JSC::Options::DumpLevel::Verbose, &quot;All JSC runtime options:&quot;);
</del><ins>+        JSC::Options::dumpAllOptions(stderr, JSC::Options::DumpLevel::Overridden, &quot;All JSC runtime options:&quot;);
</ins><span class="cx">     JSC::Options::ensureOptionsAreCoherent();
</span><span class="cx">     if (needToExit)
</span><span class="cx">         jscExit(EXIT_SUCCESS);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.cpp (194590 => 194591)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.cpp        2016-01-05 19:03:07 UTC (rev 194590)
+++ trunk/Source/JavaScriptCore/runtime/Options.cpp        2016-01-05 19:12:05 UTC (rev 194591)
</span><span class="lines">@@ -127,6 +127,21 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool Options::overrideAliasedOptionWithHeuristic(const char* name)
+{
+    const char* stringValue = getenv(name);
+    if (!stringValue)
+        return false;
+
+    String aliasedOption;
+    aliasedOption = String(&amp;name[4]) + &quot;=&quot; + stringValue;
+    if (Options::setOption(aliasedOption.utf8().data()))
+        return true;
+
+    fprintf(stderr, &quot;WARNING: failed to parse %s=%s\n&quot;, name, stringValue);
+    return false;
+}
+
</ins><span class="cx"> static unsigned computeNumberOfWorkerThreads(int maxNumberOfWorkerThreads, int minimum = 1)
</span><span class="cx"> {
</span><span class="cx">     int cpusToUse = std::min(WTF::numberOfProcessorCores(), maxNumberOfWorkerThreads);
</span><span class="lines">@@ -385,6 +400,11 @@
</span><span class="cx"> #undef FOR_EACH_OPTION
</span><span class="cx"> #endif // PLATFORM(COCOA)
</span><span class="cx"> 
</span><ins>+#define FOR_EACH_OPTION(aliasedName_, unaliasedName_, equivalence_) \
+            overrideAliasedOptionWithHeuristic(&quot;JSC_&quot; #aliasedName_);
+            JSC_ALIASED_OPTIONS(FOR_EACH_OPTION)
+#undef FOR_EACH_OPTION
+
</ins><span class="cx"> #if 0
</span><span class="cx">                 ; // Deconfuse editors that do auto indentation
</span><span class="cx"> #endif
</span><span class="lines">@@ -527,7 +547,7 @@
</span><span class="cx"> 
</span><span class="cx"> // Parses a single command line option in the format &quot;&lt;optionName&gt;=&lt;value&gt;&quot;
</span><span class="cx"> // (no spaces allowed) and set the specified option if appropriate.
</span><del>-bool Options::setOption(const char* arg)
</del><ins>+bool Options::setOptionWithoutAlias(const char* arg)
</ins><span class="cx"> {
</span><span class="cx">     // arg should look like this:
</span><span class="cx">     //   &lt;jscOptionName&gt;=&lt;appropriate value&gt;
</span><span class="lines">@@ -559,6 +579,57 @@
</span><span class="cx">     return false; // No option matched.
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static bool invertBoolOptionValue(const char* valueStr, const char*&amp; invertedValueStr)
+{
+    bool boolValue;
+    if (!parse(valueStr, boolValue))
+        return false;
+    invertedValueStr = boolValue ? &quot;false&quot; : &quot;true&quot;;
+    return true;
+}
+
+
+bool Options::setAliasedOption(const char* arg)
+{
+    // arg should look like this:
+    //   &lt;jscOptionName&gt;=&lt;appropriate value&gt;
+    const char* equalStr = strchr(arg, '=');
+    if (!equalStr)
+        return false;
+
+    // For each option, check if the specify arg is a match. If so, set the arg
+    // if the value makes sense. Otherwise, move on to checking the next option.
+#define FOR_EACH_OPTION(aliasedName_, unaliasedName_, equivalence) \
+    if (strlen(#aliasedName_) == static_cast&lt;size_t&gt;(equalStr - arg)    \
+        &amp;&amp; !strncmp(arg, #aliasedName_, equalStr - arg)) {              \
+        String unaliasedOption(#unaliasedName_);                        \
+        if (equivalence == SameOption)                                  \
+            unaliasedOption = unaliasedOption + equalStr;               \
+        else {                                                          \
+            ASSERT(equivalence == InvertedOption);                      \
+            const char* invertedValueStr = nullptr;                     \
+            if (!invertBoolOptionValue(equalStr + 1, invertedValueStr)) \
+                return false;                                           \
+            unaliasedOption = unaliasedOption + &quot;=&quot; + invertedValueStr; \
+        }                                                               \
+        return setOptionWithoutAlias(unaliasedOption.utf8().data());   \
+    }
+
+    JSC_ALIASED_OPTIONS(FOR_EACH_OPTION)
+#undef FOR_EACH_OPTION
+
+    return false; // No option matched.
+}
+
+bool Options::setOption(const char* arg)
+{
+    bool success = setOptionWithoutAlias(arg);
+    if (success)
+        return true;
+    return setAliasedOption(arg);
+}
+
+
</ins><span class="cx"> void Options::dumpAllOptions(StringBuilder&amp; builder, DumpLevel level, const char* title,
</span><span class="cx">     const char* separator, const char* optionHeader, const char* optionFooter, DumpDefaultsOption dumpDefaultsOption)
</span><span class="cx"> {
</span><span class="lines">@@ -583,7 +654,7 @@
</span><span class="cx"> {
</span><span class="cx">     StringBuilder builder;
</span><span class="cx">     dumpAllOptions(builder, level, title, nullptr, &quot;   &quot;, &quot;\n&quot;, DumpDefaults);
</span><del>-    fprintf(stream, &quot;%s&quot;, builder.toString().ascii().data());
</del><ins>+    fprintf(stream, &quot;%s&quot;, builder.toString().utf8().data());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Options::dumpOption(StringBuilder&amp; builder, DumpLevel level, OptionID id,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (194590 => 194591)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2016-01-05 19:03:07 UTC (rev 194590)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2016-01-05 19:12:05 UTC (rev 194591)
</span><span class="lines">@@ -352,6 +352,45 @@
</span><span class="cx">     v(bool, dumpModuleLoadingState, false, nullptr) \
</span><span class="cx">     v(bool, exposeInternalModuleLoader, false, &quot;expose the internal module loader object to the global space for debugging&quot;) \
</span><span class="cx"> 
</span><ins>+enum OptionEquivalence {
+    SameOption,
+    InvertedOption,
+};
+
+#define JSC_ALIASED_OPTIONS(v) \
+    v(enableFunctionDotArguments, useFunctionDotArguments, SameOption) \
+    v(enableTailCalls, useTailCalls, SameOption) \
+    v(showDisassembly, dumpDisassembly, SameOption) \
+    v(showDFGDisassembly, dumpDFGDisassembly, SameOption) \
+    v(showFTLDisassembly, dumpFTLDisassembly, SameOption) \
+    v(showAllDFGNodes, dumpAllDFGNodes, SameOption) \
+    v(alwaysDoFullCollection, useGenerationalGC, InvertedOption) \
+    v(enableOSREntryToDFG, useOSREntryToDFG, SameOption) \
+    v(enableOSREntryToFTL, useOSREntryToFTL, SameOption) \
+    v(enableLLVMFastISel, useLLVMFastISel, SameOption) \
+    v(enableAccessInlining, useAccessInlining, SameOption) \
+    v(enablePolyvariantDevirtualization, usePolyvariantDevirtualization, SameOption) \
+    v(enablePolymorphicAccessInlining, usePolymorphicAccessInlining, SameOption) \
+    v(enablePolymorphicCallInlining, usePolymorphicCallInlining, SameOption) \
+    v(enableMovHintRemoval, useMovHintRemoval, SameOption) \
+    v(enableObjectAllocationSinking, useObjectAllocationSinking, SameOption) \
+    v(enableCopyBarrierOptimization, useCopyBarrierOptimization, SameOption) \
+    v(enableConcurrentJIT, useConcurrentJIT, SameOption) \
+    v(enableProfiler, useProfiler, SameOption) \
+    v(enableArchitectureSpecificOptimizations, useArchitectureSpecificOptimizations, SameOption) \
+    v(enablePolyvariantCallInlining, usePolyvariantCallInlining, SameOption) \
+    v(enablePolyvariantByIdInlining, usePolyvariantByIdInlining, SameOption) \
+    v(enableMaximalFlushInsertionPhase, useMaximalFlushInsertionPhase, SameOption) \
+    v(objectsAreImmortal, useImmortalObjects, SameOption) \
+    v(showObjectStatistics, dumpObjectStatistics, SameOption) \
+    v(disableGC, useGC, InvertedOption) \
+    v(enableTypeProfiler, useTypeProfiler, SameOption) \
+    v(enableControlFlowProfiler, useControlFlowProfiler, SameOption) \
+    v(enableExceptionFuzz, useExceptionFuzz, SameOption) \
+    v(enableExecutableAllocationFuzz, useExecutableAllocationFuzz, SameOption) \
+    v(enableOSRExitFuzz, useOSRExitFuzz, SameOption) \
+    v(enableDollarVM, useDollarVM, SameOption) \
+
</ins><span class="cx"> class Options {
</span><span class="cx"> public:
</span><span class="cx">     enum class DumpLevel {
</span><span class="lines">@@ -438,6 +477,10 @@
</span><span class="cx">     static void dumpOption(StringBuilder&amp;, DumpLevel, OptionID,
</span><span class="cx">         const char* optionHeader, const char* optionFooter, DumpDefaultsOption);
</span><span class="cx"> 
</span><ins>+    static bool setOptionWithoutAlias(const char* arg);
+    static bool setAliasedOption(const char* arg);
+    static bool overrideAliasedOptionWithHeuristic(const char* name);
+
</ins><span class="cx">     // Declare the singleton instance of the options store:
</span><span class="cx">     JS_EXPORTDATA static Entry s_options[numberOfOptions];
</span><span class="cx">     static Entry s_defaultOptions[numberOfOptions];
</span></span></pre>
</div>
</div>

</body>
</html>