public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Alan Hayward <alan.hayward@arm.com>
To: gdb-patches@sourceware.org
Cc: nd@arm.com,	Alan Hayward <alan.hayward@arm.com>
Subject: [PATCH v2 2/3] Avoid memcpys in regcache read_part/write_part for full registers.
Date: Thu, 21 Jun 2018 09:39:00 -0000	[thread overview]
Message-ID: <20180621093802.79342-3-alan.hayward@arm.com> (raw)
In-Reply-To: <20180621093802.79342-1-alan.hayward@arm.com>

Additionally, tidy up the functions: Remove asserts, use gdb_byte,
update comments.

2018-06-21  Alan Hayward  <alan.hayward@arm.com>

	* regcache.c (readable_regcache::read_part): Avoid memcpy when
	possible.
	(regcache::write_part): Likewise.
	(readable_regcache::cooked_read_part): Update comment.
	(readable_regcache::cooked_write_part): Likewise.
	* regcache.h: (readable_regcache::read_part): Likewise.
	(regcache::write_part): Likewise.
---
 gdb/regcache.c | 92 ++++++++++++++++++++++++++++++----------------------------
 gdb/regcache.h | 12 +++++---
 2 files changed, 55 insertions(+), 49 deletions(-)

diff --git a/gdb/regcache.c b/gdb/regcache.c
index 6276b149a2..fe4742c2ee 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -775,77 +775,75 @@ regcache::cooked_write (int regnum, const gdb_byte *buf)
 				   regnum, buf);
 }
 
-/* Perform a partial register transfer using a read, modify, write
-   operation.  */
+/* See regcache.h.  */
 
 enum register_status
-readable_regcache::read_part (int regnum, int offset, int len, void *in,
-			      bool is_raw)
+readable_regcache::read_part (int regnum, int offset, int len,
+			      gdb_byte *out, bool is_raw)
 {
-  struct gdbarch *gdbarch = arch ();
-  gdb_byte *reg = (gdb_byte *) alloca (register_size (gdbarch, regnum));
+  int reg_size = register_size (arch (), regnum);
 
-  gdb_assert (in != NULL);
-  gdb_assert (offset >= 0 && offset <= m_descr->sizeof_register[regnum]);
-  gdb_assert (len >= 0 && offset + len <= m_descr->sizeof_register[regnum]);
-  /* Something to do?  */
-  if (offset + len == 0)
+  gdb_assert (out != NULL);
+  gdb_assert (offset >= 0 && len >= 0 && offset + len <= reg_size);
+
+  if (offset == 0 && len == 0)
     return REG_VALID;
-  /* Read (when needed) ...  */
+
+  if (offset == 0 && len == reg_size)
+    return (is_raw) ? raw_read (regnum, out) : cooked_read (regnum, out);
+
   enum register_status status;
+  gdb_byte *reg = (gdb_byte *) alloca (reg_size);
 
-  if (is_raw)
-    status = raw_read (regnum, reg);
-  else
-    status = cooked_read (regnum, reg);
+  /* Read full register to buffer.  */
+  status = (is_raw) ? raw_read (regnum, reg) : cooked_read (regnum, reg);
   if (status != REG_VALID)
     return status;
 
-  /* ... modify ...  */
-  memcpy (in, reg + offset, len);
-
+  /* Copy out.  */
+  memcpy (out, reg + offset, len);
   return REG_VALID;
 }
 
+/* See regcache.h.  */
+
 enum register_status
 regcache::write_part (int regnum, int offset, int len,
-		     const void *out, bool is_raw)
+		      const gdb_byte *in, bool is_raw)
 {
-  struct gdbarch *gdbarch = arch ();
-  gdb_byte *reg = (gdb_byte *) alloca (register_size (gdbarch, regnum));
+  int reg_size = register_size (arch (), regnum);
 
-  gdb_assert (out != NULL);
-  gdb_assert (offset >= 0 && offset <= m_descr->sizeof_register[regnum]);
-  gdb_assert (len >= 0 && offset + len <= m_descr->sizeof_register[regnum]);
-  /* Something to do?  */
-  if (offset + len == 0)
+  gdb_assert (in != NULL);
+  gdb_assert (offset >= 0 && len >= 0 && offset + len <= reg_size);
+
+  if (offset == 0 && len == 0)
     return REG_VALID;
-  /* Read (when needed) ...  */
-  if (offset > 0
-      || offset + len < m_descr->sizeof_register[regnum])
-    {
-      enum register_status status;
 
-      if (is_raw)
-	status = raw_read (regnum, reg);
-      else
-	status = cooked_read (regnum, reg);
-      if (status != REG_VALID)
-	return status;
+  if (offset == 0 && len == reg_size)
+    {
+      (is_raw) ? raw_write (regnum, in) : cooked_write (regnum, in);
+      return REG_VALID;
     }
 
-  memcpy (reg + offset, out, len);
-  /* ... write (when needed).  */
-  if (is_raw)
-    raw_write (regnum, reg);
-  else
-    cooked_write (regnum, reg);
+  enum register_status status;
+  gdb_byte *reg = (gdb_byte *) alloca (reg_size);
+
+  /* Read existing register to buffer.  */
+  status = (is_raw) ? raw_read (regnum, reg) : cooked_read (regnum, reg);
+  if (status != REG_VALID)
+    return status;
 
+  /* Update buffer, then write back to regcache.  */
+  memcpy (reg + offset, in, len);
+  is_raw ? raw_write (regnum, reg) : cooked_write (regnum, reg);
   return REG_VALID;
 }
 
+/* See regcache.h.  */
+
 enum register_status
-readable_regcache::raw_read_part (int regnum, int offset, int len, gdb_byte *buf)
+readable_regcache::raw_read_part (int regnum, int offset, int len,
+				  gdb_byte *buf)
 {
   assert_regnum (regnum);
   return read_part (regnum, offset, len, buf, true);
@@ -861,6 +859,8 @@ regcache::raw_write_part (int regnum, int offset, int len,
   write_part (regnum, offset, len, buf, true);
 }
 
+/* See regcache.h.  */
+
 enum register_status
 readable_regcache::cooked_read_part (int regnum, int offset, int len,
 				     gdb_byte *buf)
@@ -869,6 +869,8 @@ readable_regcache::cooked_read_part (int regnum, int offset, int len,
   return read_part (regnum, offset, len, buf, false);
 }
 
+/* See regcache.h.  */
+
 void
 regcache::cooked_write_part (int regnum, int offset, int len,
 			     const gdb_byte *buf)
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 35c41888a7..c17ce09dee 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -253,8 +253,11 @@ public:
   struct value *cooked_read_value (int regnum);
 
 protected:
-  enum register_status read_part (int regnum, int offset, int len, void *in,
-				  bool is_raw);
+
+  /* Perform a partial register transfer using a read, modify, write
+     operation.  Will fail if register is currently invalid.  */
+  enum register_status read_part (int regnum, int offset, int len,
+				  gdb_byte *out, bool is_raw);
 };
 
 /* Buffer of registers, can be read and written.  */
@@ -355,9 +358,10 @@ private:
 			int regnum, const void *in_buf,
 			void *out_buf, size_t size) const;
 
+  /* Perform a partial register transfer using a read, modify, write
+     operation.  */
   enum register_status write_part (int regnum, int offset, int len,
-				   const void *out, bool is_raw);
-
+				   const gdb_byte *out, bool is_raw);
 
   /* The address space of this register cache (for registers where it
      makes sense, like PC or SP).  */
-- 
2.15.2 (Apple Git-101.1)

  parent reply	other threads:[~2018-06-21  9:39 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-21  9:39 [PATCH v2 0/3] Support large registers in regcache transfer_regset Alan Hayward
2018-06-21  9:38 ` [PATCH v2 1/3] Use unsigned ints in regcache_map_entry Alan Hayward
2018-06-21 13:27   ` Simon Marchi
2018-06-21 13:52     ` Simon Marchi
2018-06-21 15:19       ` Alan Hayward
2018-06-21 15:34         ` Simon Marchi
2018-06-21 17:32           ` Simon Marchi
2018-06-21 19:52             ` Alan Hayward
2018-06-21  9:39 ` Alan Hayward [this message]
2018-06-21 14:00   ` [PATCH v2 2/3] Avoid memcpys in regcache read_part/write_part for full registers Simon Marchi
2018-06-21  9:39 ` [PATCH v2 3/3] Use partial register read/writes in transfer_regset Alan Hayward
2018-06-21 14:16   ` Simon Marchi
2018-06-21 19:56     ` Alan Hayward
2018-06-21 15:02   ` Simon Marchi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180621093802.79342-3-alan.hayward@arm.com \
    --to=alan.hayward@arm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=nd@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).