diff options
author | Doug Evans <dje@google.com> | 2009-08-31 20:18:46 +0000 |
---|---|---|
committer | Doug Evans <dje@google.com> | 2009-08-31 20:18:46 +0000 |
commit | 4e5d721fc0b3a9de5764a7b3bf3d6be4132ab67b (patch) | |
tree | 1818952fb05548383ecc47eded2a17631aff6ca0 /gdb/dcache.c | |
parent | f1c2d4afbe03f4303f200ba418a446da410cba17 (diff) | |
download | gdb-4e5d721fc0b3a9de5764a7b3bf3d6be4132ab67b.zip gdb-4e5d721fc0b3a9de5764a7b3bf3d6be4132ab67b.tar.gz gdb-4e5d721fc0b3a9de5764a7b3bf3d6be4132ab67b.tar.bz2 |
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.
(show_dcache_enabled_p): Flag option as deprecated.
(dcache_invalidate): Update ptid.
(dcache_invalidate_line): New function.
(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.
Update cache after write.
(dcache_update): New function.
(dcache_info): Report ptid.
(_initialize_dcache): Update text for `remotecache' to indicate it
is obsolete.
* dcache.h (dcache_update): 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.
* memattr.c (mem_enable_command): Call target_dcache_invalidate
instead of dcache_invalidate.
(mem_disable_command, mem_delete_command): Ditto.
* target.c (stack_cache_enabled_p_1): New static global.
(stack_cache_enabled_p): New static global.
(set_stack_cache_enabled_p): New function.
(show_stack_cache_enabled_p): New function.
(target_dcache): Make static.
(target_dcache_invalidate): New function.
(target_load, target_resume): Call target_dcache_invalidate
instead of dcache_invalidate.
(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.
(initialize_targets): Install new option `stack-cache'.
* target.h: Remove #include of dcache.h.
(enum target_object): New value TARGET_OBJECT_STACK_MEMORY.
(target_dcache): Delete.
(target_dcache_invalidate): Declare.
(target_read_stack): Declare.
* top.c (prepare_execute_command): New function.
(execute_command): Call prepare_execute_command
instead of free_all_values.
* top.h (prepare_execute_command): 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.
* mi/mi-main.c (mi_cmd_execute): Call prepare_execute_command
instead of free_all_values.
doc/
* gdb.texinfo (Caching Data of Remote Targets): Update text.
Mark `set/show remotecache' options as obsolete.
Document new `set/show stack-cache' option.
Update text for `info dcache'.
Diffstat (limited to 'gdb/dcache.c')
-rw-r--r-- | gdb/dcache.c | 88 |
1 files changed, 72 insertions, 16 deletions
diff --git a/gdb/dcache.c b/gdb/dcache.c index 17c948a..52375f0 100644 --- a/gdb/dcache.c +++ b/gdb/dcache.c @@ -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,16 +121,15 @@ static void dcache_info (char *exp, int tty); void _initialize_dcache (void); -static int dcache_enabled_p = 0; +static int dcache_enabled_p = 0; /* OBSOLETE */ 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 DCACHE *last_cache; /* Used by info dcache */ /* Free all the data cache blocks, thus discarding all cached data. */ @@ -152,6 +155,23 @@ dcache_invalidate (DCACHE *dcache) dcache->oldest = NULL; dcache->newest = NULL; dcache->size = 0; + dcache->ptid = null_ptid; +} + +/* Invalidate the line associated with ADDR. */ + +static void +dcache_invalidate_line (DCACHE *dcache, CORE_ADDR addr) +{ + struct dcache_block *db = dcache_hit (dcache, addr); + + if (db) + { + splay_tree_remove (dcache->tree, (splay_tree_key) db->addr); + db->newer = dcache->freelist; + dcache->freelist = db; + --dcache->size; + } } /* If addr is present in the dcache, return the address of the block @@ -198,8 +218,9 @@ dcache_read_line (DCACHE *dcache, struct dcache_block *db) 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; @@ -296,7 +317,7 @@ dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr) an area of memory which wasn't present in the cache doesn't cause it to be loaded in. - Always return 1 to simplify dcache_xfer_memory. */ + Always return 1 (meaning success) to simplify dcache_xfer_memory. */ static int dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr) @@ -338,6 +359,7 @@ dcache_init (void) dcache->newest = NULL; dcache->freelist = NULL; dcache->size = 0; + dcache->ptid = null_ptid; last_cache = dcache; return dcache; @@ -366,7 +388,7 @@ dcache_free (DCACHE *dcache) to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is nonzero. - Returns length of data written or read; 0 for error. */ + The meaning of the result is the same as for target_write. */ int dcache_xfer_memory (struct target_ops *ops, DCACHE *dcache, @@ -378,6 +400,15 @@ dcache_xfer_memory (struct target_ops *ops, DCACHE *dcache, 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. */ @@ -385,14 +416,25 @@ dcache_xfer_memory (struct target_ops *ops, DCACHE *dcache, { res = target_write (ops, TARGET_OBJECT_RAW_MEMORY, NULL, myaddr, memaddr, len); - if (res < len) - return 0; + if (res <= 0) + return res; + /* Update LEN to what was actually written. */ + len = res; } for (i = 0; i < len; i++) { if (!xfunc (dcache, memaddr + i, myaddr + i)) - return 0; + { + /* That failed. Discard its cache line so we don't have a + partially read line. */ + dcache_invalidate_line (dcache, memaddr + i); + /* If we're writing, we still wrote LEN bytes. */ + if (should_write) + return len; + else + return i; + } } return len; @@ -407,6 +449,18 @@ dcache_xfer_memory (struct target_ops *ops, DCACHE *dcache, "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 +528,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,11 +564,10 @@ _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); |