<!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>[200136] 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/200136">200136</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2016-04-27 11:36:17 -0700 (Wed, 27 Apr 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Restrict the availability of some JSC options to local debug builds only.
https://bugs.webkit.org/show_bug.cgi?id=157058

Reviewed by Geoffrey Garen.

1. Each option will be given an availability flag.
2. The functionOverrides and useDollarVM (along with its alias, enableDollarVM)
   will have &quot;Restricted&quot; availability.
3. All other options will have “Normal” availability.
4. Any options with &quot;Restricted&quot; availability will only be accessible if function
   allowRestrictedOptions() returns true.
5. For now, allowRestrictedOptions() always returns false for release builds, and
   true for debug builds.

If an option is &quot;Restricted&quot; and restricted options are not allowed, the VM will
behave semantically as if that option does not exist at all:
1. Option dumps will not show the option.
2. Attempts to set the option will fail as if the option does not exist.

Behind the scene, the option does exist, and is set to its default value
(whatever that may be) once and only once on options initialization.

* runtime/Options.cpp:
(JSC::allowRestrictedOptions):
(JSC::parse):
(JSC::overrideOptionWithHeuristic):
(JSC::Options::initialize):
(JSC::Options::setOptionWithoutAlias):
(JSC::Options::dumpOption):
* runtime/Options.h:
(JSC::Option::type):
(JSC::Option::availability):
(JSC::Option::isOverridden):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</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 (200135 => 200136)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-04-27 18:21:33 UTC (rev 200135)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-04-27 18:36:17 UTC (rev 200136)
</span><span class="lines">@@ -1,3 +1,39 @@
</span><ins>+2016-04-27  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Restrict the availability of some JSC options to local debug builds only.
+        https://bugs.webkit.org/show_bug.cgi?id=157058
+
+        Reviewed by Geoffrey Garen.
+
+        1. Each option will be given an availability flag.
+        2. The functionOverrides and useDollarVM (along with its alias, enableDollarVM)
+           will have &quot;Restricted&quot; availability.
+        3. All other options will have “Normal” availability.
+        4. Any options with &quot;Restricted&quot; availability will only be accessible if function
+           allowRestrictedOptions() returns true.
+        5. For now, allowRestrictedOptions() always returns false for release builds, and
+           true for debug builds.
+
+        If an option is &quot;Restricted&quot; and restricted options are not allowed, the VM will
+        behave semantically as if that option does not exist at all:
+        1. Option dumps will not show the option.
+        2. Attempts to set the option will fail as if the option does not exist.
+
+        Behind the scene, the option does exist, and is set to its default value
+        (whatever that may be) once and only once on options initialization.
+
+        * runtime/Options.cpp:
+        (JSC::allowRestrictedOptions):
+        (JSC::parse):
+        (JSC::overrideOptionWithHeuristic):
+        (JSC::Options::initialize):
+        (JSC::Options::setOptionWithoutAlias):
+        (JSC::Options::dumpOption):
+        * runtime/Options.h:
+        (JSC::Option::type):
+        (JSC::Option::availability):
+        (JSC::Option::isOverridden):
+
</ins><span class="cx"> 2016-04-27  Gavin Barraclough  &lt;barraclough@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Enable separated heap by default on ios
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.cpp (200135 => 200136)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.cpp        2016-04-27 18:21:33 UTC (rev 200135)
+++ trunk/Source/JavaScriptCore/runtime/Options.cpp        2016-04-27 18:36:17 UTC (rev 200136)
</span><span class="lines">@@ -53,6 +53,15 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+static bool allowRestrictedOptions()
+{
+#ifdef NDEBUG
+    return false;
+#else
+    return true;
+#endif
+}
+
</ins><span class="cx"> static bool parse(const char* string, bool&amp; value)
</span><span class="cx"> {
</span><span class="cx">     if (!strcasecmp(string, &quot;true&quot;) || !strcasecmp(string, &quot;yes&quot;) || !strcmp(string, &quot;1&quot;)) {
</span><span class="lines">@@ -115,13 +124,15 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename T&gt;
</span><del>-bool overrideOptionWithHeuristic(T&amp; variable, const char* name)
</del><ins>+bool overrideOptionWithHeuristic(T&amp; variable, const char* name, Options::Availability availability)
</ins><span class="cx"> {
</span><ins>+    bool isAvailable = (availability != Options::Availability::Restricted) || allowRestrictedOptions();
+
</ins><span class="cx">     const char* stringValue = getenv(name);
</span><span class="cx">     if (!stringValue)
</span><span class="cx">         return false;
</span><span class="cx">     
</span><del>-    if (parse(stringValue, variable))
</del><ins>+    if (isAvailable &amp;&amp; parse(stringValue, variable))
</ins><span class="cx">         return true;
</span><span class="cx">     
</span><span class="cx">     fprintf(stderr, &quot;WARNING: failed to parse %s=%s\n&quot;, name, stringValue);
</span><span class="lines">@@ -232,8 +243,8 @@
</span><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_, description_) \
-    { #name_, description_, Options::Type::type_##Type },
</del><ins>+#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
+    { #name_, description_, Options::Type::type_##Type, Availability::availability_ },
</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">@@ -362,7 +373,7 @@
</span><span class="cx">         initializeOptionsOnceFlag,
</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_, description_)      \
</del><ins>+#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
</ins><span class="cx">             name_() = defaultValue_;                                    \
</span><span class="cx">             name_##Default() = defaultValue_;
</span><span class="cx">             JSC_OPTIONS(FOR_EACH_OPTION)
</span><span class="lines">@@ -385,8 +396,8 @@
</span><span class="cx">             if (hasBadOptions &amp;&amp; Options::validateOptions())
</span><span class="cx">                 CRASH();
</span><span class="cx"> #else // PLATFORM(COCOA)
</span><del>-#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_)      \
-            overrideOptionWithHeuristic(name_(), &quot;JSC_&quot; #name_);
</del><ins>+#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
+            overrideOptionWithHeuristic(name_(), &quot;JSC_&quot; #name_, Availability::availability_);
</ins><span class="cx">             JSC_OPTIONS(FOR_EACH_OPTION)
</span><span class="cx"> #undef FOR_EACH_OPTION
</span><span class="cx"> #endif // PLATFORM(COCOA)
</span><span class="lines">@@ -550,9 +561,11 @@
</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_, description_) \
</del><ins>+#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
</ins><span class="cx">     if (strlen(#name_) == static_cast&lt;size_t&gt;(equalStr - arg)      \
</span><span class="cx">         &amp;&amp; !strncmp(arg, #name_, equalStr - arg)) {                \
</span><ins>+        if (Availability::availability_ == Availability::Restricted &amp;&amp; !allowRestrictedOptions()) \
+            return false;                                          \
</ins><span class="cx">         type_ value;                                               \
</span><span class="cx">         value = (defaultValue_);                                   \
</span><span class="cx">         bool success = parse(valueStr, value);                     \
</span><span class="lines">@@ -668,6 +681,9 @@
</span><span class="cx">         return; // Illegal option.
</span><span class="cx"> 
</span><span class="cx">     Option option(id);
</span><ins>+    if (option.availability() == Availability::Restricted &amp;&amp; !allowRestrictedOptions())
+        return;
+
</ins><span class="cx">     bool wasOverridden = option.isOverridden();
</span><span class="cx">     bool needsDescription = (level == DumpLevel::Verbose &amp;&amp; option.description());
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (200135 => 200136)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2016-04-27 18:21:33 UTC (rev 200135)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2016-04-27 18:36:17 UTC (rev 200136)
</span><span class="lines">@@ -102,265 +102,265 @@
</span><span class="cx"> typedef const char* optionString;
</span><span class="cx"> 
</span><span class="cx"> #define JSC_OPTIONS(v) \
</span><del>-    v(bool, validateOptions, false, &quot;crashes if mis-typed JSC options were passed to the VM&quot;) \
-    v(unsigned, dumpOptions, 0, &quot;dumps JSC options (0 = None, 1 = Overridden only, 2 = All, 3 = Verbose)&quot;) \
</del><ins>+    v(bool, validateOptions, false, Normal, &quot;crashes if mis-typed JSC options were passed to the VM&quot;) \
+    v(unsigned, dumpOptions, 0, Normal, &quot;dumps JSC options (0 = None, 1 = Overridden only, 2 = All, 3 = Verbose)&quot;) \
</ins><span class="cx">     \
</span><del>-    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;) \
</del><ins>+    v(bool, useLLInt,  true, Normal, &quot;allows the LLINT to be used if true&quot;) \
+    v(bool, useJIT,    true, Normal, &quot;allows the baseline JIT to be used if true&quot;) \
+    v(bool, useDFGJIT, true, Normal, &quot;allows the DFG JIT to be used if true&quot;) \
+    v(bool, useRegExpJIT, true, Normal, &quot;allows the RegExp JIT to be used if true&quot;) \
</ins><span class="cx">     \
</span><del>-    v(bool, reportMustSucceedExecutableAllocations, false, nullptr) \
</del><ins>+    v(bool, reportMustSucceedExecutableAllocations, false, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, maxPerThreadStackUsage, 4 * MB, nullptr) \
-    v(unsigned, reservedZoneSize, 128 * KB, nullptr) \
-    v(unsigned, errorModeReservedZoneSize, 64 * KB, nullptr) \
</del><ins>+    v(unsigned, maxPerThreadStackUsage, 4 * MB, Normal, nullptr) \
+    v(unsigned, reservedZoneSize, 128 * KB, Normal, nullptr) \
+    v(unsigned, errorModeReservedZoneSize, 64 * KB, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, crashIfCantAllocateJITMemory, false, nullptr) \
-    v(unsigned, jitMemoryReservationSize, 0, &quot;Set this number to change the executable allocation size in ExecutableAllocatorFixedVMPool. (In bytes.)&quot;) \
-    v(bool, useSeparatedWXHeap, false, nullptr) \
</del><ins>+    v(bool, crashIfCantAllocateJITMemory, false, Normal, nullptr) \
+    v(unsigned, jitMemoryReservationSize, 0, Normal, &quot;Set this number to change the executable allocation size in ExecutableAllocatorFixedVMPool. (In bytes.)&quot;) \
+    v(bool, useSeparatedWXHeap, false, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, forceCodeBlockLiveness, false, nullptr) \
-    v(bool, forceICFailure, false, nullptr) \
</del><ins>+    v(bool, forceCodeBlockLiveness, false, Normal, nullptr) \
+    v(bool, forceICFailure, false, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, repatchCountForCoolDown, 10, nullptr) \
-    v(unsigned, initialCoolDownCount, 20, nullptr) \
-    v(unsigned, repatchBufferingCountdown, 10, nullptr) \
</del><ins>+    v(unsigned, repatchCountForCoolDown, 10, Normal, nullptr) \
+    v(unsigned, initialCoolDownCount, 20, Normal, nullptr) \
+    v(unsigned, repatchBufferingCountdown, 10, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    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) \
</del><ins>+    v(bool, dumpGeneratedBytecodes, false, Normal, nullptr) \
+    v(bool, dumpBytecodeLivenessResults, false, Normal, nullptr) \
+    v(bool, validateBytecode, false, Normal, nullptr) \
+    v(bool, forceDebuggerBytecodeGeneration, false, Normal, nullptr) \
+    v(bool, forceProfilerBytecodeGeneration, false, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useFunctionDotArguments, true, nullptr) \
-    v(bool, useTailCalls, true, nullptr) \
-    v(bool, alwaysUseShadowChicken, false, nullptr) \
-    v(unsigned, shadowChickenLogSize, 1000, nullptr) \
-    v(unsigned, shadowChickenStackSizeLimit, 100000, nullptr) \
</del><ins>+    v(bool, useFunctionDotArguments, true, Normal, nullptr) \
+    v(bool, useTailCalls, true, Normal, nullptr) \
+    v(bool, alwaysUseShadowChicken, false, Normal, nullptr) \
+    v(unsigned, shadowChickenLogSize, 1000, Normal, nullptr) \
+    v(unsigned, shadowChickenStackSizeLimit, 100000, Normal, nullptr) \
</ins><span class="cx">     \
</span><span class="cx">     /* dumpDisassembly implies dumpDFGDisassembly. */ \
</span><del>-    v(bool, dumpDisassembly, false, &quot;dumps disassembly of all JIT compiled code upon compilation&quot;) \
-    v(bool, asyncDisassembly, false, nullptr) \
-    v(bool, dumpDFGDisassembly, false, &quot;dumps disassembly of DFG function upon compilation&quot;) \
-    v(bool, dumpFTLDisassembly, false, &quot;dumps disassembly of FTL function upon compilation&quot;) \
-    v(bool, dumpAllDFGNodes, false, nullptr) \
-    v(optionRange, bytecodeRangeToDFGCompile, 0, &quot;bytecode size range to allow DFG compilation on, e.g. 1:100&quot;) \
-    v(optionRange, bytecodeRangeToFTLCompile, 0, &quot;bytecode size range to allow FTL compilation on, e.g. 1:100&quot;) \
-    v(optionString, dfgWhitelist, 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, dumpDFGGraphAtEachPhase, false, &quot;dumps the DFG graph at each phase DFG of complitaion (note this excludes DFG graphs during FTL compilation)&quot;) \
-    v(bool, dumpDFGFTLGraphAtEachPhase, false, &quot;dumps the DFG graph at each phase DFG of complitaion when compiling FTL code&quot;) \
-    v(bool, dumpB3GraphAtEachPhase, false, &quot;dumps the B3 graph at each phase of compilation&quot;) \
-    v(bool, dumpAirGraphAtEachPhase, false, &quot;dumps the Air graph at each phase of compilation&quot;) \
-    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, reportTotalCompileTimes, false, nullptr) \
-    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, useGenerationalGC, true, nullptr) \
-    v(bool, eagerlyUpdateTopCallFrame, false, nullptr) \
</del><ins>+    v(bool, dumpDisassembly, false, Normal, &quot;dumps disassembly of all JIT compiled code upon compilation&quot;) \
+    v(bool, asyncDisassembly, false, Normal, nullptr) \
+    v(bool, dumpDFGDisassembly, false, Normal, &quot;dumps disassembly of DFG function upon compilation&quot;) \
+    v(bool, dumpFTLDisassembly, false, Normal, &quot;dumps disassembly of FTL function upon compilation&quot;) \
+    v(bool, dumpAllDFGNodes, false, Normal, nullptr) \
+    v(optionRange, bytecodeRangeToDFGCompile, 0, Normal, &quot;bytecode size range to allow DFG compilation on, e.g. 1:100&quot;) \
+    v(optionRange, bytecodeRangeToFTLCompile, 0, Normal, &quot;bytecode size range to allow FTL compilation on, e.g. 1:100&quot;) \
+    v(optionString, dfgWhitelist, nullptr, Normal, &quot;file with list of function signatures to allow DFG compilation on&quot;) \
+    v(bool, dumpSourceAtDFGTime, false, Normal, &quot;dumps source code of JS function being DFG compiled&quot;) \
+    v(bool, dumpBytecodeAtDFGTime, false, Normal, &quot;dumps bytecode of JS function being DFG compiled&quot;) \
+    v(bool, dumpGraphAfterParsing, false, Normal, nullptr) \
+    v(bool, dumpGraphAtEachPhase, false, Normal, nullptr) \
+    v(bool, dumpDFGGraphAtEachPhase, false, Normal, &quot;dumps the DFG graph at each phase DFG of complitaion (note this excludes DFG graphs during FTL compilation)&quot;) \
+    v(bool, dumpDFGFTLGraphAtEachPhase, false, Normal, &quot;dumps the DFG graph at each phase DFG of complitaion when compiling FTL code&quot;) \
+    v(bool, dumpB3GraphAtEachPhase, false, Normal, &quot;dumps the B3 graph at each phase of compilation&quot;) \
+    v(bool, dumpAirGraphAtEachPhase, false, Normal, &quot;dumps the Air graph at each phase of compilation&quot;) \
+    v(bool, verboseDFGByteCodeParsing, false, Normal, nullptr) \
+    v(bool, verboseCompilation, false, Normal, nullptr) \
+    v(bool, verboseFTLCompilation, false, Normal, nullptr) \
+    v(bool, logCompilationChanges, false, Normal, nullptr) \
+    v(bool, printEachOSRExit, false, Normal, nullptr) \
+    v(bool, validateGraph, false, Normal, nullptr) \
+    v(bool, validateGraphAtEachPhase, false, Normal, nullptr) \
+    v(bool, verboseValidationFailure, false, Normal, nullptr) \
+    v(bool, verboseOSR, false, Normal, nullptr) \
+    v(bool, verboseFTLOSRExit, false, Normal, nullptr) \
+    v(bool, verboseCallLink, false, Normal, nullptr) \
+    v(bool, verboseCompilationQueue, false, Normal, nullptr) \
+    v(bool, reportCompileTimes, false, Normal, &quot;dumps JS function signature and the time it took to compile&quot;) \
+    v(bool, reportFTLCompileTimes, false, Normal, &quot;dumps JS function signature and the time it took to FTL compile&quot;) \
+    v(bool, reportTotalCompileTimes, false, Normal, nullptr) \
+    v(bool, verboseCFA, false, Normal, nullptr) \
+    v(bool, verboseFTLToJSThunk, false, Normal, nullptr) \
+    v(bool, verboseFTLFailure, false, Normal, nullptr) \
+    v(bool, alwaysComputeHash, false, Normal, nullptr) \
+    v(bool, testTheFTL, false, Normal, nullptr) \
+    v(bool, verboseSanitizeStack, false, Normal, nullptr) \
+    v(bool, useGenerationalGC, true, Normal, nullptr) \
+    v(bool, eagerlyUpdateTopCallFrame, false, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useOSREntryToDFG, true, nullptr) \
-    v(bool, useOSREntryToFTL, true, nullptr) \
</del><ins>+    v(bool, useOSREntryToDFG, true, Normal, nullptr) \
+    v(bool, useOSREntryToFTL, true, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useFTLJIT, true, &quot;allows the FTL JIT to be used if true&quot;) \
-    v(bool, useFTLTBAA, true, nullptr) \
-    v(bool, validateFTLOSRExitLiveness, false, nullptr) \
-    v(bool, b3AlwaysFailsBeforeCompile, false, nullptr) \
-    v(bool, b3AlwaysFailsBeforeLink, false, 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, useAccessInlining, true, nullptr) \
-    v(unsigned, maxAccessVariantListSize, 13, nullptr) \
-    v(unsigned, megamorphicLoadCost, 999, nullptr) /* This used to be 10, but we're temporarily testing what happens when the feature is disabled. */\
-    v(bool, usePolyvariantDevirtualization, true, nullptr) \
-    v(bool, usePolymorphicAccessInlining, true, nullptr) \
-    v(bool, usePolymorphicCallInlining, true, nullptr) \
-    v(bool, usePolymorphicCallInliningForNonStubStatus, false, 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, createPreHeaders, true, nullptr) \
-    v(bool, useMovHintRemoval, true, nullptr) \
-    v(bool, usePutStackSinking, true, nullptr) \
-    v(bool, useObjectAllocationSinking, true, nullptr) \
</del><ins>+    v(bool, useFTLJIT, true, Normal, &quot;allows the FTL JIT to be used if true&quot;) \
+    v(bool, useFTLTBAA, true, Normal, nullptr) \
+    v(bool, validateFTLOSRExitLiveness, false, Normal, nullptr) \
+    v(bool, b3AlwaysFailsBeforeCompile, false, Normal, nullptr) \
+    v(bool, b3AlwaysFailsBeforeLink, false, Normal, nullptr) \
+    v(bool, ftlCrashes, false, Normal, nullptr) /* fool-proof way of checking that you ended up in the FTL. ;-) */\
+    v(bool, clobberAllRegsInFTLICSlowPath, !ASSERT_DISABLED, Normal, nullptr) \
+    v(bool, useAccessInlining, true, Normal, nullptr) \
+    v(unsigned, maxAccessVariantListSize, 13, Normal, nullptr) \
+    v(unsigned, megamorphicLoadCost, 999, Normal, nullptr) /* This used to be 10, but we're temporarily testing what happens when the feature is disabled. */\
+    v(bool, usePolyvariantDevirtualization, true, Normal, nullptr) \
+    v(bool, usePolymorphicAccessInlining, true, Normal, nullptr) \
+    v(bool, usePolymorphicCallInlining, true, Normal, nullptr) \
+    v(bool, usePolymorphicCallInliningForNonStubStatus, false, Normal, nullptr) \
+    v(unsigned, maxPolymorphicCallVariantListSize, 15, Normal, nullptr) \
+    v(unsigned, maxPolymorphicCallVariantListSizeForTopTier, 5, Normal, nullptr) \
+    v(unsigned, maxPolymorphicCallVariantsForInlining, 5, Normal, nullptr) \
+    v(unsigned, frequentCallThreshold, 2, Normal, nullptr) \
+    v(double, minimumCallToKnownRate, 0.51, Normal, nullptr) \
+    v(bool, createPreHeaders, true, Normal, nullptr) \
+    v(bool, useMovHintRemoval, true, Normal, nullptr) \
+    v(bool, usePutStackSinking, true, Normal, nullptr) \
+    v(bool, useObjectAllocationSinking, true, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useConcurrentJIT, 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) \
</del><ins>+    v(bool, useConcurrentJIT, true, Normal, &quot;allows the DFG / FTL compilation in threads other than the executing JS thread&quot;) \
+    v(unsigned, numberOfDFGCompilerThreads, computeNumberOfWorkerThreads(2, 2) - 1, Normal, nullptr) \
+    v(unsigned, numberOfFTLCompilerThreads, computeNumberOfWorkerThreads(8, 2) - 1, Normal, nullptr) \
+    v(int32, priorityDeltaOfDFGCompilerThreads, computePriorityDeltaOfWorkerThreads(-1, 0), Normal, nullptr) \
+    v(int32, priorityDeltaOfFTLCompilerThreads, computePriorityDeltaOfWorkerThreads(-2, 0), Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useProfiler, false, nullptr) \
-    v(bool, disassembleBaselineForProfiler, true, nullptr) \
</del><ins>+    v(bool, useProfiler, false, Normal, nullptr) \
+    v(bool, disassembleBaselineForProfiler, true, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useArchitectureSpecificOptimizations, true, nullptr) \
</del><ins>+    v(bool, useArchitectureSpecificOptimizations, true, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, breakOnThrow, false, nullptr) \
</del><ins>+    v(bool, breakOnThrow, false, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, maximumOptimizationCandidateInstructionCount, 100000, nullptr) \
</del><ins>+    v(unsigned, maximumOptimizationCandidateInstructionCount, 100000, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 180, nullptr) \
-    v(unsigned, maximumFunctionForClosureCallInlineCandidateInstructionCount, 100, nullptr) \
-    v(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 100, nullptr) \
</del><ins>+    v(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 180, Normal, nullptr) \
+    v(unsigned, maximumFunctionForClosureCallInlineCandidateInstructionCount, 100, Normal, nullptr) \
+    v(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 100, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, maximumFTLCandidateInstructionCount, 20000, nullptr) \
</del><ins>+    v(unsigned, maximumFTLCandidateInstructionCount, 20000, Normal, 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, &quot;maximum allowed inlining depth.  Depth of 1 means no inlining&quot;) \
-    v(unsigned, maximumInliningRecursion, 2, nullptr) \
</del><ins>+    v(unsigned, maximumInliningDepth, 5, Normal, &quot;maximum allowed inlining depth.  Depth of 1 means no inlining&quot;) \
+    v(unsigned, maximumInliningRecursion, 2, Normal, 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, nullptr) \
</del><ins>+    v(unsigned, maximumInliningCallerSize, 10000, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, maximumVarargsForInlining, 100, nullptr) \
</del><ins>+    v(unsigned, maximumVarargsForInlining, 100, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, usePolyvariantCallInlining, true, nullptr) \
-    v(bool, usePolyvariantByIdInlining, true, nullptr) \
</del><ins>+    v(bool, usePolyvariantCallInlining, true, Normal, nullptr) \
+    v(bool, usePolyvariantByIdInlining, true, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useMaximalFlushInsertionPhase, false, &quot;Setting to true allows the DFG's MaximalFlushInsertionPhase to run.&quot;) \
</del><ins>+    v(bool, useMaximalFlushInsertionPhase, false, Normal, &quot;Setting to true allows the DFG's MaximalFlushInsertionPhase to run.&quot;) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, maximumBinaryStringSwitchCaseLength, 50, nullptr) \
-    v(unsigned, maximumBinaryStringSwitchTotalLength, 2000, nullptr) \
</del><ins>+    v(unsigned, maximumBinaryStringSwitchCaseLength, 50, Normal, nullptr) \
+    v(unsigned, maximumBinaryStringSwitchTotalLength, 2000, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(double, jitPolicyScale, 1.0, &quot;scale JIT thresholds to this specified ratio between 0.0 (compile ASAP) and 1.0 (compile like normal).&quot;) \
-    v(bool, forceEagerCompilation, false, nullptr) \
-    v(int32, thresholdForJITAfterWarmUp, 500, nullptr) \
-    v(int32, thresholdForJITSoon, 100, nullptr) \
</del><ins>+    v(double, jitPolicyScale, 1.0, Normal, &quot;scale JIT thresholds to this specified ratio between 0.0 (compile ASAP) and 1.0 (compile like normal).&quot;) \
+    v(bool, forceEagerCompilation, false, Normal, nullptr) \
+    v(int32, thresholdForJITAfterWarmUp, 500, Normal, nullptr) \
+    v(int32, thresholdForJITSoon, 100, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    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) \
</del><ins>+    v(int32, thresholdForOptimizeAfterWarmUp, 1000, Normal, nullptr) \
+    v(int32, thresholdForOptimizeAfterLongWarmUp, 1000, Normal, nullptr) \
+    v(int32, thresholdForOptimizeSoon, 1000, Normal, nullptr) \
+    v(int32, executionCounterIncrementForLoop, 1, Normal, nullptr) \
+    v(int32, executionCounterIncrementForEntry, 15, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    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) \
</del><ins>+    v(int32, thresholdForFTLOptimizeAfterWarmUp, 100000, Normal, nullptr) \
+    v(int32, thresholdForFTLOptimizeSoon, 1000, Normal, nullptr) \
+    v(int32, ftlTierUpCounterIncrementForLoop, 1, Normal, nullptr) \
+    v(int32, ftlTierUpCounterIncrementForReturn, 15, Normal, nullptr) \
+    v(unsigned, ftlOSREntryFailureCountForReoptimization, 15, Normal, nullptr) \
+    v(unsigned, ftlOSREntryRetryThreshold, 100, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(int32, evalThresholdMultiplier, 10, nullptr) \
-    v(unsigned, maximumEvalCacheableSourceLength, 256, nullptr) \
</del><ins>+    v(int32, evalThresholdMultiplier, 10, Normal, nullptr) \
+    v(unsigned, maximumEvalCacheableSourceLength, 256, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, randomizeExecutionCountsBetweenCheckpoints, false, nullptr) \
-    v(int32, maximumExecutionCountsBetweenCheckpointsForBaseline, 1000, nullptr) \
-    v(int32, maximumExecutionCountsBetweenCheckpointsForUpperTiers, 50000, nullptr) \
</del><ins>+    v(bool, randomizeExecutionCountsBetweenCheckpoints, false, Normal, nullptr) \
+    v(int32, maximumExecutionCountsBetweenCheckpointsForBaseline, 1000, Normal, nullptr) \
+    v(int32, maximumExecutionCountsBetweenCheckpointsForUpperTiers, 50000, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, likelyToTakeSlowCaseMinimumCount, 20, nullptr) \
-    v(unsigned, couldTakeSlowCaseMinimumCount, 10, nullptr) \
</del><ins>+    v(unsigned, likelyToTakeSlowCaseMinimumCount, 20, Normal, nullptr) \
+    v(unsigned, couldTakeSlowCaseMinimumCount, 10, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, osrExitCountForReoptimization, 100, nullptr) \
-    v(unsigned, osrExitCountForReoptimizationFromLoop, 5, nullptr) \
</del><ins>+    v(unsigned, osrExitCountForReoptimization, 100, Normal, nullptr) \
+    v(unsigned, osrExitCountForReoptimizationFromLoop, 5, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, reoptimizationRetryCounterMax, 0, nullptr)  \
</del><ins>+    v(unsigned, reoptimizationRetryCounterMax, 0, Normal, nullptr)  \
</ins><span class="cx">     \
</span><del>-    v(unsigned, minimumOptimizationDelay, 1, nullptr) \
-    v(unsigned, maximumOptimizationDelay, 5, nullptr) \
-    v(double, desiredProfileLivenessRate, 0.75, nullptr) \
-    v(double, desiredProfileFullnessRate, 0.35, nullptr) \
</del><ins>+    v(unsigned, minimumOptimizationDelay, 1, Normal, nullptr) \
+    v(unsigned, maximumOptimizationDelay, 5, Normal, nullptr) \
+    v(double, desiredProfileLivenessRate, 0.75, Normal, nullptr) \
+    v(double, desiredProfileFullnessRate, 0.35, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(double, doubleVoteRatioForDoubleFormat, 2, nullptr) \
-    v(double, structureCheckVoteRatioForHoisting, 1, nullptr) \
-    v(double, checkArrayVoteRatioForHoisting, 1, nullptr) \
</del><ins>+    v(double, doubleVoteRatioForDoubleFormat, 2, Normal, nullptr) \
+    v(double, structureCheckVoteRatioForHoisting, 1, Normal, nullptr) \
+    v(double, checkArrayVoteRatioForHoisting, 1, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    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;) \
</del><ins>+    v(unsigned, minimumNumberOfScansBetweenRebalance, 100, Normal, nullptr) \
+    v(unsigned, numberOfGCMarkers, computeNumberOfGCMarkers(7), Normal, nullptr) \
+    v(unsigned, opaqueRootMergeThreshold, 1000, Normal, nullptr) \
+    v(double, minHeapUtilization, 0.8, Normal, nullptr) \
+    v(double, minCopiedBlockUtilization, 0.9, Normal, nullptr) \
+    v(double, minMarkedBlockUtilization, 0.9, Normal, nullptr) \
+    v(unsigned, slowPathAllocsBetweenGCs, 0, Normal, &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, nullptr) \
-    v(double, percentCPUPerMBForEdenTimer, 0.0025, nullptr) \
-    v(double, collectionTimerMaxPercentCPU, 0.05, nullptr) \
</del><ins>+    v(double, percentCPUPerMBForFullTimer, 0.0003125, Normal, nullptr) \
+    v(double, percentCPUPerMBForEdenTimer, 0.0025, Normal, nullptr) \
+    v(double, collectionTimerMaxPercentCPU, 0.05, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, forceWeakRandomSeed, false, nullptr) \
-    v(unsigned, forcedWeakRandomSeed, 0, nullptr) \
</del><ins>+    v(bool, forceWeakRandomSeed, false, Normal, nullptr) \
+    v(unsigned, forcedWeakRandomSeed, 0, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useZombieMode, false, &quot;debugging option to scribble over dead objects with 0xdeadbeef&quot;) \
-    v(bool, useImmortalObjects, false, &quot;debugging option to keep all objects alive forever&quot;) \
-    v(bool, dumpObjectStatistics, false, nullptr) \
</del><ins>+    v(bool, useZombieMode, false, Normal, &quot;debugging option to scribble over dead objects with 0xdeadbeef&quot;) \
+    v(bool, useImmortalObjects, false, Normal, &quot;debugging option to keep all objects alive forever&quot;) \
+    v(bool, dumpObjectStatistics, false, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(gcLogLevel, logGC, GCLogging::None, &quot;debugging option to log GC activity (0 = None, 1 = Basic, 2 = Verbose)&quot;) \
-    v(bool, useGC, true, nullptr) \
-    v(bool, gcAtEnd, false, &quot;If true, the jsc CLI will do a GC before exiting&quot;) \
-    v(bool, forceGCSlowPaths, false, &quot;If true, we will force all JIT fast allocations down their slow paths.&quot;)\
-    v(unsigned, gcMaxHeapSize, 0, nullptr) \
-    v(unsigned, forceRAMSize, 0, nullptr) \
-    v(bool, recordGCPauseTimes, false, nullptr) \
-    v(bool, logHeapStatisticsAtExit, false, nullptr) \
</del><ins>+    v(gcLogLevel, logGC, GCLogging::None, Normal, &quot;debugging option to log GC activity (0 = None, 1 = Basic, 2 = Verbose)&quot;) \
+    v(bool, useGC, true, Normal, nullptr) \
+    v(bool, gcAtEnd, false, Normal, &quot;If true, the jsc CLI will do a GC before exiting&quot;) \
+    v(bool, forceGCSlowPaths, false, Normal, &quot;If true, we will force all JIT fast allocations down their slow paths.&quot;)\
+    v(unsigned, gcMaxHeapSize, 0, Normal, nullptr) \
+    v(unsigned, forceRAMSize, 0, Normal, nullptr) \
+    v(bool, recordGCPauseTimes, false, Normal, nullptr) \
+    v(bool, logHeapStatisticsAtExit, false, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useTypeProfiler, false, nullptr) \
-    v(bool, useControlFlowProfiler, false, nullptr) \
</del><ins>+    v(bool, useTypeProfiler, false, Normal, nullptr) \
+    v(bool, useControlFlowProfiler, false, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useSamplingProfiler, false, nullptr) \
-    v(unsigned, sampleInterval, 1000, &quot;Time between stack traces in microseconds.&quot;) \
-    v(bool, collectSamplingProfilerDataForJSCShell, false, &quot;This corresponds to the JSC shell's --sample option.&quot;) \
</del><ins>+    v(bool, useSamplingProfiler, false, Normal, nullptr) \
+    v(unsigned, sampleInterval, 1000, Normal, &quot;Time between stack traces in microseconds.&quot;) \
+    v(bool, collectSamplingProfilerDataForJSCShell, false, Normal, &quot;This corresponds to the JSC shell's --sample option.&quot;) \
</ins><span class="cx">     \
</span><del>-    v(bool, alwaysGeneratePCToCodeOriginMap, false, &quot;This will make sure we always generate a PCToCodeOriginMap for JITed code.&quot;) \
</del><ins>+    v(bool, alwaysGeneratePCToCodeOriginMap, false, Normal, &quot;This will make sure we always generate a PCToCodeOriginMap for JITed code.&quot;) \
</ins><span class="cx">     \
</span><del>-    v(bool, verifyHeap, false, nullptr) \
-    v(unsigned, numberOfGCCyclesToRecordForVerification, 3, nullptr) \
</del><ins>+    v(bool, verifyHeap, false, Normal, nullptr) \
+    v(unsigned, numberOfGCCyclesToRecordForVerification, 3, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useExceptionFuzz, false, nullptr) \
-    v(unsigned, fireExceptionFuzzAt, 0, nullptr) \
-    v(bool, validateDFGExceptionHandling, false, &quot;Causes the DFG to emit code validating exception handling for each node that can exit&quot;) /* This is true by default on Debug builds */\
</del><ins>+    v(bool, useExceptionFuzz, false, Normal, nullptr) \
+    v(unsigned, fireExceptionFuzzAt, 0, Normal, nullptr) \
+    v(bool, validateDFGExceptionHandling, false, Normal, &quot;Causes the DFG to emit code validating exception handling for each node that can exit&quot;) /* This is true by default on Debug builds */\
</ins><span class="cx">     \
</span><del>-    v(bool, useExecutableAllocationFuzz, false, nullptr) \
-    v(unsigned, fireExecutableAllocationFuzzAt, 0, nullptr) \
-    v(unsigned, fireExecutableAllocationFuzzAtOrAfter, 0, nullptr) \
-    v(bool, verboseExecutableAllocationFuzz, false, nullptr) \
</del><ins>+    v(bool, useExecutableAllocationFuzz, false, Normal, nullptr) \
+    v(unsigned, fireExecutableAllocationFuzzAt, 0, Normal, nullptr) \
+    v(unsigned, fireExecutableAllocationFuzzAtOrAfter, 0, Normal, nullptr) \
+    v(bool, verboseExecutableAllocationFuzz, false, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useOSRExitFuzz, false, nullptr) \
-    v(unsigned, fireOSRExitFuzzAtStatic, 0, nullptr) \
-    v(unsigned, fireOSRExitFuzzAt, 0, nullptr) \
-    v(unsigned, fireOSRExitFuzzAtOrAfter, 0, nullptr) \
</del><ins>+    v(bool, useOSRExitFuzz, false, Normal, nullptr) \
+    v(unsigned, fireOSRExitFuzzAtStatic, 0, Normal, nullptr) \
+    v(unsigned, fireOSRExitFuzzAt, 0, Normal, nullptr) \
+    v(unsigned, fireOSRExitFuzzAtOrAfter, 0, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, logB3PhaseTimes, false, nullptr) \
-    v(double, rareBlockPenalty, 0.001, nullptr) \
-    v(bool, airSpillsEverything, false, nullptr) \
-    v(bool, logAirRegisterPressure, false, nullptr) \
-    v(unsigned, maxB3TailDupBlockSize, 3, nullptr) \
-    v(unsigned, maxB3TailDupBlockSuccessors, 3, nullptr) \
</del><ins>+    v(bool, logB3PhaseTimes, false, Normal, nullptr) \
+    v(double, rareBlockPenalty, 0.001, Normal, nullptr) \
+    v(bool, airSpillsEverything, false, Normal, nullptr) \
+    v(bool, logAirRegisterPressure, false, Normal, nullptr) \
+    v(unsigned, maxB3TailDupBlockSize, 3, Normal, nullptr) \
+    v(unsigned, maxB3TailDupBlockSuccessors, 3, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, useDollarVM, false, &quot;installs the $vm debugging tool in global objects&quot;) \
-    v(optionString, functionOverrides, nullptr, &quot;file with debugging overrides for function bodies&quot;) \
</del><ins>+    v(bool, useDollarVM, false, Restricted, &quot;installs the $vm debugging tool in global objects&quot;) \
+    v(optionString, functionOverrides, nullptr, Restricted, &quot;file with debugging overrides for function bodies&quot;) \
</ins><span class="cx">     \
</span><del>-    v(unsigned, watchdog, 0, &quot;watchdog timeout (0 = Disabled, N = a timeout period of N milliseconds)&quot;) \
</del><ins>+    v(unsigned, watchdog, 0, Normal, &quot;watchdog timeout (0 = Disabled, N = a timeout period of N milliseconds)&quot;) \
</ins><span class="cx">     \
</span><del>-    v(bool, useICStats, false, nullptr) \
</del><ins>+    v(bool, useICStats, false, Normal, nullptr) \
</ins><span class="cx">     \
</span><del>-    v(bool, dumpModuleRecord, false, nullptr) \
-    v(bool, dumpModuleLoadingState, false, nullptr) \
-    v(bool, exposeInternalModuleLoader, false, &quot;expose the internal module loader object to the global space for debugging&quot;) \
</del><ins>+    v(bool, dumpModuleRecord, false, Normal, nullptr) \
+    v(bool, dumpModuleLoadingState, false, Normal, nullptr) \
+    v(bool, exposeInternalModuleLoader, false, Normal, &quot;expose the internal module loader object to the global space for debugging&quot;) \
</ins><span class="cx">     \
</span><del>-    v(bool, useSuperSampler, false, nullptr)
</del><ins>+    v(bool, useSuperSampler, false, Normal, nullptr)
</ins><span class="cx"> 
</span><span class="cx"> enum OptionEquivalence {
</span><span class="cx">     SameOption,
</span><span class="lines">@@ -407,14 +407,19 @@
</span><span class="cx">         All,
</span><span class="cx">         Verbose
</span><span class="cx">     };
</span><del>-    
</del><ins>+
+    enum class Availability {
+        Normal = 0,
+        Restricted
+    };
+
</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_, description_) \
</del><ins>+#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
</ins><span class="cx">         name_##ID,
</span><span class="cx">         JSC_OPTIONS(FOR_EACH_OPTION)
</span><span class="cx"> #undef FOR_EACH_OPTION
</span><span class="lines">@@ -447,7 +452,7 @@
</span><span class="cx">     JS_EXPORT_PRIVATE static void ensureOptionsAreCoherent();
</span><span class="cx"> 
</span><span class="cx">     // Declare accessors for each option:
</span><del>-#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
</del><ins>+#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
</ins><span class="cx">     ALWAYS_INLINE static type_&amp; name_() { return s_options[name_##ID].type_##Val; } \
</span><span class="cx">     ALWAYS_INLINE static type_&amp; name_##Default() { return s_defaultOptions[name_##ID].type_##Val; }
</span><span class="cx"> 
</span><span class="lines">@@ -471,6 +476,7 @@
</span><span class="cx">         const char* name;
</span><span class="cx">         const char* description;
</span><span class="cx">         Type type;
</span><ins>+        Availability availability;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     Options();
</span><span class="lines">@@ -513,6 +519,7 @@
</span><span class="cx">     const char* name() const;
</span><span class="cx">     const char* description() const;
</span><span class="cx">     Options::Type type() const;
</span><ins>+    Options::Availability availability() const;
</ins><span class="cx">     bool isOverridden() const;
</span><span class="cx">     const Option defaultOption() const;
</span><span class="cx">     
</span><span class="lines">@@ -551,6 +558,11 @@
</span><span class="cx">     return Options::s_optionsInfo[m_id].type;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline Options::Availability Option::availability() const
+{
+    return Options::s_optionsInfo[m_id].availability;
+}
+
</ins><span class="cx"> inline bool Option::isOverridden() const
</span><span class="cx"> {
</span><span class="cx">     return *this != defaultOption();
</span></span></pre>
</div>
</div>

</body>
</html>