From: Hui Zhu <teawater@gmail.com>
To: Michael Snyder <msnyder@vmware.com>
Cc: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Subject: Re: [RFA] record.c - save some memory in record log.
Date: Sun, 18 Oct 2009 01:50:00 -0000 [thread overview]
Message-ID: <daef60380910171850m1de9d507v7d85b9360ad5526a@mail.gmail.com> (raw)
In-Reply-To: <4AD761AD.40307@vmware.com>
Thanks Michael, This patch is very cool.
+struct record_reg_entry
+{
+ unsigned short num;
+ unsigned short len;
+ union
+ {
+ gdb_byte *ptr;
+ gdb_byte buf[2 * sizeof (gdb_byte *)];
Why this part use "2 * sizeof (gdb_byte *)"?
+ rec->u.reg.u.ptr = (gdb_byte *) xmalloc (MAX_REGISTER_SIZE);
I suggest change MAX_REGISTER_SIZE to rec->u.reg.len.
Thanks,
Hui
On Fri, Oct 16, 2009 at 01:53, Michael Snyder <msnyder@vmware.com> wrote:
> This change saves approximately 25 percent of memory used for
> the record log in process record (my empirical measurement).
>
> It's based on the observation that the objects that we save
> (registers and small memory writes) are frequently the size of
> a pointer (or smaller). Therefore, instead of allocating both
> a pointer and some malloc memory to hold them, they can simply
> be saved in the space used for the pointer itself.
>
> Saves of larger objects (bigger memory saves, or unusually
> large registers) will still fall back to the old method.
>
> This should also represent a huge saving in heap fragmentation,
> since the vast majority of the mallocs would have been 4 bytes
> or 8 bytes.
>
>
> 2009-10-15 Michael Snyder <msnyder@vmware.com>
>
> * record.c (struct record_reg_entry): Replace ptr with union
> of ptr and buf.
> (struct record_mem_entry): Ditto.
> (record_reg_alloc): Don't alloc ptr if reg will fit into buf.
> (record_mem_alloc): Ditto.
> (record_reg_release): Don't free ptr if reg was stored in buf.
> (record_mem_release): Ditto.
> (record_get_loc): New function. Return a pointer to where the
> value (mem or reg) is to be stored.
> (record_arch_list_add_reg): Call record_get_loc instead of using ptr.
> (record_arch_list_add_mem): Ditto.
> (record_wait): Ditto.
>
> Index: record.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/record.c,v
> retrieving revision 1.23
> diff -u -p -r1.23 record.c
> --- record.c 15 Oct 2009 17:27:54 -0000 1.23
> +++ record.c 15 Oct 2009 17:48:50 -0000
> @@ -43,12 +43,6 @@
> Each struct record_entry is linked to "record_list" by "prev" and
> "next" pointers. */
>
> -struct record_reg_entry
> -{
> - int num;
> - gdb_byte *val;
> -};
> -
> struct record_mem_entry
> {
> CORE_ADDR addr;
> @@ -56,7 +50,22 @@ struct record_mem_entry
> /* Set this flag if target memory for this entry
> can no longer be accessed. */
> int mem_entry_not_accessible;
> - gdb_byte *val;
> + union
> + {
> + gdb_byte *ptr;
> + gdb_byte buf[sizeof (gdb_byte *)];
> + } u;
> +};
> +
> +struct record_reg_entry
> +{
> + unsigned short num;
> + unsigned short len;
> + union
> + {
> + gdb_byte *ptr;
> + gdb_byte buf[2 * sizeof (gdb_byte *)];
> + } u;
> };
>
> struct record_end_entry
> @@ -143,7 +152,9 @@ record_reg_alloc (struct regcache *regca
> rec = (struct record_entry *) xcalloc (1, sizeof (struct record_entry));
> rec->type = record_reg;
> rec->u.reg.num = regnum;
> - rec->u.reg.val = (gdb_byte *) xmalloc (MAX_REGISTER_SIZE);
> + rec->u.reg.len = register_size (gdbarch, regnum);
> + if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
> + rec->u.reg.u.ptr = (gdb_byte *) xmalloc (MAX_REGISTER_SIZE);
>
> return rec;
> }
> @@ -154,7 +165,8 @@ static inline void
> record_reg_release (struct record_entry *rec)
> {
> gdb_assert (rec->type == record_reg);
> - xfree (rec->u.reg.val);
> + if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
> + xfree (rec->u.reg.u.ptr);
> xfree (rec);
> }
>
> @@ -169,7 +181,8 @@ record_mem_alloc (CORE_ADDR addr, int le
> rec->type = record_mem;
> rec->u.mem.addr = addr;
> rec->u.mem.len = len;
> - rec->u.mem.val = (gdb_byte *) xmalloc (len);
> + if (rec->u.mem.len > sizeof (rec->u.mem.u.buf))
> + rec->u.mem.u.ptr = (gdb_byte *) xmalloc (len);
>
> return rec;
> }
> @@ -180,7 +193,8 @@ static inline void
> record_mem_release (struct record_entry *rec)
> {
> gdb_assert (rec->type == record_mem);
> - xfree (rec->u.mem.val);
> + if (rec->u.mem.len > sizeof (rec->u.mem.u.buf))
> + xfree (rec->u.mem.u.ptr);
> xfree (rec);
> }
>
> @@ -329,7 +343,29 @@ record_arch_list_add (struct record_entr
> }
> }
>
> -/* Record the value of a register REGNUM to record_arch_list. */
> +/* Return the value storage location of a record entry. */
> +static inline gdb_byte *
> +record_get_loc (struct record_entry *rec)
> +{
> + switch (rec->type) {
> + case record_mem:
> + if (rec->u.mem.len > sizeof (rec->u.mem.u.buf))
> + return rec->u.mem.u.ptr;
> + else
> + return rec->u.mem.u.buf;
> + case record_reg:
> + if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
> + return rec->u.reg.u.ptr;
> + else
> + return rec->u.reg.u.buf;
> + case record_end:
> + default:
> + gdb_assert (0);
> + return NULL;
> + }
> +}
> +
> +/* Record the value of a register NUM to record_arch_list. */
>
> int
> record_arch_list_add_reg (struct regcache *regcache, int regnum)
> @@ -344,7 +380,7 @@ record_arch_list_add_reg (struct regcach
>
> rec = record_reg_alloc (regcache, regnum);
>
> - regcache_raw_read (regcache, regnum, rec->u.reg.val);
> + regcache_raw_read (regcache, regnum, record_get_loc (rec));
>
> record_arch_list_add (rec);
>
> @@ -370,7 +406,7 @@ record_arch_list_add_mem (CORE_ADDR addr
>
> rec = record_mem_alloc (addr, len);
>
> - if (target_read_memory (addr, rec->u.mem.val, len))
> + if (target_read_memory (addr, record_get_loc (rec), len))
> {
> if (record_debug)
> fprintf_unfiltered (gdb_stdlog,
> @@ -857,8 +893,9 @@ record_wait (struct target_ops *ops,
> record_list->u.reg.num);
> regcache_cooked_read (regcache, record_list->u.reg.num, reg);
> regcache_cooked_write (regcache, record_list->u.reg.num,
> - record_list->u.reg.val);
> - memcpy (record_list->u.reg.val, reg, MAX_REGISTER_SIZE);
> + record_get_loc (record_list));
> + memcpy (record_get_loc (record_list), reg,
> + record_list->u.reg.len);
> }
> else if (record_list->type == record_mem)
> {
> @@ -892,7 +929,7 @@ record_wait (struct target_ops *ops,
> else
> {
> if (target_write_memory (record_list->u.mem.addr,
> - record_list->u.mem.val,
> + record_get_loc (record_list),
> record_list->u.mem.len))
> {
> if (execution_direction != EXEC_REVERSE)
> @@ -907,7 +944,7 @@ record_wait (struct target_ops *ops,
> }
> else
> {
> - memcpy (record_list->u.mem.val, mem,
> + memcpy (record_get_loc (record_list), mem,
> record_list->u.mem.len);
> }
> }
>
>
next prev parent reply other threads:[~2009-10-18 1:50 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-15 17:59 Michael Snyder
2009-10-15 19:17 ` Joel Brobecker
2009-10-18 1:53 ` Hui Zhu
2009-10-18 16:10 ` Joel Brobecker
2009-10-18 16:14 ` Michael Snyder
2009-10-18 1:50 ` Hui Zhu [this message]
2009-10-18 3:56 ` Michael Snyder
2009-10-18 4:46 ` Hui Zhu
2009-10-18 16:11 ` Michael Snyder
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=daef60380910171850m1de9d507v7d85b9360ad5526a@mail.gmail.com \
--to=teawater@gmail.com \
--cc=gdb-patches@sourceware.org \
--cc=msnyder@vmware.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