summaryrefslogtreecommitdiff
path: root/libartbase/base/flags.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libartbase/base/flags.cc')
-rw-r--r--libartbase/base/flags.cc147
1 files changed, 147 insertions, 0 deletions
diff --git a/libartbase/base/flags.cc b/libartbase/base/flags.cc
new file mode 100644
index 0000000000..46de9c0821
--- /dev/null
+++ b/libartbase/base/flags.cc
@@ -0,0 +1,147 @@
+/*
+ * 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/parseint.h"
+#include "android-base/properties.h"
+
+#include "base/utils.h"
+
+#pragma clang diagnostic push
+#pragma clang diagnostic error "-Wconversion"
+
+namespace {
+constexpr const char* kPhenotypeFlagPrefix = "persist.device_config.runtime_native.";
+constexpr const char* kSysPropertyFlagPrefix = "dalvik.vm.";
+constexpr const char* kUndefinedValue = "";
+
+// 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;
+ }
+}
+
+void ParseValue(const std::string_view value, std::optional<int>* destination) {
+ int parsed_value = 0;
+ if (::android::base::ParseInt(std::string{value}, &parsed_value)) {
+ *destination = parsed_value;
+ }
+}
+
+void ParseValue(const std::string_view value, std::optional<std::string>* destination) {
+ *destination = value;
+}
+
+} // 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;
+
+static std::string GenerateCmdLineArgName(const std::string& name) {
+ std::string result = "-X" + name + ":_";
+ std::replace(result.begin(), result.end(), '.', '-');
+ return result;
+}
+
+static std::string GenerateSysPropName(const std::string& name) {
+ return kSysPropertyFlagPrefix + name;
+}
+
+static std::string GeneratePhenotypeName(const std::string& name) {
+ return kPhenotypeFlagPrefix + name;
+}
+
+template <typename Value>
+Flag<Value>::Flag(const std::string& name, Value default_value) :
+ FlagBase(GenerateCmdLineArgName(name),
+ GenerateSysPropName(name),
+ GeneratePhenotypeName(name)),
+ initialized_{false},
+ default_{default_value} {
+ ALL_FLAGS.push_front(this);
+}
+
+template <typename Value>
+void Flag<Value>::Reload() {
+ // The cmdline flags are loaded by the parsed_options infra.
+
+ // Load system properties.
+ from_system_property_ = std::nullopt;
+ const std::string sysprop = ::android::base::GetProperty(system_property_name_, kUndefinedValue);
+ if (sysprop != kUndefinedValue) {
+ ParseValue(sysprop, &from_system_property_);
+ }
+
+ // Load the server-side configuration.
+ from_server_setting_ = std::nullopt;
+ const std::string server_config =
+ ::android::base::GetProperty(server_setting_name_, kUndefinedValue);
+ if (server_config != kUndefinedValue) {
+ ParseValue(server_config, &from_server_setting_);
+ }
+
+ initialized_ = true;
+}
+
+template <typename Value>
+void DumpValue(std::ostream& oss, const std::optional<Value>& val) {
+ if (val.has_value()) {
+ oss << val.value();
+ } else {
+ oss << kUndefinedValue;
+ }
+}
+
+template <typename Value>
+void Flag<Value>::Dump(std::ostream& oss) const {
+ std::pair<Value, std::string> valueLoc = GetValueLocation();
+ oss << "value: " << std::get<0>(valueLoc) << " (from " << std::get<1>(valueLoc) << ")";
+
+ oss << "\n default: " << default_;
+ oss << "\n " << command_line_argument_name_ << ": ";
+ DumpValue(oss, from_command_line_);
+ oss << "\n " << system_property_name_ << ": ";
+ DumpValue(oss, from_system_property_);
+ oss << "\n " << server_setting_name_ << ": ";
+ DumpValue(oss, from_server_setting_);
+}
+
+template class Flag<bool>;
+template class Flag<int>;
+template class Flag<std::string>;
+
+} // namespace art
+
+#pragma clang diagnostic pop // -Wconversion