<!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>[182304] 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/182304">182304</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2015-04-02 20:46:39 -0700 (Thu, 02 Apr 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Enhance ability to dump JSC Options.
&lt;https://webkit.org/b/143357&gt;

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).

2. 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.

3. 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.

4. 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!=):</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 (182303 => 182304)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-04-03 01:16:24 UTC (rev 182303)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-04-03 03:46:39 UTC (rev 182304)
</span><span class="lines">@@ -1,3 +1,57 @@
</span><ins>+2015-04-02  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Enhance ability to dump JSC Options.
+        &lt;https://webkit.org/b/143357&gt;
+
+        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).
+
+        2. 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.
+
+        3. 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.
+
+        4. 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!=):
+
</ins><span class="cx"> 2015-04-02  Geoffrey Garen  &lt;ggaren@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         JavaScriptCore API should support type checking for Array and Date
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (182303 => 182304)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2015-04-03 01:16:24 UTC (rev 182303)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2015-04-03 03:46:39 UTC (rev 182304)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
</span><del>- *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2012, 2013, 2015 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2004-2008, 2012-2013, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2006 Bjoern Graf (bjoern.graf@gmail.com)
</span><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="lines">@@ -1462,7 +1462,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);
</del><ins>+        JSC::Options::dumpAllOptions(JSC::Options::DumpLevel::Verbose, &quot;All JSC runtime options:&quot;, stderr);
</ins><span class="cx">     if (needToExit)
</span><span class="cx">         jscExit(EXIT_SUCCESS);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.cpp (182303 => 182304)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.cpp        2015-04-03 01:16:24 UTC (rev 182303)
+++ trunk/Source/JavaScriptCore/runtime/Options.cpp        2015-04-03 03:46:39 UTC (rev 182304)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2012, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2012, 2014-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -201,11 +201,12 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Options::Entry Options::s_options[Options::numberOfOptions];
</span><ins>+Options::Entry Options::s_defaultOptions[Options::numberOfOptions];
</ins><span class="cx"> 
</span><span class="cx"> // Realize the names for each of the options:
</span><span class="cx"> const Options::EntryInfo Options::s_optionsInfo[Options::numberOfOptions] = {
</span><del>-#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
-    { #name_, Options::type_##Type },
</del><ins>+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
+    { #name_, description_, Options::type_##Type },
</ins><span class="cx">     JSC_OPTIONS(FOR_EACH_OPTION)
</span><span class="cx"> #undef FOR_EACH_OPTION
</span><span class="cx"> };
</span><span class="lines">@@ -270,17 +271,17 @@
</span><span class="cx"> void Options::initialize()
</span><span class="cx"> {
</span><span class="cx">     // Initialize each of the options with their default values:
</span><del>-#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
-    name_() = defaultValue_;
</del><ins>+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
+    name_() = defaultValue_; \
+    name_##Default() = defaultValue_;
</ins><span class="cx">     JSC_OPTIONS(FOR_EACH_OPTION)
</span><span class="cx"> #undef FOR_EACH_OPTION
</span><span class="cx">         
</span><span class="cx">     // Allow environment vars to override options if applicable.
</span><span class="cx">     // The evn var should be the name of the option prefixed with
</span><span class="cx">     // &quot;JSC_&quot;.
</span><del>-#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
-    if (overrideOptionWithHeuristic(name_(), &quot;JSC_&quot; #name_)) \
-        s_options[OPT_##name_].didOverride = true;
</del><ins>+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
+    overrideOptionWithHeuristic(name_(), &quot;JSC_&quot; #name_);
</ins><span class="cx">     JSC_OPTIONS(FOR_EACH_OPTION)
</span><span class="cx"> #undef FOR_EACH_OPTION
</span><span class="cx"> 
</span><span class="lines">@@ -294,6 +295,28 @@
</span><span class="cx">     ASSERT(Options::thresholdForOptimizeAfterLongWarmUp() &gt;= Options::thresholdForOptimizeAfterWarmUp());
</span><span class="cx">     ASSERT(Options::thresholdForOptimizeAfterWarmUp() &gt;= Options::thresholdForOptimizeSoon());
</span><span class="cx">     ASSERT(Options::thresholdForOptimizeAfterWarmUp() &gt;= 0);
</span><ins>+
+    if (Options::showOptions()) {
+        DumpLevel level = static_cast&lt;DumpLevel&gt;(Options::showOptions());
+        if (level &gt; DumpLevel::Verbose)
+            level = DumpLevel::Verbose;
+
+        const char* title = nullptr;
+        switch (level) {
+        case DumpLevel::None:
+            break;
+        case DumpLevel::Overridden:
+            title = &quot;Overridden JSC options:&quot;;
+            break;
+        case DumpLevel::All:
+            title = &quot;All JSC options:&quot;;
+            break;
+        case DumpLevel::Verbose:
+            title = &quot;All JSC options with descriptions:&quot;;
+            break;
+        }
+        dumpAllOptions(level, title);
+    }
</ins><span class="cx"> }
</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="lines">@@ -310,14 +333,13 @@
</span><span class="cx"> 
</span><span class="cx">     // For each option, check if the specify arg is a match. If so, set the arg
</span><span class="cx">     // if the value makes sense. Otherwise, move on to checking the next option.
</span><del>-#define FOR_EACH_OPTION(type_, name_, defaultValue_)    \
</del><ins>+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
</ins><span class="cx">     if (!strncmp(arg, #name_, equalStr - arg)) {        \
</span><span class="cx">         type_ value;                                    \
</span><span class="cx">         value = (defaultValue_);                        \
</span><span class="cx">         bool success = parse(valueStr, value);          \
</span><span class="cx">         if (success) {                                  \
</span><span class="cx">             name_() = value;                            \
</span><del>-            s_options[OPT_##name_].didOverride = true;  \
</del><span class="cx">             recomputeDependentOptions();                \
</span><span class="cx">             return true;                                \
</span><span class="cx">         }                                               \
</span><span class="lines">@@ -330,49 +352,97 @@
</span><span class="cx">     return false; // No option matched.
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Options::dumpAllOptions(FILE* stream)
</del><ins>+void Options::dumpAllOptions(DumpLevel level, const char* title, FILE* stream)
</ins><span class="cx"> {
</span><del>-    fprintf(stream, &quot;JSC runtime options:\n&quot;);
</del><ins>+    if (title)
+        fprintf(stream, &quot;%s\n&quot;, title);
</ins><span class="cx">     for (int id = 0; id &lt; numberOfOptions; id++)
</span><del>-        dumpOption(static_cast&lt;OptionID&gt;(id), stream, &quot;   &quot;, &quot;\n&quot;);
</del><ins>+        dumpOption(level, static_cast&lt;OptionID&gt;(id), stream, &quot;   &quot;, &quot;\n&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Options::dumpOption(OptionID id, FILE* stream, const char* header, const char* footer)
</del><ins>+void Options::dumpOption(DumpLevel level, OptionID id, FILE* stream, const char* header, const char* footer)
</ins><span class="cx"> {
</span><span class="cx">     if (id &gt;= numberOfOptions)
</span><span class="cx">         return; // Illegal option.
</span><span class="cx"> 
</span><ins>+    EntryType type = s_optionsInfo[id].type;
+    Option option(type, s_options[id]);
+    Option defaultOption(type, s_defaultOptions[id]);
+
+    bool wasOverridden = (option != defaultOption);
+    bool needsDescription = (level == DumpLevel::Verbose &amp;&amp; s_optionsInfo[id].description);
+
+    if (level == DumpLevel::Overridden &amp;&amp; !wasOverridden)
+        return;
+
</ins><span class="cx">     fprintf(stream, &quot;%s%s: &quot;, header, s_optionsInfo[id].name);
</span><del>-    switch (s_optionsInfo[id].type) {
</del><ins>+    option.dump(stream);
+
+    if (wasOverridden) {
+        fprintf(stream, &quot; (default: &quot;);
+        defaultOption.dump(stream);
+        fprintf(stream, &quot;)&quot;);
+    }
+
+    if (needsDescription)
+        fprintf(stream, &quot;\n%s   - %s&quot;, header, s_optionsInfo[id].description);
+
+    fprintf(stream, &quot;%s&quot;, footer);
+}
+
+void Options::Option::dump(FILE* stream) const
+{
+    switch (m_type) {
</ins><span class="cx">     case boolType:
</span><del>-        fprintf(stream, &quot;%s&quot;, s_options[id].u.boolVal?&quot;true&quot;:&quot;false&quot;);
</del><ins>+        fprintf(stream, &quot;%s&quot;, m_entry.boolVal ? &quot;true&quot; : &quot;false&quot;);
</ins><span class="cx">         break;
</span><span class="cx">     case unsignedType:
</span><del>-        fprintf(stream, &quot;%u&quot;, s_options[id].u.unsignedVal);
</del><ins>+        fprintf(stream, &quot;%u&quot;, m_entry.unsignedVal);
</ins><span class="cx">         break;
</span><span class="cx">     case doubleType:
</span><del>-        fprintf(stream, &quot;%lf&quot;, s_options[id].u.doubleVal);
</del><ins>+        fprintf(stream, &quot;%lf&quot;, m_entry.doubleVal);
</ins><span class="cx">         break;
</span><span class="cx">     case int32Type:
</span><del>-        fprintf(stream, &quot;%d&quot;, s_options[id].u.int32Val);
</del><ins>+        fprintf(stream, &quot;%d&quot;, m_entry.int32Val);
</ins><span class="cx">         break;
</span><span class="cx">     case optionRangeType:
</span><del>-        fprintf(stream, &quot;%s&quot;, s_options[id].u.optionRangeVal.rangeString());
</del><ins>+        fprintf(stream, &quot;%s&quot;, m_entry.optionRangeVal.rangeString());
</ins><span class="cx">         break;
</span><span class="cx">     case optionStringType: {
</span><del>-        const char* option = s_options[id].u.optionStringVal;
</del><ins>+        const char* option = m_entry.optionStringVal;
</ins><span class="cx">         if (!option)
</span><span class="cx">             option = &quot;&quot;;
</span><span class="cx">         fprintf(stream, &quot;%s&quot;, option);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     case gcLogLevelType: {
</span><del>-        fprintf(stream, &quot;%s&quot;, GCLogging::levelAsString(s_options[id].u.gcLogLevelVal));
</del><ins>+        fprintf(stream, &quot;%s&quot;, GCLogging::levelAsString(m_entry.gcLogLevelVal));
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     }
</span><del>-    fprintf(stream, &quot;%s&quot;, footer);
</del><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool Options::Option::operator==(const Options::Option&amp; other) const
+{
+    switch (m_type) {
+    case boolType:
+        return m_entry.boolVal == other.m_entry.boolVal;
+    case unsignedType:
+        return m_entry.unsignedVal == other.m_entry.unsignedVal;
+    case doubleType:
+        return (m_entry.doubleVal == other.m_entry.doubleVal) || (isnan(m_entry.doubleVal) &amp;&amp; isnan(other.m_entry.doubleVal));
+    case int32Type:
+        return m_entry.int32Val == other.m_entry.int32Val;
+    case optionRangeType:
+        return m_entry.optionRangeVal.rangeString() == other.m_entry.optionRangeVal.rangeString();
+    case optionStringType:
+        return (m_entry.optionStringVal == other.m_entry.optionStringVal)
+            || (m_entry.optionStringVal &amp;&amp; other.m_entry.optionStringVal &amp;&amp; !strcmp(m_entry.optionStringVal, other.m_entry.optionStringVal));
+    case gcLogLevelType:
+        return m_entry.gcLogLevelVal == other.m_entry.gcLogLevelVal;
+    }
+    return false;
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (182303 => 182304)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2015-04-03 01:16:24 UTC (rev 182303)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2015-04-03 03:46:39 UTC (rev 182304)
</span><span class="lines">@@ -79,7 +79,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool init(const char*);
</span><span class="cx">     bool isInRange(unsigned);
</span><del>-    const char* rangeString() { return (m_state &gt; InitError) ? m_rangeString : &quot;&lt;null&gt;&quot;; }
</del><ins>+    const char* rangeString() const { return (m_state &gt; InitError) ? m_rangeString : &quot;&lt;null&gt;&quot;; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     RangeState m_state;
</span><span class="lines">@@ -92,225 +92,234 @@
</span><span class="cx"> typedef const char* optionString;
</span><span class="cx"> 
</span><span class="cx"> #define JSC_OPTIONS(v) \
</span><del>-    v(bool, useLLInt,  true) \
-    v(bool, useJIT,    true) \
-    v(bool, useDFGJIT, true) \
-    v(bool, useRegExpJIT, true) \
</del><ins>+    v(unsigned, showOptions, 0, &quot;shows JSC options (0 = None, 1 = Overridden only, 2 = All, 3 = Verbose)&quot;) \
</ins><span class="cx">     \
</span><del>-    v(bool, reportMustSucceedExecutableAllocations, false) \
</del><ins>+    v(bool, useLLInt,  true, &quot;allows the LLINT to be used if true&quot;) \
+    v(bool, useJIT,    true, &quot;allows the baseline JIT to be used if true&quot;) \
+    v(bool, useDFGJIT, true, &quot;allows the DFG JIT to be used if true&quot;) \
+    v(bool, useRegExpJIT, true, &quot;allows the RegExp JIT to be used if true&quot;) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, maxPerThreadStackUsage, 4 * MB) \
-    v(unsigned, reservedZoneSize, 128 * KB) \
-    v(unsigned, errorModeReservedZoneSize, 64 * KB) \
</del><ins>+    v(bool, reportMustSucceedExecutableAllocations, false, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, crashIfCantAllocateJITMemory, false) \
</del><ins>+    v(unsigned, maxPerThreadStackUsage, 4 * MB, nullptr) \
+    v(unsigned, reservedZoneSize, 128 * KB, nullptr) \
+    v(unsigned, errorModeReservedZoneSize, 64 * KB, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, forceDFGCodeBlockLiveness, false) \
-    v(bool, forceICFailure, false) \
</del><ins>+    v(bool, crashIfCantAllocateJITMemory, false, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, dumpGeneratedBytecodes, false) \
-    v(bool, dumpBytecodeLivenessResults, false) \
-    v(bool, validateBytecode, false) \
-    v(bool, forceDebuggerBytecodeGeneration, false) \
-    v(bool, forceProfilerBytecodeGeneration, false) \
</del><ins>+    v(bool, forceDFGCodeBlockLiveness, false, nullptr) \
+    v(bool, forceICFailure, false, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, enableFunctionDotArguments, true) \
</del><ins>+    v(bool, dumpGeneratedBytecodes, false, nullptr) \
+    v(bool, dumpBytecodeLivenessResults, false, nullptr) \
+    v(bool, validateBytecode, false, nullptr) \
+    v(bool, forceDebuggerBytecodeGeneration, false, nullptr) \
+    v(bool, forceProfilerBytecodeGeneration, false, nullptr) \
</ins><span class="cx">     \
</span><ins>+    v(bool, enableFunctionDotArguments, true, nullptr) \
+    \
</ins><span class="cx">     /* showDisassembly implies showDFGDisassembly. */ \
</span><del>-    v(bool, showDisassembly, false) \
-    v(bool, asyncDisassembly, false) \
-    v(bool, showDFGDisassembly, false) \
-    v(bool, showFTLDisassembly, false) \
-    v(bool, showAllDFGNodes, false) \
-    v(optionRange, bytecodeRangeToDFGCompile, 0) \
-    v(optionString, dfgFunctionWhitelistFile, nullptr) \
-    v(bool, dumpSourceAtDFGTime, false) \
-    v(bool, dumpBytecodeAtDFGTime, false) \
-    v(bool, dumpGraphAfterParsing, false) \
-    v(bool, dumpGraphAtEachPhase, false) \
-    v(bool, verboseDFGByteCodeParsing, false) \
-    v(bool, verboseCompilation, false) \
-    v(bool, verboseFTLCompilation, false) \
-    v(bool, logCompilationChanges, false) \
-    v(bool, printEachOSRExit, false) \
-    v(bool, validateGraph, false) \
-    v(bool, validateGraphAtEachPhase, false) \
-    v(bool, verboseValidationFailure, false) \
-    v(bool, verboseOSR, false) \
-    v(bool, verboseFTLOSRExit, false) \
-    v(bool, verboseCallLink, false) \
-    v(bool, verboseCompilationQueue, false) \
-    v(bool, reportCompileTimes, false) \
-    v(bool, reportFTLCompileTimes, false) \
-    v(bool, verboseCFA, false) \
-    v(bool, verboseFTLToJSThunk, false) \
-    v(bool, verboseFTLFailure, false) \
-    v(bool, alwaysComputeHash, false) \
-    v(bool, testTheFTL, false) \
-    v(bool, verboseSanitizeStack, false) \
-    v(bool, alwaysDoFullCollection, false) \
-    v(bool, eagerlyUpdateTopCallFrame, false) \
</del><ins>+    v(bool, showDisassembly, false, &quot;dumps disassembly of all JIT compiled code upon compilation&quot;) \
+    v(bool, asyncDisassembly, false, nullptr) \
+    v(bool, showDFGDisassembly, false, &quot;dumps disassembly of DFG function upon compilation&quot;) \
+    v(bool, showFTLDisassembly, false, &quot;dumps disassembly of FTL function upon compilation&quot;) \
+    v(bool, showAllDFGNodes, false, nullptr) \
+    v(optionRange, bytecodeRangeToDFGCompile, 0, &quot;bytecode size range to allow DFG compilation on, e.g. 1:100&quot;) \
+    v(optionString, dfgFunctionWhitelistFile, nullptr, &quot;file with list of function signatures to allow DFG compilation on&quot;) \
+    v(bool, dumpSourceAtDFGTime, false, &quot;dumps source code of JS function being DFG compiled&quot;) \
+    v(bool, dumpBytecodeAtDFGTime, false, &quot;dumps bytecode of JS function being DFG compiled&quot;) \
+    v(bool, dumpGraphAfterParsing, false, nullptr) \
+    v(bool, dumpGraphAtEachPhase, false, nullptr) \
+    v(bool, verboseDFGByteCodeParsing, false, nullptr) \
+    v(bool, verboseCompilation, false, nullptr) \
+    v(bool, verboseFTLCompilation, false, nullptr) \
+    v(bool, logCompilationChanges, false, nullptr) \
+    v(bool, printEachOSRExit, false, nullptr) \
+    v(bool, validateGraph, false, nullptr) \
+    v(bool, validateGraphAtEachPhase, false, nullptr) \
+    v(bool, verboseValidationFailure, false, nullptr) \
+    v(bool, verboseOSR, false, nullptr) \
+    v(bool, verboseFTLOSRExit, false, nullptr) \
+    v(bool, verboseCallLink, false, nullptr) \
+    v(bool, verboseCompilationQueue, false, nullptr) \
+    v(bool, reportCompileTimes, false, &quot;dumps JS function signature and the time it took to compile&quot;) \
+    v(bool, reportFTLCompileTimes, false, &quot;dumps JS function signature and the time it took to FTL compile&quot;) \
+    v(bool, verboseCFA, false, nullptr) \
+    v(bool, verboseFTLToJSThunk, false, nullptr) \
+    v(bool, verboseFTLFailure, false, nullptr) \
+    v(bool, alwaysComputeHash, false, nullptr) \
+    v(bool, testTheFTL, false, nullptr) \
+    v(bool, verboseSanitizeStack, false, nullptr) \
+    v(bool, alwaysDoFullCollection, false, nullptr) \
+    v(bool, eagerlyUpdateTopCallFrame, false, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, enableOSREntryToDFG, true) \
-    v(bool, enableOSREntryToFTL, true) \
</del><ins>+    v(bool, enableOSREntryToDFG, true, nullptr) \
+    v(bool, enableOSREntryToFTL, true, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useFTLJIT, true) \
-    v(bool, useFTLTBAA, true) \
-    v(bool, enableLLVMFastISel, false) \
-    v(bool, useLLVMSmallCodeModel, false) \
-    v(bool, dumpLLVMIR, false) \
-    v(bool, validateFTLOSRExitLiveness, false) \
-    v(bool, llvmAlwaysFailsBeforeCompile, false) \
-    v(bool, llvmAlwaysFailsBeforeLink, false) \
-    v(bool, llvmSimpleOpt, true) \
-    v(unsigned, llvmBackendOptimizationLevel, 2) \
-    v(unsigned, llvmOptimizationLevel, 2) \
-    v(unsigned, llvmSizeLevel, 0) \
-    v(unsigned, llvmMaxStackSize, 128 * KB) \
-    v(bool, llvmDisallowAVX, true) \
-    v(bool, ftlCrashes, false) /* fool-proof way of checking that you ended up in the FTL. ;-) */\
-    v(bool, clobberAllRegsInFTLICSlowPath, !ASSERT_DISABLED) \
-    v(bool, assumeAllRegsInFTLICAreLive, false) \
-    v(bool, enableAccessInlining, true) \
-    v(bool, enablePolyvariantDevirtualization, true) \
-    v(bool, enablePolymorphicAccessInlining, true) \
-    v(bool, enablePolymorphicCallInlining, true) \
-    v(unsigned, maxPolymorphicCallVariantListSize, 15) \
-    v(unsigned, maxPolymorphicCallVariantListSizeForTopTier, 5) \
-    v(unsigned, maxPolymorphicCallVariantsForInlining, 5) \
-    v(unsigned, frequentCallThreshold, 2) \
-    v(double, minimumCallToKnownRate, 0.51) \
-    v(bool, optimizeNativeCalls, false) \
-    v(bool, enableObjectAllocationSinking, true) \
</del><ins>+    v(bool, useFTLJIT, true, &quot;allows the FTL JIT to be used if true&quot;) \
+    v(bool, useFTLTBAA, true, nullptr) \
+    v(bool, enableLLVMFastISel, false, nullptr) \
+    v(bool, useLLVMSmallCodeModel, false, nullptr) \
+    v(bool, dumpLLVMIR, false, nullptr) \
+    v(bool, validateFTLOSRExitLiveness, false, nullptr) \
+    v(bool, llvmAlwaysFailsBeforeCompile, false, nullptr) \
+    v(bool, llvmAlwaysFailsBeforeLink, false, nullptr) \
+    v(bool, llvmSimpleOpt, true, nullptr) \
+    v(unsigned, llvmBackendOptimizationLevel, 2, nullptr) \
+    v(unsigned, llvmOptimizationLevel, 2, nullptr) \
+    v(unsigned, llvmSizeLevel, 0, nullptr) \
+    v(unsigned, llvmMaxStackSize, 128 * KB, nullptr) \
+    v(bool, llvmDisallowAVX, true, nullptr) \
+    v(bool, ftlCrashes, false, nullptr) /* fool-proof way of checking that you ended up in the FTL. ;-) */\
+    v(bool, clobberAllRegsInFTLICSlowPath, !ASSERT_DISABLED, nullptr) \
+    v(bool, assumeAllRegsInFTLICAreLive, false, nullptr) \
+    v(bool, enableAccessInlining, true, nullptr) \
+    v(bool, enablePolyvariantDevirtualization, true, nullptr) \
+    v(bool, enablePolymorphicAccessInlining, true, nullptr) \
+    v(bool, enablePolymorphicCallInlining, true, nullptr) \
+    v(unsigned, maxPolymorphicCallVariantListSize, 15, nullptr) \
+    v(unsigned, maxPolymorphicCallVariantListSizeForTopTier, 5, nullptr) \
+    v(unsigned, maxPolymorphicCallVariantsForInlining, 5, nullptr) \
+    v(unsigned, frequentCallThreshold, 2, nullptr) \
+    v(double, minimumCallToKnownRate, 0.51, nullptr) \
+    v(bool, optimizeNativeCalls, false, nullptr) \
+    v(bool, enableObjectAllocationSinking, true, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, enableConcurrentJIT, true) \
-    v(unsigned, numberOfDFGCompilerThreads, computeNumberOfWorkerThreads(2, 2) - 1) \
-    v(unsigned, numberOfFTLCompilerThreads, computeNumberOfWorkerThreads(8, 2) - 1) \
-    v(int32, priorityDeltaOfDFGCompilerThreads, computePriorityDeltaOfWorkerThreads(-1, 0)) \
-    v(int32, priorityDeltaOfFTLCompilerThreads, computePriorityDeltaOfWorkerThreads(-2, 0)) \
</del><ins>+    v(bool, enableConcurrentJIT, true, &quot;allows the DFG / FTL compilation in threads other than the executing JS thread&quot;) \
+    v(unsigned, numberOfDFGCompilerThreads, computeNumberOfWorkerThreads(2, 2) - 1, nullptr) \
+    v(unsigned, numberOfFTLCompilerThreads, computeNumberOfWorkerThreads(8, 2) - 1, nullptr) \
+    v(int32, priorityDeltaOfDFGCompilerThreads, computePriorityDeltaOfWorkerThreads(-1, 0), nullptr) \
+    v(int32, priorityDeltaOfFTLCompilerThreads, computePriorityDeltaOfWorkerThreads(-2, 0), nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, enableProfiler, false) \
</del><ins>+    v(bool, enableProfiler, false, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, forceUDis86Disassembler, false) \
-    v(bool, forceLLVMDisassembler, false) \
</del><ins>+    v(bool, forceUDis86Disassembler, false, nullptr) \
+    v(bool, forceLLVMDisassembler, false, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, enableArchitectureSpecificOptimizations, true) \
</del><ins>+    v(bool, enableArchitectureSpecificOptimizations, true, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, breakOnThrow, false) \
</del><ins>+    v(bool, breakOnThrow, false, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, maximumOptimizationCandidateInstructionCount, 100000) \
</del><ins>+    v(unsigned, maximumOptimizationCandidateInstructionCount, 100000, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 180) \
-    v(unsigned, maximumFunctionForClosureCallInlineCandidateInstructionCount, 100) \
-    v(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 100) \
</del><ins>+    v(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 180, nullptr) \
+    v(unsigned, maximumFunctionForClosureCallInlineCandidateInstructionCount, 100, nullptr) \
+    v(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 100, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, maximumFTLCandidateInstructionCount, 20000) \
</del><ins>+    v(unsigned, maximumFTLCandidateInstructionCount, 20000, nullptr) \
</ins><span class="cx">     \
</span><span class="cx">     /* Depth of inline stack, so 1 = no inlining, 2 = one level, etc. */ \
</span><del>-    v(unsigned, maximumInliningDepth, 5) \
-    v(unsigned, maximumInliningRecursion, 2) \
</del><ins>+    v(unsigned, maximumInliningDepth, 5, &quot;maximum allowed inlining depth.  Depth of 1 means no inlining&quot;) \
+    v(unsigned, maximumInliningRecursion, 2, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, maximumLLVMInstructionCountForNativeInlining, 80) \
</del><ins>+    v(unsigned, maximumLLVMInstructionCountForNativeInlining, 80, nullptr) \
</ins><span class="cx">     \
</span><span class="cx">     /* Maximum size of a caller for enabling inlining. This is purely to protect us */\
</span><span class="cx">     /* from super long compiles that take a lot of memory. */\
</span><del>-    v(unsigned, maximumInliningCallerSize, 10000) \
</del><ins>+    v(unsigned, maximumInliningCallerSize, 10000, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, maximumVarargsForInlining, 100) \
</del><ins>+    v(unsigned, maximumVarargsForInlining, 100, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, enablePolyvariantCallInlining, true) \
-    v(bool, enablePolyvariantByIdInlining, true) \
</del><ins>+    v(bool, enablePolyvariantCallInlining, true, nullptr) \
+    v(bool, enablePolyvariantByIdInlining, true, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, maximumBinaryStringSwitchCaseLength, 50) \
-    v(unsigned, maximumBinaryStringSwitchTotalLength, 2000) \
</del><ins>+    v(unsigned, maximumBinaryStringSwitchCaseLength, 50, nullptr) \
+    v(unsigned, maximumBinaryStringSwitchTotalLength, 2000, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(int32, thresholdForJITAfterWarmUp, 500) \
-    v(int32, thresholdForJITSoon, 100) \
</del><ins>+    v(int32, thresholdForJITAfterWarmUp, 500, nullptr) \
+    v(int32, thresholdForJITSoon, 100, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(int32, thresholdForOptimizeAfterWarmUp, 1000) \
-    v(int32, thresholdForOptimizeAfterLongWarmUp, 1000) \
-    v(int32, thresholdForOptimizeSoon, 1000) \
-    v(int32, executionCounterIncrementForLoop, 1) \
-    v(int32, executionCounterIncrementForEntry, 15) \
</del><ins>+    v(int32, thresholdForOptimizeAfterWarmUp, 1000, nullptr) \
+    v(int32, thresholdForOptimizeAfterLongWarmUp, 1000, nullptr) \
+    v(int32, thresholdForOptimizeSoon, 1000, nullptr) \
+    v(int32, executionCounterIncrementForLoop, 1, nullptr) \
+    v(int32, executionCounterIncrementForEntry, 15, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(int32, thresholdForFTLOptimizeAfterWarmUp, 100000) \
-    v(int32, thresholdForFTLOptimizeSoon, 1000) \
-    v(int32, ftlTierUpCounterIncrementForLoop, 1) \
-    v(int32, ftlTierUpCounterIncrementForReturn, 15) \
-    v(unsigned, ftlOSREntryFailureCountForReoptimization, 15) \
-    v(unsigned, ftlOSREntryRetryThreshold, 100) \
</del><ins>+    v(int32, thresholdForFTLOptimizeAfterWarmUp, 100000, nullptr) \
+    v(int32, thresholdForFTLOptimizeSoon, 1000, nullptr) \
+    v(int32, ftlTierUpCounterIncrementForLoop, 1, nullptr) \
+    v(int32, ftlTierUpCounterIncrementForReturn, 15, nullptr) \
+    v(unsigned, ftlOSREntryFailureCountForReoptimization, 15, nullptr) \
+    v(unsigned, ftlOSREntryRetryThreshold, 100, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(int32, evalThresholdMultiplier, 10) \
-    v(unsigned, maximumEvalCacheableSourceLength, 256) \
</del><ins>+    v(int32, evalThresholdMultiplier, 10, nullptr) \
+    v(unsigned, maximumEvalCacheableSourceLength, 256, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, randomizeExecutionCountsBetweenCheckpoints, false) \
-    v(int32, maximumExecutionCountsBetweenCheckpointsForBaseline, 1000) \
-    v(int32, maximumExecutionCountsBetweenCheckpointsForUpperTiers, 50000) \
</del><ins>+    v(bool, randomizeExecutionCountsBetweenCheckpoints, false, nullptr) \
+    v(int32, maximumExecutionCountsBetweenCheckpointsForBaseline, 1000, nullptr) \
+    v(int32, maximumExecutionCountsBetweenCheckpointsForUpperTiers, 50000, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, likelyToTakeSlowCaseMinimumCount, 20) \
-    v(unsigned, couldTakeSlowCaseMinimumCount, 10) \
</del><ins>+    v(unsigned, likelyToTakeSlowCaseMinimumCount, 20, nullptr) \
+    v(unsigned, couldTakeSlowCaseMinimumCount, 10, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, osrExitCountForReoptimization, 100) \
-    v(unsigned, osrExitCountForReoptimizationFromLoop, 5) \
</del><ins>+    v(unsigned, osrExitCountForReoptimization, 100, nullptr) \
+    v(unsigned, osrExitCountForReoptimizationFromLoop, 5, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, reoptimizationRetryCounterMax, 0)  \
</del><ins>+    v(unsigned, reoptimizationRetryCounterMax, 0, nullptr)  \
</ins><span class="cx">     \
</span><del>-    v(unsigned, minimumOptimizationDelay, 1) \
-    v(unsigned, maximumOptimizationDelay, 5) \
-    v(double, desiredProfileLivenessRate, 0.75) \
-    v(double, desiredProfileFullnessRate, 0.35) \
</del><ins>+    v(unsigned, minimumOptimizationDelay, 1, nullptr) \
+    v(unsigned, maximumOptimizationDelay, 5, nullptr) \
+    v(double, desiredProfileLivenessRate, 0.75, nullptr) \
+    v(double, desiredProfileFullnessRate, 0.35, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(double, doubleVoteRatioForDoubleFormat, 2) \
-    v(double, structureCheckVoteRatioForHoisting, 1) \
-    v(double, checkArrayVoteRatioForHoisting, 1) \
</del><ins>+    v(double, doubleVoteRatioForDoubleFormat, 2, nullptr) \
+    v(double, structureCheckVoteRatioForHoisting, 1, nullptr) \
+    v(double, checkArrayVoteRatioForHoisting, 1, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, minimumNumberOfScansBetweenRebalance, 100) \
-    v(unsigned, numberOfGCMarkers, computeNumberOfGCMarkers(7)) \
-    v(unsigned, opaqueRootMergeThreshold, 1000) \
-    v(double, minHeapUtilization, 0.8) \
-    v(double, minCopiedBlockUtilization, 0.9) \
-    v(double, minMarkedBlockUtilization, 0.9) \
-    v(unsigned, slowPathAllocsBetweenGCs, 0) \
</del><ins>+    v(unsigned, minimumNumberOfScansBetweenRebalance, 100, nullptr) \
+    v(unsigned, numberOfGCMarkers, computeNumberOfGCMarkers(7), nullptr) \
+    v(unsigned, opaqueRootMergeThreshold, 1000, nullptr) \
+    v(double, minHeapUtilization, 0.8, nullptr) \
+    v(double, minCopiedBlockUtilization, 0.9, nullptr) \
+    v(double, minMarkedBlockUtilization, 0.9, nullptr) \
+    v(unsigned, slowPathAllocsBetweenGCs, 0, &quot;force a GC on every Nth slow path alloc, where N is specified by this option&quot;) \
</ins><span class="cx">     \
</span><del>-    v(double, percentCPUPerMBForFullTimer, 0.0003125) \
-    v(double, percentCPUPerMBForEdenTimer, 0.0025) \
-    v(double, collectionTimerMaxPercentCPU, 0.05) \
</del><ins>+    v(double, percentCPUPerMBForFullTimer, 0.0003125, nullptr) \
+    v(double, percentCPUPerMBForEdenTimer, 0.0025, nullptr) \
+    v(double, collectionTimerMaxPercentCPU, 0.05, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, forceWeakRandomSeed, false) \
-    v(unsigned, forcedWeakRandomSeed, 0) \
</del><ins>+    v(bool, forceWeakRandomSeed, false, nullptr) \
+    v(unsigned, forcedWeakRandomSeed, 0, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useZombieMode, false) \
-    v(bool, objectsAreImmortal, false) \
-    v(bool, showObjectStatistics, false) \
</del><ins>+    v(bool, useZombieMode, false, &quot;debugging option to scribble over dead objects with 0xdeadbeef&quot;) \
+    v(bool, objectsAreImmortal, false, &quot;debugging option to keep all objects alive forever&quot;) \
+    v(bool, showObjectStatistics, false, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(gcLogLevel, logGC, GCLogging::None) \
-    v(bool, disableGC, false) \
-    v(unsigned, gcMaxHeapSize, 0) \
-    v(bool, recordGCPauseTimes, false) \
-    v(bool, logHeapStatisticsAtExit, false) \
-    v(bool, enableTypeProfiler, false) \
-    v(bool, enableControlFlowProfiler, false) \
</del><ins>+    v(gcLogLevel, logGC, GCLogging::None, &quot;debugging option to log GC activity (0 = None, 1 = Basic, 2 = Verbose)&quot;) \
+    v(bool, disableGC, false, nullptr) \
+    v(unsigned, gcMaxHeapSize, 0, nullptr) \
+    v(bool, recordGCPauseTimes, false, nullptr) \
+    v(bool, logHeapStatisticsAtExit, false, nullptr) \
+    v(bool, enableTypeProfiler, false, nullptr) \
+    v(bool, enableControlFlowProfiler, false, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, verifyHeap, false) \
-    v(unsigned, numberOfGCCyclesToRecordForVerification, 3) \
</del><ins>+    v(bool, verifyHeap, false, nullptr) \
+    v(unsigned, numberOfGCCyclesToRecordForVerification, 3, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, enableExceptionFuzz, false) \
-    v(unsigned, fireExceptionFuzzAt, 0) \
</del><ins>+    v(bool, enableExceptionFuzz, false, nullptr) \
+    v(unsigned, fireExceptionFuzzAt, 0, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, enableExecutableAllocationFuzz, false) \
-    v(unsigned, fireExecutableAllocationFuzzAt, 0) \
-    v(unsigned, fireExecutableAllocationFuzzAtOrAfter, 0) \
-    v(bool, verboseExecutableAllocationFuzz, false)
</del><ins>+    v(bool, enableExecutableAllocationFuzz, false, nullptr) \
+    v(unsigned, fireExecutableAllocationFuzzAt, 0, nullptr) \
+    v(unsigned, fireExecutableAllocationFuzzAtOrAfter, 0, nullptr) \
+    v(bool, verboseExecutableAllocationFuzz, false, nullptr)
</ins><span class="cx"> 
</span><span class="cx"> class Options {
</span><span class="cx"> public:
</span><ins>+    enum class DumpLevel {
+        None = 0,
+        Overridden,
+        All,
+        Verbose
+    };
+    
</ins><span class="cx">     // This typedef is to allow us to eliminate the '_' in the field name in
</span><span class="cx">     // union inside Entry. This is needed to keep the style checker happy.
</span><span class="cx">     typedef int32_t int32;
</span><span class="cx"> 
</span><span class="cx">     // Declare the option IDs:
</span><span class="cx">     enum OptionID {
</span><del>-#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
</del><ins>+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
</ins><span class="cx">         OPT_##name_,
</span><span class="cx">         JSC_OPTIONS(FOR_EACH_OPTION)
</span><span class="cx"> #undef FOR_EACH_OPTION
</span><span class="lines">@@ -323,13 +332,13 @@
</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><span class="cx">     JS_EXPORT_PRIVATE static bool setOption(const char* arg);
</span><del>-    JS_EXPORT_PRIVATE static void dumpAllOptions(FILE* stream = stdout);
-    static void dumpOption(OptionID id, FILE* stream = stdout, const char* header = &quot;&quot;, const char* footer = &quot;&quot;);
</del><ins>+    JS_EXPORT_PRIVATE static void dumpAllOptions(DumpLevel, const char* title = nullptr, FILE* stream = stdout);
+    static void dumpOption(DumpLevel, OptionID, FILE* stream = stdout, const char* header = &quot;&quot;, const char* footer = &quot;&quot;);
</ins><span class="cx"> 
</span><span class="cx">     // Declare accessors for each option:
</span><del>-#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
-    ALWAYS_INLINE static type_&amp; name_() { return s_options[OPT_##name_].u.type_##Val; } \
-    static bool name_##WasOverridden() { return s_options[OPT_##name_].didOverride; }
</del><ins>+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
+    ALWAYS_INLINE static type_&amp; name_() { return s_options[OPT_##name_].type_##Val; } \
+    ALWAYS_INLINE static type_&amp; name_##Default() { return s_defaultOptions[OPT_##name_].type_##Val; }
</ins><span class="cx"> 
</span><span class="cx">     JSC_OPTIONS(FOR_EACH_OPTION)
</span><span class="cx"> #undef FOR_EACH_OPTION
</span><span class="lines">@@ -346,35 +355,45 @@
</span><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     // For storing for an option value:
</span><del>-    struct Entry {
-        union {
-            bool boolVal;
-            unsigned unsignedVal;
-            double doubleVal;
-            int32 int32Val;
-            OptionRange optionRangeVal;
-            const char* optionStringVal;
-            GCLogging::Level gcLogLevelVal;
-        } u;
-        bool didOverride;
</del><ins>+    union Entry {
+        bool boolVal;
+        unsigned unsignedVal;
+        double doubleVal;
+        int32 int32Val;
+        OptionRange optionRangeVal;
+        const char* optionStringVal;
+        GCLogging::Level gcLogLevelVal;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    class Option {
+    public:
+        Option(EntryType type, Entry&amp; entry)
+            : m_type(type)
+            , m_entry(entry)
+        {
+        }
+
+        void dump(FILE*) const;
+        bool operator==(const Option&amp; other) const;
+        bool operator!=(const Option&amp; other) const { return !(*this == other); }
+
+    private:
+        EntryType m_type;
+        Entry&amp; m_entry;
+    };
+
</ins><span class="cx">     // For storing constant meta data about each option:
</span><span class="cx">     struct EntryInfo {
</span><span class="cx">         const char* name;
</span><ins>+        const char* description;
</ins><span class="cx">         EntryType type;
</span><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     Options();
</span><span class="cx"> 
</span><del>-    // Declare the options:
-#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
-    type_ m_##name_;
-    JSC_OPTIONS(FOR_EACH_OPTION)
-#undef FOR_EACH_OPTION
-
</del><span class="cx">     // Declare the singleton instance of the options store:
</span><span class="cx">     JS_EXPORTDATA static Entry s_options[numberOfOptions];
</span><ins>+    static Entry s_defaultOptions[numberOfOptions];
</ins><span class="cx">     static const EntryInfo s_optionsInfo[numberOfOptions];
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>