From 2e2e7fe7825b58a910dcdde442e61307b16907d6 Mon Sep 17 00:00:00 2001
From: Alexey Spiridonov <lesha@meta.com>
Date: Fri, 24 May 2024 23:57:06 -0700
Subject: [PATCH] Save ~2ns from GLIBCXX `exception_ptr_get_type` and
 `exception_ptr_get_object`

Summary:
I noticed `get_type` was unexpectedly slow at ~2.5ns. yfeldblum pointed out that `ptr.__cxa_exception_type` probably incurs a PLT lookup, and that we can safely elide this.

The new `exception_ptr_get_type_` implementation is exactly the same as the FreeBSD version.

I also visually checked the implementation against:
 - https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/eh_ptr.cc#L138
 - https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/unwind-cxx.h

Reviewed By: yfeldblum

Differential Revision: D57792972

fbshipit-source-id: 1658ac7ef1f1f33cead11bf68747948cd522de33
---
 folly/lang/Exception.cpp | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/folly/lang/Exception.cpp b/folly/lang/Exception.cpp
index 34ecbc7f978..320f73c9820 100644
--- a/folly/lang/Exception.cpp
+++ b/folly/lang/Exception.cpp
@@ -243,7 +243,12 @@ bool exception_ptr_access_rt_v_() noexcept {
 
 std::type_info const* exception_ptr_get_type_(
     std::exception_ptr const& ptr) noexcept {
-  return !ptr ? nullptr : ptr.__cxa_exception_type();
+  if (!ptr) {
+    return nullptr;
+  }
+  auto object = reinterpret_cast<void* const&>(ptr);
+  auto exception = static_cast<abi::__cxa_exception*>(object) - 1;
+  return exception->exceptionType;
 }
 
 void* exception_ptr_get_object_(
@@ -253,7 +258,7 @@ void* exception_ptr_get_object_(
     return nullptr;
   }
   auto object = reinterpret_cast<void* const&>(ptr);
-  auto type = ptr.__cxa_exception_type();
+  auto type = exception_ptr_get_type_(ptr);
   return !target || target->__do_catch(type, &object, 1) ? object : nullptr;
 }