// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/public/common/profiling_utils.h" #include #include #include #include "base/base_paths.h" #include "base/command_line.h" #include "base/environment.h" #include "base/files/file.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/guid.h" #include "base/logging.h" #include "base/path_service.h" #include "base/rand_util.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" namespace content { namespace { // Returns the path where the PGO profiles should be saved. // On Android this is always a static path, on other platforms it's either // the path specified by the LLVM_PROFILE_FILE environment variable or the // current path if it's not set. base::FilePath GetProfileFileDirectory() { base::FilePath path; // Android differs from the other platforms because it's not possible to // write in base::DIR_CURRENT and environment variables aren't well supported. #if BUILDFLAG(IS_ANDROID) base::PathService::Get(base::DIR_TEMP, &path); path = path.Append("pgo_profiles/"); #else // !BUILDFLAG(IS_ANDROID) std::string prof_template; std::unique_ptr env(base::Environment::Create()); if (env->GetVar("LLVM_PROFILE_FILE", &prof_template)) { #if BUILDFLAG(IS_WIN) path = base::FilePath(base::UTF8ToWide(prof_template)).DirName(); #else path = base::FilePath(prof_template).DirName(); #endif } #endif if (!path.empty()) { base::CreateDirectory(path); } else { base::PathService::Get(base::DIR_CURRENT, &path); } return path; } } // namespace base::File OpenProfilingFile() { base::ScopedAllowBlockingForTesting allows_blocking; base::FilePath path = GetProfileFileDirectory(); // sajjadm@ and liaoyuke@ experimentally determined that a size 4 pool works // well for the coverage builder. // TODO(https://crbug.com/1059335): Check if this is an appropriate value for // the PGO builds. int pool_index = base::RandInt(0, 3); std::string filename = base::StrCat( {"child_pool-", base::NumberToString(pool_index), ".profraw"}); #if BUILDFLAG(IS_WIN) path = path.Append(base::UTF8ToWide(filename)); #else path = path.Append(filename); #endif uint32_t flags = base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ | base::File::FLAG_WRITE; base::File file(path, flags); if (!file.IsValid()) { LOG(ERROR) << "Opening file: " << path << " failed with " << file.error_details(); } return file; } } // namespace content