From: Doug Evans <dje@google.com>
To: Pedro Alves <pedro@codesourcery.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [RFA] Use data cache for stack accesses
Date: Tue, 25 Aug 2009 03:00:00 -0000 [thread overview]
Message-ID: <e394668d0908241748h769c8f8av1e3d8121688bc98f@mail.gmail.com> (raw)
In-Reply-To: <e394668d0908202300v2982d0c4y7e8f71d337f0b1d7@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3729 bytes --]
On Thu, Aug 20, 2009 at 11:00 PM, Doug Evans<dje@google.com> wrote:
> On Wed, Jul 8, 2009 at 1:46 PM, Pedro Alves<pedro@codesourcery.com> wrote:
>> On Wednesday 08 July 2009 21:08:00, Jacob Potter write:
>>> --- a/gdb/thread.c
>>> +++ b/gdb/thread.c
>>> @@ -848,6 +848,9 @@ switch_to_thread (ptid_t ptid)
>>> if (ptid_equal (ptid, inferior_ptid))
>>> return;
>>>
>>> + if (ptid_get_pid (ptid) != ptid_get_pid (inferior_ptid))
>>> + dcache_invalidate (target_dcache);
>>> +
>>
>> I'm not sure this would be 100% multi-address space safe.
>>
>> Do we not have places where we switch inferior_ptid temporarily
>> before calling reading memory, with save_inferior_ptid, without
>> going through the high level switch_to_thread ?
>
> Yeah.
>
>> What if we do this within dcache itself, similarly
>> to get_thread_regcache? That would be probably in [dcache_xfer_partial].
>
> It seems that given that we can temporarily change inferiors without
> giving subsystems notice of the change, and given vfork, then we need
> to have intelligence in dcache to handle this (and then it's not clear
> if we should keep one dcache per inferior).
>
> How about having memory_xfer_partial notify dcache of every
> write/read, and then dcache could keep just one copy of the cache and
> flush it appropriately?
>
Something like this?
2009-08-24 Jacob Potter <jdpotter@google.com>
Doug Evans <dje@google.com>
Implement TARGET_OBJECT_STACK_MEMORY.
* NEWS: Add note on new "set stack-cache" option.
* corefile.c (read_stack): New function.
* dcache.c (dcache_struct): New member ptid.
(dcache_enable_p): Mark as obsolete.
(stack_cache_enabled_p): New static global.
(show_dcache_enabled_p): Flag option as deprecated.
(show_stack_cache_enabled_p): New function.
(dcache_invalidate): Update ptid.
(dcache_read_line): No longer check cacheable attribute, stack
accesses get cached despite attribute.
(dcache_init): Set ptid.
(dcache_xfer_memory): Flush cache if from different ptid than before.
(dcache_update): New function.
(dcache_info): Report ptid.
(_initialize_dcache): Update text for `remotecache' to indicate it
is obsolete. Install new option `stack-cache'.
* dcache.h (dcache_update): Declare.
(stack_cache_enabled_p): Declare.
* dwarf2loc.c (dwarf2_evaluate_loc_desc): Mark values on stack with
set_value_stack.
* frame-unwind.c (frame_unwind_got_memory): Ditto.
* gdbcore.h (read_stack): Declare.
* target.c (memory_xfer_partial): New arg object, all callers updated.
Check for existing inferior before calling dcache routines.
When writing non-TARGET_OBJECT_STACK_MEMORY, notify dcache.
(target_xfer_partial): Call memory_xfer_partial for
TARGET_OBJECT_STACK_MEMORY.
(target_read_stack): New function.
* target.h (enum target_object): New value TARGET_OBJECT_STACK_MEMORY.
(target_read_stack): Declare.
* valops.c (get_value_at): New function.
(value_at): Guts moved to get_value_at.
(value_at_lazy): Similarly.
(value_fetch_lazy): Call read_stack for stack values.
* value.c (struct value): New member `stack'.
(value_stack, set_value_stack): New functions.
* value.h (value_stack, set_value_stack): Declare.
* doc/gdb.texinfo (Caching Data of Remote Targets): Update text.
(set remotecache): Mark option as obsolete.
(set stack-cache): Document new option.
(info dcache): Update text.
[-- Attachment #2: 090824-jdpotter-stack-cache-3.patch.txt --]
[-- Type: text/plain, Size: 23331 bytes --]
2009-08-24 Jacob Potter <jdpotter@google.com>
Doug Evans <dje@google.com>
Implement TARGET_OBJECT_STACK_MEMORY.
* NEWS: Add note on new "set stack-cache" option.
* corefile.c (read_stack): New function.
* dcache.c (dcache_struct): New member ptid.
(dcache_enable_p): Mark as obsolete.
(stack_cache_enabled_p): New static global.
(show_dcache_enabled_p): Flag option as deprecated.
(show_stack_cache_enabled_p): New function.
(dcache_invalidate): Update ptid.
(dcache_read_line): No longer check cacheable attribute, stack
accesses get cached despite attribute.
(dcache_init): Set ptid.
(dcache_xfer_memory): Flush cache if from different ptid than before.
(dcache_update): New function.
(dcache_info): Report ptid.
(_initialize_dcache): Update text for `remotecache' to indicate it
is obsolete. Install new option `stack-cache'.
* dcache.h (dcache_update): Declare.
(stack_cache_enabled_p): Declare.
* dwarf2loc.c (dwarf2_evaluate_loc_desc): Mark values on stack with
set_value_stack.
* frame-unwind.c (frame_unwind_got_memory): Ditto.
* gdbcore.h (read_stack): Declare.
* target.c (memory_xfer_partial): New arg object, all callers updated.
Check for existing inferior before calling dcache routines.
When writing non-TARGET_OBJECT_STACK_MEMORY, notify dcache.
(target_xfer_partial): Call memory_xfer_partial for
TARGET_OBJECT_STACK_MEMORY.
(target_read_stack): New function.
* target.h (enum target_object): New value TARGET_OBJECT_STACK_MEMORY.
(target_read_stack): Declare.
* valops.c (get_value_at): New function.
(value_at): Guts moved to get_value_at.
(value_at_lazy): Similarly.
(value_fetch_lazy): Call read_stack for stack values.
* value.c (struct value): New member `stack'.
(value_stack, set_value_stack): New functions.
* value.h (value_stack, set_value_stack): Declare.
* doc/gdb.texinfo (Caching Data of Remote Targets): Update text.
(set remotecache): Mark option as obsolete.
(set stack-cache): Document new option.
(info dcache): Update text.
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.326
diff -u -p -r1.326 NEWS
--- NEWS 20 Aug 2009 18:02:47 -0000 1.326
+++ NEWS 25 Aug 2009 00:23:18 -0000
@@ -395,6 +395,12 @@ show schedule-multiple
Allow GDB to resume all threads of all processes or only threads of
the current process.
+set stack-cache
+show stack-cache
+ Use more aggressive caching for accesses to the stack. This improves
+ performance of remote debugging (particularly backtraces) without
+ affecting correctness.
+
* Removed commands
info forks
Index: corefile.c
===================================================================
RCS file: /cvs/src/src/gdb/corefile.c,v
retrieving revision 1.54
diff -u -p -r1.54 corefile.c
--- corefile.c 2 Jul 2009 17:25:53 -0000 1.54
+++ corefile.c 25 Aug 2009 00:23:18 -0000
@@ -228,6 +228,7 @@ memory_error (int status, CORE_ADDR mema
}
/* Same as target_read_memory, but report an error if can't read. */
+
void
read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
{
@@ -237,6 +238,17 @@ read_memory (CORE_ADDR memaddr, gdb_byte
memory_error (status, memaddr);
}
+/* Same as target_read_stack, but report an error if can't read. */
+
+void
+read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+{
+ int status;
+ status = target_read_stack (memaddr, myaddr, len);
+ if (status != 0)
+ memory_error (status, memaddr);
+}
+
/* Argument / return result struct for use with
do_captured_read_memory_integer(). MEMADDR and LEN are filled in
by gdb_read_memory_integer(). RESULT is the contents that were
Index: dcache.c
===================================================================
RCS file: /cvs/src/src/gdb/dcache.c,v
retrieving revision 1.35
diff -u -p -r1.35 dcache.c
--- dcache.c 20 Aug 2009 23:30:15 -0000 1.35
+++ dcache.c 25 Aug 2009 00:23:18 -0000
@@ -24,6 +24,7 @@
#include "gdb_string.h"
#include "gdbcore.h"
#include "target.h"
+#include "inferior.h"
#include "splay-tree.h"
/* The data cache could lead to incorrect results because it doesn't
@@ -103,6 +104,9 @@ struct dcache_struct
/* The number of in-use lines in the cache. */
int size;
+
+ /* The ptid of last inferior to use cache or null_ptid. */
+ ptid_t ptid;
};
static struct dcache_block *dcache_hit (DCACHE *dcache, CORE_ADDR addr);
@@ -117,15 +121,23 @@ static void dcache_info (char *exp, int
void _initialize_dcache (void);
-static int dcache_enabled_p = 0;
+static int dcache_enabled_p = 0; /* OBSOLETE */
+
+int stack_cache_enabled_p = 1;
static void
show_dcache_enabled_p (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
- fprintf_filtered (file, _("Cache use for remote targets is %s.\n"), value);
+ fprintf_filtered (file, _("Deprecated remotecache flag is %s.\n"), value);
}
+static void
+show_stack_cache_enabled_p (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Cache use for stack accesses is %s.\n"), value);
+}
static DCACHE *last_cache; /* Used by info dcache */
@@ -152,6 +164,7 @@ dcache_invalidate (DCACHE *dcache)
dcache->oldest = NULL;
dcache->newest = NULL;
dcache->size = 0;
+ dcache->ptid = null_ptid;
}
/* If addr is present in the dcache, return the address of the block
@@ -198,8 +211,9 @@ dcache_read_line (DCACHE *dcache, struct
else
reg_len = region->hi - memaddr;
- /* Skip non-cacheable/non-readable regions. */
- if (!region->attrib.cache || region->attrib.mode == MEM_WO)
+ /* Skip non-readable regions. The cache attribute can be ignored,
+ since we may be loading this for a stack access. */
+ if (region->attrib.mode == MEM_WO)
{
memaddr += reg_len;
myaddr += reg_len;
@@ -338,6 +352,7 @@ dcache_init (void)
dcache->newest = NULL;
dcache->freelist = NULL;
dcache->size = 0;
+ dcache->ptid = null_ptid;
last_cache = dcache;
return dcache;
@@ -378,6 +393,15 @@ dcache_xfer_memory (struct target_ops *o
int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr);
xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;
+ /* If this is a different inferior from what we've recorded,
+ flush the cache. */
+
+ if (! ptid_equal (inferior_ptid, dcache->ptid))
+ {
+ dcache_invalidate (dcache);
+ dcache->ptid = inferior_ptid;
+ }
+
/* Do write-through first, so that if it fails, we don't write to
the cache at all. */
@@ -407,6 +431,18 @@ dcache_xfer_memory (struct target_ops *o
"logically" connected but not actually a single call to one of the
memory transfer functions. */
+/* Just update any cache lines which are already present. This is called
+ by memory_xfer_partial in cases where the access would otherwise not go
+ through the cache. */
+
+void
+dcache_update (DCACHE *dcache, CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ dcache_poke_byte (dcache, memaddr + i, myaddr + i);
+}
+
static void
dcache_print_line (int index)
{
@@ -474,12 +510,15 @@ dcache_info (char *exp, int tty)
printf_filtered (_("Dcache line width %d, maximum size %d\n"),
LINE_SIZE, DCACHE_SIZE);
- if (!last_cache)
+ if (!last_cache || ptid_equal (last_cache->ptid, null_ptid))
{
printf_filtered (_("No data cache available.\n"));
return;
}
+ printf_filtered (_("Contains data for %s\n"),
+ target_pid_to_str (last_cache->ptid));
+
refcount = 0;
n = splay_tree_min (last_cache->tree);
@@ -507,15 +546,25 @@ _initialize_dcache (void)
&dcache_enabled_p, _("\
Set cache use for remote targets."), _("\
Show cache use for remote targets."), _("\
-When on, use data caching for remote targets. For many remote targets\n\
-this option can offer better throughput for reading target memory.\n\
-Unfortunately, gdb does not currently know anything about volatile\n\
-registers and thus data caching will produce incorrect results with\n\
-volatile registers are in use. By default, this option is off."),
+This used to enable the data cache for remote targets. The cache\n\
+functionality is now controlled by the memory region system and the\n\
+\"stack-cache\" flag; \"remotecache\" now does nothing and\n\
+exists only for compatibility reasons."),
NULL,
show_dcache_enabled_p,
&setlist, &showlist);
+ add_setshow_boolean_cmd ("stack-cache", class_support,
+ &stack_cache_enabled_p, _("\
+Set cache use for stack access."), _("\
+Show cache use for stack access."), _("\
+When on, use the data cache for all stack access, regardless of any\n\
+configured memory regions. This improves remote performance significantly.\n\
+By default, caching for stack access is on."),
+ NULL,
+ show_stack_cache_enabled_p,
+ &setlist, &showlist);
+
add_info ("dcache", dcache_info,
_("\
Print information on the dcache performance.\n\
Index: dcache.h
===================================================================
RCS file: /cvs/src/src/gdb/dcache.h,v
retrieving revision 1.15
diff -u -p -r1.15 dcache.h
--- dcache.h 20 Aug 2009 22:30:12 -0000 1.15
+++ dcache.h 25 Aug 2009 00:23:18 -0000
@@ -38,4 +38,10 @@ void dcache_free (DCACHE *);
int dcache_xfer_memory (struct target_ops *ops, DCACHE *cache, CORE_ADDR mem,
gdb_byte *my, int len, int should_write);
+void dcache_update (DCACHE *dcache, CORE_ADDR memaddr, gdb_byte *myaddr,
+ int len);
+
+/* Should we use the dcache for stack access? */
+extern int stack_cache_enabled_p;
+
#endif /* DCACHE_H */
Index: dwarf2loc.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.63
diff -u -p -r1.63 dwarf2loc.c
--- dwarf2loc.c 11 Aug 2009 20:36:49 -0000 1.63
+++ dwarf2loc.c 25 Aug 2009 00:23:18 -0000
@@ -280,6 +280,7 @@ dwarf2_evaluate_loc_desc (struct symbol
retval = allocate_value (SYMBOL_TYPE (var));
VALUE_LVAL (retval) = lval_memory;
set_value_lazy (retval, 1);
+ set_value_stack (retval, 1);
set_value_address (retval, address);
}
Index: frame-unwind.c
===================================================================
RCS file: /cvs/src/src/gdb/frame-unwind.c,v
retrieving revision 1.26
diff -u -p -r1.26 frame-unwind.c
--- frame-unwind.c 2 Jul 2009 17:25:53 -0000 1.26
+++ frame-unwind.c 25 Aug 2009 00:23:18 -0000
@@ -153,8 +153,10 @@ struct value *
frame_unwind_got_memory (struct frame_info *frame, int regnum, CORE_ADDR addr)
{
struct gdbarch *gdbarch = frame_unwind_arch (frame);
+ struct value *v = value_at_lazy (register_type (gdbarch, regnum), addr);
- return value_at_lazy (register_type (gdbarch, regnum), addr);
+ set_value_stack (v, 1);
+ return v;
}
/* Return a value which indicates that FRAME's saved version of
Index: gdbcore.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbcore.h,v
retrieving revision 1.35
diff -u -p -r1.35 gdbcore.h
--- gdbcore.h 2 Jul 2009 17:25:53 -0000 1.35
+++ gdbcore.h 25 Aug 2009 00:23:18 -0000
@@ -47,6 +47,10 @@ extern void memory_error (int status, CO
extern void read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len);
+/* Like target_read_stack, but report an error if can't read. */
+
+extern void read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, int len);
+
/* Read an integer from debugged memory, given address and number of
bytes. */
Index: target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.221
diff -u -p -r1.221 target.c
--- target.c 20 Aug 2009 22:30:12 -0000 1.221
+++ target.c 25 Aug 2009 00:23:18 -0000
@@ -210,6 +210,7 @@ show_targetdebug (struct ui_file *file,
static void setup_target_debug (void);
+/* Cache of memory operations, to speed up remote access. */
DCACHE *target_dcache;
/* The user just typed 'target' without the name of a target. */
@@ -1143,12 +1144,14 @@ target_section_by_addr (struct target_op
value are just as for target_xfer_partial. */
static LONGEST
-memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf,
- ULONGEST memaddr, LONGEST len)
+memory_xfer_partial (struct target_ops *ops, enum target_object object,
+ void *readbuf, const void *writebuf, ULONGEST memaddr,
+ LONGEST len)
{
LONGEST res;
int reg_len;
struct mem_region *region;
+ struct inferior *inf;
/* Zero length requests are ok and require no work. */
if (len == 0)
@@ -1223,7 +1226,11 @@ memory_xfer_partial (struct target_ops *
return -1;
}
- if (region->attrib.cache)
+ inf = find_inferior_pid (ptid_get_pid (inferior_ptid));
+
+ if (inf
+ && (region->attrib.cache
+ || (stack_cache_enabled_p && object == TARGET_OBJECT_STACK_MEMORY)))
{
if (readbuf != NULL)
res = dcache_xfer_memory (ops, target_dcache, memaddr, readbuf,
@@ -1245,6 +1252,19 @@ memory_xfer_partial (struct target_ops *
}
}
+ /* Make sure the cache gets updated no matter what - if we are writing
+ to the stack, even if this write is not tagged as such, we still need
+ to update the cache. */
+
+ if (inf
+ && readbuf == NULL
+ && !region->attrib.cache
+ && stack_cache_enabled_p
+ && object != TARGET_OBJECT_STACK_MEMORY)
+ {
+ dcache_update (target_dcache, memaddr, (void *) writebuf, reg_len);
+ }
+
/* If none of those methods found the memory we wanted, fall back
to a target partial transfer. Normally a single call to
to_xfer_partial is enough; if it doesn't recognize an object
@@ -1308,8 +1328,9 @@ target_xfer_partial (struct target_ops *
/* If this is a memory transfer, let the memory-specific code
have a look at it instead. Memory transfers are more
complicated. */
- if (object == TARGET_OBJECT_MEMORY)
- retval = memory_xfer_partial (ops, readbuf, writebuf, offset, len);
+ if (object == TARGET_OBJECT_MEMORY || object == TARGET_OBJECT_STACK_MEMORY)
+ retval = memory_xfer_partial (ops, object, readbuf,
+ writebuf, offset, len);
else
{
enum target_object raw_object = object;
@@ -1391,6 +1412,23 @@ target_read_memory (CORE_ADDR memaddr, g
return EIO;
}
+/* Like target_read_memory, but specify explicitly that this is a read from
+ the target's stack. This may trigger different cache behavior. */
+
+int
+target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+{
+ /* Dispatch to the topmost target, not the flattened current_target.
+ Memory accesses check target->to_has_(all_)memory, and the
+ flattened target doesn't inherit those. */
+
+ if (target_read (current_target.beneath, TARGET_OBJECT_STACK_MEMORY, NULL,
+ myaddr, memaddr, len) == len)
+ return 0;
+ else
+ return EIO;
+}
+
int
target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
{
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.162
diff -u -p -r1.162 target.h
--- target.h 31 Jul 2009 15:28:27 -0000 1.162
+++ target.h 25 Aug 2009 00:23:18 -0000
@@ -203,6 +203,10 @@ enum target_object
Target implementations of to_xfer_partial never need to handle
this object, and most callers should not use it. */
TARGET_OBJECT_RAW_MEMORY,
+ /* Memory known to be part of the target's stack. This is cached even
+ if it is not in a region marked as such, since it is known to be
+ "normal" RAM. */
+ TARGET_OBJECT_STACK_MEMORY,
/* Kernel Unwind Table. See "ia64-tdep.c". */
TARGET_OBJECT_UNWIND_TABLE,
/* Transfer auxilliary vector. */
@@ -677,6 +681,8 @@ extern int target_read_string (CORE_ADDR
extern int target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len);
+extern int target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, int len);
+
extern int target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr,
int len);
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.224
diff -u -p -r1.224 valops.c
--- valops.c 21 Jul 2009 18:15:32 -0000 1.224
+++ valops.c 25 Aug 2009 00:23:18 -0000
@@ -565,6 +565,32 @@ value_one (struct type *type, enum lval_
return val;
}
+/* Helper function for value_at, value_at_lazy, and value_at_lazy_stack. */
+
+static struct value *
+get_value_at (struct type *type, CORE_ADDR addr, int lazy)
+{
+ struct value *val;
+
+ if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
+ error (_("Attempt to dereference a generic pointer."));
+
+ if (lazy)
+ {
+ val = allocate_value_lazy (type);
+ }
+ else
+ {
+ val = allocate_value (type);
+ read_memory (addr, value_contents_all_raw (val), TYPE_LENGTH (type));
+ }
+
+ VALUE_LVAL (val) = lval_memory;
+ set_value_address (val, addr);
+
+ return val;
+}
+
/* Return a value with type TYPE located at ADDR.
Call value_at only if the data needs to be fetched immediately;
@@ -580,19 +606,7 @@ value_one (struct type *type, enum lval_
struct value *
value_at (struct type *type, CORE_ADDR addr)
{
- struct value *val;
-
- if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
- error (_("Attempt to dereference a generic pointer."));
-
- val = allocate_value (type);
-
- read_memory (addr, value_contents_all_raw (val), TYPE_LENGTH (type));
-
- VALUE_LVAL (val) = lval_memory;
- set_value_address (val, addr);
-
- return val;
+ return get_value_at (type, addr, 0);
}
/* Return a lazy value with type TYPE located at ADDR (cf. value_at). */
@@ -600,17 +614,7 @@ value_at (struct type *type, CORE_ADDR a
struct value *
value_at_lazy (struct type *type, CORE_ADDR addr)
{
- struct value *val;
-
- if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
- error (_("Attempt to dereference a generic pointer."));
-
- val = allocate_value_lazy (type);
-
- VALUE_LVAL (val) = lval_memory;
- set_value_address (val, addr);
-
- return val;
+ return get_value_at (type, addr, 1);
}
/* Called only from the value_contents and value_contents_all()
@@ -656,7 +660,12 @@ value_fetch_lazy (struct value *val)
int length = TYPE_LENGTH (check_typedef (value_enclosing_type (val)));
if (length)
- read_memory (addr, value_contents_all_raw (val), length);
+ {
+ if (value_stack (val))
+ read_stack (addr, value_contents_all_raw (val), length);
+ else
+ read_memory (addr, value_contents_all_raw (val), length);
+ }
}
else if (VALUE_LVAL (val) == lval_register)
{
Index: value.c
===================================================================
RCS file: /cvs/src/src/gdb/value.c,v
retrieving revision 1.93
diff -u -p -r1.93 value.c
--- value.c 19 Aug 2009 13:00:28 -0000 1.93
+++ value.c 25 Aug 2009 00:23:18 -0000
@@ -196,6 +196,10 @@ struct value
/* If value is a variable, is it initialized or not. */
int initialized;
+ /* If value is from the stack. If this is set, read_stack will be
+ used instead of read_memory to enable extra caching. */
+ int stack;
+
/* Actual contents of the value. Target byte-order. NULL or not
valid if lazy is nonzero. */
gdb_byte *contents;
@@ -424,6 +428,18 @@ set_value_lazy (struct value *value, int
value->lazy = val;
}
+int
+value_stack (struct value *value)
+{
+ return value->stack;
+}
+
+void
+set_value_stack (struct value *value, int val)
+{
+ value->stack = val;
+}
+
const gdb_byte *
value_contents (struct value *value)
{
Index: value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.148
diff -u -p -r1.148 value.h
--- value.h 13 Aug 2009 18:39:20 -0000 1.148
+++ value.h 25 Aug 2009 00:23:18 -0000
@@ -215,6 +215,9 @@ extern void *value_computed_closure (str
extern int value_lazy (struct value *);
extern void set_value_lazy (struct value *value, int val);
+extern int value_stack (struct value *);
+extern void set_value_stack (struct value *value, int val);
+
/* value_contents() and value_contents_raw() both return the address
of the gdb buffer used to hold a copy of the contents of the lval.
value_contents() is used when the contents of the buffer are needed
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.616
diff -u -p -r1.616 gdb.texinfo
--- doc/gdb.texinfo 20 Aug 2009 18:02:48 -0000 1.616
+++ doc/gdb.texinfo 25 Aug 2009 00:23:19 -0000
@@ -8398,32 +8398,47 @@ character.
@section Caching Data of Remote Targets
@cindex caching data of remote targets
-@value{GDBN} can cache data exchanged between the debugger and a
+@value{GDBN} caches data exchanged between the debugger and a
remote target (@pxref{Remote Debugging}). Such caching generally improves
performance, because it reduces the overhead of the remote protocol by
-bundling memory reads and writes into large chunks. Unfortunately,
-@value{GDBN} does not currently know anything about volatile
-registers, and thus data caching will produce incorrect results when
-volatile registers are in use.
+bundling memory reads and writes into large chunks. Unfortunately, simply
+caching everything would lead to incorrect results, since @value{GDBN}
+does not necessarily know anything about volatile values, memory-mapped I/O
+addresses, etc. Therefore, by default, @value{GDBN} only caches data
+known to be on the stack. Other regions of memory can be explicitly marked
+cacheable; see @pxref{Memory Region Attributes}.
@table @code
@kindex set remotecache
@item set remotecache on
@itemx set remotecache off
-Set caching state for remote targets. When @code{ON}, use data
-caching. By default, this option is @code{OFF}.
+This option no longer does anything; it exists for compatibility
+with old scripts.
@kindex show remotecache
@item show remotecache
-Show the current state of data caching for remote targets.
+Show the current state of the obsolete remotecache flag.
+
+@kindex set stack-cache
+@item set stack-cache on
+@itemx set stack-cache off
+Enable or disable caching of stack accesses. When @code{ON}, use
+caching. By default, this option is @code{ON}.
+
+@kindex show stack-cache
+@item show stack-cache
+Show the current state of data caching for memory accesses.
@kindex info dcache
-@item info dcache
+@item info dcache @r{[}line@r{]}
Print the information about the data cache performance. The
-information displayed includes: the dcache width and depth; and for
-each cache line, how many times it was referenced, and its data and
-state (invalid, dirty, valid). This command is useful for debugging
-the data cache operation.
+information displayed includes the dcache width and depth, and for
+each cache line, its number, address, and how many times it was
+referenced. This command is useful for debugging the data cache
+operation.
+
+If a line number is specified, the contents of that line will be
+printed in hex.
@end table
@node Searching Memory
next prev parent reply other threads:[~2009-08-25 0:48 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-08 20:49 Jacob Potter
2009-07-08 20:51 ` Pedro Alves
2009-07-08 20:58 ` Pedro Alves
2009-07-08 23:46 ` Daniel Jacobowitz
2009-07-09 3:06 ` Pedro Alves
2009-07-10 9:34 ` Pedro Alves
2009-07-10 8:45 ` Jacob Potter
2009-07-10 14:19 ` Pedro Alves
2009-07-13 19:25 ` Jacob Potter
2009-08-21 6:25 ` Doug Evans
2009-08-25 3:00 ` Doug Evans [this message]
2009-08-25 18:55 ` Pedro Alves
2009-08-26 16:36 ` Doug Evans
2009-08-26 22:45 ` Pedro Alves
2009-08-27 0:46 ` Doug Evans
2009-08-27 3:11 ` Doug Evans
2009-08-29 5:16 ` Doug Evans
2009-08-29 18:28 ` Doug Evans
2009-08-29 20:25 ` Pedro Alves
2009-09-02 20:43 ` Tom Tromey
2009-09-03 15:38 ` Doug Evans
2009-09-03 19:38 ` Tom Tromey
2009-09-03 19:45 ` Daniel Jacobowitz
2009-07-09 12:20 ` Eli Zaretskii
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=e394668d0908241748h769c8f8av1e3d8121688bc98f@mail.gmail.com \
--to=dje@google.com \
--cc=gdb-patches@sourceware.org \
--cc=pedro@codesourcery.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