diff --git a/src/native/external/llvm-libunwind/src/EHHeaderParser.hpp b/src/native/external/llvm-libunwind/src/EHHeaderParser.hpp
index ed4317c89055c9..69ffe7036d948c 100644
--- a/src/native/external/llvm-libunwind/src/EHHeaderParser.hpp
+++ b/src/native/external/llvm-libunwind/src/EHHeaderParser.hpp
@@ -112,6 +112,67 @@ bool EHHeaderParser::findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart,
if (hdrInfo.fde_count == 0) return false;
+ pint_t tableEntryDebug = 0;
+
+ // Special-case the most common encoding with faster binary search implementation
+ if (hdrInfo.table_enc == (DW_EH_PE_sdata4 | DW_EH_PE_datarel))
+ {
+ size_t tableEntrySize = 8;
+
+ pint_t relpc = pc - ehHdrStart;
+
+ size_t low = 0;
+ size_t high = hdrInfo.fde_count - 1;
+
+ // Binary search the entry table
+ // Use linear search once we get down to a small number of elements
+ // to avoid binary search overhead.
+ while (high - low > 10) {
+ size_t middle = low + (high - low) / 2;
+
+ pint_t tableEntry = hdrInfo.table + middle * tableEntrySize;
+ pint_t relstart = (pint_t)(int32_t)addressSpace.get32(tableEntry);
+
+ if (relpc < relstart) {
+ high = middle - 1;
+ } else {
+ low = middle;
+ }
+ }
+
+ for (size_t i = low; i < high; i++) {
+ pint_t tableEntry = hdrInfo.table + (i + 1) * tableEntrySize;
+ pint_t relstart = (pint_t)(int32_t)addressSpace.get32(tableEntry);
+
+ if (relpc < relstart) {
+ high = i;
+ break;
+ }
+ }
+
+ pint_t tableEntry = hdrInfo.table + high * tableEntrySize;
+
+ // Have to decode the whole FDE for the PC range anyway, so just throw away
+ // the PC start.
+ pint_t fde =
+ (pint_t)(int32_t)addressSpace.get32(tableEntry + 4) + ehHdrStart;
+ const char *message =
+ CFI_Parser::decodeFDE(addressSpace, fde, fdeInfo, cieInfo);
+ if (message != NULL) {
+ _LIBUNWIND_DEBUG_LOG("EHHeaderParser::decodeTableEntry: bad fde: %s",
+ message);
+ return false;
+ }
+
+#if defined(NDEBUG)
+ if (pc >= fdeInfo->pcStart && pc < fdeInfo->pcEnd)
+ return true;
+ return false;
+#else
+ tableEntryDebug = tableEntry;
+#endif
+ }
+
size_t tableEntrySize = getTableEntrySize(hdrInfo.table_enc);
pint_t tableEntry;
@@ -134,6 +195,9 @@ bool EHHeaderParser::findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart,
}
tableEntry = hdrInfo.table + low * tableEntrySize;
+
+ assert(tableEntry == tableEntryDebug);
+
if (decodeTableEntry(addressSpace, tableEntry, ehHdrStart, ehHdrEnd,
hdrInfo.table_enc, fdeInfo, cieInfo)) {
if (pc >= fdeInfo->pcStart && pc < fdeInfo->pcEnd)
diff --git a/src/native/external/llvm-libunwind/src/UnwindCursor.hpp b/src/native/external/llvm-libunwind/src/UnwindCursor.hpp
index b57134cdd19bb9..12b9ca2a9154b0 100644
--- a/src/native/external/llvm-libunwind/src/UnwindCursor.hpp
+++ b/src/native/external/llvm-libunwind/src/UnwindCursor.hpp
@@ -124,6 +124,25 @@ class _LIBUNWIND_HIDDEN DwarfFDECache {
static entry _initialBuffer[64];
};
+template
+typename A::pint_t DwarfFDECache::findFDE(pint_t mh, pint_t pc) {
+ return 0;
+}
+
+template
+void DwarfFDECache::add(pint_t mh, pint_t ip_start, pint_t ip_end,
+ pint_t fde) {
+}
+
+template void DwarfFDECache::removeAllIn(pint_t mh) {
+}
+
+template
+void DwarfFDECache::iterateCacheEntries(void (*func)(
+ unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) {
+}
+
+#if 0
template
typename DwarfFDECache::entry *
DwarfFDECache::_buffer = _initialBuffer;
@@ -226,6 +245,8 @@ void DwarfFDECache::iterateCacheEntries(void (*func)(
}
_LIBUNWIND_LOG_IF_FALSE(_lock.unlock());
}
+#endif
+
#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)