From: Fangrui Song Date: Thu, 7 Jan 2021 22:05:46 +0000 (-0800) Subject: [libc++abi] Simplify __gxx_personality_v0 X-Git-Tag: llvmorg-13-init~1802 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=85f86e8a3cf9e05347691fdde30e9e98a6657d92;p=platform%2Fupstream%2Fllvm.git [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 --- diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp index f276257..45639ec 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(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(results.ttypeIndex); - exception_header->actionRecord = results.actionRecord; - exception_header->languageSpecificData = results.languageSpecificData; - exception_header->catchTemp = reinterpret_cast(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(results.ttypeIndex); + exc->actionRecord = results.actionRecord; + exc->languageSpecificData = results.languageSpecificData; + exc->catchTemp = reinterpret_cast(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(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__)