Improve dex location canonicalization-related performance.
Eagerly add canonical dex file locations to the OatFile's
primary lookup map in Setup(). This moves the boot.oat work
from every app startup to the zygote initialization. Since
we always ended up initializing the canonical location map
anyway due to the way that we're loading dex files, the lazy
initialization didn't save anything.
Clean up dex file name canonicalization to make sure we
free() the memory returned by realpath() rather than using
std::unique_ptr<> with the default deleter.
Avoid some unnecessary duplicate OatDexFile lookups.
Bug: 16828525
Bug: 17346103
(cherry picked from commit aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4)
Change-Id: Icc4b14ebe903282ca91ce24e33a6d7c75dff991c
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 1da1f81..50d7e54 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -389,14 +389,21 @@
// For normal dex files, location and base location coincide. If a dex file is part of a multidex
// archive, the base location is the name of the originating jar/apk, stripped of any internal
// classes*.dex path.
- const std::string GetBaseLocation() const {
- if (IsMultiDexLocation(location_.c_str())) {
- std::pair<const char*, const char*> pair = SplitMultiDexLocation(location_.c_str());
- std::string res(pair.first);
- delete[] pair.first;
- return res;
+ static std::string GetBaseLocation(const char* location) {
+ const char* pos = strrchr(location, kMultiDexSeparator);
+ if (pos == nullptr) {
+ return location;
} else {
+ return std::string(location, pos - location);
+ }
+ }
+
+ std::string GetBaseLocation() const {
+ size_t pos = location_.rfind(kMultiDexSeparator);
+ if (pos == std::string::npos) {
return location_;
+ } else {
+ return location_.substr(0, pos);
}
}
@@ -918,13 +925,6 @@
// whether the string contains the separator character.
static bool IsMultiDexLocation(const char* location);
- // Splits a multidex location at the last separator character. The second component is a pointer
- // to the character after the separator. The first is a copy of the substring up to the separator.
- //
- // Note: It's the caller's job to free the first component of the returned pair.
- // Bug 15313523: gcc/libc++ don't allow a unique_ptr for the first component
- static std::pair<const char*, const char*> SplitMultiDexLocation(const char* location);
-
// The base address of the memory mapping.
const byte* const begin_;