+void Options::dumpOption(DumpLevel level, OptionID id, FILE* stream, const char* header, const char* footer)
+{
+ if (id >= numberOfOptions)
+ return; // Illegal option.
+
+ Option option(id);
+ bool wasOverridden = option.isOverridden();
+ bool needsDescription = (level == DumpLevel::Verbose && option.description());
+
+ if (level == DumpLevel::Overridden && !wasOverridden)
+ return;
+
+ fprintf(stream, "%s%s: ", header, option.name());
+ option.dump(stream);
+
+ if (wasOverridden) {
+ fprintf(stream, " (default: ");
+ option.defaultOption().dump(stream);
+ fprintf(stream, ")");
+ }
+
+ if (needsDescription)
+ fprintf(stream, " ... %s", option.description());
+
+ fprintf(stream, "%s", footer);
+}
+
+void Options::ensureOptionsAreCoherent()
+{
+ bool coherent = true;
+ if (!(useLLInt() || useJIT())) {
+ coherent = false;
+ dataLog("INCOHERENT OPTIONS: at least one of useLLInt or useJIT must be true\n");
+ }
+ if (!coherent)
+ CRASH();
+}
+
+void Option::dump(FILE* stream) const
+{
+ switch (type()) {
+ case Options::Type::boolType:
+ fprintf(stream, "%s", m_entry.boolVal ? "true" : "false");
+ break;
+ case Options::Type::unsignedType:
+ fprintf(stream, "%u", m_entry.unsignedVal);
+ break;
+ case Options::Type::doubleType:
+ fprintf(stream, "%lf", m_entry.doubleVal);
+ break;
+ case Options::Type::int32Type:
+ fprintf(stream, "%d", m_entry.int32Val);
+ break;
+ case Options::Type::optionRangeType:
+ fprintf(stream, "%s", m_entry.optionRangeVal.rangeString());
+ break;
+ case Options::Type::optionStringType: {
+ const char* option = m_entry.optionStringVal;
+ if (!option)
+ option = "";
+ fprintf(stream, "%s", option);
+ break;
+ }
+ case Options::Type::gcLogLevelType: {
+ fprintf(stream, "%s", GCLogging::levelAsString(m_entry.gcLogLevelVal));
+ break;
+ }
+ }
+}
+
+bool Option::operator==(const Option& other) const
+{
+ switch (type()) {
+ case Options::Type::boolType:
+ return m_entry.boolVal == other.m_entry.boolVal;
+ case Options::Type::unsignedType:
+ return m_entry.unsignedVal == other.m_entry.unsignedVal;
+ case Options::Type::doubleType:
+ return (m_entry.doubleVal == other.m_entry.doubleVal) || (isnan(m_entry.doubleVal) && isnan(other.m_entry.doubleVal));
+ case Options::Type::int32Type:
+ return m_entry.int32Val == other.m_entry.int32Val;
+ case Options::Type::optionRangeType:
+ return m_entry.optionRangeVal.rangeString() == other.m_entry.optionRangeVal.rangeString();
+ case Options::Type::optionStringType:
+ return (m_entry.optionStringVal == other.m_entry.optionStringVal)
+ || (m_entry.optionStringVal && other.m_entry.optionStringVal && !strcmp(m_entry.optionStringVal, other.m_entry.optionStringVal));
+ case Options::Type::gcLogLevelType:
+ return m_entry.gcLogLevelVal == other.m_entry.gcLogLevelVal;
+ }
+ return false;
+}