Attach the running bitness to the boot image profile

Also, add tests for the profile saver.

Bug: 139884006
Test: gtest
Change-Id: I134c951e40859e4e6560cbdf43710c99de6b11fc
diff --git a/build/apex/art_apex_test.py b/build/apex/art_apex_test.py
index b46f038..87a9843 100755
--- a/build/apex/art_apex_test.py
+++ b/build/apex/art_apex_test.py
@@ -869,6 +869,7 @@
     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 69c6946..cfa16f8 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -644,6 +644,7 @@
         "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 fc6ec45..7f31f5c 100644
--- a/runtime/jit/profile_saver.cc
+++ b/runtime/jit/profile_saver.cc
@@ -465,10 +465,10 @@
                      << " 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 @@
                      << " 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 @@
       // 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 @@
   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(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 5cd8bff..ed0ba9f 100644
--- a/runtime/jit/profile_saver.h
+++ b/runtime/jit/profile_saver.h
@@ -106,6 +106,9 @@
   // 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 @@
   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 0000000..9a866a3
--- /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