Deduplicate interned image strings.
Also fix a bug in relocation; even for -Xnorelocate we need
to relocate second and later extension if it's not compiled
against all previous boot image components.
Also clean up InternTable includes.
Test: New tests in image_space_test.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: aosp_taimen-userdebug boots.
Bug: 152037801
Change-Id: Ie6ae70721f4ffb48950bd248ffa123dee460bcd7
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index 640e182..a846346 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -41,7 +41,9 @@
#include "dex/art_dex_file_loader.h"
#include "dex/dex_file-inl.h"
#include "dex/dex_file_loader.h"
+#include "dex/method_reference.h"
#include "dex/primitive.h"
+#include "dex/type_reference.h"
#include "gc/heap.h"
#include "gc/space/image_space.h"
#include "gc_root-inl.h"
@@ -56,6 +58,7 @@
#include "mirror/object_array-alloc-inl.h"
#include "native/dalvik_system_DexFile.h"
#include "noop_compiler_callbacks.h"
+#include "profile/profile_compilation_info.h"
#include "runtime-inl.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"
@@ -408,18 +411,16 @@
}
bool CommonRuntimeTestImpl::StartDex2OatCommandLine(/*out*/std::vector<std::string>* argv,
- /*out*/std::string* error_msg) {
+ /*out*/std::string* error_msg,
+ bool use_runtime_bcp_and_image) {
DCHECK(argv != nullptr);
DCHECK(argv->empty());
Runtime* runtime = Runtime::Current();
- const std::vector<gc::space::ImageSpace*>& image_spaces =
- runtime->GetHeap()->GetBootImageSpaces();
- if (image_spaces.empty()) {
+ if (use_runtime_bcp_and_image && runtime->GetHeap()->GetBootImageSpaces().empty()) {
*error_msg = "No image location found for Dex2Oat.";
return false;
}
- std::string image_location = image_spaces[0]->GetImageLocation();
argv->push_back(runtime->GetCompilerExecutable());
if (runtime->IsJavaDebuggable()) {
@@ -427,12 +428,17 @@
}
runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(argv);
- argv->push_back("--runtime-arg");
- argv->push_back(GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames()));
- argv->push_back("--runtime-arg");
- argv->push_back(GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations()));
+ if (use_runtime_bcp_and_image) {
+ argv->push_back("--runtime-arg");
+ argv->push_back(GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames()));
+ argv->push_back("--runtime-arg");
+ argv->push_back(GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations()));
- argv->push_back("--boot-image=" + image_location);
+ const std::vector<gc::space::ImageSpace*>& image_spaces =
+ runtime->GetHeap()->GetBootImageSpaces();
+ DCHECK(!image_spaces.empty());
+ argv->push_back("--boot-image=" + image_spaces[0]->GetImageLocation());
+ }
std::vector<std::string> compiler_options = runtime->GetCompilerOptions();
argv->insert(argv->end(), compiler_options.begin(), compiler_options.end());
@@ -560,6 +566,64 @@
return Runtime::Current()->IsTransactionAborted();
}
+void CommonRuntimeTestImpl::VisitDexes(ArrayRef<const std::string> dexes,
+ const std::function<void(MethodReference)>& method_visitor,
+ const std::function<void(TypeReference)>& class_visitor,
+ size_t method_frequency,
+ size_t class_frequency) {
+ size_t method_counter = 0;
+ size_t class_counter = 0;
+ for (const std::string& dex : dexes) {
+ std::vector<std::unique_ptr<const DexFile>> dex_files;
+ std::string error_msg;
+ const ArtDexFileLoader dex_file_loader;
+ CHECK(dex_file_loader.Open(dex.c_str(),
+ dex,
+ /*verify*/ true,
+ /*verify_checksum*/ false,
+ &error_msg,
+ &dex_files))
+ << error_msg;
+ for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
+ for (size_t i = 0; i < dex_file->NumMethodIds(); ++i) {
+ if (++method_counter % method_frequency == 0) {
+ method_visitor(MethodReference(dex_file.get(), i));
+ }
+ }
+ for (size_t i = 0; i < dex_file->NumTypeIds(); ++i) {
+ if (++class_counter % class_frequency == 0) {
+ class_visitor(TypeReference(dex_file.get(), dex::TypeIndex(i)));
+ }
+ }
+ }
+ }
+}
+
+void CommonRuntimeTestImpl::GenerateProfile(ArrayRef<const std::string> dexes,
+ File* out_file,
+ size_t method_frequency,
+ size_t type_frequency) {
+ ProfileCompilationInfo profile;
+ VisitDexes(
+ dexes,
+ [&profile](MethodReference ref) {
+ uint32_t flags = ProfileCompilationInfo::MethodHotness::kFlagHot |
+ ProfileCompilationInfo::MethodHotness::kFlagStartup;
+ EXPECT_TRUE(profile.AddMethod(
+ ProfileMethodInfo(ref),
+ static_cast<ProfileCompilationInfo::MethodHotness::Flag>(flags)));
+ },
+ [&profile](TypeReference ref) {
+ std::set<dex::TypeIndex> classes;
+ classes.insert(ref.TypeIndex());
+ EXPECT_TRUE(profile.AddClassesForDex(ref.dex_file, classes.begin(), classes.end()));
+ },
+ method_frequency,
+ type_frequency);
+ profile.Save(out_file->Fd());
+ EXPECT_EQ(out_file->Flush(), 0);
+}
+
CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
vm_->SetCheckJniAbortHook(Hook, &actual_);
}