diff options
-rwxr-xr-x | build/apex/art_apex_test.py | 1 | ||||
-rw-r--r-- | runtime/Android.bp | 1 | ||||
-rw-r--r-- | runtime/jit/profile_saver.cc | 32 | ||||
-rw-r--r-- | runtime/jit/profile_saver.h | 7 | ||||
-rw-r--r-- | runtime/jit/profile_saver_test.cc | 110 |
5 files changed, 142 insertions, 9 deletions
diff --git a/build/apex/art_apex_test.py b/build/apex/art_apex_test.py index b46f0383c1..87a9843f95 100755 --- a/build/apex/art_apex_test.py +++ b/build/apex/art_apex_test.py @@ -869,6 +869,7 @@ class TestingTargetChecker: self._checker.check_art_test_executable('parsed_options_test') self._checker.check_art_test_executable('prebuilt_tools_test') self._checker.check_art_test_executable('profiling_info_test') + self._checker.check_art_test_executable('profile_saver_test') self._checker.check_art_test_executable('proxy_test') self._checker.check_art_test_executable('quick_trampoline_entrypoints_test') self._checker.check_art_test_executable('reference_queue_test') diff --git a/runtime/Android.bp b/runtime/Android.bp index 69c6946388..cfa16f87dc 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -644,6 +644,7 @@ art_cc_test { "interpreter/unstarted_runtime_test.cc", "jdwp/jdwp_options_test.cc", "jit/jit_memory_region_test.cc", + "jit/profile_saver_test.cc", "jit/profiling_info_test.cc", "jni/java_vm_ext_test.cc", "jni/jni_internal_test.cc", diff --git a/runtime/jit/profile_saver.cc b/runtime/jit/profile_saver.cc index fc6ec455db..7f31f5cbb1 100644 --- a/runtime/jit/profile_saver.cc +++ b/runtime/jit/profile_saver.cc @@ -465,10 +465,10 @@ void ProfileSaver::FetchAndCacheResolvedClassesAndMethods(bool startup) { << " found=" << (locations.find(base_location) != locations.end()) << " indices size=" << indices.size(); if (locations.find(base_location) != locations.end()) { - uint8_t flags = Hotness::kFlagHot; + uint32_t flags = Hotness::kFlagHot; flags |= startup ? Hotness::kFlagStartup : Hotness::kFlagPostStartup; cached_info->AddMethodsForDex( - static_cast<Hotness::Flag>(flags), + AnnotateSampleFlags(flags), dex_file, indices.begin(), indices.end(), @@ -483,11 +483,12 @@ void ProfileSaver::FetchAndCacheResolvedClassesAndMethods(bool startup) { << " found=" << (locations.find(base_location) != locations.end()) << " indices size=" << indices.size(); if (locations.find(base_location) != locations.end()) { - cached_info->AddMethodsForDex(startup ? Hotness::kFlagStartup : Hotness::kFlagPostStartup, - dex_file, - indices.begin(), - indices.end(), - GetProfileSampleAnnotation()); + cached_info->AddMethodsForDex( + AnnotateSampleFlags(startup ? Hotness::kFlagStartup : Hotness::kFlagPostStartup), + dex_file, + indices.begin(), + indices.end(), + GetProfileSampleAnnotation()); } } for (const auto& pair : resolved_classes.GetMap()) { @@ -576,7 +577,7 @@ bool ProfileSaver::ProcessProfilingInfo(bool force_save, /*out*/uint16_t* number // If this happens we clear the profile data and for the save to ensure the file is cleared. if (!info.AddMethods( profile_methods, - static_cast<Hotness::Flag>(Hotness::kFlagHot | Hotness::kFlagPostStartup), + AnnotateSampleFlags(Hotness::kFlagHot | Hotness::kFlagPostStartup), GetProfileSampleAnnotation())) { LOG(WARNING) << "Could not add methods to the existing profiler. " << "Clearing the profile data."; @@ -702,7 +703,7 @@ static bool ShouldProfileLocation(const std::string& location, bool profile_aot_ return true; } -void ProfileSaver::Start(const ProfileSaverOptions& options, +void ProfileSaver::Start(const ProfileSaverOptions& options, const std::string& output_filename, jit::JitCodeCache* jit_code_cache, const std::vector<std::string>& code_paths) { @@ -987,4 +988,17 @@ ProfileCompilationInfo::ProfileSampleAnnotation ProfileSaver::GetProfileSampleAn ? ProfileCompilationInfo::ProfileSampleAnnotation(package_name) : ProfileCompilationInfo::ProfileSampleAnnotation::kNone; } + +Hotness::Flag ProfileSaver::AnnotateSampleFlags(uint32_t flags) { + uint32_t extra_flags = 0; + // We only add the extra flags for the boot image profile because individual apps do not use + // this information. + if (options_.GetProfileBootClassPath()) { + extra_flags = Is64BitInstructionSet(Runtime::Current()->GetInstructionSet()) + ? Hotness::kFlag64bit + : Hotness::kFlag32bit; + } + return static_cast<Hotness::Flag>(flags | extra_flags); +} + } // namespace art diff --git a/runtime/jit/profile_saver.h b/runtime/jit/profile_saver.h index 5cd8bff5a2..ed0ba9f0c5 100644 --- a/runtime/jit/profile_saver.h +++ b/runtime/jit/profile_saver.h @@ -106,6 +106,9 @@ class ProfileSaver { // profile saver session. ProfileCompilationInfo::ProfileSampleAnnotation GetProfileSampleAnnotation(); + // Extends the given set of flags with global flags if necessary (e.g. the running architecture). + ProfileCompilationInfo::MethodHotness::Flag AnnotateSampleFlags(uint32_t flags); + // The only instance of the saver. static ProfileSaver* instance_ GUARDED_BY(Locks::profiler_lock_); // Profile saver thread. @@ -152,6 +155,10 @@ class ProfileSaver { uint64_t total_number_of_wake_ups_; const ProfileSaverOptions options_; + + friend class ProfileSaverTest; + friend class ProfileSaverForBootTest; + DISALLOW_COPY_AND_ASSIGN(ProfileSaver); }; diff --git a/runtime/jit/profile_saver_test.cc b/runtime/jit/profile_saver_test.cc new file mode 100644 index 0000000000..9a866a3eb4 --- /dev/null +++ b/runtime/jit/profile_saver_test.cc @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2019 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 <gtest/gtest.h> + +#include "common_runtime_test.h" +#include "compiler_callbacks.h" +#include "jit/jit.h" +#include "profile_saver.h" +#include "profile/profile_compilation_info.h" + +namespace art { + +using Hotness = ProfileCompilationInfo::MethodHotness; + +class ProfileSaverTest : public CommonRuntimeTest { + public: + void SetUpRuntimeOptions(RuntimeOptions *options) override { + // Reset the callbacks so that the runtime doesn't think it's for AOT. + callbacks_ = nullptr; + CommonRuntimeTest::SetUpRuntimeOptions(options); + // Enable profile saving and the jit. + options->push_back(std::make_pair("-Xjitsaveprofilinginfo", nullptr)); + options->push_back(std::make_pair("-Xusejit:true", nullptr)); + } + + void PostRuntimeCreate() override { + // Create a profile saver. + Runtime* runtime = Runtime::Current(); + const std::vector<std::string> code_paths; + const std::string fake_file = "fake_file"; + profile_saver_ = new ProfileSaver( + runtime->GetJITOptions()->GetProfileSaverOptions(), + fake_file, + runtime->GetJitCodeCache(), + code_paths); + } + + ~ProfileSaverTest() { + if (profile_saver_ != nullptr) { + delete profile_saver_; + } + } + + ProfileCompilationInfo::ProfileSampleAnnotation GetProfileSampleAnnotation() { + return profile_saver_->GetProfileSampleAnnotation(); + } + + Hotness::Flag AnnotateSampleFlags(uint32_t flags) { + return profile_saver_->AnnotateSampleFlags(flags); + } + + protected: + ProfileSaver* profile_saver_ = nullptr; +}; + +// Test profile saving operations for boot image. +class ProfileSaverForBootTest : public ProfileSaverTest { + public: + void SetUpRuntimeOptions(RuntimeOptions *options) override { + ProfileSaverTest::SetUpRuntimeOptions(options); + options->push_back(std::make_pair("-Xps-profile-boot-class-path", nullptr)); + } +}; + +TEST_F(ProfileSaverTest, GetProfileSampleAnnotation) { + ASSERT_EQ(ProfileCompilationInfo::ProfileSampleAnnotation::kNone, + GetProfileSampleAnnotation()); +} + +TEST_F(ProfileSaverForBootTest, GetProfileSampleAnnotationUnkown) { + ProfileCompilationInfo::ProfileSampleAnnotation expected("unknown"); + ASSERT_EQ(expected, GetProfileSampleAnnotation()); +} + +TEST_F(ProfileSaverForBootTest, GetProfileSampleAnnotation) { + Runtime::Current()->SetProcessPackageName("test.package"); + ProfileCompilationInfo::ProfileSampleAnnotation expected("test.package"); + ASSERT_EQ(expected, GetProfileSampleAnnotation()); +} + +TEST_F(ProfileSaverForBootTest, AnnotateSampleFlags) { + Hotness::Flag expected_flag = Is64BitInstructionSet(Runtime::Current()->GetInstructionSet()) + ? Hotness::kFlag64bit + : Hotness::kFlag32bit; + Hotness::Flag actual = AnnotateSampleFlags(Hotness::kFlagHot); + + ASSERT_EQ(static_cast<Hotness::Flag>(expected_flag | Hotness::kFlagHot), actual); +} + +TEST_F(ProfileSaverTest, AnnotateSampleFlags) { + Hotness::Flag actual = AnnotateSampleFlags(Hotness::kFlagHot); + + ASSERT_EQ(Hotness::kFlagHot, actual); +} + +} // namespace art |