[PATCH] Make SJLJ exceptions more efficient

Tom Tromey tromey@adacore.com
Tue Apr 23 14:44:00 GMT 2019


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(-)

diff --git a/gdb/common/common-exceptions.c b/gdb/common/common-exceptions.c
index 6378dc40d6d..f22224a0505 100644
--- a/gdb/common/common-exceptions.c
+++ b/gdb/common/common-exceptions.c
@@ -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
diff --git a/gdb/common/common-exceptions.h b/gdb/common/common-exceptions.h
index 3f47caec775..3c0bd7494eb 100644
--- a/gdb/common/common-exceptions.h
+++ b/gdb/common/common-exceptions.h
@@ -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
diff --git a/gdb/event-top.c b/gdb/event-top.c
index cd54eb5a2c5..6704c24c5ab 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -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
-- 
2.20.1



More information about the Gdb-patches mailing list