This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 3/5] 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 control use code cache or not.

The invalidation of code cache is identical to stack cache, with this
patch, function target_dcache_invalidate invalidates both.  Command
"set {stack,code}-cache" invalidates either of them.

gdb:

2013-10-23  Yao Qi  <yao@codesourcery.com>

	* target.c (struct target_dcache) <code>: New field.
	(target_dcache_alloc): Initialize field 'code'.
	(set_stack_cache_enabled_p): Invalidate corresponding dcache.
	(code_cache_enabled_p_1): New.
	(code_cache_enabled_p): New.
	(set_code_cache_enabled_p): New function.
	(show_code_cache_enabled_p): New function.
	(target_dcache_xfree): Free code cache.
	(target_dcache_invalidate): Invalidate code cache.
	(memory_xfer_partial_1): Handle TARGET_OBJECT_CODE_MEMORY and
	code_cache_enabled_p.
	(target_xfer_partial): Likewise.
	(target_read_code): New function.
	(initialize_targets): Register command.
	* target.h (enum target_object) <TARGET_OBJECT_CODE_MEMORY>: New.
	(target_read_code): Declare.
---
 gdb/target.c |   97 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 gdb/target.h |    5 +++
 2 files changed, 89 insertions(+), 13 deletions(-)

diff --git a/gdb/target.c b/gdb/target.c
index 2ae42a8..624d41a 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -218,6 +218,9 @@ struct target_dcache
   /* Cache the memory on stack and areas specified by memory
      attributes.  */
   DCACHE *general;
+
+  /* Cache the code.  */
+  DCACHE *code;
 };
 
 /* Allocate an instance of struct target_dcache.  */
@@ -228,6 +231,7 @@ target_dcache_alloc (void)
   struct target_dcache *dcache = xmalloc (sizeof (*dcache));
 
   dcache->general = dcache_init ();
+  dcache->code = dcache_init ();
 
   return dcache;
 }
@@ -240,6 +244,7 @@ target_dcache_xfree (struct target_dcache *dcache)
   if (dcache != NULL)
     {
       dcache_free (dcache->general);
+      dcache_free (dcache->code);
       xfree (dcache);
     }
 }
@@ -289,7 +294,7 @@ set_stack_cache_enabled_p (char *args, int from_tty,
 			   struct cmd_list_element *c)
 {
   if (stack_cache_enabled_p != stack_cache_enabled_p_1)
-    target_dcache_invalidate ();
+    dcache_invalidate (target_dcache_get ()->general);
 
   stack_cache_enabled_p = stack_cache_enabled_p_1;
 }
@@ -301,6 +306,35 @@ show_stack_cache_enabled_p (struct ui_file *file, int from_tty,
   fprintf_filtered (file, _("Cache use for stack accesses is %s.\n"), value);
 }
 
+/* The option sets this.  */
+static int code_cache_enabled_p_1 = 1;
+/* And set_code_cache_enabled_p 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_p = 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_enabled_p (char *args, int from_tty,
+			  struct cmd_list_element *c)
+{
+  if (code_cache_enabled_p != code_cache_enabled_p_1)
+    dcache_invalidate (target_dcache_get ()->code);
+
+  code_cache_enabled_p = code_cache_enabled_p_1;
+}
+
+static void
+show_code_cache_enabled_p (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);
+}
+
 /* Invalidate the target dcache.  */
 
 void
@@ -309,6 +343,7 @@ target_dcache_invalidate (void)
   struct target_dcache *td = target_dcache_get ();
 
   dcache_invalidate (td->general);
+  dcache_invalidate (td->code);
 }
 
 /* The user just typed 'target' without the name of a target.  */
@@ -1651,17 +1686,24 @@ 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)))
     {
+      struct target_dcache *td = target_dcache_get ();
+      DCACHE *dcache = NULL;
+
+      if (code_cache_enabled_p && object == TARGET_OBJECT_CODE_MEMORY)
+	dcache = td->code;
+      else
+	dcache = td->general;
+
       if (readbuf != NULL)
-	res = dcache_xfer_memory (ops, target_dcache_get ()->general,
-				  memaddr, readbuf, reg_len, 0);
+	res = dcache_xfer_memory (ops, dcache, memaddr, readbuf, reg_len, 0);
       else
 	/* FIXME drow/2006-08-09: If we're going to preserve const
 	   correctness dcache_xfer_memory should take readbuf and
 	   writebuf.  */
-	res = dcache_xfer_memory (ops, target_dcache_get ()->general,
-				  memaddr, (void *) writebuf,
+	res = dcache_xfer_memory (ops, dcache, memaddr, (void *) writebuf,
 				  reg_len, 1);
       if (res <= 0)
 	return -1;
@@ -1701,13 +1743,17 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
 
   if (res > 0
       && inf != NULL
-      && writebuf != NULL
-      && !region->attrib.cache
-      && stack_cache_enabled_p
-      && object != TARGET_OBJECT_STACK_MEMORY)
+      && writebuf != NULL)
     {
-      dcache_update (target_dcache_get ()->general, memaddr,
-		     (void *) writebuf, res);
+      struct target_dcache *td = target_dcache_get ();
+
+      if (!region->attrib.cache
+	  && stack_cache_enabled_p
+	  && object != TARGET_OBJECT_STACK_MEMORY)
+	dcache_update (td->general, memaddr, (void *) writebuf, res);
+
+      if (code_cache_enabled_p && object != TARGET_OBJECT_CODE_MEMORY)
+	dcache_update (td->code, memaddr, (void *) writebuf, res);
     }
 
   /* If we still haven't got anything, return the last error.  We
@@ -1792,7 +1838,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
@@ -1894,6 +1941,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
@@ -5199,6 +5259,17 @@ By default, caching for stack access is on."),
 			   show_stack_cache_enabled_p,
 			   &setlist, &showlist);
 
+  add_setshow_boolean_cmd ("code-cache", class_support,
+			   &code_cache_enabled_p_1, _("\
+Set cache use for code access."), _("\
+Show cache use for code access."), _("\
+When on, use the data cache for all code access, regardless of any\n\
+configured memory regions.  This improves remote performance significantly.\n\
+By default, caching for code access is on."),
+			   set_code_cache_enabled_p,
+			   show_code_cache_enabled_p,
+			   &setlist, &showlist);
+
   add_setshow_boolean_cmd ("may-write-registers", class_support,
 			   &may_write_registers_1, _("\
 Set permission to write into registers."), _("\
diff --git a/gdb/target.h b/gdb/target.h
index 56ca40c..eb00b83 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -144,6 +144,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.  */
@@ -1052,6 +1055,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);
 
-- 
1.7.7.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]