diff options
author | 2021-01-30 02:03:29 +0000 | |
---|---|---|
committer | 2021-02-17 15:05:02 +0000 | |
commit | 3dba023d4fb47882fa215715c196cfa3be30c098 (patch) | |
tree | da22f82b7cde87f37100f715a0e05f332b377f73 /libartbase/base/flags.cc | |
parent | 381d35c1b01401e193544f679bfaf4f5c197f7cd (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.cc')
-rw-r--r-- | libartbase/base/flags.cc | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/libartbase/base/flags.cc b/libartbase/base/flags.cc new file mode 100644 index 0000000000..079694c835 --- /dev/null +++ b/libartbase/base/flags.cc @@ -0,0 +1,115 @@ +/* + * 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. + */ + +#include "flags.h" + +#include <algorithm> + +#include "android-base/parsebool.h" +#include "android-base/properties.h" + +#pragma clang diagnostic push +#pragma clang diagnostic error "-Wconversion" + +namespace { +constexpr const char* kServerConfigurableFlagsPrefix = "persist.device_config.runtime_native_boot."; +constexpr const char* kUndefinedValue = "UNSET"; + +// The various ParseValue functions store the parsed value into *destination. If parsing fails for +// some reason, ParseValue makes no changes to *destination. + +void ParseValue(const std::string_view value, std::optional<bool>* destination) { + switch (::android::base::ParseBool(value)) { + case ::android::base::ParseBoolResult::kError: + return; + case ::android::base::ParseBoolResult::kTrue: + *destination = true; + return; + case ::android::base::ParseBoolResult::kFalse: + *destination = false; + return; + } +} + +} // namespace + +namespace art { + +template <> +std::forward_list<FlagBase*> FlagBase::ALL_FLAGS{}; + +// gFlags must be defined after FlagBase::ALL_FLAGS so the constructors run in the right order. +Flags gFlags; + +template <typename Value> +Flag<Value>::Flag(const std::string& name, Value default_value) : default_{default_value} { + command_line_argument_name_ = "-X" + name + "=_"; + std::replace(command_line_argument_name_.begin(), command_line_argument_name_.end(), '.', '-'); + system_property_name_ = "dalvik.vm." + name; + + std::string server_setting = name; + std::replace(server_setting.begin(), server_setting.end(), '.', '_'); + std::replace(server_setting.begin(), server_setting.end(), '-', '_'); + server_setting_name_ = kServerConfigurableFlagsPrefix + server_setting; + + ALL_FLAGS.push_front(this); +} + +template <typename Value> +Value Flag<Value>::operator()() { + if (!initialized_) { + Reload(); + } + if (from_command_line_.has_value()) { + return from_command_line_.value(); + } + if (from_server_setting_.has_value()) { + return from_server_setting_.value(); + } + if (from_system_property_.has_value()) { + return from_system_property_.value(); + } + return default_; +} + +template <typename Value> +void Flag<Value>::Reload() { + // Check system properties and server configured value. + from_system_property_ = std::nullopt; + const std::string sysprop = ::android::base::GetProperty(system_property_name_, kUndefinedValue); + if (sysprop != kUndefinedValue) { + ParseValue(sysprop, &from_system_property_); + } + + // Check the server-side configuration + from_server_setting_ = std::nullopt; + // Read the device_config setting directly to avoid a dependency on server_configurable_flags. + const std::string server_config = + ::android::base::GetProperty(server_setting_name_, kUndefinedValue); + if (server_config != kUndefinedValue) { + ParseValue(server_config, &from_server_setting_); + } + + // Command line argument cannot be reloaded. It must be set during initial command line parsing. + + initialized_ = true; +} + +template class Flag<bool>; + +} // namespace art + +#pragma clang diagnostic pop // -Wconversion |