Make SJLJ exceptions more efficient
Commit Message
This changes the SJLJ exception handling code to be a bit more
efficient, by using rvalue references and move assignment when
possible.
Tested by the buildbot.
gdb/ChangeLog
2019-04-23 Tom Tromey <tromey@adacore.com>
* event-top.c (gdb_rl_callback_read_char_wrapper_noexcept)
(gdb_rl_callback_handler): Use std::move.
* common/common-exceptions.h (struct gdb_exception): Add move
assignment operator.
(throw_exception_sjlj): Change "exception" to rvalue reference.
* common/common-exceptions.c (exceptions_state_mc_catch): Update.
(throw_exception_sjlj): Change "exception" to rvalue reference.
---
gdb/ChangeLog | 10 ++++++++++
gdb/common/common-exceptions.c | 4 ++--
gdb/common/common-exceptions.h | 4 +++-
gdb/event-top.c | 8 ++++----
4 files changed, 19 insertions(+), 7 deletions(-)
Comments
>>>>> "Tom" == Tom Tromey <tromey@adacore.com> writes:
Tom> This changes the SJLJ exception handling code to be a bit more
Tom> efficient, by using rvalue references and move assignment when
Tom> possible.
Soon I'll send an updated version of this patch that also fixes the
memory leak in PR 24475.
Tom
@@ -146,7 +146,7 @@ exceptions_state_mc_catch (struct gdb_exception *exception,
/* The caller didn't request that the event be caught, relay the
event to the next exception_catch/CATCH_SJLJ. */
- throw_exception_sjlj (*exception);
+ throw_exception_sjlj (std::move (*exception));
}
/* No exception was thrown. */
@@ -168,7 +168,7 @@ exceptions_state_mc_action_iter_1 (void)
/* Return EXCEPTION to the nearest containing CATCH_SJLJ block. */
void
-throw_exception_sjlj (struct gdb_exception exception)
+throw_exception_sjlj (struct gdb_exception &&exception)
{
/* Jump to the nearest CATCH_SJLJ block, communicating REASON to
that call via setjmp's return value. Note that REASON can't be
@@ -152,6 +152,8 @@ struct gdb_exception
return *this;
}
+ gdb_exception &operator= (gdb_exception &&other) noexcept = default;
+
/* Return the contents of the exception message, as a C string. The
string remains owned by the exception object. */
const char *what () const noexcept
@@ -281,7 +283,7 @@ extern void throw_exception (const gdb_exception &exception)
containing exception handler established using TRY_SJLJ. Necessary
in some cases where we need to throw GDB exceptions across
third-party library code (e.g., readline). */
-extern void throw_exception_sjlj (struct gdb_exception exception)
+extern void throw_exception_sjlj (struct gdb_exception &&exception)
ATTRIBUTE_NORETURN;
/* Convenience wrappers around throw_exception that throw GDB
@@ -178,7 +178,7 @@ gdb_rl_callback_read_char_wrapper_noexcept () noexcept
}
CATCH_SJLJ (ex, RETURN_MASK_ALL)
{
- gdb_expt = ex;
+ gdb_expt = std::move (ex);
}
END_CATCH_SJLJ
@@ -212,9 +212,9 @@ gdb_rl_callback_handler (char *rl) noexcept
{
ui->input_handler (gdb::unique_xmalloc_ptr<char> (rl));
}
- catch (const gdb_exception &ex)
+ catch (gdb_exception &ex)
{
- gdb_rl_expt = ex;
+ gdb_rl_expt = std::move (ex);
}
/* If we caught a GDB exception, longjmp out of the readline
@@ -225,7 +225,7 @@ gdb_rl_callback_handler (char *rl) noexcept
a C program.) Note that since we're long jumping, local variable
dtors are NOT run automatically. */
if (gdb_rl_expt.reason < 0)
- throw_exception_sjlj (gdb_rl_expt);
+ throw_exception_sjlj (std::move (gdb_rl_expt));
}
/* Change the function to be invoked every time there is a character