Loading cmds/installd/dexopt.cpp +5 −4 Original line number Diff line number Diff line Loading @@ -1917,10 +1917,11 @@ int dexopt(const char* dex_path, uid_t uid, const char* pkgname, const char* ins // Open the reference profile if needed. UniqueFile reference_profile = maybe_open_reference_profile( pkgname, dex_path, profile_name, profile_guided, is_public, uid, is_secondary_dex); if (reference_profile.fd() == -1) { // We don't create an app image without reference profile since there is no speedup from // loading it in that case and instead will be a small overhead. struct stat sbuf; if (reference_profile.fd() == -1 || (fstat(reference_profile.fd(), &sbuf) != -1 && sbuf.st_size == 0)) { // We don't create an app image with empty or non existing reference profile since there // is no speedup from loading it in that case and instead will be a small overhead. generate_app_image = false; } Loading cmds/installd/tests/installd_dexopt_test.cpp +52 −32 Original line number Diff line number Diff line Loading @@ -185,7 +185,7 @@ protected: std::optional<std::string> volume_uuid_; std::string package_name_; std::string apk_path_; std::string empty_dm_file_; std::string dm_file_; std::string app_apk_dir_; std::string app_private_dir_ce_; std::string app_private_dir_de_; Loading Loading @@ -248,26 +248,6 @@ protected: << " : " << error_msg; } // Create an empty dm file. empty_dm_file_ = apk_path_ + ".dm"; { int fd = open(empty_dm_file_.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); if (fd < 0) { return ::testing::AssertionFailure() << "Could not open " << empty_dm_file_; } FILE* file = fdopen(fd, "wb"); if (file == nullptr) { return ::testing::AssertionFailure() << "Null file for " << empty_dm_file_ << " fd=" << fd; } ZipWriter writer(file); // Add vdex to zip. writer.StartEntry("primary.prof", ZipWriter::kCompress); writer.FinishEntry(); writer.Finish(); fclose(file); } // Create the app user data. binder::Status status = service_->createAppData( volume_uuid_, Loading Loading @@ -316,6 +296,46 @@ protected: << secondary_dex_de_ << " : " << error_msg; } // Create a non-empty dm file. dm_file_ = apk_path_ + ".dm"; { android::base::unique_fd fd(open(dm_file_.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)); if (fd.get() < 0) { return ::testing::AssertionFailure() << "Could not open " << dm_file_; } FILE* file = fdopen(fd.release(), "wb"); if (file == nullptr) { return ::testing::AssertionFailure() << "Null file for " << dm_file_ << " fd=" << fd.get(); } // Create a profile file. std::string profile_file = app_private_dir_ce_ + "/primary.prof"; run_cmd("profman --generate-test-profile=" + profile_file); // Add profile to zip. ZipWriter writer(file); writer.StartEntry("primary.prof", ZipWriter::kCompress); android::base::unique_fd profile_fd(open(profile_file.c_str(), O_RDONLY)); if (profile_fd.get() < 0) { return ::testing::AssertionFailure() << "Failed to open profile '" << profile_file << "'"; } std::string profile_content; if (!android::base::ReadFdToString(profile_fd, &profile_content)) { return ::testing::AssertionFailure() << "Failed to read profile " << profile_file << "'"; } writer.WriteBytes(profile_content.c_str(), profile_content.length()); writer.FinishEntry(); writer.Finish(); fclose(file); // Delete the temp file. unlink(profile_file.c_str()); } // Fix app data uid. status = service_->fixupAppData(volume_uuid_, kTestUserId); if (!status.isOk()) { Loading Loading @@ -608,7 +628,7 @@ protected: kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); int64_t odex_size = GetSize(GetPrimaryDexArtifact(oat_dir, apk_path_, Loading Loading @@ -657,13 +677,13 @@ protected: DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED | DEXOPT_PUBLIC | DEXOPT_GENERATE_APP_IMAGE, oat_dir, kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); /*binder_result=*/nullptr, dm_file_.c_str()); checkVisibility(in_dalvik_cache, ODEX_IS_PUBLIC); CompilePrimaryDexOk("speed-profile", DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED | DEXOPT_GENERATE_APP_IMAGE, oat_dir, kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); /*binder_result=*/nullptr, dm_file_.c_str()); checkVisibility(in_dalvik_cache, ODEX_IS_PRIVATE); } }; Loading Loading @@ -787,7 +807,7 @@ TEST_F(DexoptTest, DexoptPrimaryProfileNonPublic) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); } TEST_F(DexoptTest, DexoptPrimaryProfilePublic) { Loading @@ -799,7 +819,7 @@ TEST_F(DexoptTest, DexoptPrimaryProfilePublic) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); } TEST_F(DexoptTest, DexoptPrimaryBackgroundOk) { Loading @@ -811,7 +831,7 @@ TEST_F(DexoptTest, DexoptPrimaryBackgroundOk) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); } TEST_F(DexoptTest, DexoptBlockPrimary) { Loading Loading @@ -874,7 +894,7 @@ TEST_F(DexoptTest, ResolveStartupConstStrings) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); run_cmd_and_process_output( "oatdump --header-only --oat-file=" + odex, [&](const std::string& line) { Loading @@ -893,7 +913,7 @@ TEST_F(DexoptTest, ResolveStartupConstStrings) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); run_cmd_and_process_output( "oatdump --header-only --oat-file=" + odex, [&](const std::string& line) { Loading Loading @@ -926,7 +946,7 @@ TEST_F(DexoptTest, DexoptDex2oat64Enabled) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); // Enable the property and use dex2oat64. ASSERT_TRUE(android::base::SetProperty(property, "true")) << property; CompilePrimaryDexOk("speed-profile", Loading @@ -936,7 +956,7 @@ TEST_F(DexoptTest, DexoptDex2oat64Enabled) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); } class PrimaryDexReCompilationTest : public DexoptTest { Loading Loading @@ -1143,7 +1163,7 @@ class ProfileTest : public DexoptTest { service_->prepareAppProfile(package_name, has_user_id ? kTestUserId : USER_NULL, kTestAppId, profile_name, apk_path_, has_dex_metadata ? std::make_optional<std::string>( empty_dm_file_) dm_file_) : std::nullopt, &result)); ASSERT_EQ(expected_result, result); Loading include/input/PropertyMap.h +7 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,10 @@ #include <android-base/result.h> #include <utils/Tokenizer.h> #include <string> #include <unordered_map> #include <unordered_set> namespace android { Loading Loading @@ -57,6 +60,9 @@ public: */ void addProperty(const std::string& key, const std::string& value); /* Returns a set of all property keys starting with the given prefix. */ std::unordered_set<std::string> getKeysWithPrefix(const std::string& prefix) const; /* Gets the value of a property and parses it. * Returns true and sets outValue if the key was found and its value was parsed successfully. * Otherwise returns false and does not modify outValue. (Also logs a warning.) Loading @@ -65,6 +71,7 @@ public: bool tryGetProperty(const std::string& key, bool& outValue) const; bool tryGetProperty(const std::string& key, int32_t& outValue) const; bool tryGetProperty(const std::string& key, float& outValue) const; bool tryGetProperty(const std::string& key, double& outValue) const; /* Adds all values from the specified property map. */ void addAll(const PropertyMap* map); Loading libs/binder/RpcSession.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <dlfcn.h> #include <inttypes.h> #include <netinet/tcp.h> #include <poll.h> #include <unistd.h> Loading Loading @@ -608,6 +609,18 @@ status_t RpcSession::setupOneSocketConnection(const RpcSocketAddress& addr, return -savedErrno; } if (addr.addr()->sa_family == AF_INET || addr.addr()->sa_family == AF_INET6) { int noDelay = 1; int result = setsockopt(serverFd.get(), IPPROTO_TCP, TCP_NODELAY, &noDelay, sizeof(noDelay)); if (result < 0) { int savedErrno = errno; ALOGE("Could not set TCP_NODELAY on %s: %s", addr.toString().c_str(), strerror(savedErrno)); return -savedErrno; } } RpcTransportFd transportFd(std::move(serverFd)); if (0 != TEMP_FAILURE_RETRY(connect(transportFd.fd.get(), addr.addr(), addr.addrSize()))) { Loading libs/binder/RpcState.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -1036,8 +1036,8 @@ processTransactInternalTailCall: return DEAD_OBJECT; } if (it->second.asyncTodo.size() == 0) return OK; if (it->second.asyncTodo.top().asyncNumber == it->second.asyncNumber) { if (it->second.asyncTodo.size() != 0 && it->second.asyncTodo.top().asyncNumber == it->second.asyncNumber) { LOG_RPC_DETAIL("Found next async transaction %" PRIu64 " on %" PRIu64, it->second.asyncNumber, addr); Loading Loading
cmds/installd/dexopt.cpp +5 −4 Original line number Diff line number Diff line Loading @@ -1917,10 +1917,11 @@ int dexopt(const char* dex_path, uid_t uid, const char* pkgname, const char* ins // Open the reference profile if needed. UniqueFile reference_profile = maybe_open_reference_profile( pkgname, dex_path, profile_name, profile_guided, is_public, uid, is_secondary_dex); if (reference_profile.fd() == -1) { // We don't create an app image without reference profile since there is no speedup from // loading it in that case and instead will be a small overhead. struct stat sbuf; if (reference_profile.fd() == -1 || (fstat(reference_profile.fd(), &sbuf) != -1 && sbuf.st_size == 0)) { // We don't create an app image with empty or non existing reference profile since there // is no speedup from loading it in that case and instead will be a small overhead. generate_app_image = false; } Loading
cmds/installd/tests/installd_dexopt_test.cpp +52 −32 Original line number Diff line number Diff line Loading @@ -185,7 +185,7 @@ protected: std::optional<std::string> volume_uuid_; std::string package_name_; std::string apk_path_; std::string empty_dm_file_; std::string dm_file_; std::string app_apk_dir_; std::string app_private_dir_ce_; std::string app_private_dir_de_; Loading Loading @@ -248,26 +248,6 @@ protected: << " : " << error_msg; } // Create an empty dm file. empty_dm_file_ = apk_path_ + ".dm"; { int fd = open(empty_dm_file_.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); if (fd < 0) { return ::testing::AssertionFailure() << "Could not open " << empty_dm_file_; } FILE* file = fdopen(fd, "wb"); if (file == nullptr) { return ::testing::AssertionFailure() << "Null file for " << empty_dm_file_ << " fd=" << fd; } ZipWriter writer(file); // Add vdex to zip. writer.StartEntry("primary.prof", ZipWriter::kCompress); writer.FinishEntry(); writer.Finish(); fclose(file); } // Create the app user data. binder::Status status = service_->createAppData( volume_uuid_, Loading Loading @@ -316,6 +296,46 @@ protected: << secondary_dex_de_ << " : " << error_msg; } // Create a non-empty dm file. dm_file_ = apk_path_ + ".dm"; { android::base::unique_fd fd(open(dm_file_.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)); if (fd.get() < 0) { return ::testing::AssertionFailure() << "Could not open " << dm_file_; } FILE* file = fdopen(fd.release(), "wb"); if (file == nullptr) { return ::testing::AssertionFailure() << "Null file for " << dm_file_ << " fd=" << fd.get(); } // Create a profile file. std::string profile_file = app_private_dir_ce_ + "/primary.prof"; run_cmd("profman --generate-test-profile=" + profile_file); // Add profile to zip. ZipWriter writer(file); writer.StartEntry("primary.prof", ZipWriter::kCompress); android::base::unique_fd profile_fd(open(profile_file.c_str(), O_RDONLY)); if (profile_fd.get() < 0) { return ::testing::AssertionFailure() << "Failed to open profile '" << profile_file << "'"; } std::string profile_content; if (!android::base::ReadFdToString(profile_fd, &profile_content)) { return ::testing::AssertionFailure() << "Failed to read profile " << profile_file << "'"; } writer.WriteBytes(profile_content.c_str(), profile_content.length()); writer.FinishEntry(); writer.Finish(); fclose(file); // Delete the temp file. unlink(profile_file.c_str()); } // Fix app data uid. status = service_->fixupAppData(volume_uuid_, kTestUserId); if (!status.isOk()) { Loading Loading @@ -608,7 +628,7 @@ protected: kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); int64_t odex_size = GetSize(GetPrimaryDexArtifact(oat_dir, apk_path_, Loading Loading @@ -657,13 +677,13 @@ protected: DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED | DEXOPT_PUBLIC | DEXOPT_GENERATE_APP_IMAGE, oat_dir, kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); /*binder_result=*/nullptr, dm_file_.c_str()); checkVisibility(in_dalvik_cache, ODEX_IS_PUBLIC); CompilePrimaryDexOk("speed-profile", DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED | DEXOPT_GENERATE_APP_IMAGE, oat_dir, kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); /*binder_result=*/nullptr, dm_file_.c_str()); checkVisibility(in_dalvik_cache, ODEX_IS_PRIVATE); } }; Loading Loading @@ -787,7 +807,7 @@ TEST_F(DexoptTest, DexoptPrimaryProfileNonPublic) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); } TEST_F(DexoptTest, DexoptPrimaryProfilePublic) { Loading @@ -799,7 +819,7 @@ TEST_F(DexoptTest, DexoptPrimaryProfilePublic) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); } TEST_F(DexoptTest, DexoptPrimaryBackgroundOk) { Loading @@ -811,7 +831,7 @@ TEST_F(DexoptTest, DexoptPrimaryBackgroundOk) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); } TEST_F(DexoptTest, DexoptBlockPrimary) { Loading Loading @@ -874,7 +894,7 @@ TEST_F(DexoptTest, ResolveStartupConstStrings) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); run_cmd_and_process_output( "oatdump --header-only --oat-file=" + odex, [&](const std::string& line) { Loading @@ -893,7 +913,7 @@ TEST_F(DexoptTest, ResolveStartupConstStrings) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); run_cmd_and_process_output( "oatdump --header-only --oat-file=" + odex, [&](const std::string& line) { Loading Loading @@ -926,7 +946,7 @@ TEST_F(DexoptTest, DexoptDex2oat64Enabled) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); // Enable the property and use dex2oat64. ASSERT_TRUE(android::base::SetProperty(property, "true")) << property; CompilePrimaryDexOk("speed-profile", Loading @@ -936,7 +956,7 @@ TEST_F(DexoptTest, DexoptDex2oat64Enabled) { kTestAppGid, DEX2OAT_FROM_SCRATCH, /*binder_result=*/nullptr, empty_dm_file_.c_str()); dm_file_.c_str()); } class PrimaryDexReCompilationTest : public DexoptTest { Loading Loading @@ -1143,7 +1163,7 @@ class ProfileTest : public DexoptTest { service_->prepareAppProfile(package_name, has_user_id ? kTestUserId : USER_NULL, kTestAppId, profile_name, apk_path_, has_dex_metadata ? std::make_optional<std::string>( empty_dm_file_) dm_file_) : std::nullopt, &result)); ASSERT_EQ(expected_result, result); Loading
include/input/PropertyMap.h +7 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,10 @@ #include <android-base/result.h> #include <utils/Tokenizer.h> #include <string> #include <unordered_map> #include <unordered_set> namespace android { Loading Loading @@ -57,6 +60,9 @@ public: */ void addProperty(const std::string& key, const std::string& value); /* Returns a set of all property keys starting with the given prefix. */ std::unordered_set<std::string> getKeysWithPrefix(const std::string& prefix) const; /* Gets the value of a property and parses it. * Returns true and sets outValue if the key was found and its value was parsed successfully. * Otherwise returns false and does not modify outValue. (Also logs a warning.) Loading @@ -65,6 +71,7 @@ public: bool tryGetProperty(const std::string& key, bool& outValue) const; bool tryGetProperty(const std::string& key, int32_t& outValue) const; bool tryGetProperty(const std::string& key, float& outValue) const; bool tryGetProperty(const std::string& key, double& outValue) const; /* Adds all values from the specified property map. */ void addAll(const PropertyMap* map); Loading
libs/binder/RpcSession.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <dlfcn.h> #include <inttypes.h> #include <netinet/tcp.h> #include <poll.h> #include <unistd.h> Loading Loading @@ -608,6 +609,18 @@ status_t RpcSession::setupOneSocketConnection(const RpcSocketAddress& addr, return -savedErrno; } if (addr.addr()->sa_family == AF_INET || addr.addr()->sa_family == AF_INET6) { int noDelay = 1; int result = setsockopt(serverFd.get(), IPPROTO_TCP, TCP_NODELAY, &noDelay, sizeof(noDelay)); if (result < 0) { int savedErrno = errno; ALOGE("Could not set TCP_NODELAY on %s: %s", addr.toString().c_str(), strerror(savedErrno)); return -savedErrno; } } RpcTransportFd transportFd(std::move(serverFd)); if (0 != TEMP_FAILURE_RETRY(connect(transportFd.fd.get(), addr.addr(), addr.addrSize()))) { Loading
libs/binder/RpcState.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -1036,8 +1036,8 @@ processTransactInternalTailCall: return DEAD_OBJECT; } if (it->second.asyncTodo.size() == 0) return OK; if (it->second.asyncTodo.top().asyncNumber == it->second.asyncNumber) { if (it->second.asyncTodo.size() != 0 && it->second.asyncTodo.top().asyncNumber == it->second.asyncNumber) { LOG_RPC_DETAIL("Found next async transaction %" PRIu64 " on %" PRIu64, it->second.asyncNumber, addr); Loading