Handle gracefully profiles with invalid classes or methods

Bug: 38410980
Test: m test-art-host-run-test-707
Change-Id: I8c1b0a00c113c0faf0cc5d141e67e4183322520f
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index 41b9f99..1c32898 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -759,4 +759,63 @@
   CheckProfileInfo(profile1, info1);
 }
 
+TEST_F(ProfileAssistantTest, TestProfileCreateWithInvalidData) {
+  // Create the profile content.
+  std::vector<std::string> profile_methods = {
+    "LTestInline;->inlineMonomorphic(LSuper;)I+invalid_class",
+    "LTestInline;->invalid_method",
+    "invalid_class"
+  };
+  std::string input_file_contents;
+  for (std::string& m : profile_methods) {
+    input_file_contents += m + std::string("\n");
+  }
+
+  // Create the profile and save it to disk.
+  ScratchFile profile_file;
+  std::string dex_filename = GetTestDexFileName("ProfileTestMultiDex");
+  ASSERT_TRUE(CreateProfile(input_file_contents,
+                            profile_file.GetFilename(),
+                            dex_filename));
+
+  // Load the profile from disk.
+  ProfileCompilationInfo info;
+  profile_file.GetFile()->ResetOffset();
+  ASSERT_TRUE(info.Load(GetFd(profile_file)));
+
+  // Load the dex files and verify that the profile contains the expected methods info.
+  ScopedObjectAccess soa(Thread::Current());
+  jobject class_loader = LoadDex("ProfileTestMultiDex");
+  ASSERT_NE(class_loader, nullptr);
+
+  ArtMethod* inline_monomorphic = GetVirtualMethod(class_loader,
+                                                   "LTestInline;",
+                                                   "inlineMonomorphic");
+  const DexFile* dex_file = inline_monomorphic->GetDexFile();
+
+  // Verify that the inline cache contains the invalid type.
+  std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> pmi =
+      info.GetMethod(dex_file->GetLocation(),
+                     dex_file->GetLocationChecksum(),
+                     inline_monomorphic->GetDexMethodIndex());
+  ASSERT_TRUE(pmi != nullptr);
+  ASSERT_EQ(pmi->inline_caches->size(), 1u);
+  const ProfileCompilationInfo::DexPcData& dex_pc_data = pmi->inline_caches->begin()->second;
+  dex::TypeIndex invalid_class_index(std::numeric_limits<uint16_t>::max() - 1);
+  ASSERT_EQ(1u, dex_pc_data.classes.size());
+  ASSERT_EQ(invalid_class_index, dex_pc_data.classes.begin()->type_index);
+
+  // Verify that the start-up classes contain the invalid class.
+  std::set<dex::TypeIndex> classes;
+  std::set<uint16_t> methods;
+  ASSERT_TRUE(info.GetClassesAndMethods(*dex_file, &classes, &methods));
+  ASSERT_EQ(1u, classes.size());
+  ASSERT_TRUE(classes.find(invalid_class_index) != classes.end());
+
+  // Verify that the invalid method is in the profile.
+  ASSERT_EQ(2u, methods.size());
+  uint16_t invalid_method_index = std::numeric_limits<uint16_t>::max() - 1;
+  ASSERT_TRUE(methods.find(invalid_method_index) != methods.end());
+}
+
 }  // namespace art