summaryrefslogtreecommitdiff
path: root/libartbase/base/flags.h
diff options
context:
space:
mode:
author Eric Holk <eholk@google.com> 2021-01-30 02:03:29 +0000
committer Treehugger Robot <treehugger-gerrit@google.com> 2021-02-17 15:05:02 +0000
commit3dba023d4fb47882fa215715c196cfa3be30c098 (patch)
treeda22f82b7cde87f37100f715a0e05f332b377f73 /libartbase/base/flags.h
parent381d35c1b01401e193544f679bfaf4f5c197f7cd (diff)
Add a server-configurable flags API
Adds a new set of flags that can be set by the command line, server configuration, or system properties. These flags can be used to enable or disable certain features or otherwise change their behavior. The flexible configuration options facilitate both development and also experimentation. As an example of their use, this CL also moves the -Xwrite-metrics-to-log command line option to the flags system instead. Future work will migrate the rest of the metrics settings. Test: ./test/run-test --host --jit 2232-write-metrics-to-log Bug: 175050458 Change-Id: I1ef37e7d355204a3172b7aa5c0baa4cbd8c7076b
Diffstat (limited to 'libartbase/base/flags.h')
-rw-r--r--libartbase/base/flags.h150
1 files changed, 150 insertions, 0 deletions
diff --git a/libartbase/base/flags.h b/libartbase/base/flags.h
new file mode 100644
index 0000000000..5bd18e5328
--- /dev/null
+++ b/libartbase/base/flags.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_LIBARTBASE_BASE_FLAGS_H_
+#define ART_LIBARTBASE_BASE_FLAGS_H_
+
+#include <forward_list>
+#include <optional>
+#include <string>
+#include <variant>
+
+// This file defines a set of flags that can be used to enable/disable features within ART or
+// otherwise tune ART's behavior. Flags can be set through command line options, server side
+// configuration, system properties, or default values. This flexibility enables easier development
+// and also larger experiments.
+//
+// The flags are defined in the Flags struct near the bottom of the file. To define a new flag, add
+// a Flag field to the struct. Then to read the value of the flag, use gFlag.MyNewFlag().
+
+#pragma clang diagnostic push
+#pragma clang diagnostic error "-Wconversion"
+
+namespace art {
+
+// FlagMetaBase handles automatically adding flags to the command line parser. It is parameterized
+// by all supported flag types. In general, this should be treated as though it does not exist and
+// FlagBase, which is already specialized to the types we support, should be used instead.
+template <typename... T>
+class FlagMetaBase {
+ public:
+ virtual ~FlagMetaBase() {}
+
+ template <typename Builder>
+ static void AddFlagsToCmdlineParser(Builder* builder) {
+ for (auto* flag : ALL_FLAGS) {
+ // Each flag can return a pointer to where its command line value is stored. Because these can
+ // be different types, the return value comes as a variant. The cases list below contains a
+ // lambda that is specialized to handle each branch of the variant and call the correct
+ // methods on the command line parser builder.
+ FlagValuePointer location = flag->GetLocation();
+ auto cases = {[&]() {
+ if (std::holds_alternative<std::optional<T>*>(location)) {
+ builder = &builder->Define(flag->command_line_argument_name_.c_str())
+ .template WithType<T>()
+ .IntoLocation(std::get<std::optional<T>*>(location));
+ }
+ }...};
+ for (auto c : cases) {
+ c();
+ }
+ }
+ }
+
+ protected:
+ using FlagValuePointer = std::variant<std::optional<T>*...>;
+ static std::forward_list<FlagMetaBase<T...>*> ALL_FLAGS;
+
+ std::string command_line_argument_name_;
+ std::string system_property_name_;
+ std::string server_setting_name_;
+
+ virtual FlagValuePointer GetLocation() = 0;
+};
+
+using FlagBase = FlagMetaBase<bool>;
+
+template <>
+std::forward_list<FlagBase*> FlagBase::ALL_FLAGS;
+
+// This class defines a flag with a value of a particular type.
+template <typename Value>
+class Flag : public FlagBase {
+ public:
+ // Create a new Flag. The name parameter is used to generate the names from the various parameter
+ // sources. See the documentation on the Flags struct for an example.
+ explicit Flag(const std::string& name, Value default_value = {});
+ virtual ~Flag() {}
+
+ // Returns the value of the flag.
+ //
+ // The value returned will be the command line argument, if present, otherwise the
+ // server-configured value, if present, otherwise the system property value, if present, and
+ // finally, the default value.
+ Value operator()();
+
+ // Reload the server-configured value and system property values. In general this should not be
+ // used directly, but it can be used to support reloading the value without restarting the device.
+ void Reload();
+
+ protected:
+ FlagValuePointer GetLocation() override { return &from_command_line_; }
+
+ private:
+ bool initialized_{false};
+ const Value default_;
+ std::optional<Value> from_command_line_;
+ std::optional<Value> from_system_property_;
+ std::optional<Value> from_server_setting_;
+};
+
+// This struct contains the list of ART flags. Flags are parameterized by the type of value they
+// support (bool, int, string, etc.). In addition to field name, flags have a name for the parameter
+// as well.
+//
+// Example:
+//
+// Flag<bool> WriteMetricsToLog{"metrics.write-to-log", false};
+//
+// This creates a boolean flag that can be read through gFlags.WriteMetricsToLog(). The default
+// value is false. Note that the default value can be left unspecified, in which the value of the
+// type's default constructor will be used.
+//
+// The flag can be set through the following generated means:
+//
+// Command Line:
+//
+// -Xmetrics-write-to-log=true
+//
+// Server Side Configuration:
+//
+// runtime_native_boot.metrics_write_to_log
+//
+// System Property:
+//
+// setprop dalvik.vm.metrics.write-to-log true
+struct Flags {
+ Flag<bool> WriteMetricsToLog{"metrics.write-to-log", false};
+};
+
+// This is the actual instance of all the flags.
+extern Flags gFlags;
+
+} // namespace art
+
+#pragma clang diagnostic pop // -Wconversion
+
+#endif // ART_LIBARTBASE_BASE_FLAGS_H_