From: Joel Rosdahl Date: Sat, 20 Jan 2024 14:03:02 +0000 (+0100) Subject: perf: Use util::PathString instead of fs::path copy X-Git-Tag: v4.10~119 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1921266957dc8b719f80e7ee15419d62d3429d3c;p=thirdparty%2Fccache.git perf: Use util::PathString instead of fs::path copy --- diff --git a/src/argprocessing.cpp b/src/argprocessing.cpp index 9f6001dd8..a61317e5f 100644 --- a/src/argprocessing.cpp +++ b/src/argprocessing.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -40,8 +41,10 @@ #include namespace fs = util::filesystem; + using core::Statistic; using util::DirEntry; +using pstr = util::PathString; namespace { @@ -162,7 +165,7 @@ detect_pch(const std::string& option, fs::path file = fs::path(arg).replace_extension(".pch"); if (fs::is_regular_file(file)) { LOG("Detected use of precompiled header: {}", file); - pch_file = file.string(); + pch_file = pstr(file).str(); } } } else if (option == "-Fp") { @@ -1232,7 +1235,7 @@ process_args(Context& ctx) if (state.input_files.size() > 1) { if (is_link) { LOG_RAW("Called for link"); - return state.input_files.front().string().find("conftest.") + return pstr(state.input_files.front()).str().find("conftest.") != std::string::npos ? Statistic::autoconf_test : Statistic::called_for_link; @@ -1242,7 +1245,7 @@ process_args(Context& ctx) } } - args_info.orig_input_file = state.input_files.front().string(); + args_info.orig_input_file = pstr(state.input_files.front()).str(); // Rewrite to relative to increase hit rate. args_info.input_file = Util::make_relative_path(ctx, args_info.orig_input_file); @@ -1293,10 +1296,10 @@ process_args(Context& ctx) } else { extension = get_default_object_file_extension(ctx.config); } - args_info.output_obj += fs::path(args_info.input_file) - .filename() - .replace_extension(extension) - .string(); + args_info.output_obj += + pstr( + fs::path(args_info.input_file).filename().replace_extension(extension)) + .str(); } args_info.orig_output_obj = args_info.output_obj; @@ -1425,7 +1428,7 @@ process_args(Context& ctx) args_info.seen_split_dwarf = false; } else { args_info.output_dwo = - fs::path(args_info.output_obj).replace_extension(".dwo").string(); + pstr(fs::path(args_info.output_obj).replace_extension(".dwo")).str(); } } @@ -1487,7 +1490,7 @@ process_args(Context& ctx) if (args_info.generating_dependencies) { if (state.output_dep_origin == OutputDepOrigin::none) { args_info.output_dep = - fs::path(args_info.output_obj).replace_extension(".d").string(); + pstr(fs::path(args_info.output_obj).replace_extension(".d")).str(); if (!config.run_second_cpp()) { // If we're compiling preprocessed code we're sending dep_args to the // preprocessor so we need to use -MF to write to the correct .d file diff --git a/src/ccache.cpp b/src/ccache.cpp index 66420e241..d73f4dec6 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -82,6 +83,7 @@ namespace fs = util::filesystem; using core::Statistic; using util::DirEntry; +using pstr = util::PathString; // This is a string that identifies the current "version" of the hash sum // computed by ccache. If, for any reason, we want to force the hash sum to be @@ -207,7 +209,7 @@ prepare_debug_path(const fs::path& cwd, static_cast(time_of_invocation.sec())); } return FMT("{}.{}_{:06}.ccache-{}", - prefix.string(), + pstr(prefix).str(), timestamp, time_of_invocation.nsec_decimal_part() / 1000, suffix); @@ -265,7 +267,7 @@ static CompilerType do_guess_compiler(const fs::path& path) { const auto name = - util::to_lowercase(path.filename().replace_extension("").string()); + util::to_lowercase(pstr(path.filename().replace_extension("")).str()); if (name.find("clang-cl") != std::string_view::npos) { return CompilerType::clang_cl; } else if (name.find("clang") != std::string_view::npos) { @@ -673,7 +675,7 @@ get_tmp_fd(Context& ctx, auto tmp_stdout = util::value_or_throw(util::TemporaryFile::create( FMT("{}/{}", ctx.config.temporary_dir(), description))); - ctx.register_pending_tmp_file(tmp_stdout.path.string()); + ctx.register_pending_tmp_file(pstr(tmp_stdout.path)); return {std::move(tmp_stdout.fd), std::move(tmp_stdout.path)}; } else { const auto dev_null_path = util::get_dev_null_path(); @@ -1439,7 +1441,7 @@ hash_common_info(const Context& ctx, // Also hash the compiler name as some compilers use hard links and behave // differently depending on the real name. hash.hash_delimiter("cc_name"); - hash.hash(fs::path(args[0]).filename().string()); + hash.hash(pstr(fs::path(args[0]).filename()).str()); // Hash variables that may affect the compilation. const char* always_hash_env_vars[] = { @@ -1570,7 +1572,7 @@ hash_common_info(const Context& ctx, util::split_path_list(ctx.config.extra_files_to_hash())) { LOG("Hashing extra file {}", path); hash.hash_delimiter("extrafile"); - if (!hash_binary_file(ctx, hash, path.string())) { + if (!hash_binary_file(ctx, hash, pstr(path))) { return tl::unexpected(Statistic::error_hashing_extra_file); } } @@ -1889,7 +1891,7 @@ hash_profile_data_file(const Context& ctx, Hash& hash) { const std::string& profile_path = ctx.args_info.profile_path; const std::string base_name = - fs::path(ctx.args_info.output_obj).replace_extension("").string(); + pstr(fs::path(ctx.args_info.output_obj).replace_extension("")).str(); std::string hashified_cwd = ctx.apparent_cwd; std::replace(hashified_cwd.begin(), hashified_cwd.end(), '/', '#'); @@ -2742,8 +2744,9 @@ ccache_main(int argc, const char* const* argv) try { if (is_ccache_executable(argv[0])) { if (argc < 2) { - PRINT_RAW(stderr, - core::get_usage_text(fs::path(argv[0]).filename().string())); + PRINT_RAW( + stderr, + core::get_usage_text(pstr(fs::path(argv[0]).filename()).str())); exit(EXIT_FAILURE); } // If the first argument isn't an option, then assume we are being diff --git a/src/core/common.cpp b/src/core/common.cpp index 1a69f815b..29b825a61 100644 --- a/src/core/common.cpp +++ b/src/core/common.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #include using IncludeDelimiter = util::Tokenizer::IncludeDelimiter; +using pstr = util::PathString; namespace fs = util::filesystem; @@ -104,7 +106,7 @@ rewrite_stderr_to_absolute_paths(std::string_view text) result.append(line.data(), line.length()); } else { fs::path path(line.substr(0, path_end)); - result += fs::canonical(path).value_or(path).string(); + result += pstr(fs::canonical(path).value_or(path)).str(); auto tail = line.substr(path_end); result.append(tail.data(), tail.length()); } diff --git a/src/core/mainoptions.cpp b/src/core/mainoptions.cpp index 371a272fa..37d45fee3 100644 --- a/src/core/mainoptions.cpp +++ b/src/core/mainoptions.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -77,6 +78,7 @@ extern "C" { namespace fs = util::filesystem; using util::DirEntry; +using pstr = util::PathString; namespace core { @@ -791,7 +793,7 @@ process_main_options(int argc, const char* const* argv) case 'V': // --version { - PRINT_RAW(stdout, get_version_text(fs::path(argv[0]).stem().string())); + PRINT_RAW(stdout, get_version_text(pstr(fs::path(argv[0]).stem()).str())); break; } diff --git a/src/execute.cpp b/src/execute.cpp index efa89558c..0c51671bf 100644 --- a/src/execute.cpp +++ b/src/execute.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,8 @@ namespace fs = util::filesystem; +using pstr = util::PathString; + #ifdef _WIN32 static int win32execute(const char* path, const char* const* argv, @@ -87,9 +90,9 @@ win32getshell(const std::string& path) { const char* path_list = getenv("PATH"); std::string sh; - if (util::to_lowercase(fs::path(path).extension().string()) == ".sh" + if (util::to_lowercase(pstr(fs::path(path).extension()).str()) == ".sh" && path_list) { - sh = find_executable_in_path("sh.exe", path_list).string(); + sh = pstr(find_executable_in_path("sh.exe", path_list)).str(); } if (sh.empty() && getenv("CCACHE_DETECT_SHEBANG")) { // Detect shebang. @@ -98,7 +101,7 @@ win32getshell(const std::string& path) char buf[10] = {0}; fgets(buf, sizeof(buf) - 1, fp.get()); if (std::string(buf) == "#!/bin/sh" && path_list) { - sh = find_executable_in_path("sh.exe", path_list).string(); + sh = pstr(find_executable_in_path("sh.exe", path_list)).str(); } } } diff --git a/src/storage/local/LocalStorage.cpp b/src/storage/local/LocalStorage.cpp index daac0fbe7..65d1615f6 100644 --- a/src/storage/local/LocalStorage.cpp +++ b/src/storage/local/LocalStorage.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -89,6 +90,8 @@ using core::Statistic; using core::StatisticsCounters; using util::DirEntry; +using pstr = util::PathString; + namespace storage::local { // How often (in seconds) to scan $CCACHE_DIR/tmp for left-over temporary @@ -343,15 +346,15 @@ clean_dir( // Delete any tmp files older than 1 hour right away. if (file.mtime() + util::Duration(3600) < current_time && util::TemporaryFile::is_tmp_file(file.path())) { - util::remove(file.path().string()); + util::remove(file.path()); continue; } if (namespace_ && file_type_from_path(file.path()) == FileType::raw) { + auto path_str = pstr(file.path()); const auto result_filename = - FMT("{}R", - file.path().string().substr(0, file.path().string().length() - 2)); - raw_files_map[result_filename].push_back(file.path().string()); + FMT("{}R", path_str.str().substr(0, path_str.str().length() - 2)); + raw_files_map[result_filename].push_back(pstr(file.path()).str()); } cache_size += file.size_on_disk(); @@ -399,7 +402,7 @@ clean_dir( // For namespace eviction we need to remove raw files based on result // filename since they don't have a header. if (file_type_from_path(file.path()) == FileType::result) { - const auto entry = raw_files_map.find(file.path().string()); + const auto entry = raw_files_map.find(pstr(file.path())); if (entry != raw_files_map.end()) { for (const auto& raw_file : entry->second) { delete_file(DirEntry(raw_file), cache_size, files_in_cache); @@ -427,7 +430,7 @@ clean_dir( FileType file_type_from_path(const fs::path& path) { - auto filename = path.filename().string(); + std::string filename = pstr(path.filename()).str(); if (util::ends_with(filename, "M")) { return FileType::manifest; } else if (util::ends_with(filename, "R")) { diff --git a/src/storage/local/util.cpp b/src/storage/local/util.cpp index 9d8e9d664..50ba754d2 100644 --- a/src/storage/local/util.cpp +++ b/src/storage/local/util.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2023 Joel Rosdahl and other contributors +// Copyright (C) 2021-2024 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -20,12 +20,14 @@ #include #include +#include #include #include #include #include using util::DirEntry; +using pstr = util::PathString; namespace storage::local { @@ -74,7 +76,7 @@ get_cache_dir_files(const std::string& dir) } util::throw_on_error( util::traverse_directory(dir, [&](const auto& de) { - auto name = de.path().filename().string(); + std::string name = pstr(de.path().filename()).str(); if (name == "CACHEDIR.TAG" || name == "stats" || util::starts_with(name, ".nfs")) { return; diff --git a/src/util/DirEntry.cpp b/src/util/DirEntry.cpp index b031181c5..1f4388f6f 100644 --- a/src/util/DirEntry.cpp +++ b/src/util/DirEntry.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023 Joel Rosdahl and other contributors +// Copyright (C) 2019-2024 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -19,6 +19,7 @@ #include "DirEntry.hpp" #include +#include #include #include #include @@ -28,6 +29,8 @@ # include #endif +using pstr = util::PathString; + namespace { #ifdef _WIN32 @@ -249,7 +252,9 @@ DirEntry::do_stat() const m_exists = false; m_is_symlink = false; - int result = lstat_func(m_path.string().c_str(), &m_stat); + auto path = pstr(m_path); + + int result = lstat_func(path, &m_stat); if (result == 0) { m_errno = 0; if (S_ISLNK(m_stat.st_mode) @@ -259,7 +264,7 @@ DirEntry::do_stat() const ) { m_is_symlink = true; stat_t st; - if (stat_func(m_path.string().c_str(), &st) == 0) { + if (stat_func(path, &st) == 0) { m_stat = st; m_exists = true; } @@ -269,7 +274,7 @@ DirEntry::do_stat() const } else { m_errno = errno; if (m_log_on_error == LogOnError::yes) { - LOG("Failed to lstat {}: {}", m_path.string(), strerror(m_errno)); + LOG("Failed to lstat {}: {}", m_path, strerror(m_errno)); } } diff --git a/src/util/LockFile.cpp b/src/util/LockFile.cpp index 3a60cfacb..55ffc0fc2 100644 --- a/src/util/LockFile.cpp +++ b/src/util/LockFile.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2023 Joel Rosdahl and other contributors +// Copyright (C) 2020-2024 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -21,6 +21,7 @@ #include "Util.hpp" #include +#include #include #include #include @@ -46,6 +47,8 @@ const util::Duration k_staleness_limit(2); namespace fs = util::filesystem; +using pstr = util::PathString; + namespace { class RandomNumberGenerator @@ -74,9 +77,9 @@ private: namespace util { LockFile::LockFile(const fs::path& path) - : m_lock_file(path.string() + ".lock"), + : m_lock_file(pstr(path).str() + ".lock"), #ifndef _WIN32 - m_alive_file(path.string() + ".alive"), + m_alive_file(pstr(path).str() + ".alive"), m_acquired(false) #else m_handle(INVALID_HANDLE_VALUE) @@ -360,7 +363,7 @@ LockFile::do_acquire(const bool blocking) while (true) { DWORD flags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE; - handle = CreateFile(m_lock_file.string().c_str(), + handle = CreateFile(pstr(m_lock_file), GENERIC_WRITE, // desired access 0, // shared mode (0 = not shared) nullptr, // security attributes diff --git a/src/util/TemporaryFile.cpp b/src/util/TemporaryFile.cpp index 744b46a3c..1964174cb 100644 --- a/src/util/TemporaryFile.cpp +++ b/src/util/TemporaryFile.cpp @@ -18,6 +18,7 @@ #include "TemporaryFile.hpp" +#include #include #include #include @@ -35,6 +36,8 @@ namespace fs = util::filesystem; +using pstr = util::PathString; + namespace util { TemporaryFile::TemporaryFile(Fd&& fd_, const fs::path& path_) @@ -81,7 +84,7 @@ TemporaryFile::create(const fs::path& path_prefix, std::string_view suffix) bool TemporaryFile::is_tmp_file(const fs::path& path) { - return path.filename().string().find(tmp_file_infix) != std::string::npos; + return pstr(path.filename()).str().find(tmp_file_infix) != std::string::npos; } } // namespace util diff --git a/src/util/file.cpp b/src/util/file.cpp index 11d5baccc..51a999844 100644 --- a/src/util/file.cpp +++ b/src/util/file.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -62,18 +63,20 @@ namespace fs = util::filesystem; +using pstr = util::PathString; + namespace util { tl::expected copy_file(const fs::path& src, const fs::path& dest, ViaTmpFile via_tmp_file) { - Fd src_fd(open(src.string().c_str(), O_RDONLY | O_BINARY)); + Fd src_fd(open(pstr(src), O_RDONLY | O_BINARY)); if (!src_fd) { return tl::unexpected( FMT("Failed to open {} for reading: {}", src, strerror(errno))); } - unlink(dest.string().c_str()); + unlink(pstr(dest)); Fd dest_fd; fs::path tmp_file; @@ -85,8 +88,8 @@ copy_file(const fs::path& src, const fs::path& dest, ViaTmpFile via_tmp_file) dest_fd = std::move(temp_file->fd); tmp_file = std::move(temp_file->path); } else { - dest_fd = Fd(open( - dest.string().c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)); + dest_fd = + Fd(open(pstr(dest), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)); if (!dest_fd) { return tl::unexpected( FMT("Failed to open {} for writing: {}", dest, strerror(errno))); @@ -247,7 +250,7 @@ read_file(const fs::path& path, size_t size_hint) return O_RDONLY | O_BINARY; } }(); - Fd fd(open(path.string().c_str(), open_flags)); + Fd fd(open(pstr(path), open_flags)); if (!fd) { return tl::unexpected(strerror(errno)); } @@ -340,7 +343,7 @@ read_file_part(const fs::path& path, size_t pos, size_t count) return result; } - Fd fd(open(path.string().c_str(), O_RDONLY | O_BINARY)); + Fd fd(open(pstr(path), O_RDONLY | O_BINARY)); if (!fd) { LOG("Failed to open {}: {}", path, strerror(errno)); return tl::unexpected(strerror(errno)); @@ -445,7 +448,7 @@ set_timestamps(const fs::path& path, atime_mtime[0] = (atime ? *atime : *mtime).to_timespec(); atime_mtime[1] = mtime->to_timespec(); } - utimensat(AT_FDCWD, path.string().c_str(), mtime ? atime_mtime : nullptr, 0); + utimensat(AT_FDCWD, pstr(path), mtime ? atime_mtime : nullptr, 0); #elif defined(HAVE_UTIMES) timeval atime_mtime[2]; if (mtime) { @@ -455,15 +458,15 @@ set_timestamps(const fs::path& path, atime_mtime[1].tv_sec = mtime->sec(); atime_mtime[1].tv_usec = mtime->nsec_decimal_part() / 1000; } - utimes(path.string().c_str(), mtime ? atime_mtime : nullptr); + utimes(pstr(path), mtime ? atime_mtime : nullptr); #else utimbuf atime_mtime; if (mtime) { atime_mtime.actime = atime ? atime->sec() : mtime->sec(); atime_mtime.modtime = mtime->sec(); - utime(path.string().c_str(), &atime_mtime); + utime(pstr(path), &atime_mtime); } else { - utime(path.string().c_str(), nullptr); + utime(pstr(path), nullptr); } #endif } @@ -474,7 +477,7 @@ tl::expected traverse_directory(const fs::path& directory, const TraverseDirectoryVisitor& visitor) { - DIR* dir = opendir(directory.string().c_str()); + DIR* dir = opendir(pstr(directory)); if (!dir) { return tl::unexpected( FMT("Failed to traverse {}: {}", directory, strerror(errno))); @@ -575,11 +578,11 @@ write_fd(int fd, const void* data, size_t size) tl::expected write_file(const fs::path& path, std::string_view data, InPlace in_place) { + auto path_str = pstr(path); if (in_place == InPlace::no) { - unlink(path.string().c_str()); + unlink(path_str); } - Fd fd( - open(path.string().c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, 0666)); + Fd fd(open(path_str, O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, 0666)); if (!fd) { return tl::unexpected(strerror(errno)); } @@ -591,11 +594,11 @@ write_file(const fs::path& path, nonstd::span data, InPlace in_place) { + auto path_str = pstr(path); if (in_place == InPlace::no) { - unlink(path.string().c_str()); + unlink(path_str); } - Fd fd( - open(path.string().c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)); + Fd fd(open(path_str, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)); if (!fd) { return tl::unexpected(strerror(errno)); }