Revert^2 "Compile link-time thunks in codegen."

The linker crash (the reason for revert) is flaky and maybe
we shall not see it with this CL now that unrelated source
code has changed.

Test: Rely on TreeHugger
Bug: 36141117
Bug: 77581732

This reverts commit 5806a9ec99b5494b511e84c74f494f0b3a8ebec5.

Change-Id: I3a4a058847dff601681ba391abf45833424fa06d
diff --git a/compiler/driver/compiled_method_storage.cc b/compiler/driver/compiled_method_storage.cc
index a26a985..aa8277e 100644
--- a/compiler/driver/compiled_method_storage.cc
+++ b/compiler/driver/compiled_method_storage.cc
@@ -161,6 +161,46 @@
   SwapSpace* const swap_space_;
 };
 
+class CompiledMethodStorage::ThunkMapKey {
+ public:
+  ThunkMapKey(linker::LinkerPatch::Type type, uint32_t custom_value1, uint32_t custom_value2)
+      : type_(type), custom_value1_(custom_value1), custom_value2_(custom_value2) {}
+
+  bool operator<(const ThunkMapKey& other) const {
+    if (custom_value1_ != other.custom_value1_) {
+      return custom_value1_ < other.custom_value1_;
+    }
+    if (custom_value2_ != other.custom_value2_) {
+      return custom_value2_ < other.custom_value2_;
+    }
+    return type_ < other.type_;
+  }
+
+ private:
+  linker::LinkerPatch::Type type_;
+  uint32_t custom_value1_;
+  uint32_t custom_value2_;
+};
+
+class CompiledMethodStorage::ThunkMapValue {
+ public:
+  ThunkMapValue(std::vector<uint8_t, SwapAllocator<uint8_t>>&& code,
+                const std::string& debug_name)
+      : code_(std::move(code)), debug_name_(debug_name) {}
+
+  ArrayRef<const uint8_t> GetCode() const {
+    return ArrayRef<const uint8_t>(code_);
+  }
+
+  const std::string& GetDebugName() const {
+    return debug_name_;
+  }
+
+ private:
+  std::vector<uint8_t, SwapAllocator<uint8_t>> code_;
+  std::string debug_name_;
+};
+
 CompiledMethodStorage::CompiledMethodStorage(int swap_fd)
     : swap_space_(swap_fd == -1 ? nullptr : new SwapSpace(swap_fd, 10 * MB)),
       dedupe_enabled_(true),
@@ -171,7 +211,9 @@
                          LengthPrefixedArrayAlloc<uint8_t>(swap_space_.get())),
       dedupe_cfi_info_("dedupe cfi info", LengthPrefixedArrayAlloc<uint8_t>(swap_space_.get())),
       dedupe_linker_patches_("dedupe cfi info",
-                             LengthPrefixedArrayAlloc<linker::LinkerPatch>(swap_space_.get())) {
+                             LengthPrefixedArrayAlloc<linker::LinkerPatch>(swap_space_.get())),
+      thunk_map_lock_("thunk_map_lock"),
+      thunk_map_(std::less<ThunkMapKey>(), SwapAllocator<ThunkMapValueType>(swap_space_.get())) {
 }
 
 CompiledMethodStorage::~CompiledMethodStorage() {
@@ -237,4 +279,55 @@
   ReleaseArrayIfNotDeduplicated(linker_patches);
 }
 
+CompiledMethodStorage::ThunkMapKey CompiledMethodStorage::GetThunkMapKey(
+    const linker::LinkerPatch& linker_patch) {
+  uint32_t custom_value1 = 0u;
+  uint32_t custom_value2 = 0u;
+  switch (linker_patch.GetType()) {
+    case linker::LinkerPatch::Type::kBakerReadBarrierBranch:
+      custom_value1 = linker_patch.GetBakerCustomValue1();
+      custom_value2 = linker_patch.GetBakerCustomValue2();
+      break;
+    case linker::LinkerPatch::Type::kCallRelative:
+      // No custom values.
+      break;
+    default:
+      LOG(FATAL) << "Unexpected patch type: " << linker_patch.GetType();
+      UNREACHABLE();
+  }
+  return ThunkMapKey(linker_patch.GetType(), custom_value1, custom_value2);
+}
+
+ArrayRef<const uint8_t> CompiledMethodStorage::GetThunkCode(const linker::LinkerPatch& linker_patch,
+                                                            /*out*/ std::string* debug_name) {
+  ThunkMapKey key = GetThunkMapKey(linker_patch);
+  MutexLock lock(Thread::Current(), thunk_map_lock_);
+  auto it = thunk_map_.find(key);
+  if (it != thunk_map_.end()) {
+    const ThunkMapValue& value = it->second;
+    if (debug_name != nullptr) {
+      *debug_name = value.GetDebugName();
+    }
+    return value.GetCode();
+  } else {
+    if (debug_name != nullptr) {
+      *debug_name = std::string();
+    }
+    return ArrayRef<const uint8_t>();
+  }
+}
+
+void CompiledMethodStorage::SetThunkCode(const linker::LinkerPatch& linker_patch,
+                                         ArrayRef<const uint8_t> code,
+                                         const std::string& debug_name) {
+  DCHECK(!code.empty());
+  ThunkMapKey key = GetThunkMapKey(linker_patch);
+  std::vector<uint8_t, SwapAllocator<uint8_t>> code_copy(
+      code.begin(), code.end(), SwapAllocator<uint8_t>(swap_space_.get()));
+  ThunkMapValue value(std::move(code_copy), debug_name);
+  MutexLock lock(Thread::Current(), thunk_map_lock_);
+  // Note: Multiple threads can try and compile the same thunk, so this may not create a new entry.
+  thunk_map_.emplace(key, std::move(value));
+}
+
 }  // namespace art