Kernel: Move CommandLine API to use AK::StringView instead of AK::String

The current CommandLine API unfortunately allocates Strings just to
query the presence of arguments on the command line. Switch the API
to use StringView instead to reduce the number of String allocations.
This commit is contained in:
Brian Gianforcaro 2021-05-31 01:59:02 -07:00 committed by Ali Mohammad Pur
parent 89dceb178b
commit 35a97884aa
Notes: sideshowbarker 2024-07-18 17:08:44 +09:00
2 changed files with 43 additions and 42 deletions

View File

@ -50,17 +50,18 @@ UNMAP_AFTER_INIT void CommandLine::build_commandline(const String& cmdline_from_
m_string = builder.to_string();
}
UNMAP_AFTER_INIT void CommandLine::add_arguments(const Vector<String>& args)
UNMAP_AFTER_INIT void CommandLine::add_arguments(const Vector<StringView>& args)
{
for (auto&& str : args) {
if (str == "") {
if (str == ""sv) {
continue;
}
auto pair = str.split_limit('=', 2);
auto pair = str.split_view('=', false);
VERIFY(pair.size() == 2 || pair.size() == 1);
if (pair.size() == 1) {
m_params.set(move(pair[0]), "");
m_params.set(move(pair[0]), ""sv);
} else {
m_params.set(move(pair[0]), move(pair[1]));
}
@ -71,114 +72,114 @@ UNMAP_AFTER_INIT CommandLine::CommandLine(const String& cmdline_from_bootloader)
{
s_the = this;
build_commandline(cmdline_from_bootloader);
const auto& args = m_string.split(' ');
const auto& args = m_string.split_view(' ');
m_params.ensure_capacity(args.size());
add_arguments(args);
}
Optional<String> CommandLine::lookup(const String& key) const
Optional<String> CommandLine::lookup(const StringView& key) const
{
return m_params.get(key);
}
bool CommandLine::contains(const String& key) const
bool CommandLine::contains(const StringView& key) const
{
return m_params.contains(key);
}
UNMAP_AFTER_INIT bool CommandLine::is_boot_profiling_enabled() const
{
return contains("boot_prof");
return contains("boot_prof"sv);
}
UNMAP_AFTER_INIT bool CommandLine::is_ide_enabled() const
{
return !contains("disable_ide");
return !contains("disable_ide"sv);
}
UNMAP_AFTER_INIT bool CommandLine::is_smp_enabled() const
{
return lookup("smp").value_or("off") == "on";
return lookup("smp"sv).value_or("off"sv) == "on"sv;
}
UNMAP_AFTER_INIT bool CommandLine::is_vmmouse_enabled() const
{
return lookup("vmmouse").value_or("on") == "on";
return lookup("vmmouse"sv).value_or("on") == "on"sv;
}
UNMAP_AFTER_INIT PCIAccessLevel CommandLine::pci_access_level() const
{
auto value = lookup("pci_ecam").value_or("off");
if (value == "on")
auto value = lookup("pci_ecam"sv).value_or("off"sv);
if (value == "on"sv)
return PCIAccessLevel::MappingPerBus;
if (value == "per-device")
if (value == "per-device"sv)
return PCIAccessLevel::MappingPerDevice;
if (value == "off")
if (value == "off"sv)
return PCIAccessLevel::IOAddressing;
PANIC("Unknown PCI ECAM setting: {}", value);
}
UNMAP_AFTER_INIT bool CommandLine::is_legacy_time_enabled() const
{
return lookup("time").value_or("modern") == "legacy";
return lookup("time"sv).value_or("modern"sv) == "legacy"sv;
}
UNMAP_AFTER_INIT bool CommandLine::is_force_pio() const
{
return contains("force_pio");
return contains("force_pio"sv);
}
UNMAP_AFTER_INIT String CommandLine::root_device() const
{
return lookup("root").value_or("/dev/hda");
return lookup("root"sv).value_or("/dev/hda"sv);
}
UNMAP_AFTER_INIT AcpiFeatureLevel CommandLine::acpi_feature_level() const
{
auto value = kernel_command_line().lookup("acpi").value_or("on");
if (value == "limited")
auto value = kernel_command_line().lookup("acpi"sv).value_or("on"sv);
if (value == "limited"sv)
return AcpiFeatureLevel::Limited;
if (value == "off")
if (value == "off"sv)
return AcpiFeatureLevel::Disabled;
return AcpiFeatureLevel::Enabled;
}
UNMAP_AFTER_INIT HPETMode CommandLine::hpet_mode() const
{
auto hpet_mode = lookup("hpet").value_or("periodic");
if (hpet_mode == "periodic")
auto hpet_mode = lookup("hpet"sv).value_or("periodic"sv);
if (hpet_mode == "periodic"sv)
return HPETMode::Periodic;
if (hpet_mode == "nonperiodic")
if (hpet_mode == "nonperiodic"sv)
return HPETMode::NonPeriodic;
PANIC("Unknown HPETMode: {}", hpet_mode);
}
UNMAP_AFTER_INIT bool CommandLine::disable_ps2_controller() const
{
return contains("disable_ps2_controller");
return contains("disable_ps2_controller"sv);
}
UNMAP_AFTER_INIT bool CommandLine::disable_physical_storage() const
{
return contains("disable_physical_storage");
return contains("disable_physical_storage"sv);
}
UNMAP_AFTER_INIT bool CommandLine::disable_uhci_controller() const
{
return contains("disable_uhci_controller");
return contains("disable_uhci_controller"sv);
}
UNMAP_AFTER_INIT bool CommandLine::disable_virtio() const
{
return contains("disable_virtio");
return contains("disable_virtio"sv);
}
UNMAP_AFTER_INIT AHCIResetMode CommandLine::ahci_reset_mode() const
{
const auto ahci_reset_mode = lookup("ahci_reset_mode").value_or("controller");
if (ahci_reset_mode == "controller") {
const auto ahci_reset_mode = lookup("ahci_reset_mode"sv).value_or("controllers"sv);
if (ahci_reset_mode == "controllers"sv) {
return AHCIResetMode::ControllerOnly;
} else if (ahci_reset_mode == "aggressive") {
} else if (ahci_reset_mode == "aggressive"sv) {
return AHCIResetMode::Aggressive;
}
PANIC("Unknown AHCIResetMode: {}", ahci_reset_mode);
@ -186,12 +187,12 @@ UNMAP_AFTER_INIT AHCIResetMode CommandLine::ahci_reset_mode() const
UNMAP_AFTER_INIT BootMode CommandLine::boot_mode() const
{
const auto boot_mode = lookup("boot_mode").value_or("graphical");
if (boot_mode == "no-fbdev") {
const auto boot_mode = lookup("boot_mode"sv).value_or("graphical"sv);
if (boot_mode == "no-fbdevsv") {
return BootMode::NoFramebufferDevices;
} else if (boot_mode == "self-test") {
} else if (boot_mode == "self-test"sv) {
return BootMode::SelfTest;
} else if (boot_mode == "graphical") {
} else if (boot_mode == "graphical"sv) {
return BootMode::Graphical;
}
PANIC("Unknown BootMode: {}", boot_mode);
@ -205,12 +206,12 @@ UNMAP_AFTER_INIT bool CommandLine::is_no_framebuffer_devices_mode() const
String CommandLine::userspace_init() const
{
return lookup("init").value_or("/bin/SystemServer");
return lookup("init"sv).value_or("/bin/SystemServer"sv);
}
Vector<String> CommandLine::userspace_init_args() const
{
auto init_args = lookup("init_args").value_or("").split(',');
auto init_args = lookup("init_args"sv).value_or(""sv).split(',');
if (!init_args.is_empty())
init_args.prepend(userspace_init());
@ -219,7 +220,7 @@ Vector<String> CommandLine::userspace_init_args() const
UNMAP_AFTER_INIT size_t CommandLine::switch_to_tty() const
{
const auto default_tty = lookup("switch_to_tty").value_or("1");
const auto default_tty = lookup("switch_to_tty"sv).value_or("1"sv);
auto switch_tty_number = default_tty.to_uint();
if (switch_tty_number.has_value() && switch_tty_number.value() >= 1) {
return switch_tty_number.value() - 1;

View File

@ -49,8 +49,8 @@ public:
static void initialize();
[[nodiscard]] const String& string() const { return m_string; }
Optional<String> lookup(const String& key) const;
[[nodiscard]] bool contains(const String& key) const;
Optional<String> lookup(const StringView& key) const;
[[nodiscard]] bool contains(const StringView& key) const;
[[nodiscard]] bool is_boot_profiling_enabled() const;
[[nodiscard]] bool is_ide_enabled() const;
@ -76,11 +76,11 @@ public:
private:
CommandLine(const String&);
void add_arguments(const Vector<String>& args);
void add_arguments(const Vector<StringView>& args);
void build_commandline(const String& cmdline_from_bootloader);
String m_string;
HashMap<String, String> m_params;
HashMap<StringView, StringView> m_params;
};
const CommandLine& kernel_command_line();