diff options
22 files changed, 256 insertions, 109 deletions
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index 778e7899b3..6915b7cdd6 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -22,11 +22,11 @@ #include <string> #include <vector> +#include "base/compiler_filter.h" #include "base/globals.h" #include "base/hash_set.h" #include "base/macros.h" #include "base/utils.h" -#include "compiler_filter.h" #include "optimizing/register_allocator.h" namespace art { diff --git a/compiler/driver/compiler_options_map.h b/compiler/driver/compiler_options_map.h index 14f511286a..7e2f8466e0 100644 --- a/compiler/driver/compiler_options_map.h +++ b/compiler/driver/compiler_options_map.h @@ -20,9 +20,9 @@ #include <string> #include <vector> +#include "base/compiler_filter.h" #include "base/variant_map.h" #include "cmdline_types.h" -#include "compiler_filter.h" namespace art { diff --git a/dexoptanalyzer/dexoptanalyzer.cc b/dexoptanalyzer/dexoptanalyzer.cc index c3304b5823..515a37c451 100644 --- a/dexoptanalyzer/dexoptanalyzer.cc +++ b/dexoptanalyzer/dexoptanalyzer.cc @@ -22,13 +22,13 @@ #include "android-base/stringprintf.h" #include "android-base/strings.h" +#include "base/compiler_filter.h" #include "base/file_utils.h" #include "base/logging.h" // For InitLogging. #include "base/mutex.h" #include "base/os.h" #include "base/string_view_cpp20.h" #include "base/utils.h" -#include "compiler_filter.h" #include "class_loader_context.h" #include "dex/dex_file.h" #include "noop_compiler_callbacks.h" diff --git a/dexoptanalyzer/dexoptanalyzer_test.cc b/dexoptanalyzer/dexoptanalyzer_test.cc index 4fb0b9e391..42be4735a2 100644 --- a/dexoptanalyzer/dexoptanalyzer_test.cc +++ b/dexoptanalyzer/dexoptanalyzer_test.cc @@ -17,7 +17,7 @@ #include <gtest/gtest.h> #include "arch/instruction_set.h" -#include "compiler_filter.h" +#include "base/compiler_filter.h" #include "dexopt_test.h" namespace art { diff --git a/libartbase/Android.bp b/libartbase/Android.bp index 60dcf17932..c3a63643e4 100644 --- a/libartbase/Android.bp +++ b/libartbase/Android.bp @@ -24,6 +24,7 @@ cc_defaults { "base/arena_allocator.cc", "base/arena_bit_vector.cc", "base/bit_vector.cc", + "base/compiler_filter.cc", "base/enums.cc", "base/file_magic.cc", "base/file_utils.cc", @@ -243,6 +244,7 @@ art_cc_test { "base/bit_table_test.cc", "base/bit_utils_test.cc", "base/bit_vector_test.cc", + "base/compiler_filter_test.cc", "base/file_utils_test.cc", "base/hash_map_test.cc", "base/hash_set_test.cc", diff --git a/runtime/compiler_filter.cc b/libartbase/base/compiler_filter.cc index 6291329f5a..6291329f5a 100644 --- a/runtime/compiler_filter.cc +++ b/libartbase/base/compiler_filter.cc diff --git a/runtime/compiler_filter.h b/libartbase/base/compiler_filter.h index 0b930a433b..b4a83ece10 100644 --- a/runtime/compiler_filter.h +++ b/libartbase/base/compiler_filter.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef ART_RUNTIME_COMPILER_FILTER_H_ -#define ART_RUNTIME_COMPILER_FILTER_H_ +#ifndef ART_LIBARTBASE_BASE_COMPILER_FILTER_H_ +#define ART_LIBARTBASE_BASE_COMPILER_FILTER_H_ #include <iosfwd> #include <string> @@ -110,4 +110,4 @@ std::ostream& operator<<(std::ostream& os, const CompilerFilter::Filter& rhs); } // namespace art -#endif // ART_RUNTIME_COMPILER_FILTER_H_ +#endif // ART_LIBARTBASE_BASE_COMPILER_FILTER_H_ diff --git a/runtime/compiler_filter_test.cc b/libartbase/base/compiler_filter_test.cc index df7c8e74a8..df7c8e74a8 100644 --- a/runtime/compiler_filter_test.cc +++ b/libartbase/base/compiler_filter_test.cc diff --git a/libartbase/base/metrics/metrics.h b/libartbase/base/metrics/metrics.h index 18f84e9d81..20bbc528ca 100644 --- a/libartbase/base/metrics/metrics.h +++ b/libartbase/base/metrics/metrics.h @@ -22,12 +22,13 @@ #include <array> #include <atomic> #include <optional> -#include <ostream> +#include <sstream> #include <string_view> #include <thread> #include <vector> #include "android-base/logging.h" +#include "base/compiler_filter.h" #include "base/time_utils.h" #pragma clang diagnostic push @@ -79,10 +80,59 @@ enum class DatumId { #undef ART_HISTOGRAM }; +// We log compilation reasons as part of the metadata we report. Since elsewhere compilation reasons +// are specified as a string, we define them as an enum here which indicates the reasons that we +// support. +enum class CompilationReason { + kError, + kUnknown, + kFirstBoot, + kBoot, + kInstall, + kBgDexopt, + kABOTA, + kInactive, + kShared, + kInstallWithDexMetadata, +}; + +constexpr const char* CompilationReasonName(CompilationReason reason) { + switch (reason) { + case CompilationReason::kError: + return "Error"; + case CompilationReason::kUnknown: + return "Unknown"; + case CompilationReason::kFirstBoot: + return "FirstBoot"; + case CompilationReason::kBoot: + return "Boot"; + case CompilationReason::kInstall: + return "Install"; + case CompilationReason::kBgDexopt: + return "BgDexopt"; + case CompilationReason::kABOTA: + return "ABOTA"; + case CompilationReason::kInactive: + return "Inactive"; + case CompilationReason::kShared: + return "Shared"; + case CompilationReason::kInstallWithDexMetadata: + return "InstallWithDexMetadata"; + } +} + +// SessionData contains metadata about a metrics session (basically the lifetime of an ART process). +// This information should not change for the lifetime of the session. struct SessionData { - const uint64_t session_id; - const std::string_view package_name; - // TODO: compiler filter / dexopt state + static SessionData CreateDefault(); + + static constexpr int64_t kInvalidSessionId = -1; + static constexpr int32_t kInvalidUserId = -1; + + int64_t session_id; + int32_t uid; + CompilationReason compilation_reason; + std::optional<CompilerFilter::Filter> compiler_filter; }; // MetricsBackends are used by a metrics reporter to write metrics to some external location. For @@ -91,7 +141,6 @@ class MetricsBackend { public: virtual ~MetricsBackend() {} - protected: // Begins an ART metrics session. // // This is called by the metrics reporter when the runtime is starting up. The session_data @@ -100,12 +149,9 @@ class MetricsBackend { // for this process. virtual void BeginSession(const SessionData& session_data) = 0; - // Marks the end of a metrics session. - // - // The metrics reporter will call this when metrics reported ends (e.g. when the runtime is - // shutting down). No further metrics will be reported for this session. Note that EndSession is - // not guaranteed to be called, since clean shutdowns for the runtime are quite rare in practice. - virtual void EndSession() = 0; + protected: + // Called by the metrics reporter to indicate that a new metrics report is starting. + virtual void BeginReport(uint64_t timestamp_millis) = 0; // Called by the metrics reporter to give the current value of the counter with id counter_type. // @@ -129,10 +175,14 @@ class MetricsBackend { int64_t maximum_value, const std::vector<uint32_t>& buckets) = 0; + // Called by the metrics reporter to indicate that the current metrics report is complete. + virtual void EndReport() = 0; + template <DatumId counter_type> friend class MetricsCounter; template <DatumId histogram_type, size_t num_buckets, int64_t low_value, int64_t high_value> friend class MetricsHistogram; + friend class ArtMetrics; }; template <DatumId counter_type> @@ -208,13 +258,16 @@ class MetricsHistogram { static_assert(std::atomic<value_t>::is_always_lock_free); }; -// A backend that writes metrics in a human-readable format to an std::ostream. -class StreamBackend : public MetricsBackend { +// A backend that writes metrics in a human-readable format to a string. +// +// This is used as a base for LogBackend and FileBackend. +class StringBackend : public MetricsBackend { public: - explicit StreamBackend(std::ostream& os); + StringBackend(); void BeginSession(const SessionData& session_data) override; - void EndSession() override; + + void BeginReport(uint64_t timestamp_millis) override; void ReportCounter(DatumId counter_type, uint64_t value) override; @@ -223,8 +276,40 @@ class StreamBackend : public MetricsBackend { int64_t high_value, const std::vector<uint32_t>& buckets) override; + void EndReport() override; + + std::string GetAndResetBuffer(); + private: - std::ostream& os_; + std::ostringstream os_; + std::optional<SessionData> session_data_; +}; + +// A backend that writes metrics in human-readable format to the log (i.e. logcat). +class LogBackend : public StringBackend { + public: + explicit LogBackend(android::base::LogSeverity level); + + void BeginReport(uint64_t timestamp_millis) override; + void EndReport() override; + + private: + android::base::LogSeverity level_; +}; + +// A backend that writes metrics to a file. +// +// These are currently written in the same human-readable format used by StringBackend and +// LogBackend, but we will probably want a more machine-readable format in the future. +class FileBackend : public StringBackend { + public: + explicit FileBackend(std::string filename); + + void BeginReport(uint64_t timestamp_millis) override; + void EndReport() override; + + private: + std::string filename_; }; /** @@ -323,14 +408,7 @@ class ArtMetrics { #undef ART_HISTOGRAM private: - // This field is only included to allow us expand the ART_COUNTERS and ART_HISTOGRAMS macro in - // the initializer list in ArtMetrics::ArtMetrics. See metrics.cc for how it's used. - // - // It's declared as a zero-length array so it has no runtime space impact. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-private-field" - int unused_[0]; -#pragma clang diagnostic pop // -Wunused-private-field + uint64_t beginning_timestamp_; #define ART_COUNTER(name) MetricsCounter<DatumId::k##name> name##_; ART_COUNTERS(ART_COUNTER) diff --git a/libartbase/base/metrics/metrics_common.cc b/libartbase/base/metrics/metrics_common.cc index 81d7215403..c650fdf760 100644 --- a/libartbase/base/metrics/metrics_common.cc +++ b/libartbase/base/metrics/metrics_common.cc @@ -16,8 +16,10 @@ #include <sstream> +#include "android-base/file.h" #include "android-base/logging.h" #include "base/macros.h" +#include "base/scoped_flock.h" #include "metrics.h" #pragma clang diagnostic push @@ -46,7 +48,22 @@ std::string DatumName(DatumId datum) { } } -ArtMetrics::ArtMetrics() : unused_ {} +SessionData SessionData::CreateDefault() { +#ifdef _WIN32 + int32_t uid = kInvalidUserId; // Windows does not support getuid(); +#else + int32_t uid = static_cast<int32_t>(getuid()); +#endif + + return SessionData{ + .compilation_reason = CompilationReason::kUnknown, + .compiler_filter = std::nullopt, + .session_id = kInvalidSessionId, + .uid = uid, + }; +} + +ArtMetrics::ArtMetrics() : beginning_timestamp_ {MilliTime()} #define ART_COUNTER(name) \ , name##_ {} ART_COUNTERS(ART_COUNTER) @@ -59,6 +76,8 @@ ART_HISTOGRAMS(ART_HISTOGRAM) } void ArtMetrics::ReportAllMetrics(MetricsBackend* backend) const { + backend->BeginReport(MilliTime() - beginning_timestamp_); + // Dump counters #define ART_COUNTER(name) name()->Report(backend); ART_COUNTERS(ART_COUNTER) @@ -68,34 +87,58 @@ void ArtMetrics::ReportAllMetrics(MetricsBackend* backend) const { #define ART_HISTOGRAM(name, num_buckets, low_value, high_value) name()->Report(backend); ART_HISTOGRAMS(ART_HISTOGRAM) #undef ART_HISTOGRAM + + backend->EndReport(); } void ArtMetrics::DumpForSigQuit(std::ostream& os) const { - os << "\n*** ART internal metrics ***\n\n"; - StreamBackend backend{os}; + StringBackend backend; ReportAllMetrics(&backend); - os << "\n*** Done dumping ART internal metrics ***\n"; + os << backend.GetAndResetBuffer(); } -StreamBackend::StreamBackend(std::ostream& os) : os_{os} {} +StringBackend::StringBackend() {} -void StreamBackend::BeginSession([[maybe_unused]] const SessionData& session_data) { - // Not needed for now. +std::string StringBackend::GetAndResetBuffer() { + std::string result = os_.str(); + os_.clear(); + os_.str(""); + return result; } -void StreamBackend::EndSession() { - // Not needed for now. +void StringBackend::BeginSession(const SessionData& session_data) { + session_data_ = session_data; } -void StreamBackend::ReportCounter(DatumId counter_type, uint64_t value) { - os_ << DatumName(counter_type) << ": count = " << value << "\n"; +void StringBackend::BeginReport(uint64_t timestamp_since_start_ms) { + os_ << "\n*** ART internal metrics ***\n"; + os_ << " Metadata:\n"; + os_ << " timestamp_since_start_ms: " << timestamp_since_start_ms << "\n"; + if (session_data_.has_value()) { + os_ << " session_id: " << session_data_->session_id << "\n"; + os_ << " uid: " << session_data_->uid << "\n"; + os_ << " compilation_reason: " << CompilationReasonName(session_data_->compilation_reason) + << "\n"; + os_ << " compiler_filter: " + << (session_data_->compiler_filter.has_value() + ? CompilerFilter::NameOfFilter(session_data_->compiler_filter.value()) + : "(unspecified)") + << "\n"; + } + os_ << " Metrics:\n"; } -void StreamBackend::ReportHistogram(DatumId histogram_type, +void StringBackend::EndReport() { os_ << "*** Done dumping ART internal metrics ***\n"; } + +void StringBackend::ReportCounter(DatumId counter_type, uint64_t value) { + os_ << " " << DatumName(counter_type) << ": count = " << value << "\n"; +} + +void StringBackend::ReportHistogram(DatumId histogram_type, int64_t minimum_value_, int64_t maximum_value_, const std::vector<uint32_t>& buckets) { - os_ << DatumName(histogram_type) << ": range = " << minimum_value_ << "..." << maximum_value_; + os_ << " " << DatumName(histogram_type) << ": range = " << minimum_value_ << "..." << maximum_value_; if (buckets.size() > 0) { os_ << ", buckets: "; bool first = true; @@ -112,6 +155,39 @@ void StreamBackend::ReportHistogram(DatumId histogram_type, } } +LogBackend::LogBackend(android::base::LogSeverity level) : level_{level} {} + +void LogBackend::BeginReport(uint64_t timestamp_since_start_ms) { + GetAndResetBuffer(); + StringBackend::BeginReport(timestamp_since_start_ms); +} + +void LogBackend::EndReport() { + StringBackend::EndReport(); + LOG_STREAM(level_) << GetAndResetBuffer(); +} + +FileBackend::FileBackend(std::string filename) : filename_{filename} {} + +void FileBackend::BeginReport(uint64_t timestamp_since_start_ms) { + GetAndResetBuffer(); + StringBackend::BeginReport(timestamp_since_start_ms); +} + +void FileBackend::EndReport() { + StringBackend::EndReport(); + std::string error_message; + auto file{ + LockedFile::Open(filename_.c_str(), O_CREAT | O_WRONLY | O_APPEND, true, &error_message)}; + if (file.get() == nullptr) { + LOG(WARNING) << "Could open metrics file '" << filename_ << "': " << error_message; + } else { + if (!android::base::WriteStringToFd(GetAndResetBuffer(), file.get()->Fd())) { + PLOG(WARNING) << "Error writing metrics to file"; + } + } +} + } // namespace metrics } // namespace art diff --git a/libartbase/base/metrics/metrics_test.cc b/libartbase/base/metrics/metrics_test.cc index f568ea0df9..4643f140d2 100644 --- a/libartbase/base/metrics/metrics_test.cc +++ b/libartbase/base/metrics/metrics_test.cc @@ -208,20 +208,20 @@ TEST_F(MetricsTest, HistogramTimer) { // Makes sure all defined metrics are included when dumping through StreamBackend. TEST_F(MetricsTest, StreamBackendDumpAllMetrics) { ArtMetrics metrics; - std::stringstream os; - StreamBackend backend(os); + StringBackend backend; metrics.ReportAllMetrics(&backend); // Make sure the resulting string lists all the counters. + const std::string result = backend.GetAndResetBuffer(); #define COUNTER(name) \ - EXPECT_NE(os.str().find(DatumName(DatumId::k##name)), std::string::npos) + EXPECT_NE(result.find(DatumName(DatumId::k##name)), std::string::npos) ART_COUNTERS(COUNTER); #undef COUNTER // Make sure the resulting string lists all the histograms. #define HISTOGRAM(name, num_buckets, minimum_value, maximum_value) \ - EXPECT_NE(os.str().find(DatumName(DatumId::k##name)), std::string::npos) + EXPECT_NE(result.find(DatumName(DatumId::k##name)), std::string::npos) ART_HISTOGRAMS(HISTOGRAM); #undef HISTOGRAM } diff --git a/libartbase/base/metrics/metrics_test.h b/libartbase/base/metrics/metrics_test.h index 72ca90e1f1..4a7dad8025 100644 --- a/libartbase/base/metrics/metrics_test.h +++ b/libartbase/base/metrics/metrics_test.h @@ -34,7 +34,8 @@ namespace test { class TestBackendBase : public MetricsBackend { public: void BeginSession([[maybe_unused]] const SessionData& session_data) override {} - void EndSession() override {} + + void BeginReport([[maybe_unused]] uint64_t timestamp_since_start_ms) override {} void ReportCounter([[maybe_unused]] DatumId counter_type, [[maybe_unused]] uint64_t value) override {} @@ -43,6 +44,8 @@ class TestBackendBase : public MetricsBackend { [[maybe_unused]] int64_t low_value_, [[maybe_unused]] int64_t high_value, [[maybe_unused]] const std::vector<uint32_t>& buckets) override {} + + void EndReport() override {} }; template <DatumId counter_type> diff --git a/runtime/Android.bp b/runtime/Android.bp index ca82dcf5b1..4608af1977 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -80,7 +80,6 @@ libart_cc_defaults { "class_table.cc", "common_throws.cc", "compat_framework.cc", - "compiler_filter.cc", "debug_print.cc", "debugger.cc", "dex/dex_file_annotations.cc", @@ -660,7 +659,6 @@ art_cc_test { "class_linker_test.cc", "class_loader_context_test.cc", "class_table_test.cc", - "compiler_filter_test.cc", "entrypoints/math_entrypoints_test.cc", "entrypoints/quick/quick_trampoline_entrypoints_test.cc", "entrypoints_order_test.cc", diff --git a/runtime/jit/profile_saver.cc b/runtime/jit/profile_saver.cc index c7d5230953..dcc3d8d600 100644 --- a/runtime/jit/profile_saver.cc +++ b/runtime/jit/profile_saver.cc @@ -24,6 +24,7 @@ #include "android-base/strings.h" #include "art_method-inl.h" +#include "base/compiler_filter.h" #include "base/enums.h" #include "base/logging.h" // For VLOG. #include "base/scoped_arena_containers.h" @@ -31,7 +32,6 @@ #include "base/systrace.h" #include "base/time_utils.h" #include "class_table-inl.h" -#include "compiler_filter.h" #include "dex/dex_file_loader.h" #include "dex_reference_collection.h" #include "gc/collector_type.h" diff --git a/runtime/metrics_reporter.cc b/runtime/metrics_reporter.cc index d3ec909a63..2004c7d918 100644 --- a/runtime/metrics_reporter.cc +++ b/runtime/metrics_reporter.cc @@ -16,8 +16,6 @@ #include "metrics_reporter.h" -#include "android-base/file.h" -#include "base/scoped_flock.h" #include "runtime.h" #include "runtime_options.h" #include "thread-current-inl.h" @@ -28,8 +26,6 @@ namespace art { namespace metrics { -using android::base::WriteStringToFd; - std::unique_ptr<MetricsReporter> MetricsReporter::Create(ReportingConfig config, Runtime* runtime) { // We can't use std::make_unique here because the MetricsReporter constructor is private. return std::unique_ptr<MetricsReporter>{new MetricsReporter{std::move(config), runtime}}; @@ -40,12 +36,12 @@ MetricsReporter::MetricsReporter(ReportingConfig config, Runtime* runtime) MetricsReporter::~MetricsReporter() { MaybeStopBackgroundThread(); } -void MetricsReporter::MaybeStartBackgroundThread() { - if (config_.BackgroundReportingEnabled()) { - CHECK(!thread_.has_value()); +void MetricsReporter::MaybeStartBackgroundThread(SessionData session_data) { + CHECK(!thread_.has_value()); - thread_.emplace(&MetricsReporter::BackgroundThreadRun, this); - } + thread_.emplace(&MetricsReporter::BackgroundThreadRun, this); + + messages_.SendMessage(BeginSessionMessage{session_data}); } void MetricsReporter::MaybeStopBackgroundThread() { @@ -53,10 +49,6 @@ void MetricsReporter::MaybeStopBackgroundThread() { messages_.SendMessage(ShutdownRequestedMessage{}); thread_->join(); } - // Do one final metrics report, if enabled. - if (config_.report_metrics_on_shutdown) { - ReportMetrics(); - } } void MetricsReporter::NotifyStartupCompleted() { @@ -76,13 +68,33 @@ void MetricsReporter::BackgroundThreadRun() { /*create_peer=*/true); bool running = true; + // Configure the backends + if (config_.dump_to_logcat) { + backends_.emplace_back(new LogBackend(LogSeverity::INFO)); + } + if (config_.dump_to_file.has_value()) { + backends_.emplace_back(new FileBackend(config_.dump_to_file.value())); + } + MaybeResetTimeout(); while (running) { messages_.SwitchReceive( + [&](BeginSessionMessage message) { + LOG_STREAM(DEBUG) << "Received session metadata"; + + for (auto& backend : backends_) { + backend->BeginSession(message.session_data); + } + }, [&]([[maybe_unused]] ShutdownRequestedMessage message) { LOG_STREAM(DEBUG) << "Shutdown request received"; running = false; + + // Do one final metrics report, if enabled. + if (config_.report_metrics_on_shutdown) { + ReportMetrics(); + } }, [&]([[maybe_unused]] TimeoutExpiredMessage message) { LOG_STREAM(DEBUG) << "Timer expired, reporting metrics"; @@ -110,34 +122,10 @@ void MetricsReporter::MaybeResetTimeout() { } void MetricsReporter::ReportMetrics() const { - if (config_.dump_to_logcat) { - LOG_STREAM(INFO) << "\n*** ART internal metrics ***\n\n"; - // LOG_STREAM(INFO) destroys the stream at the end of the statement, which makes it tricky pass - // it to store as a field in StreamBackend. To get around this, we use an immediately-invoked - // lambda expression to act as a let-binding, letting us access the stream for long enough to - // dump the metrics. - [this](std::ostream& os) { - StreamBackend backend{os}; - runtime_->GetMetrics()->ReportAllMetrics(&backend); - }(LOG_STREAM(INFO)); - LOG_STREAM(INFO) << "\n*** Done dumping ART internal metrics ***\n"; - } - if (config_.dump_to_file.has_value()) { - const auto& filename = config_.dump_to_file.value(); - std::ostringstream stream; - StreamBackend backend{stream}; - runtime_->GetMetrics()->ReportAllMetrics(&backend); - - std::string error_message; - auto file{ - LockedFile::Open(filename.c_str(), O_CREAT | O_WRONLY | O_APPEND, true, &error_message)}; - if (file.get() == nullptr) { - LOG(WARNING) << "Could open metrics file '" << filename << "': " << error_message; - } else { - if (!WriteStringToFd(stream.str(), file.get()->Fd())) { - PLOG(WARNING) << "Error writing metrics to file"; - } - } + ArtMetrics* metrics{runtime_->GetMetrics()}; + + for (auto& backend : backends_) { + metrics->ReportAllMetrics(backend.get()); } } diff --git a/runtime/metrics_reporter.h b/runtime/metrics_reporter.h index 4b5dbe55d0..a9cd1f381d 100644 --- a/runtime/metrics_reporter.h +++ b/runtime/metrics_reporter.h @@ -46,13 +46,6 @@ struct ReportingConfig { // Returns whether any options are set that enables metrics reporting. constexpr bool ReportingEnabled() const { return dump_to_logcat || dump_to_file.has_value(); } - - // Returns whether any options are set that requires a background reporting thread. - constexpr bool BackgroundReportingEnabled() const { - // If any reporting is enabled, we always need to do at least the startup report in the - // background. - return ReportingEnabled(); - } }; // MetricsReporter handles periodically reporting ART metrics. @@ -64,7 +57,7 @@ class MetricsReporter { ~MetricsReporter(); // Creates and runs the background reporting thread. - void MaybeStartBackgroundThread(); + void MaybeStartBackgroundThread(SessionData session_data); // Sends a request to the background thread to shutdown. void MaybeStopBackgroundThread(); @@ -89,7 +82,7 @@ class MetricsReporter { const ReportingConfig config_; Runtime* runtime_; - + std::vector<std::unique_ptr<MetricsBackend>> backends_; std::optional<std::thread> thread_; // A message indicating that the reporting thread should shut down. @@ -98,7 +91,13 @@ class MetricsReporter { // A message indicating that app startup has completed. struct StartupCompletedMessage {}; - MessageQueue<ShutdownRequestedMessage, StartupCompletedMessage> messages_; + // A message marking the beginning of a metrics logging session. + // + // The primary purpose of this is to pass the session metadata from the Runtime to the metrics + // backends. + struct BeginSessionMessage{ SessionData session_data; }; + + MessageQueue<ShutdownRequestedMessage, StartupCompletedMessage, BeginSessionMessage> messages_; }; } // namespace metrics diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc index 8bb8ce8310..a966d6644c 100644 --- a/runtime/native/dalvik_system_DexFile.cc +++ b/runtime/native/dalvik_system_DexFile.cc @@ -21,6 +21,7 @@ #include "android-base/stringprintf.h" #include "base/casts.h" +#include "base/compiler_filter.h" #include "base/file_utils.h" #include "base/hiddenapi_domain.h" #include "base/logging.h" @@ -31,7 +32,6 @@ #include "class_linker.h" #include "class_loader_context.h" #include "common_throws.h" -#include "compiler_filter.h" #include "dex/art_dex_file_loader.h" #include "dex/descriptors_names.h" #include "dex/dex_file-inl.h" diff --git a/runtime/oat.h b/runtime/oat.h index 0dc49c3d4d..e7e9a5863e 100644 --- a/runtime/oat.h +++ b/runtime/oat.h @@ -20,9 +20,9 @@ #include <array> #include <vector> +#include "base/compiler_filter.h" #include "base/macros.h" #include "base/safe_map.h" -#include "compiler_filter.h" namespace art { diff --git a/runtime/oat_file.h b/runtime/oat_file.h index 9e21b7e9e3..d4f4d95e06 100644 --- a/runtime/oat_file.h +++ b/runtime/oat_file.h @@ -23,12 +23,12 @@ #include <vector> #include "base/array_ref.h" +#include "base/compiler_filter.h" #include "base/mutex.h" #include "base/os.h" #include "base/safe_map.h" #include "base/tracking_safe_map.h" #include "class_status.h" -#include "compiler_filter.h" #include "dex/dex_file_layout.h" #include "dex/type_lookup_table.h" #include "dex/utf.h" diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc index 97254d223d..f9e099b2cb 100644 --- a/runtime/oat_file_assistant.cc +++ b/runtime/oat_file_assistant.cc @@ -24,6 +24,7 @@ #include "android-base/stringprintf.h" #include "android-base/strings.h" +#include "base/compiler_filter.h" #include "base/file_utils.h" #include "base/logging.h" // For VLOG. #include "base/macros.h" @@ -34,7 +35,6 @@ #include "base/utils.h" #include "class_linker.h" #include "class_loader_context.h" -#include "compiler_filter.h" #include "dex/art_dex_file_loader.h" #include "dex/dex_file_loader.h" #include "exec_utils.h" diff --git a/runtime/oat_file_assistant.h b/runtime/oat_file_assistant.h index 19c625b84a..9f9c91f154 100644 --- a/runtime/oat_file_assistant.h +++ b/runtime/oat_file_assistant.h @@ -22,11 +22,11 @@ #include <sstream> #include <string> +#include "base/compiler_filter.h" #include "arch/instruction_set.h" #include "base/os.h" #include "base/scoped_flock.h" #include "base/unix_file/fd_file.h" -#include "compiler_filter.h" #include "class_loader_context.h" #include "oat_file.h" diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 043384d7ee..2eeb373657 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -1070,7 +1070,10 @@ void Runtime::InitNonZygoteOrPostFork( heap_->ResetGcPerformanceInfo(); if (metrics_reporter_ != nullptr) { - metrics_reporter_->MaybeStartBackgroundThread(); + metrics::SessionData session_data{metrics::SessionData::CreateDefault()}; + session_data.session_id = GetRandomNumber<int64_t>(0, std::numeric_limits<int64_t>::max()); + // TODO: set session_data.compilation_reason and session_data.compiler_filter + metrics_reporter_->MaybeStartBackgroundThread(session_data); } StartSignalCatcher(); |