Title: [295656] trunk/Source
Revision
295656
Author
[email protected]
Date
2022-06-17 21:26:27 -0700 (Fri, 17 Jun 2022)

Log Message

Enhance Options::useOSLog to accept an os log type value.
https://bugs.webkit.org/show_bug.cgi?id=241719

Reviewed by Yusuke Suzuki.

This option only applies to OS(DARWIN).

For example, we can now use any of these:
    --useOSLog=default    // logs to OS_LOG_TYPE_DEFAULT
    --useOSLog=info       // logs to OS_LOG_TYPE_INFO
    --useOSLog=debug      // logs to OS_LOG_TYPE_DEBUG
    --useOSLog=error      // logs to OS_LOG_TYPE_ERROR
    --useOSLog=fault.     // logs to OS_LOG_TYPE_FAULT

We can still use --useOSLog=0 or false (which means do the normal dataLog) and
--useOSLog=1 or true (which means dataLog to OS_LOG_TYPE_ERROR).

Previously, when we specify --useOSLog=1, we will log to OS_LOG_TYPE_INFO.  This
has been a source of friction in usage because no one ever remembers that we need
to enable OS_LOG_TYPE_INFO in the log stream to see this logging.  Instead,
--useOSLog=1 will now log to OS_LOG_TYPE_ERROR, which ensures that logging will
show up in log stream.  This is fine to do because the --useOSLog=1 option
indicates that the client really wants to see the logs.  Otherwise, the client
can use one of the other os log types if they want something different.

Secondly, because --useOSLog=1 indicates that the client really wants to see the
logs, logging to OS_LOG_TYPE_ERROR ensures that the logging is flushed to the
file system instead of sitting in a memory buffer, and potentially not showing up
in the log stream.

Also made the following changes:

1. Changed Options::dumpAllOptions to use dataLog instead of printing to stderr.
   This allows its output to be diverted using Options::useOSLog as well.

2. Moved the call to WTF::setDataFile from Options::initialize to
   Options::recomputeDependentOptions.  This allows Options::useOSLog to be
   specified using the jsc shell's --useOSLog argument instead of requiring it
   to be specified using the JSC_useOSLog env var in order to work.

   To enable this, added a useOSLogOptionHasChanged flag that can be set in
   the parser of the Options::useOSLog option.  This prevents
   Options::recomputeDependentOptions from calling initializeDatafileToUseOSLog()
   repeatedly every time any option is set.

3. Added initializeDatafileToUseOSLog() which now instantiates the appropriate
   OSLogPrintStream and sets it using WTF::setDataFile.

   initializeDatafileToUseOSLog() also asserts that it is called at most once.

4. Added an assertion in WTF::setDataFile() to ensure that it is not called more
   than once.

5. #if out the calls to overrideAliasedOptionWithHeuristic() on PLATFORM(COCOA).
   They are not needed because, on PLATFORM(COCOA), we already iterate through
   every env var starting with JSC_ and call Options::setOption() on it.
   Options::setOption() will also handle aliased options.

For reference, this is an example of how we can view the logs using log stream
once --useOSLog=1 is used:

    # log stream --predicate 'category == "DataLog"'

* Source/_javascript_Core/API/glib/JSCOptions.cpp:
* Source/_javascript_Core/jsc.cpp:
(CommandLine::parseArguments):
* Source/_javascript_Core/runtime/Options.cpp:
(JSC::parse):
(JSC::asDarwinOSLogType):
(JSC::initializeDatafileToUseOSLog):
(JSC::asString):
(JSC::Options::recomputeDependentOptions):
(JSC::Options::initialize):
(JSC::Options::setOptionWithoutAlias):
(JSC::Options::dumpAllOptions):
(JSC::OptionReader::Option::initValue):
(JSC::OptionReader::Option::dump const):
(JSC::OptionReader::Option::operator== const):
* Source/_javascript_Core/runtime/Options.h:
* Source/_javascript_Core/runtime/OptionsList.h:
* Source/WTF/wtf/DataLog.cpp:
(WTF::setDataFile):

Canonical link: https://commits.webkit.org/251661@main

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/API/glib/JSCOptions.cpp (295655 => 295656)


--- trunk/Source/_javascript_Core/API/glib/JSCOptions.cpp	2022-06-18 03:57:40 UTC (rev 295655)
+++ trunk/Source/_javascript_Core/API/glib/JSCOptions.cpp	2022-06-18 04:26:27 UTC (rev 295656)
@@ -164,6 +164,20 @@
     }
 }
 
+static bool valueFromGValue(const GValue* gValue, OSLogType& value)
+{
+    unsigned optionValue = g_value_get_uint(gValue);
+    if (optionValue > static_cast<unsigned>(OSLogType::Fault))
+        return false;
+    value = static_cast<OSLogType>(optionValue);
+    return true;
+}
+
+static void valueToGValue(OSLogType value, GValue* gValue)
+{
+    g_value_set_uint(gValue, static_cast<unsigned>(value));
+}
+
 static gboolean jscOptionsSetValue(const char* option, const GValue* value)
 {
 #define SET_OPTION_VALUE(type_, name_, defaultValue_, availability_, description_) \
@@ -569,6 +583,11 @@
     return JSC_OPTION_RANGE_STRING;
 }
 
+static JSCOptionType jscOptionsType(const OSLogType&)
+{
+    return JSC_OPTION_UINT;
+}
+
 /**
  * JSCOptionType:
  * @JSC_OPTION_BOOLEAN: A #gboolean option type.

Modified: trunk/Source/_javascript_Core/jsc.cpp (295655 => 295656)


--- trunk/Source/_javascript_Core/jsc.cpp	2022-06-18 03:57:40 UTC (rev 295655)
+++ trunk/Source/_javascript_Core/jsc.cpp	2022-06-18 04:26:27 UTC (rev 295656)
@@ -3684,7 +3684,7 @@
         const char* optionsTitle = (dumpOptionsLevel == JSC::Options::DumpLevel::Overridden)
             ? "Modified JSC runtime options:"
             : "All JSC runtime options:";
-        JSC::Options::dumpAllOptions(stderr, dumpOptionsLevel, optionsTitle);
+        JSC::Options::dumpAllOptions(dumpOptionsLevel, optionsTitle);
     }
     JSC::Options::ensureOptionsAreCoherent();
     if (needToExit)

Modified: trunk/Source/_javascript_Core/runtime/Options.cpp (295655 => 295656)


--- trunk/Source/_javascript_Core/runtime/Options.cpp	2022-06-18 03:57:40 UTC (rev 295655)
+++ trunk/Source/_javascript_Core/runtime/Options.cpp	2022-06-18 04:26:27 UTC (rev 295656)
@@ -58,6 +58,8 @@
 
 namespace JSC {
 
+bool useOSLogOptionHasChanged = false;
+
 template<typename T>
 std::optional<T> parse(const char* string);
 
@@ -146,6 +148,83 @@
     return std::nullopt;
 }
 
+template<>
+std::optional<OptionsStorage::OSLogType> parse(const char* string)
+{
+    std::optional<OptionsStorage::OSLogType> result;
+
+    if (equalLettersIgnoringASCIICase(string, "false"_s) || !strcmp(string, "0"))
+        result = OSLogType::None;
+    else if (equalLettersIgnoringASCIICase(string, "true"_s) || !strcmp(string, "1"))
+        result = OSLogType::Error;
+    else if (equalLettersIgnoringASCIICase(string, "default"_s))
+        result = OSLogType::Default;
+    else if (equalLettersIgnoringASCIICase(string, "info"_s))
+        result = OSLogType::Info;
+    else if (equalLettersIgnoringASCIICase(string, "debug"_s))
+        result = OSLogType::Debug;
+    else if (equalLettersIgnoringASCIICase(string, "error"_s))
+        result = OSLogType::Error;
+    else if (equalLettersIgnoringASCIICase(string, "fault"_s))
+        result = OSLogType::Fault;
+
+    if (result && result.value() != Options::useOSLog())
+        useOSLogOptionHasChanged = true;
+    return result;
+}
+
+#if OS(DARWIN)
+static os_log_type_t asDarwinOSLogType(OSLogType type)
+{
+    switch (type) {
+    case OSLogType::None:
+        RELEASE_ASSERT_NOT_REACHED();
+    case OSLogType::Default:
+        return OS_LOG_TYPE_DEFAULT;
+    case OSLogType::Info:
+        return OS_LOG_TYPE_INFO;
+    case OSLogType::Debug:
+        return OS_LOG_TYPE_DEBUG;
+    case OSLogType::Error:
+        return OS_LOG_TYPE_ERROR;
+    case OSLogType::Fault:
+        return OS_LOG_TYPE_FAULT;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return OS_LOG_TYPE_DEFAULT;
+}
+
+static void initializeDatafileToUseOSLog()
+{
+    static bool alreadyInitialized = false;
+    RELEASE_ASSERT(!alreadyInitialized);
+    WTF::setDataFile(OSLogPrintStream::open("com.apple._javascript_Core", "DataLog", asDarwinOSLogType(Options::useOSLog())));
+    alreadyInitialized = true;
+    // Make sure no one jumped here for nefarious reasons...
+    RELEASE_ASSERT(Options::useOSLog() != OSLogType::None);
+}
+#endif // OS(DARWIN)
+
+static const char* asString(OSLogType type)
+{
+    switch (type) {
+    case OSLogType::None:
+        return "none";
+    case OSLogType::Default:
+        return "default";
+    case OSLogType::Info:
+        return "info";
+    case OSLogType::Debug:
+        return "debug";
+    case OSLogType::Error:
+        return "error";
+    case OSLogType::Fault:
+        return "fault";
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
 bool Options::isAvailable(Options::ID id, Options::Availability availability)
 {
     if (availability == Availability::Restricted)
@@ -172,6 +251,8 @@
     return false;
 }
 
+#if !PLATFORM(COCOA)
+
 template<typename T>
 bool overrideOptionWithHeuristic(T& variable, Options::ID id, const char* name, Options::Availability availability)
 {
@@ -208,6 +289,8 @@
     return false;
 }
 
+#endif // !PLATFORM(COCOA)
+
 static unsigned computeNumberOfWorkerThreads(int maxNumberOfWorkerThreads, int minimum = 1)
 {
     int cpusToUse = std::min(kernTCSMAwareNumberOfProcessorCores(), maxNumberOfWorkerThreads);
@@ -575,6 +658,13 @@
         FOR_EACH_JSC_EXPERIMENTAL_OPTION(DISABLE_TIERS);
     }
 
+#if OS(DARWIN)
+    if (useOSLogOptionHasChanged) {
+        initializeDatafileToUseOSLog();
+        useOSLogOptionHasChanged = false;
+    }
+#endif
+
     if (Options::verboseVerifyGC())
         Options::verifyGC() = true;
 }
@@ -651,7 +741,6 @@
             overrideOptionWithHeuristic(name_(), name_##ID, "JSC_" #name_, Availability::availability_);
             FOR_EACH_JSC_OPTION(OVERRIDE_OPTION_WITH_HEURISTICS)
 #undef OVERRIDE_OPTION_WITH_HEURISTICS
-#endif // PLATFORM(COCOA)
 
 #define OVERRIDE_ALIASED_OPTION_WITH_HEURISTICS(aliasedName_, unaliasedName_, equivalence_) \
             overrideAliasedOptionWithHeuristic("JSC_" #aliasedName_);
@@ -658,6 +747,8 @@
             FOR_EACH_JSC_ALIASED_OPTION(OVERRIDE_ALIASED_OPTION_WITH_HEURISTICS)
 #undef OVERRIDE_ALIASED_OPTION_WITH_HEURISTICS
 
+#endif // PLATFORM(COCOA)
+
 #if 0
                 ; // Deconfuse editors that do auto indentation
 #endif
@@ -677,14 +768,6 @@
                 handleSignalsWithMach();
 #endif
 
-#if OS(DARWIN)
-            if (Options::useOSLog()) {
-                WTF::setDataFile(OSLogPrintStream::open("com.apple._javascript_Core", "DataLog", OS_LOG_TYPE_INFO));
-                // Make sure no one jumped here for nefarious reasons...
-                RELEASE_ASSERT(useOSLog());
-            }
-#endif
-
 #if ASAN_ENABLED && OS(LINUX) && ENABLE(WEBASSEMBLY_SIGNALING_MEMORY)
             if (Options::useWebAssemblyFastMemory() || Options::useSharedArrayBuffer()) {
                 const char* asanOptions = getenv("ASAN_OPTIONS");
@@ -853,7 +936,7 @@
         if (Availability::availability_ != Availability::Normal    \
             && !isAvailable(name_##ID, Availability::availability_)) \
             return false;                                          \
-        std::optional<OptionsStorage::type_> value;                     \
+        std::optional<OptionsStorage::type_> value;                \
         value = parse<OptionsStorage::type_>(valueStr);            \
         if (value) {                                               \
             name_() = value.value();                               \
@@ -946,11 +1029,11 @@
     dumpAllOptions(builder, DumpLevel::All, nullptr, " ", nullptr, nullptr, DontDumpDefaults);
 }
 
-void Options::dumpAllOptions(FILE* stream, DumpLevel level, const char* title)
+void Options::dumpAllOptions(DumpLevel level, const char* title)
 {
     StringBuilder builder;
     dumpAllOptions(builder, level, title, nullptr, "   ", "\n", DumpDefaults);
-    fprintf(stream, "%s", builder.toString().utf8().data());
+    dataLog(builder.toString().utf8().data());
 }
 
 struct OptionReader {
@@ -986,6 +1069,7 @@
             OptionRange m_optionRange;
             const char* m_optionString;
             GCLogging::Level m_gcLogLevel;
+            OSLogType m_osLogType;
         };
 
         friend struct OptionReader;
@@ -1087,6 +1171,9 @@
     case Options::Type::GCLogLevel:
         memcpy(&m_gcLogLevel, addressOfValue, sizeof(OptionsStorage::GCLogLevel));
         break;
+    case Options::Type::OSLogType:
+        memcpy(&m_osLogType, addressOfValue, sizeof(OptionsStorage::OSLogType));
+        break;
     }
 }
 
@@ -1117,6 +1204,9 @@
     case Options::Type::GCLogLevel:
         builder.append(GCLogging::levelAsString(m_gcLogLevel));
         break;
+    case Options::Type::OSLogType:
+        builder.append(asString(m_osLogType));
+        break;
     }
 }
 
@@ -1141,6 +1231,8 @@
             || (m_optionString && other.m_optionString && !strcmp(m_optionString, other.m_optionString));
     case Options::Type::GCLogLevel:
         return m_gcLogLevel == other.m_gcLogLevel;
+    case Options::Type::OSLogType:
+        return m_osLogType == other.m_osLogType;
     }
     return false;
 }

Modified: trunk/Source/_javascript_Core/runtime/Options.h (295655 => 295656)


--- trunk/Source/_javascript_Core/runtime/Options.h	2022-06-18 03:57:40 UTC (rev 295655)
+++ trunk/Source/_javascript_Core/runtime/Options.h	2022-06-18 04:26:27 UTC (rev 295656)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2022 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,7 +28,6 @@
 #include "JSCConfig.h"
 #include "JSExportMacros.h"
 #include <stdint.h>
-#include <stdio.h>
 #include <wtf/ForbidHeapAllocation.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/PrintStream.h>
@@ -73,6 +72,7 @@
         OptionRange,
         OptionString,
         GCLogLevel,
+        OSLogType,
     };
 
     class AllowUnfinalizedAccessScope {
@@ -113,7 +113,7 @@
     // (no spaces allowed) and set the specified option if appropriate.
     JS_EXPORT_PRIVATE static bool setOption(const char* arg);
 
-    JS_EXPORT_PRIVATE static void dumpAllOptions(FILE*, DumpLevel, const char* title = nullptr);
+    JS_EXPORT_PRIVATE static void dumpAllOptions(DumpLevel, const char* title = nullptr);
     JS_EXPORT_PRIVATE static void dumpAllOptionsInALine(StringBuilder&);
 
     JS_EXPORT_PRIVATE static void ensureOptionsAreCoherent();
@@ -158,7 +158,9 @@
 
     static bool setOptionWithoutAlias(const char* arg);
     static bool setAliasedOption(const char* arg);
+#if !PLATFORM(COCOA)
     static bool overrideAliasedOptionWithHeuristic(const char* name);
+#endif
 
     inline static void* addressOfOption(Options::ID);
     inline static void* addressOfOptionDefault(Options::ID);

Modified: trunk/Source/_javascript_Core/runtime/OptionsList.h (295655 => 295656)


--- trunk/Source/_javascript_Core/runtime/OptionsList.h	2022-06-18 03:57:40 UTC (rev 295655)
+++ trunk/Source/_javascript_Core/runtime/OptionsList.h	2022-06-18 04:26:27 UTC (rev 295656)
@@ -125,7 +125,7 @@
     \
     v(Bool, useIterationIntrinsics, true, Normal, nullptr) \
     \
-    v(Bool, useOSLog, false, Normal, "Log dataLog()s to os_log instead of stderr") \
+    v(OSLogType, useOSLog, OSLogType::None, Normal, "Log dataLog()s to os_log instead of stderr") \
     /* dumpDisassembly implies dumpDFGDisassembly. */ \
     v(Bool, needDisassemblySupport, false, Normal, nullptr) \
     v(Bool, dumpDisassembly, false, Normal, "dumps disassembly of all JIT compiled code upon compilation") \
@@ -650,6 +650,16 @@
     unsigned m_highLimit;
 };
 
+enum class OSLogType : uint8_t {
+    None,
+    // These corresponds to OS_LOG_TYPE_xxx.
+    Default,
+    Info,
+    Debug,
+    Error,
+    Fault
+};
+
 struct OptionsStorage {
     using Bool = bool;
     using Unsigned = unsigned;
@@ -659,6 +669,7 @@
     using OptionRange = JSC::OptionRange;
     using OptionString = const char*;
     using GCLogLevel = GCLogging::Level;
+    using OSLogType = JSC::OSLogType;
 
     bool allowUnfinalizedAccess;
     bool isFinalized;

Modified: trunk/Source/WTF/wtf/DataLog.cpp (295655 => 295656)


--- trunk/Source/WTF/wtf/DataLog.cpp	2022-06-18 03:57:40 UTC (rev 295655)
+++ trunk/Source/WTF/wtf/DataLog.cpp	2022-06-18 04:26:27 UTC (rev 295656)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2022 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
 
 #include <stdarg.h>
 #include <string.h>
+#include <wtf/Assertions.h>
 #include <wtf/FilePrintStream.h>
 #include <wtf/LockedPrintStream.h>
 #include <wtf/ProcessID.h>
@@ -160,6 +161,7 @@
 
 void setDataFile(std::unique_ptr<PrintStream>&& file)
 {
+    RELEASE_ASSERT(!s_file || reinterpret_cast<void*>(s_file) == &s_lockedFileData[0]);
     s_file = file.release();
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to