Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Felix Willgerodt via Gdb-patches <gdb-patches@sourceware.org>
To: gdb-patches@sourceware.org
Subject: [PATCH 3/4] gdb, gdbserver: Allocate only a sane amount of buffer when fetching registers.
Date: Fri,  6 May 2022 14:12:25 +0200	[thread overview]
Message-ID: <20220506121226.137608-4-felix.willgerodt@intel.com> (raw)
In-Reply-To: <20220506121226.137608-1-felix.willgerodt@intel.com>

A couple of functions blindly allocate a buffer of the size of
I386_MAX_REGISTER_SIZE.  With the addition of AMX, this size has increased
drastically from 64 bytes to 8192.  This changes these buffer allocations
to only use the actual amount needed, similar to how it is already done in
amd64-tdep.c (amd64_pseudo_register_read_value).

For the i387_collect_xsave and i387_cache_to_xsave functions any feedback is
welcome.  I opted to take the middle ground and only distinguish
between "AMX" and "Not-AMX".  That might be unnecessary optimization,
we could alternatively be okay with using an 8kB buffer unconditionally or
be okay with having many smaller buffer allocations.
---
 gdb/i386-tdep.c      | 21 ++++++++++++++++-----
 gdb/i387-tdep.c      | 19 ++++++++++++++-----
 gdbserver/i387-fp.cc |  8 +++++++-
 3 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 921b24ab60f..94106668e50 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -2944,7 +2944,7 @@ i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
 {
   i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int len = TYPE_LENGTH (type);
-  gdb_byte buf[I386_MAX_REGISTER_SIZE];
+  gdb_byte buf[register_size (gdbarch, I386_ST0_REGNUM)];
 
   /* _Float16 and _Float16 _Complex values are returned via xmm0.  */
   if (((type->code () == TYPE_CODE_FLT) && len == 2)
@@ -3006,7 +3006,7 @@ i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
   if (type->code () == TYPE_CODE_FLT)
     {
       ULONGEST fstat;
-      gdb_byte buf[I386_MAX_REGISTER_SIZE];
+      gdb_byte buf[register_size (gdbarch, I386_ST0_REGNUM)];
 
       if (tdep->st0_regnum < 0)
 	{
@@ -3591,13 +3591,13 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
 				      int regnum,
 				      struct value *result_value)
 {
-  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
   enum register_status status;
   gdb_byte *buf = value_contents_raw (result_value).data ();
 
   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
       int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
+      gdb_byte raw_buf[register_size (gdbarch, regnum)];
 
       /* Extract (always little endian).  */
       status = regcache->raw_read (fpnum, raw_buf);
@@ -3613,6 +3613,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
       if (i386_bnd_regnum_p (gdbarch, regnum))
 	{
 	  regnum -= tdep->bnd0_regnum;
+	  gdb_byte raw_buf[register_size (gdbarch, I387_BND0R_REGNUM (tdep))];
 
 	  /* Extract (always little endian).  Read lower 128bits.  */
 	  status = regcache->raw_read (I387_BND0R_REGNUM (tdep) + regnum,
@@ -3636,6 +3637,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
       else if (i386_k_regnum_p (gdbarch, regnum))
 	{
 	  regnum -= tdep->k0_regnum;
+	  gdb_byte raw_buf[register_size (gdbarch, tdep->k0_regnum)];
 
 	  /* Extract (always little endian).  */
 	  status = regcache->raw_read (tdep->k0_regnum + regnum, raw_buf);
@@ -3647,6 +3649,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
       else if (i386_zmm_regnum_p (gdbarch, regnum))
 	{
 	  regnum -= tdep->zmm0_regnum;
+	  gdb_byte raw_buf[register_size (gdbarch, tdep->zmm0_regnum)];
 
 	  if (regnum < num_lower_zmm_regs)
 	    {
@@ -3698,6 +3701,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
       else if (i386_ymm_regnum_p (gdbarch, regnum))
 	{
 	  regnum -= tdep->ymm0_regnum;
+	  gdb_byte raw_buf[register_size (gdbarch, tdep->ymm0_regnum)];
 
 	  /* Extract (always little endian).  Read lower 128bits.  */
 	  status = regcache->raw_read (I387_XMM0_REGNUM (tdep) + regnum,
@@ -3717,6 +3721,8 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
       else if (i386_ymm_avx512_regnum_p (gdbarch, regnum))
 	{
 	  regnum -= tdep->ymm16_regnum;
+	  gdb_byte raw_buf[register_size (gdbarch, tdep->ymm0_regnum)];
+
 	  /* Extract (always little endian).  Read lower 128bits.  */
 	  status = regcache->raw_read (I387_XMM16_REGNUM (tdep) + regnum,
 				       raw_buf);
@@ -3735,6 +3741,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
       else if (i386_word_regnum_p (gdbarch, regnum))
 	{
 	  int gpnum = regnum - tdep->ax_regnum;
+	  gdb_byte raw_buf[register_size (gdbarch, gpnum)];
 
 	  /* Extract (always little endian).  */
 	  status = regcache->raw_read (gpnum, raw_buf);
@@ -3747,6 +3754,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
       else if (i386_byte_regnum_p (gdbarch, regnum))
 	{
 	  int gpnum = regnum - tdep->al_regnum;
+	  gdb_byte raw_buf[register_size (gdbarch, gpnum % 4)];
 
 	  /* Extract (always little endian).  We read both lower and
 	     upper registers.  */
@@ -3784,11 +3792,10 @@ void
 i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 			    int regnum, const gdb_byte *buf)
 {
-  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
-
   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
       int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
+      gdb_byte raw_buf[register_size (gdbarch, regnum)];
 
       /* Read ...  */
       regcache->raw_read (fpnum, raw_buf);
@@ -3813,6 +3820,8 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 	  upper = extract_unsigned_integer (buf + size, size, byte_order);
 
 	  /* Fetching register buffer.  */
+	  gdb_byte raw_buf[register_size (gdbarch,
+					  I387_BND0R_REGNUM (tdep) + regnum)];
 	  regcache->raw_read (I387_BND0R_REGNUM (tdep) + regnum,
 			      raw_buf);
 
@@ -3874,6 +3883,7 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
       else if (i386_word_regnum_p (gdbarch, regnum))
 	{
 	  int gpnum = regnum - tdep->ax_regnum;
+	  gdb_byte raw_buf[register_size (gdbarch, gpnum)];
 
 	  /* Read ...  */
 	  regcache->raw_read (gpnum, raw_buf);
@@ -3885,6 +3895,7 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
       else if (i386_byte_regnum_p (gdbarch, regnum))
 	{
 	  int gpnum = regnum - tdep->al_regnum;
+	  gdb_byte raw_buf[register_size (gdbarch, gpnum)];
 
 	  /* Read ...  We read both lower and upper registers.  */
 	  regcache->raw_read (gpnum % 4, raw_buf);
diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
index 38ffa3f967b..56239539402 100644
--- a/gdb/i387-tdep.c
+++ b/gdb/i387-tdep.c
@@ -350,7 +350,7 @@ i387_register_to_value (struct frame_info *frame, int regnum,
 			int *optimizedp, int *unavailablep)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte from[I386_MAX_REGISTER_SIZE];
+  gdb_byte from[register_size (gdbarch, regnum)];
 
   gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
 
@@ -384,7 +384,7 @@ i387_value_to_register (struct frame_info *frame, int regnum,
 			struct type *type, const gdb_byte *from)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte to[I386_MAX_REGISTER_SIZE];
+  gdb_byte to[register_size (gdbarch, regnum)];
 
   gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
 
@@ -1419,7 +1419,6 @@ i387_collect_xsave (const struct regcache *regcache, int regnum,
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   gdb_byte *p, *regs = (gdb_byte *) xsave;
-  gdb_byte raw[I386_MAX_REGISTER_SIZE];
   ULONGEST initial_xstate_bv, clear_bv, xstate_bv = 0;
   unsigned int i;
   /* See the comment in i387_supply_xsave().  */
@@ -1604,6 +1603,14 @@ i387_collect_xsave (const struct regcache *regcache, int regnum,
 
   if (regclass == all)
     {
+      /* This used to blindly allocate I386_MAX_REGISTER_SIZE of space.
+	 With AMX that became a bit much to do unconditionally.  For now
+	 this seems to be the best trade-off between saving space and
+	 the performance penalty for adding individual allocations.  */
+      const uint32_t buf_size
+	  = (tdep->xcr0 & X86_XSTATE_TILEDATA) ? I386_MAX_REGISTER_SIZE : 64;
+      gdb_byte raw[buf_size];
+
       /* Check if the tilecfg register is changed.  */
       if ((tdep->xcr0 & X86_XSTATE_TILECFG))
 	{
@@ -1791,6 +1798,7 @@ i387_collect_xsave (const struct regcache *regcache, int regnum,
   else
     {
       /* Check if REGNUM is changed.  */
+      gdb_byte raw[register_size (gdbarch, regnum)];
       regcache->raw_collect (regnum, raw);
 
       switch (regclass)
@@ -1988,10 +1996,11 @@ i387_collect_xsave (const struct regcache *regcache, int regnum,
 	  }
 	else
 	  {
-	    int regsize;
+	    int regsize = register_size (gdbarch, i);
 
+	    gdb_byte raw[regsize];
 	    regcache->raw_collect (i, raw);
-	    regsize = regcache_register_size (regcache, i);
+
 	    p = FXSAVE_ADDR (tdep, regs, i);
 	    if (memcmp (raw, p, regsize))
 	      {
diff --git a/gdbserver/i387-fp.cc b/gdbserver/i387-fp.cc
index 2d22b0419f8..0b80d287a47 100644
--- a/gdbserver/i387-fp.cc
+++ b/gdbserver/i387-fp.cc
@@ -265,7 +265,6 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
   unsigned long val, val2;
   unsigned long long xstate_bv = 0;
   unsigned long long clear_bv = 0;
-  char raw[8192];
   char *p;
 
   /* Amd64 has 16 xmm regs; I386 has 8 xmm regs.  */
@@ -348,6 +347,13 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
 	}
     }
 
+  /* This used to blindly allocate 64 bytes of space.
+     With AMX that became a bit much to do unconditionally.  For now
+     this seems to be the best trade-off between saving space and
+     the performance penalty for adding individual allocations.  */
+  const uint32_t buf_size = (x86_xcr0 & X86_XSTATE_TILEDATA) ? 8192 : 64;
+  char raw[buf_size];
+
   /* Check if any x87 registers are changed.  */
   if ((x86_xcr0 & X86_XSTATE_X87))
     {
-- 
2.34.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


  parent reply	other threads:[~2022-05-06 12:14 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-06 12:12 [PATCH 0/4] Add AMX support Felix Willgerodt via Gdb-patches
2022-05-06 12:12 ` [PATCH 1/4] gdb: define int512 and uint512 as built-in types Felix Willgerodt via Gdb-patches
2022-05-06 12:19   ` Eli Zaretskii via Gdb-patches
2022-06-27 18:17   ` Pedro Alves
2022-05-06 12:12 ` [PATCH 2/4] gdb, gdbserver: Add AMX registers Felix Willgerodt via Gdb-patches
2022-05-06 12:25   ` Eli Zaretskii via Gdb-patches
2022-05-11  8:14     ` Willgerodt, Felix via Gdb-patches
2022-05-11 11:41       ` Eli Zaretskii via Gdb-patches
2022-06-27 18:16         ` Pedro Alves
2022-06-27 18:24           ` Eli Zaretskii via Gdb-patches
2022-06-27 19:15             ` Pedro Alves
2022-06-28 12:09               ` Eli Zaretskii via Gdb-patches
2022-06-28 13:35                 ` Pedro Alves
2022-05-06 16:17   ` John Baldwin
2022-05-09  7:04     ` Willgerodt, Felix via Gdb-patches
2022-05-09 16:31       ` John Baldwin
2022-06-27 18:12   ` Pedro Alves
2022-07-14 10:54     ` Willgerodt, Felix via Gdb-patches
2022-07-15 11:51       ` Willgerodt, Felix via Gdb-patches
2022-08-08  9:15     ` Willgerodt, Felix via Gdb-patches
2022-08-08 17:16       ` John Baldwin
2022-05-06 12:12 ` Felix Willgerodt via Gdb-patches [this message]
2022-05-06 16:08   ` [PATCH 3/4] gdb, gdbserver: Allocate only a sane amount of buffer when fetching registers John Baldwin
2022-05-09  7:04     ` Willgerodt, Felix via Gdb-patches
2022-06-27 18:30   ` Pedro Alves
2022-05-06 12:12 ` [PATCH 4/4] gdb: Clear tilecfg.start_row for any PC modification Felix Willgerodt via Gdb-patches
2022-06-27 18:55   ` Pedro Alves

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=20220506121226.137608-4-felix.willgerodt@intel.com \
    --to=gdb-patches@sourceware.org \
    --cc=felix.willgerodt@intel.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