[patch 2/2] Speed up JIT support

Paul Pluzhnikov ppluzhnikov@google.com
Thu Feb 3 21:58:00 GMT 2011


Greetings,

This is the second part of the JIT speedup patch (applies on top of the
first patch).

I vaguely remember (but can't find a reference) that there is no CORE_ADDR
that is guaranteed to always be invalid, and so my use of -1 for
INVALID_CORE_ADDR may be problematic.

I also forgot to mention: tested on Linux/x86_64, no regressions.

Thanks,
--
Paul Pluzhnikov


2010-02-03  Paul Pluzhnikov  <ppluzhnikov@google.com>

	* breakpoint.c (longjmp_names): New variable.
	(struct breakpoint_objfile_data): New type.
	(breakpoint_objfile_key): New variable.
	(get_breakpoint_objfile_data): New function.
	(create_overlay_event_breakpoint): Adjust.
	(create_longjmp_master_breakpoint): Adjust.
	(create_std_terminate_master_breakpoint): Adjust.
	(create_exception_master_breakpoint): Adjust.
	(_initialize_breakpoint): Adjust.
-------------- next part --------------
--- breakpoint.c.orig	2011-02-03 13:46:47.000000000 -0800
+++ breakpoint.c	2011-02-03 13:51:46.000000000 -0800
@@ -2217,6 +2217,46 @@ create_internal_breakpoint (struct gdbar
   return b;
 }
 
+static const char *const longjmp_names[] =
+  {
+    "longjmp", "_longjmp", "siglongjmp", "_siglongjmp"
+  };
+#define NUM_LONGJMP_NAMES \
+  (sizeof (longjmp_names) / sizeof (longjmp_names[0]))
+
+/* Per-objfile data private to breakpoint.c  */
+struct breakpoint_objfile_data
+{
+  CORE_ADDR overlay_bp_addr;
+  CORE_ADDR longjmp_bp_addr[NUM_LONGJMP_NAMES];
+  CORE_ADDR terminate_bp_addr;
+  CORE_ADDR exception_bp_addr;
+};
+
+static const struct objfile_data *breakpoint_objfile_key;
+
+/* Return per-objfile data needed by breakpoint.c.
+   Allocate the data if necessary.  */
+
+static struct breakpoint_objfile_data *
+get_breakpoint_objfile_data (struct objfile *objfile)
+{
+  struct breakpoint_objfile_data *bp_objfile_data;
+
+  bp_objfile_data = objfile_data (objfile, breakpoint_objfile_key);
+  if (bp_objfile_data == NULL)
+    {
+      bp_objfile_data = obstack_alloc (&objfile->objfile_obstack,
+				       sizeof (*bp_objfile_data));
+
+      memset (bp_objfile_data, 0, sizeof (*bp_objfile_data));
+      set_objfile_data (objfile, breakpoint_objfile_key, bp_objfile_data);
+    }
+  return bp_objfile_data;
+}
+
+#define INVALID_CORE_ADDR ((CORE_ADDR)-1)
+
 static void
 create_overlay_event_breakpoint (void)
 {
@@ -2226,14 +2266,29 @@ create_overlay_event_breakpoint (void)
   ALL_OBJFILES (objfile)
     {
       struct breakpoint *b;
-      struct minimal_symbol *m;
+      struct breakpoint_objfile_data *bp_objfile_data;
 
-      m = lookup_minimal_symbol_text (func_name, objfile);
-      if (m == NULL)
-        continue;
+      bp_objfile_data = get_breakpoint_objfile_data (objfile);
+
+      if (bp_objfile_data->overlay_bp_addr == INVALID_CORE_ADDR)
+	continue;
+
+      if (bp_objfile_data->overlay_bp_addr == 0)
+	{
+	  struct minimal_symbol *m;
+
+	  m = lookup_minimal_symbol_text (func_name, objfile);
+	  if (m == NULL)
+	    {
+	      /* Avoid future lookups in this objfile.  */
+	      bp_objfile_data->overlay_bp_addr = INVALID_CORE_ADDR;
+	      continue;
+	    }
+	  bp_objfile_data->overlay_bp_addr = SYMBOL_VALUE_ADDRESS (m);
+	}
 
       b = create_internal_breakpoint (get_objfile_arch (objfile),
-				      SYMBOL_VALUE_ADDRESS (m),
+				      bp_objfile_data->overlay_bp_addr,
                                       bp_overlay_event);
       b->addr_string = xstrdup (func_name);
 
@@ -2267,30 +2322,41 @@ create_longjmp_master_breakpoint (void)
 
     ALL_OBJFILES (objfile)
     {
-      const char *const longjmp_names[]
-	= { "longjmp", "_longjmp", "siglongjmp", "_siglongjmp" };
-      const int num_longjmp_names
-	= sizeof (longjmp_names) / sizeof (longjmp_names[0]);
       int i;
       struct gdbarch *gdbarch;
+      struct breakpoint_objfile_data *bp_objfile_data;
 
       gdbarch = get_objfile_arch (objfile);
       if (!gdbarch_get_longjmp_target_p (gdbarch))
 	continue;
 
-      for (i = 0; i < num_longjmp_names; i++)
+      bp_objfile_data = get_breakpoint_objfile_data (objfile);
+
+      for (i = 0; i < NUM_LONGJMP_NAMES; i++)
 	{
 	  struct breakpoint *b;
-	  struct minimal_symbol *m;
 	  const char *func_name;
 
-	  func_name = longjmp_names[i];
-	  m = lookup_minimal_symbol_text (func_name, objfile);
-	  if (m == NULL)
+	  if (bp_objfile_data->longjmp_bp_addr[i] == INVALID_CORE_ADDR)
 	    continue;
 
+	  func_name = longjmp_names[i];
+	  if (bp_objfile_data->longjmp_bp_addr[i] == 0)
+	    {
+	      struct minimal_symbol *m;
+
+	      m = lookup_minimal_symbol_text (func_name, objfile);
+	      if (m == NULL)
+		{
+		  /* Prevent future lookups in this objfile.  */
+		  bp_objfile_data->longjmp_bp_addr[i] = INVALID_CORE_ADDR;
+		  continue;
+		}
+	      bp_objfile_data->longjmp_bp_addr[i] = SYMBOL_VALUE_ADDRESS (m);
+	    }
+
 	  b = create_internal_breakpoint (gdbarch,
-					  SYMBOL_VALUE_ADDRESS (m),
+					  bp_objfile_data->longjmp_bp_addr[i],
 					  bp_longjmp_master);
 	  b->addr_string = xstrdup (func_name);
 	  b->enable_state = bp_disabled;
@@ -2307,31 +2373,50 @@ static void
 create_std_terminate_master_breakpoint (void)
 {
   struct program_space *pspace;
-  struct objfile *objfile;
   struct cleanup *old_chain;
   const char *const func_name = "std::terminate()";
 
   old_chain = save_current_program_space ();
 
   ALL_PSPACES (pspace)
+  {
+    struct objfile *objfile;
+
+    set_current_program_space (pspace);
+
     ALL_OBJFILES (objfile)
     {
       struct breakpoint *b;
-      struct minimal_symbol *m;
+      struct breakpoint_objfile_data *bp_objfile_data;
 
-      set_current_program_space (pspace);
+      bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
-      m = lookup_minimal_symbol (func_name, NULL, objfile);
-      if (m == NULL || (MSYMBOL_TYPE (m) != mst_text
-			&& MSYMBOL_TYPE (m) != mst_file_text))
-        continue;
+      if (bp_objfile_data->terminate_bp_addr == INVALID_CORE_ADDR)
+	continue;
+
+      if (bp_objfile_data->terminate_bp_addr == 0)
+	{
+	  struct minimal_symbol *m;
+
+	  m = lookup_minimal_symbol (func_name, NULL, objfile);
+	  if (m == NULL || (MSYMBOL_TYPE (m) != mst_text
+			    && MSYMBOL_TYPE (m) != mst_file_text))
+	    {
+	      /* Prevent future lookups in this objfile.  */
+	      bp_objfile_data->terminate_bp_addr = INVALID_CORE_ADDR;
+	      continue;
+	    }
+	  bp_objfile_data->terminate_bp_addr = SYMBOL_VALUE_ADDRESS (m);
+	}
 
       b = create_internal_breakpoint (get_objfile_arch (objfile),
-				      SYMBOL_VALUE_ADDRESS (m),
+				      bp_objfile_data->terminate_bp_addr,
                                       bp_std_terminate_master);
       b->addr_string = xstrdup (func_name);
       b->enable_state = bp_disabled;
     }
+  }
+
   update_global_location_list (1);
 
   do_cleanups (old_chain);
@@ -2343,24 +2428,45 @@ void
 create_exception_master_breakpoint (void)
 {
   struct objfile *objfile;
+  const char *const func_name = "_Unwind_DebugHook";
 
   ALL_OBJFILES (objfile)
     {
-      struct minimal_symbol *debug_hook;
+      struct breakpoint *b;
+      struct gdbarch *gdbarch;
+      struct breakpoint_objfile_data *bp_objfile_data;
 
-      debug_hook = lookup_minimal_symbol ("_Unwind_DebugHook", NULL, objfile);
-      if (debug_hook != NULL)
+      bp_objfile_data = get_breakpoint_objfile_data (objfile);
+
+      if (bp_objfile_data->exception_bp_addr == INVALID_CORE_ADDR)
+	continue;
+
+      gdbarch = get_objfile_arch (objfile);
+
+      if (bp_objfile_data->exception_bp_addr == 0)
 	{
-	  struct breakpoint *b;
-	  CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (debug_hook);
-	  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+	  struct minimal_symbol *debug_hook;
+	  CORE_ADDR addr;
 
-	  addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
-						     &current_target);
-	  b = create_internal_breakpoint (gdbarch, addr, bp_exception_master);
-	  b->addr_string = xstrdup ("_Unwind_DebugHook");
-	  b->enable_state = bp_disabled;
+	  debug_hook = lookup_minimal_symbol (func_name, NULL, objfile);
+	  if (debug_hook == NULL)
+	    {
+	      bp_objfile_data->exception_bp_addr = INVALID_CORE_ADDR;
+	      continue;
+	    }
+
+	  addr = SYMBOL_VALUE_ADDRESS (debug_hook);
+
+	  bp_objfile_data->exception_bp_addr
+	    = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
+						  &current_target);
 	}
+
+      b = create_internal_breakpoint (gdbarch,
+				      bp_objfile_data->exception_bp_addr,
+				      bp_exception_master);
+      b->addr_string = xstrdup (func_name);
+      b->enable_state = bp_disabled;
     }
 
   update_global_location_list (1);
@@ -12071,6 +12177,8 @@ _initialize_breakpoint (void)
   observer_attach_inferior_exit (clear_syscall_counts);
   observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
 
+  breakpoint_objfile_key = register_objfile_data ();
+
   breakpoint_chain = 0;
   /* Don't bother to call set_breakpoint_count.  $bpnum isn't useful
      before a breakpoint is set.  */


More information about the Gdb-patches mailing list