Move class static variables to function static

Chrome bans use of static initializers. As a result we can't roll
libdexfile changes into Chromium.
This CL moves static class members DexFile::g_lock and
DexFile::g_mapped_dex_files into the static function
DexFile::CreateFromDisk(the only user of those
static class members).

Test:
  - Build `chrome/android:monochrome_static_initializers` successfully
    https://chromium.googlesource.com/chromium/src.git/+/HEAD/docs/static_initializers.md#step-1-use-objdump-to-report-them

Bug: 1365904
Change-Id: Ibfe96c18e1747c2483db0b2f0a39b4918c809298
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/third_party/libunwindstack/+/3942065
Reviewed-by: Tushar Agarwal <agarwaltushar@google.com>
Reviewed-by: Mike Wittman <wittman@chromium.org>
diff --git a/README.chromium b/README.chromium
index 3411e8a..f576ea0 100644
--- a/README.chromium
+++ b/README.chromium
@@ -180,3 +180,11 @@
   don't compile the unused sections. Required to make component debug builds
   compile
 
+- 0012-remove-class-static-variables.patch
+
+  Chrome bans static initializers:
+  https://chromium.googlesource.com/chromium/src.git/+/HEAD/docs/static_initializers.md
+  This patch moves class static variables to function static variables so
+  they can be initialized on first use instead of being initialzed at
+  app launch.
+
diff --git a/patches/0012-remove-class-static-variables.patch b/patches/0012-remove-class-static-variables.patch
new file mode 100644
index 0000000..75570d0
--- /dev/null
+++ b/patches/0012-remove-class-static-variables.patch
@@ -0,0 +1,49 @@
+diff --git a/src/libunwindstack/DexFile.cpp b/src/libunwindstack/DexFile.cpp
+index 220ee82..fb4ec49 100644
+--- a/src/libunwindstack/DexFile.cpp
++++ b/src/libunwindstack/DexFile.cpp
+@@ -34,9 +34,6 @@
+ 
+ namespace unwindstack {
+ 
+-std::map<DexFile::MappedFileKey, std::weak_ptr<DexFile::DexFileApi>> DexFile::g_mapped_dex_files;
+-std::mutex DexFile::g_lock;
+-
+ static bool CheckDexSupport() {
+   if (std::string err_msg; !art_api::dex::TryLoadLibdexfile(&err_msg)) {
+     Log::Error("Failed to initialize DEX file support: %s", err_msg.c_str());
+@@ -46,6 +43,9 @@ static bool CheckDexSupport() {
+ }
+ 
+ std::shared_ptr<DexFile> DexFile::CreateFromDisk(uint64_t addr, uint64_t size, MapInfo* map) {
++  static auto& mapped_dex_files = *new std::map<MappedFileKey, std::weak_ptr<DexFileApi>>;
++  static auto& lock = *new std::mutex;  // Guards the static cache above.
++
+   if (map == nullptr || map->name().empty()) {
+     return nullptr;  // MapInfo not backed by file.
+   }
+@@ -58,9 +58,9 @@ std::shared_ptr<DexFile> DexFile::CreateFromDisk(uint64_t addr, uint64_t size, M
+   uint64_t offset_in_file = (addr - map->start()) + map->offset();
+ 
+   // Fast-path: Check if the dex file was already mapped from disk.
+-  std::lock_guard<std::mutex> guard(g_lock);
++  std::lock_guard<std::mutex> guard(lock);
+   MappedFileKey cache_key(map->name(), offset_in_file, size);
+-  std::weak_ptr<DexFileApi>& cache_entry = g_mapped_dex_files[cache_key];
++  std::weak_ptr<DexFileApi>& cache_entry = mapped_dex_files[cache_key];
+   std::shared_ptr<DexFileApi> dex_api = cache_entry.lock();
+   if (dex_api != nullptr) {
+     return std::shared_ptr<DexFile>(new DexFile(addr, size, std::move(dex_api)));
+diff --git a/src/libunwindstack/DexFile.h b/src/libunwindstack/DexFile.h
+index 3bb65da..330dabc 100644
+--- a/src/libunwindstack/DexFile.h
++++ b/src/libunwindstack/DexFile.h
+@@ -74,8 +74,6 @@ class DexFile {
+   // Therefore, we maintain cache to avoid loading the same file (sub-range) many times.
+   // The cache is weak: It will not keep DexFiles alive (the weak_ptr will become null).
+   using MappedFileKey = std::tuple<std::string, uint64_t, uint64_t>;  // (path, offset, size).
+-  static std::map<MappedFileKey, std::weak_ptr<DexFileApi>> g_mapped_dex_files;
+-  static std::mutex g_lock;  // Guards the static cache above.
+ };
+ 
+ }  // namespace unwindstack
diff --git a/src/libunwindstack/DexFile.cpp b/src/libunwindstack/DexFile.cpp
index 220ee82..fb4ec49 100644
--- a/src/libunwindstack/DexFile.cpp
+++ b/src/libunwindstack/DexFile.cpp
@@ -34,9 +34,6 @@
 
 namespace unwindstack {
 
-std::map<DexFile::MappedFileKey, std::weak_ptr<DexFile::DexFileApi>> DexFile::g_mapped_dex_files;
-std::mutex DexFile::g_lock;
-
 static bool CheckDexSupport() {
   if (std::string err_msg; !art_api::dex::TryLoadLibdexfile(&err_msg)) {
     Log::Error("Failed to initialize DEX file support: %s", err_msg.c_str());
@@ -46,6 +43,9 @@
 }
 
 std::shared_ptr<DexFile> DexFile::CreateFromDisk(uint64_t addr, uint64_t size, MapInfo* map) {
+  static auto& mapped_dex_files = *new std::map<MappedFileKey, std::weak_ptr<DexFileApi>>;
+  static auto& lock = *new std::mutex;  // Guards the static cache above.
+
   if (map == nullptr || map->name().empty()) {
     return nullptr;  // MapInfo not backed by file.
   }
@@ -58,9 +58,9 @@
   uint64_t offset_in_file = (addr - map->start()) + map->offset();
 
   // Fast-path: Check if the dex file was already mapped from disk.
-  std::lock_guard<std::mutex> guard(g_lock);
+  std::lock_guard<std::mutex> guard(lock);
   MappedFileKey cache_key(map->name(), offset_in_file, size);
-  std::weak_ptr<DexFileApi>& cache_entry = g_mapped_dex_files[cache_key];
+  std::weak_ptr<DexFileApi>& cache_entry = mapped_dex_files[cache_key];
   std::shared_ptr<DexFileApi> dex_api = cache_entry.lock();
   if (dex_api != nullptr) {
     return std::shared_ptr<DexFile>(new DexFile(addr, size, std::move(dex_api)));
diff --git a/src/libunwindstack/DexFile.h b/src/libunwindstack/DexFile.h
index 3bb65da..330dabc 100644
--- a/src/libunwindstack/DexFile.h
+++ b/src/libunwindstack/DexFile.h
@@ -74,8 +74,6 @@
   // Therefore, we maintain cache to avoid loading the same file (sub-range) many times.
   // The cache is weak: It will not keep DexFiles alive (the weak_ptr will become null).
   using MappedFileKey = std::tuple<std::string, uint64_t, uint64_t>;  // (path, offset, size).
-  static std::map<MappedFileKey, std::weak_ptr<DexFileApi>> g_mapped_dex_files;
-  static std::mutex g_lock;  // Guards the static cache above.
 };
 
 }  // namespace unwindstack