From 29453a14557af65ed7a0867722b0145bb9f0e0c2 Mon Sep 17 00:00:00 2001 From: Yao Qi Date: Fri, 1 Nov 2013 12:26:10 +0800 Subject: [PATCH] set/show code-cache Similar to stack cache, in this patch, we add TARGET_OBJECT_CODE_MEMORY to read code from target and add a new option "set code-cache on|off" to optimize code accesses by using the target memory cache. In V4: - Remove "without affecting correctness" from NEWS and doc. - Replace "ON" with "on" in doc. - "access" -> "accesses". In V3: - Rename functions and variables. - Update command help, doc and NEWS entry. - Invalidate cache on option transitions, to align with the behaviour of "stack-cache". Since cache invalidation is transparent to users, users don't know option "stack-cache" transitions cause code cache invalidation. V2 was reviewed by Doug. There are some changes in V3, so I post it here. gdb: 2013-11-24 Yao Qi * NEWS: Add note on new "set code-cache" option. * target-dcache.c (code_cache_enabled_1): New variable. (code_cache_enabled): New variable. (show_code_cache, set_code_cache): New function. (code_cache_enabled_p): New function. (_initialize_target_dcache): Register command. * target-dcache.h (code_cache_enabled_p): Declare. * target.c (memory_xfer_partial_1):Handle TARGET_OBJECT_CODE_MEMORY and code_cache_enabled. (target_read_code): New function. * target.h (enum target_object) : New. (target_read_code): Declare. gdb/doc: 2013-11-24 Yao Qi * gdb.texinfo (Caching Remote Data): Document new "set/show stack-cache" option. --- gdb/ChangeLog | 16 ++++++++++++++++ gdb/NEWS | 5 +++++ gdb/doc/ChangeLog | 5 +++++ gdb/doc/gdb.texinfo | 15 ++++++++++++++- gdb/target-dcache.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gdb/target-dcache.h | 2 ++ gdb/target.c | 23 +++++++++++++++++++---- gdb/target.h | 5 +++++ 8 files changed, 118 insertions(+), 5 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 869c860..b91eb51 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,21 @@ 2013-11-24 Yao Qi + * NEWS: Add note on new "set code-cache" option. + * target-dcache.c (code_cache_enabled_1): New variable. + (code_cache_enabled): New variable. + (show_code_cache, set_code_cache): New function. + (code_cache_enabled_p): New function. + (_initialize_target_dcache): Register command. + * target-dcache.h (code_cache_enabled_p): Declare. + * target.c (memory_xfer_partial_1):Handle + TARGET_OBJECT_CODE_MEMORY and code_cache_enabled. + (target_read_code): New function. + * target.h (enum target_object) : + New. + (target_read_code): Declare. + +2013-11-24 Yao Qi + * target-dcache.c (stack_cache_enabled_p_1): Rename to ... (stack_cache_enabled_1): ... this. New variable. (stack_cache_enabled_p): Rename to ... diff --git a/gdb/NEWS b/gdb/NEWS index 9fc3638..5110b27 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -117,6 +117,11 @@ show startup-with-shell Specifies whether Unix child processes are started via a shell or directly. +set code-cache +show code-cache + Use the target memory cache for accesses to the code segment. This + improves performance of remote debugging (particularly disassembly). + * You can now use a literal value 'unlimited' for options that interpret 0 or -1 as meaning "unlimited". E.g., "set trace-buffer-size unlimited" is now an alias for "set diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 7ec3f61..141d47f 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,5 +1,10 @@ 2013-11-24 Yao Qi + * gdb.texinfo (Caching Remote Data): Document new + "set/show stack-cache" option. + +2013-11-24 Yao Qi + * gdb.texinfo (Caching Target Data): Replace "ON" with "on". (Maintenance Commands): Replace "ON" and "OFF" with "on" and "off" respectively. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 830a156..004c376 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -10842,7 +10842,8 @@ Therefore, by default, @value{GDBN} only caches data known to be on the stack@footnote{In non-stop mode, it is moderately rare for a running thread to modify the stack of a stopped thread in a way that would interfere with a backtrace, and caching of -stack reads provides a significant speed up of remote backtraces.}. +stack reads provides a significant speed up of remote backtraces.} or +in the code segment. Other regions of memory can be explicitly marked as cacheable; @pxref{Memory Region Attributes}. @@ -10867,6 +10868,18 @@ caching. By default, this option is @code{on}. @item show stack-cache Show the current state of data caching for memory accesses. +@kindex set code-cache +@item set code-cache on +@itemx set code-cache off +Enable or disable caching of code segment accesses. When @code{on}, +use caching. By default, this option is @code{on}. This improves +performance of disassembly in remote debugging. + +@kindex show code-cache +@item show code-cache +Show the current state of target memory cache for code segment +accesses. + @kindex info dcache @item info dcache @r{[}line@r{]} Print the information about the performance of data cache of the diff --git a/gdb/target-dcache.c b/gdb/target-dcache.c index 6b7986a..7f68ddc 100644 --- a/gdb/target-dcache.c +++ b/gdb/target-dcache.c @@ -124,6 +124,46 @@ stack_cache_enabled_p (void) return stack_cache_enabled; } +/* The option sets this. */ + +static int code_cache_enabled_1 = 1; + +/* And set_code_cache updates this. + The reason for the separation is so that we don't flush the cache for + on->on transitions. */ +static int code_cache_enabled = 1; + +/* This is called *after* the code-cache has been set. + Flush the cache for off->on and on->off transitions. + There's no real need to flush the cache for on->off transitions, + except cleanliness. */ + +static void +set_code_cache (char *args, int from_tty, struct cmd_list_element *c) +{ + if (code_cache_enabled != code_cache_enabled_1) + target_dcache_invalidate (); + + code_cache_enabled = code_cache_enabled_1; +} + +/* Show option "code-cache". */ + +static void +show_code_cache (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Cache use for code accesses is %s.\n"), value); +} + +/* Return true if "code cache" is enabled, otherwise, return false. */ + +int +code_cache_enabled_p (void) +{ + return code_cache_enabled; +} + /* -Wmissing-prototypes */ extern initialize_file_ftype _initialize_target_dcache; @@ -141,6 +181,18 @@ By default, caching for stack access is on."), show_stack_cache, &setlist, &showlist); + add_setshow_boolean_cmd ("code-cache", class_support, + &code_cache_enabled_1, _("\ +Set cache use for code segment access."), _("\ +Show cache use for code segment access."), _("\ +When on, use the target memory cache for all code segment accesses,\n\ +regardless of any configured memory regions. This improves remote\n\ +performance significantly. By default, caching for code segment\n\ +access is on."), + set_code_cache, + show_code_cache, + &setlist, &showlist); + target_dcache_aspace_key = register_address_space_data_with_cleanup (NULL, target_dcache_cleanup); diff --git a/gdb/target-dcache.h b/gdb/target-dcache.h index 3200dd9..59e0b3d 100644 --- a/gdb/target-dcache.h +++ b/gdb/target-dcache.h @@ -30,4 +30,6 @@ extern int target_dcache_init_p (void); extern int stack_cache_enabled_p (void); +extern int code_cache_enabled_p (void); + #endif /* TARGET_DCACHE_H */ diff --git a/gdb/target.c b/gdb/target.c index f402a18..cc6194b 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -1547,7 +1547,8 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object, the collected memory range fails. */ && get_traceframe_number () == -1 && (region->attrib.cache - || (stack_cache_enabled_p () && object == TARGET_OBJECT_STACK_MEMORY))) + || (stack_cache_enabled_p () && object == TARGET_OBJECT_STACK_MEMORY) + || (code_cache_enabled_p () && object == TARGET_OBJECT_CODE_MEMORY))) { DCACHE *dcache = target_dcache_get_or_init (); @@ -1600,8 +1601,8 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object, && writebuf != NULL && target_dcache_init_p () && !region->attrib.cache - && stack_cache_enabled_p () - && object != TARGET_OBJECT_STACK_MEMORY) + && ((stack_cache_enabled_p () && object != TARGET_OBJECT_STACK_MEMORY) + || (code_cache_enabled_p () && object != TARGET_OBJECT_CODE_MEMORY))) { DCACHE *dcache = target_dcache_get (); @@ -1697,7 +1698,8 @@ target_xfer_partial (struct target_ops *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 || object == TARGET_OBJECT_STACK_MEMORY) + if (object == TARGET_OBJECT_MEMORY || object == TARGET_OBJECT_STACK_MEMORY + || object == TARGET_OBJECT_CODE_MEMORY) retval = memory_xfer_partial (ops, object, readbuf, writebuf, offset, len); else @@ -1799,6 +1801,19 @@ target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len) return TARGET_XFER_E_IO; } +/* Like target_read_memory, but specify explicitly that this is a read from + the target's code. This may trigger different cache behavior. */ + +int +target_read_code (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len) +{ + if (target_read (current_target.beneath, TARGET_OBJECT_CODE_MEMORY, NULL, + myaddr, memaddr, len) == len) + return 0; + else + return TARGET_XFER_E_IO; +} + /* Write LEN bytes from MYADDR to target memory at address MEMADDR. Returns either 0 for success or a target_xfer_error value if any error occurs. If an error occurs, no guarantee is made about how diff --git a/gdb/target.h b/gdb/target.h index 646907a..890171d 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -145,6 +145,9 @@ enum target_object if it is not in a region marked as such, since it is known to be "normal" RAM. */ TARGET_OBJECT_STACK_MEMORY, + /* Memory known to be part of the target code. This is cached even + if it is not in a region marked as such. */ + TARGET_OBJECT_CODE_MEMORY, /* Kernel Unwind Table. See "ia64-tdep.c". */ TARGET_OBJECT_UNWIND_TABLE, /* Transfer auxilliary vector. */ @@ -1050,6 +1053,8 @@ extern int target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, extern int target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len); +extern int target_read_code (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len); + extern int target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len); -- 2.7.4