[llvm-branch-commits] [libcxxabi] 85f86e8 - [libc++abi] Simplify __gxx_personality_v0
Fangrui Song via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jan 7 14:09:53 PST 2021
Author: Fangrui Song
Date: 2021-01-07T14:05:46-08:00
New Revision: 85f86e8a3cf9e05347691fdde30e9e98a6657d92
URL: https://github.com/llvm/llvm-project/commit/85f86e8a3cf9e05347691fdde30e9e98a6657d92
DIFF: https://github.com/llvm/llvm-project/commit/85f86e8a3cf9e05347691fdde30e9e98a6657d92.diff
LOG: [libc++abi] Simplify __gxx_personality_v0
In three cases we call `scan_eh_tab` to parse LSDA:
* `actions & _UA_SEARCH_PHASE`
* `actions & _UA_CLEANUP_PHASE && actions & _UA_HANDLER_FRAME && !native_exception`
* `actions & _UA_CLEANUP_PHASE && !(actions & _UA_HANDLER_FRAME)`
Check
`actions & _UA_CLEANUP_PHASE && actions & _UA_HANDLER_FRAME && native_exception` first,
then we can move three `scan_eh_tab` into one place.
Another simplification is that we can check whether the result of `scan_eh_tab`
is `_UA_CONTINUE_UNWIND` or `_UA_FATAL_PHASE1_ERROR` first. Then many of the
original checks will be dead and can thus be deleted.
Reviewed By: #libc_abi, ldionne
Differential Revision: https://reviews.llvm.org/D93186
Added:
Modified:
libcxxabi/src/cxa_personality.cpp
Removed:
################################################################################
diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp
index f27625776111..45639ec03bcd 100644
--- a/libcxxabi/src/cxa_personality.cpp
+++ b/libcxxabi/src/cxa_personality.cpp
@@ -962,78 +962,51 @@ __gxx_personality_v0
bool native_exception = (exceptionClass & get_vendor_and_language) ==
(kOurExceptionClass & get_vendor_and_language);
scan_results results;
+ // Process a catch handler for a native exception first.
+ if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME) &&
+ native_exception) {
+ // Reload the results from the phase 1 cache.
+ __cxa_exception* exception_header =
+ (__cxa_exception*)(unwind_exception + 1) - 1;
+ results.ttypeIndex = exception_header->handlerSwitchValue;
+ results.actionRecord = exception_header->actionRecord;
+ results.languageSpecificData = exception_header->languageSpecificData;
+ results.landingPad =
+ reinterpret_cast<uintptr_t>(exception_header->catchTemp);
+ results.adjustedPtr = exception_header->adjustedPtr;
+
+ // Jump to the handler.
+ set_registers(unwind_exception, context, results);
+ return _URC_INSTALL_CONTEXT;
+ }
+
+ // In other cases we need to scan LSDA.
+ scan_eh_tab(results, actions, native_exception, unwind_exception, context);
+ if (results.reason == _URC_CONTINUE_UNWIND ||
+ results.reason == _URC_FATAL_PHASE1_ERROR)
+ return results.reason;
+
if (actions & _UA_SEARCH_PHASE)
{
// Phase 1 search: All we're looking for in phase 1 is a handler that
// halts unwinding
- scan_eh_tab(results, actions, native_exception, unwind_exception, context);
- if (results.reason == _URC_HANDLER_FOUND)
- {
- // Found one. Can we cache the results somewhere to optimize phase 2?
- if (native_exception)
- {
- __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
- exception_header->handlerSwitchValue = static_cast<int>(results.ttypeIndex);
- exception_header->actionRecord = results.actionRecord;
- exception_header->languageSpecificData = results.languageSpecificData;
- exception_header->catchTemp = reinterpret_cast<void*>(results.landingPad);
- exception_header->adjustedPtr = results.adjustedPtr;
- }
- return _URC_HANDLER_FOUND;
+ assert(results.reason == _URC_HANDLER_FOUND);
+ if (native_exception) {
+ // For a native exception, cache the LSDA result.
+ __cxa_exception* exc = (__cxa_exception*)(unwind_exception + 1) - 1;
+ exc->handlerSwitchValue = static_cast<int>(results.ttypeIndex);
+ exc->actionRecord = results.actionRecord;
+ exc->languageSpecificData = results.languageSpecificData;
+ exc->catchTemp = reinterpret_cast<void*>(results.landingPad);
+ exc->adjustedPtr = results.adjustedPtr;
}
- // Did not find a catching-handler. Return the results of the scan
- // (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE1_ERROR
- // if we were called improperly).
- return results.reason;
+ return _URC_HANDLER_FOUND;
}
- if (actions & _UA_CLEANUP_PHASE)
- {
- // Phase 2 search:
- // Did we find a catching handler in phase 1?
- if (actions & _UA_HANDLER_FRAME)
- {
- // Yes, phase 1 said we have a catching handler here.
- // Did we cache the results of the scan?
- if (native_exception)
- {
- // Yes, reload the results from the cache.
- __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
- results.ttypeIndex = exception_header->handlerSwitchValue;
- results.actionRecord = exception_header->actionRecord;
- results.languageSpecificData = exception_header->languageSpecificData;
- results.landingPad = reinterpret_cast<uintptr_t>(exception_header->catchTemp);
- results.adjustedPtr = exception_header->adjustedPtr;
- }
- else
- {
- // No, do the scan again to reload the results.
- scan_eh_tab(results, actions, native_exception, unwind_exception, context);
- // Phase 1 told us we would find a handler. Now in Phase 2 we
- // didn't find a handler. The eh table should not be changing!
- if (results.reason != _URC_HANDLER_FOUND)
- call_terminate(native_exception, unwind_exception);
- }
- // Jump to the handler
- set_registers(unwind_exception, context, results);
- return _URC_INSTALL_CONTEXT;
- }
- // Either we didn't do a phase 1 search (due to forced unwinding), or
- // phase 1 reported no catching-handlers.
- // Search for a (non-catching) cleanup
- scan_eh_tab(results, actions, native_exception, unwind_exception, context);
- if (results.reason == _URC_HANDLER_FOUND)
- {
- // Found a non-catching handler. Jump to it:
- set_registers(unwind_exception, context, results);
- return _URC_INSTALL_CONTEXT;
- }
- // Did not find a cleanup. Return the results of the scan
- // (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE2_ERROR
- // if we were called improperly).
- return results.reason;
- }
- // We were called improperly: neither a phase 1 or phase 2 search
- return _URC_FATAL_PHASE1_ERROR;
+
+ assert(actions & _UA_CLEANUP_PHASE);
+ assert(results.reason == _URC_HANDLER_FOUND);
+ set_registers(unwind_exception, context, results);
+ return _URC_INSTALL_CONTEXT;
}
#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
More information about the llvm-branch-commits
mailing list