Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH v2 0/7] gdb.perf/: Add JIT performance test
@ 2022-05-30 22:11 Ilya Leoshkevich via Gdb-patches
  2022-05-30 22:11 ` [PATCH v2 1/7] gdb.perf/: Fix tcl_string_list_to_python_list {x} Ilya Leoshkevich via Gdb-patches
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Ilya Leoshkevich via Gdb-patches @ 2022-05-30 22:11 UTC (permalink / raw)
  To: Tom Tromey, Andrew Burgess
  Cc: Ulrich Weigand, Andreas Arnez, gdb-patches, Pedro Alves,
	Ilya Leoshkevich

Hi,

This series implements a JIT performance test as discussed in [1].
Patch 1 is a small fix, patches 2-6 are preparations and patch 7 is
the test itself.

ChangeLog:
v1: https://sourceware.org/pipermail/gdb-patches/2022-May/189427.html
v1 -> v2:
* Make sure shared objects contain virtual addresses they are loaded
  at by reusing parts of jit-elf-helpers.exp.  By default, virtual
  addresses in all shared objects are relative to 0 - this creates a
  lots of overlaps and forces sort_cmp () to go through the slow "Sort
  on sequence number of the objfile in the chain" path, which is not a
  useful performance testing scenario.
* Fix DEFAULT_BINARY_LINK_WITH_SHLIBS style (Andrew).
* Rename SHLIB to TOTAL_NR_SHLIBS (Andrew).
* Add SOLIB_COUNT (Andrew).
* Drop "gdb.perf/: Compile the binary with -DSHLIB", it's superseded by
  "Allow adjusting GenPerfTest compile options".

The test can be used as follows:

$ make build-perf -j"$(nproc)" RUNTESTFLAGS=jit.exp
$ make check-perf RUNTESTFLAGS=jit-check.exp GDB_PERFTEST_MODE=run

The results can be converted to gnuplot-friendly format as follows:

$ perl -ne 'if (/:register_times:(\d+) (.+)/) { print "$1 $2\n"; }' \
      <gdb.perf/outputs/jit/pieces/perftest.sum >jit.txt

I've uploaded the results to [2].  They are similar to the ones from
Andrew and show that [1] is an improvement.  The third result shown on
the chart is from [3] - with it I can pass the 10k JITed objects mark
and debug CoreCLR JIT with GDB.  It's still WIP though - the testsuite
shows a couple of failures.

Best regards,
Ilya

[1] https://sourceware.org/pipermail/gdb-patches/2022-May/189341.html
[2] https://github.com/iii-i/binutils-gdb/blob/section-map-20220530-2/gdb/testsuite/jit.png
[3] https://github.com/iii-i/binutils-gdb/commits/section-map-20220530-2

Ilya Leoshkevich (7):
  gdb.perf/: Fix tcl_string_list_to_python_list {x}
  gdb.perf/: Add binary_link_with_shlibs setting to GenPerfTest
  gdb.perf/: Allow adjusting GenPerfTest compile options
  gdb.base/: Introduce jit-protocol-util.h
  gdb.base/: Introduce jit_compile_options
  gdb.base/: Introduce n_jit_so_address
  gdb.perf/: Add JIT performance test

 gdb/testsuite/gdb.base/jit-elf-fork-main.c | 48 ++----------
 gdb/testsuite/gdb.base/jit-elf-main.c      | 48 ++----------
 gdb/testsuite/gdb.base/jit-elf-util.h      | 17 +++++
 gdb/testsuite/gdb.base/jit-protocol-util.h | 74 ++++++++++++++++++
 gdb/testsuite/gdb.base/jit-reader-host.c   |  8 +-
 gdb/testsuite/gdb.perf/jit-check.exp       | 25 +++++++
 gdb/testsuite/gdb.perf/jit-check.py        | 60 +++++++++++++++
 gdb/testsuite/gdb.perf/jit-solib.c         | 27 +++++++
 gdb/testsuite/gdb.perf/jit.c               | 87 ++++++++++++++++++++++
 gdb/testsuite/gdb.perf/jit.exp             | 79 ++++++++++++++++++++
 gdb/testsuite/lib/gen-perf-test.exp        | 54 +++++++++++---
 gdb/testsuite/lib/jit-elf-helpers.exp      | 22 ++++--
 gdb/testsuite/lib/perftest.exp             |  2 +-
 13 files changed, 439 insertions(+), 112 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/jit-protocol-util.h
 create mode 100644 gdb/testsuite/gdb.perf/jit-check.exp
 create mode 100644 gdb/testsuite/gdb.perf/jit-check.py
 create mode 100644 gdb/testsuite/gdb.perf/jit-solib.c
 create mode 100644 gdb/testsuite/gdb.perf/jit.c
 create mode 100644 gdb/testsuite/gdb.perf/jit.exp

-- 
2.35.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 1/7] gdb.perf/: Fix tcl_string_list_to_python_list {x}
  2022-05-30 22:11 [PATCH v2 0/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
@ 2022-05-30 22:11 ` Ilya Leoshkevich via Gdb-patches
  2022-05-30 22:11 ` [PATCH v2 2/7] gdb.perf/: Add binary_link_with_shlibs setting to GenPerfTest Ilya Leoshkevich via Gdb-patches
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ilya Leoshkevich via Gdb-patches @ 2022-05-30 22:11 UTC (permalink / raw)
  To: Tom Tromey, Andrew Burgess
  Cc: Ulrich Weigand, Andreas Arnez, gdb-patches, Pedro Alves,
	Ilya Leoshkevich

tcl_string_list_to_python_list {x} returns "(x)", which is not a tuple
(the valid tuple syntax would be "(x,)").  Instead of special-casing
this, just change the function to return what its name says: lists.
This way in the problematic case we will get "[x]".
---
 gdb/testsuite/lib/perftest.exp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gdb/testsuite/lib/perftest.exp b/gdb/testsuite/lib/perftest.exp
index bf4eb45bba5..0df4ff15864 100644
--- a/gdb/testsuite/lib/perftest.exp
+++ b/gdb/testsuite/lib/perftest.exp
@@ -159,7 +159,7 @@ proc tcl_string_list_to_python_list { l } {
     foreach elm $l {
 	lappend quoted_list [quote $elm]
     }
-    return "([join $quoted_list {, }])"
+    return "\[[join $quoted_list {, }]\]"
 }
 
 # Helper routine for PerfTest::assemble "run" step implementations.
-- 
2.35.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 2/7] gdb.perf/: Add binary_link_with_shlibs setting to GenPerfTest
  2022-05-30 22:11 [PATCH v2 0/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
  2022-05-30 22:11 ` [PATCH v2 1/7] gdb.perf/: Fix tcl_string_list_to_python_list {x} Ilya Leoshkevich via Gdb-patches
@ 2022-05-30 22:11 ` Ilya Leoshkevich via Gdb-patches
  2022-05-30 22:11 ` [PATCH v2 3/7] gdb.perf/: Allow adjusting GenPerfTest compile options Ilya Leoshkevich via Gdb-patches
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ilya Leoshkevich via Gdb-patches @ 2022-05-30 22:11 UTC (permalink / raw)
  To: Tom Tromey, Andrew Burgess
  Cc: Ulrich Weigand, Andreas Arnez, gdb-patches, Pedro Alves,
	Ilya Leoshkevich

Performance tests that dynamically load generated shared libraries do
not need to link with them.  Provide an option to avoid this.
---
 gdb/testsuite/lib/gen-perf-test.exp | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/gdb/testsuite/lib/gen-perf-test.exp b/gdb/testsuite/lib/gen-perf-test.exp
index 0a5607c2c9a..07007db0834 100644
--- a/gdb/testsuite/lib/gen-perf-test.exp
+++ b/gdb/testsuite/lib/gen-perf-test.exp
@@ -100,6 +100,9 @@ namespace eval GenPerfTest {
     # The number of compunits in each objfile.
     set DEFAULT_NR_COMPUNITS 1
 
+    # Should the binary be linked with the generated shared libraries?
+    set DEFAULT_BINARY_LINK_WITH_SHLIBS true
+
     # The number of public globals in each compunit.
     set DEFAULT_NR_EXTERN_GLOBALS 1
 
@@ -254,6 +257,7 @@ namespace eval GenPerfTest {
 	set testcase(tail_shlib_headers) $GenPerfTest::DEFAULT_TAIL_SHLIB_HEADERS
 	set testcase(nr_gen_shlibs) $GenPerfTest::DEFAULT_NR_GEN_SHLIBS
 	set testcase(nr_compunits) $GenPerfTest::DEFAULT_NR_COMPUNITS
+	set testcase(binary_link_with_shlibs) $GenPerfTest::DEFAULT_BINARY_LINK_WITH_SHLIBS
 
 	set testcase(nr_extern_globals) $GenPerfTest::DEFAULT_NR_EXTERN_GLOBALS
 	set testcase(nr_static_globals) $GenPerfTest::DEFAULT_NR_STATIC_GLOBALS
@@ -281,7 +285,7 @@ namespace eval GenPerfTest {
 	    binary_extra_sources binary_extra_headers
 	    gen_shlib_extra_sources gen_shlib_extra_headers
 	    tail_shlib_sources tail_shlib_headers
-	    nr_gen_shlibs nr_compunits
+	    nr_gen_shlibs nr_compunits binary_link_with_shlibs
 	    nr_extern_globals nr_static_globals
 	    nr_extern_functions nr_static_functions
 	    class_specs
@@ -1298,14 +1302,16 @@ namespace eval GenPerfTest {
 
     proc _make_shlib_options { self_var static run_nr } {
 	upvar 1 $self_var self
-	set nr_gen_shlibs [_get_param $self(nr_gen_shlibs) $run_nr]
 	set result ""
-	for { set i 0 } { $i < $nr_gen_shlibs } { incr i } {
-	    lappend result "shlib=[_make_shlib_name self $static $run_nr $i]"
-	}
-	set tail_shlib_name [_make_tail_shlib_name self $static $run_nr]
-	if { "$tail_shlib_name" != "" } {
-	    lappend result "shlib=$tail_shlib_name"
+	if { [_get_param $self(binary_link_with_shlibs) $run_nr] } {
+	    set nr_gen_shlibs [_get_param $self(nr_gen_shlibs) $run_nr]
+	    for { set i 0 } { $i < $nr_gen_shlibs } { incr i } {
+		lappend result "shlib=[_make_shlib_name self $static $run_nr $i]"
+	    }
+	    set tail_shlib_name [_make_tail_shlib_name self $static $run_nr]
+	    if { "$tail_shlib_name" != "" } {
+		lappend result "shlib=$tail_shlib_name"
+	    }
 	}
 	return $result
     }
-- 
2.35.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 3/7] gdb.perf/: Allow adjusting GenPerfTest compile options
  2022-05-30 22:11 [PATCH v2 0/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
  2022-05-30 22:11 ` [PATCH v2 1/7] gdb.perf/: Fix tcl_string_list_to_python_list {x} Ilya Leoshkevich via Gdb-patches
  2022-05-30 22:11 ` [PATCH v2 2/7] gdb.perf/: Add binary_link_with_shlibs setting to GenPerfTest Ilya Leoshkevich via Gdb-patches
@ 2022-05-30 22:11 ` Ilya Leoshkevich via Gdb-patches
  2022-05-30 22:11 ` [PATCH v2 4/7] gdb.base/: Introduce jit-protocol-util.h Ilya Leoshkevich via Gdb-patches
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ilya Leoshkevich via Gdb-patches @ 2022-05-30 22:11 UTC (permalink / raw)
  To: Tom Tromey, Andrew Burgess
  Cc: Ulrich Weigand, Andreas Arnez, gdb-patches, Pedro Alves,
	Ilya Leoshkevich

Introduce new callbacks to adjust the compile options based on
certain criteria: the total number of shared objects for the binary and
the shared object index for shared objects (no criteria are defined for
the tail shared object at the moment).  This is useful for setting
shared objects' load addresses in performance tests.
---
 gdb/testsuite/lib/gen-perf-test.exp | 32 ++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/gdb/testsuite/lib/gen-perf-test.exp b/gdb/testsuite/lib/gen-perf-test.exp
index 07007db0834..eab6b5499d4 100644
--- a/gdb/testsuite/lib/gen-perf-test.exp
+++ b/gdb/testsuite/lib/gen-perf-test.exp
@@ -76,6 +76,9 @@ namespace eval GenPerfTest {
     # Header files used by generated files and extra sources.
     set DEFAULT_BINARY_EXTRA_HEADERS {}
 
+    # The name of the function that adjusts binary's compile options.
+    set DEFAULT_BINARY_ADJUST_COMPILE_OPTIONS GenPerfTest::default_adjust_compile_options
+
     # Extra source files for each generated shlib.
     # The compiler passes -DSHLIB=NNN which the source can use, for example,
     # to define unique symbols for each shlib.
@@ -84,6 +87,10 @@ namespace eval GenPerfTest {
     # Header files used by generated files and extra sources.
     set DEFAULT_GEN_SHLIB_EXTRA_HEADERS {}
 
+    # The name of the function that adjusts each generated shlib's compile
+    # options.
+    set DEFAULT_GEN_SHLIB_ADJUST_COMPILE_OPTIONS GenPerfTest::default_adjust_compile_options
+
     # Source files for a tail shlib, or empty if none.
     # This library is loaded after all other shlibs (except any system shlibs
     # like libstdc++).  It is useful for exercising issues that can appear
@@ -94,6 +101,9 @@ namespace eval GenPerfTest {
     # Header files for the tail shlib.
     set DEFAULT_TAIL_SHLIB_HEADERS {}
 
+    # The name of the function that adjusts tail shlib's compile options.
+    set DEFAULT_TAIL_SHLIB_ADJUST_COMPILE_OPTIONS GenPerfTest::default_adjust_compile_options
+
     # The number of shared libraries to create.
     set DEFAULT_NR_GEN_SHLIBS 0
 
@@ -184,6 +194,12 @@ namespace eval GenPerfTest {
     set source_suffixes(c) "c"
     set source_suffixes(c++) "cc"
 
+    # Do not adjust any compile options by default.
+
+    proc default_adjust_compile_options { options args } {
+	return $options
+    }
+
     # Generate .worker files that control building all the "pieces" of the
     # testcase.  This doesn't include "main" or any test-specific stuff.
     # This mostly consists of the "bulk" (aka "crap" :-)) of the testcase to
@@ -251,10 +267,13 @@ namespace eval GenPerfTest {
 	set testcase(run_names) [list $name]
 	set testcase(binary_extra_sources) $GenPerfTest::DEFAULT_BINARY_EXTRA_SOURCES
 	set testcase(binary_extra_headers) $GenPerfTest::DEFAULT_BINARY_EXTRA_HEADERS
+	set testcase(binary_adjust_compile_options) $GenPerfTest::DEFAULT_BINARY_ADJUST_COMPILE_OPTIONS
 	set testcase(gen_shlib_extra_sources) $GenPerfTest::DEFAULT_GEN_SHLIB_EXTRA_SOURCES
 	set testcase(gen_shlib_extra_headers) $GenPerfTest::DEFAULT_GEN_SHLIB_EXTRA_HEADERS
+	set testcase(gen_shlib_adjust_compile_options) $GenPerfTest::DEFAULT_GEN_SHLIB_ADJUST_COMPILE_OPTIONS
 	set testcase(tail_shlib_sources) $GenPerfTest::DEFAULT_TAIL_SHLIB_SOURCES
 	set testcase(tail_shlib_headers) $GenPerfTest::DEFAULT_TAIL_SHLIB_HEADERS
+	set testcase(tail_shlib_adjust_compile_options) $GenPerfTest::DEFAULT_TAIL_SHLIB_ADJUST_COMPILE_OPTIONS
 	set testcase(nr_gen_shlibs) $GenPerfTest::DEFAULT_NR_GEN_SHLIBS
 	set testcase(nr_compunits) $GenPerfTest::DEFAULT_NR_COMPUNITS
 	set testcase(binary_link_with_shlibs) $GenPerfTest::DEFAULT_BINARY_LINK_WITH_SHLIBS
@@ -282,9 +301,9 @@ namespace eval GenPerfTest {
     proc _verify_parameter_lengths { self_var } {
 	upvar 1 $self_var self
 	set params {
-	    binary_extra_sources binary_extra_headers
-	    gen_shlib_extra_sources gen_shlib_extra_headers
-	    tail_shlib_sources tail_shlib_headers
+	    binary_extra_sources binary_extra_headers binary_adjust_compile_options
+	    gen_shlib_extra_sources gen_shlib_extra_headers gen_shlib_adjust_compile_options
+	    tail_shlib_sources tail_shlib_headers tail_shlib_adjust_compile_options
 	    nr_gen_shlibs nr_compunits binary_link_with_shlibs
 	    nr_extern_globals nr_static_globals
 	    nr_extern_functions nr_static_functions
@@ -1174,6 +1193,8 @@ namespace eval GenPerfTest {
 	set extra_headers [_get_param $self(gen_shlib_extra_headers) $run_nr]
 	set shlib_file [_make_shlib_name self $static $run_nr $so_nr]
 	set compile_options "[_compile_options self] additional_flags=-DSHLIB=$so_nr"
+	set adjust_compile_options [_get_param $self(gen_shlib_adjust_compile_options) $run_nr]
+	set compile_options [$adjust_compile_options $compile_options [expr $so_nr + 1]]
 	set all_header_files $header_files
 	append all_header_files $extra_headers
 	set compile_result [_perftest_compile self $source_files $all_header_files $shlib_file shlib $compile_options]
@@ -1218,6 +1239,8 @@ namespace eval GenPerfTest {
 	set header_files [_get_param $self(tail_shlib_headers) $run_nr]
 	set shlib_file [_make_tail_shlib_name self $static $run_nr]
 	set compile_options [_compile_options self]
+	set adjust_compile_options [_get_param $self(tail_shlib_adjust_compile_options) $run_nr]
+	set compile_options [$adjust_compile_options $compile_options]
 	set compile_result [_perftest_compile self $source_files $header_files $shlib_file shlib $compile_options]
 	if { $compile_result != "" } {
 	    verbose -log "_compile_tail_shlib failed: $compile_result"
@@ -1322,6 +1345,9 @@ namespace eval GenPerfTest {
 	set extra_headers [_get_param $self(binary_extra_headers) $run_nr]
 	set binary_file [_make_binary_name self $run_nr]
 	set compile_options [_compile_options self]
+	set adjust_compile_options [_get_param $self(binary_adjust_compile_options) $run_nr]
+	set nr_gen_shlibs [_get_param $self(nr_gen_shlibs) $run_nr]
+	set compile_options [$adjust_compile_options $compile_options $nr_gen_shlibs]
 	set shlib_options [_make_shlib_options self $static $run_nr]
 	if { [llength $shlib_options] > 0 } {
 	    append compile_options " " $shlib_options
-- 
2.35.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 4/7] gdb.base/: Introduce jit-protocol-util.h
  2022-05-30 22:11 [PATCH v2 0/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
                   ` (2 preceding siblings ...)
  2022-05-30 22:11 ` [PATCH v2 3/7] gdb.perf/: Allow adjusting GenPerfTest compile options Ilya Leoshkevich via Gdb-patches
@ 2022-05-30 22:11 ` Ilya Leoshkevich via Gdb-patches
  2022-05-30 22:11 ` [PATCH v2 5/7] gdb.base/: Introduce jit_compile_options Ilya Leoshkevich via Gdb-patches
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ilya Leoshkevich via Gdb-patches @ 2022-05-30 22:11 UTC (permalink / raw)
  To: Tom Tromey, Andrew Burgess
  Cc: Ulrich Weigand, Andreas Arnez, gdb-patches, Pedro Alves,
	Ilya Leoshkevich

jit-elf-fork-main, jit-elf-main and jit-reader-host use the same
boilerplate to register and unregister JITed code.  Move it to a new
header that can be shared with performance tests.
---
 gdb/testsuite/gdb.base/jit-elf-fork-main.c | 37 ++---------
 gdb/testsuite/gdb.base/jit-elf-main.c      | 37 ++---------
 gdb/testsuite/gdb.base/jit-protocol-util.h | 74 ++++++++++++++++++++++
 gdb/testsuite/gdb.base/jit-reader-host.c   |  8 +--
 4 files changed, 84 insertions(+), 72 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/jit-protocol-util.h

diff --git a/gdb/testsuite/gdb.base/jit-elf-fork-main.c b/gdb/testsuite/gdb.base/jit-elf-fork-main.c
index 45792622548..96fadaa57b7 100644
--- a/gdb/testsuite/gdb.base/jit-elf-fork-main.c
+++ b/gdb/testsuite/gdb.base/jit-elf-fork-main.c
@@ -29,8 +29,8 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
-#include "jit-protocol.h"
 #include "jit-elf-util.h"
+#include "jit-protocol-util.h"
 
 static void
 usage (void)
@@ -77,17 +77,7 @@ main (int argc, char *argv[])
       struct jit_code_entry *const entry = calloc (1, sizeof (*entry));
       entry->symfile_addr = (const char *)addr;
       entry->symfile_size = obj_size;
-      entry->prev_entry = __jit_debug_descriptor.relevant_entry;
-      __jit_debug_descriptor.relevant_entry = entry;
-
-      if (entry->prev_entry != NULL)
-	entry->prev_entry->next_entry = entry;
-      else
-	__jit_debug_descriptor.first_entry = entry;
-
-      /* Notify GDB.  */
-      __jit_debug_descriptor.action_flag = JIT_REGISTER;
-      __jit_debug_register_code ();
+      jit_push_back (entry);
 
       if (jit_function () != 42)
 	{
@@ -103,27 +93,8 @@ main (int argc, char *argv[])
   i = 0;  /* break after fork */
 
   /* Now unregister them all in reverse order.  */
-  while (__jit_debug_descriptor.relevant_entry != NULL)
-    {
-      struct jit_code_entry *const entry =
-	__jit_debug_descriptor.relevant_entry;
-      struct jit_code_entry *const prev_entry = entry->prev_entry;
-
-      if (prev_entry != NULL)
-	{
-	  prev_entry->next_entry = NULL;
-	  entry->prev_entry = NULL;
-	}
-      else
-	__jit_debug_descriptor.first_entry = NULL;
-
-      /* Notify GDB.  */
-      __jit_debug_descriptor.action_flag = JIT_UNREGISTER;
-      __jit_debug_register_code ();
-
-      __jit_debug_descriptor.relevant_entry = prev_entry;
-      free (entry);
-    }
+  while (!jit_empty ())
+    free (jit_pop_back ());
 
   return 0;  /* break before return  */
 }
diff --git a/gdb/testsuite/gdb.base/jit-elf-main.c b/gdb/testsuite/gdb.base/jit-elf-main.c
index 948530f3197..8f482748ee5 100644
--- a/gdb/testsuite/gdb.base/jit-elf-main.c
+++ b/gdb/testsuite/gdb.base/jit-elf-main.c
@@ -29,8 +29,8 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
-#include "jit-protocol.h"
 #include "jit-elf-util.h"
+#include "jit-protocol-util.h"
 
 static void
 usage (void)
@@ -96,17 +96,7 @@ MAIN (int argc, char *argv[])
       struct jit_code_entry *const entry = calloc (1, sizeof (*entry));
       entry->symfile_addr = (const char *)addr;
       entry->symfile_size = obj_size;
-      entry->prev_entry = __jit_debug_descriptor.relevant_entry;
-      __jit_debug_descriptor.relevant_entry = entry;
-
-      if (entry->prev_entry != NULL)
-	entry->prev_entry->next_entry = entry;
-      else
-	__jit_debug_descriptor.first_entry = entry;
-
-      /* Notify GDB.  */
-      __jit_debug_descriptor.action_flag = JIT_REGISTER;
-      __jit_debug_register_code ();
+      jit_push_back (entry);
 
       if (jit_function () != 42)
 	{
@@ -118,27 +108,8 @@ MAIN (int argc, char *argv[])
   WAIT_FOR_GDB; i = 0;  /* gdb break here 1 */
 
   /* Now unregister them all in reverse order.  */
-  while (__jit_debug_descriptor.relevant_entry != NULL)
-    {
-      struct jit_code_entry *const entry =
-	__jit_debug_descriptor.relevant_entry;
-      struct jit_code_entry *const prev_entry = entry->prev_entry;
-
-      if (prev_entry != NULL)
-	{
-	  prev_entry->next_entry = NULL;
-	  entry->prev_entry = NULL;
-	}
-      else
-	__jit_debug_descriptor.first_entry = NULL;
-
-      /* Notify GDB.  */
-      __jit_debug_descriptor.action_flag = JIT_UNREGISTER;
-      __jit_debug_register_code ();
-
-      __jit_debug_descriptor.relevant_entry = prev_entry;
-      free (entry);
-    }
+  while (!jit_empty ())
+    free (jit_pop_back ());
 
   WAIT_FOR_GDB; return 0;  /* gdb break here 2  */
 }
diff --git a/gdb/testsuite/gdb.base/jit-protocol-util.h b/gdb/testsuite/gdb.base/jit-protocol-util.h
new file mode 100644
index 00000000000..d0a59518429
--- /dev/null
+++ b/gdb/testsuite/gdb.base/jit-protocol-util.h
@@ -0,0 +1,74 @@
+/* This test program is part of GDB, the GNU debugger.
+
+   Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Frequently used functions for testing JITed objects.  */
+
+#ifndef JIT_PROTOCOL_UTIL_H
+#define JIT_PROTOCOL_UTIL_H
+
+#include "jit-protocol.h"
+#include <stddef.h>
+
+/* Return whether there are no registered JITed objects.  */
+static int
+jit_empty (void)
+{
+  return __jit_debug_descriptor.relevant_entry == NULL;
+}
+
+/* Register JITed object.  symfile_addr and symfile_size must be set.  */
+static void
+jit_push_back (struct jit_code_entry *entry)
+{
+  entry->prev_entry = __jit_debug_descriptor.relevant_entry;
+  __jit_debug_descriptor.relevant_entry = entry;
+
+  if (entry->prev_entry != NULL)
+    entry->prev_entry->next_entry = entry;
+  else
+    __jit_debug_descriptor.first_entry = entry;
+
+  /* Notify GDB.  */
+  __jit_debug_descriptor.action_flag = JIT_REGISTER;
+  __jit_debug_register_code ();
+}
+
+/* Unregister the last registered JITed object.  */
+static struct jit_code_entry *
+jit_pop_back (void)
+{
+  struct jit_code_entry *const entry = __jit_debug_descriptor.relevant_entry;
+  struct jit_code_entry *const prev_entry = entry->prev_entry;
+
+  if (prev_entry != NULL)
+    {
+      prev_entry->next_entry = NULL;
+      entry->prev_entry = NULL;
+    }
+  else
+    __jit_debug_descriptor.first_entry = NULL;
+
+  /* Notify GDB.  */
+  __jit_debug_descriptor.action_flag = JIT_UNREGISTER;
+  __jit_debug_register_code ();
+
+  __jit_debug_descriptor.relevant_entry = prev_entry;
+
+  return entry;
+}
+
+#endif /* JIT_PROTOCOL_UTIL_H */
diff --git a/gdb/testsuite/gdb.base/jit-reader-host.c b/gdb/testsuite/gdb.base/jit-reader-host.c
index 0cca894a3a5..65f77b981d6 100644
--- a/gdb/testsuite/gdb.base/jit-reader-host.c
+++ b/gdb/testsuite/gdb.base/jit-reader-host.c
@@ -24,8 +24,8 @@
 #include <sys/mman.h>
 
 #include JIT_READER_H  /* Please see jit-reader.exp for an explanation.  */
+#include "jit-protocol-util.h"
 #include "jit-reader-host.h"
-#include "jit-protocol.h"
 
 struct jit_code_entry only_entry;
 
@@ -85,11 +85,7 @@ main (int argc, char **argv)
   only_entry.symfile_addr = symfile;
   only_entry.symfile_size = sizeof (struct jithost_abi);
 
-  __jit_debug_descriptor.first_entry = &only_entry;
-  __jit_debug_descriptor.relevant_entry = &only_entry;
-  __jit_debug_descriptor.action_flag = JIT_REGISTER;
-  __jit_debug_descriptor.version = 1;
-  __jit_debug_register_code ();
+  jit_push_back (&only_entry);
 
   function_stack_mangle ();
   function_add (5, 6);
-- 
2.35.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 5/7] gdb.base/: Introduce jit_compile_options
  2022-05-30 22:11 [PATCH v2 0/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
                   ` (3 preceding siblings ...)
  2022-05-30 22:11 ` [PATCH v2 4/7] gdb.base/: Introduce jit-protocol-util.h Ilya Leoshkevich via Gdb-patches
@ 2022-05-30 22:11 ` Ilya Leoshkevich via Gdb-patches
  2022-05-30 22:11 ` [PATCH v2 6/7] gdb.base/: Introduce n_jit_so_address Ilya Leoshkevich via Gdb-patches
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ilya Leoshkevich via Gdb-patches @ 2022-05-30 22:11 UTC (permalink / raw)
  To: Tom Tromey, Andrew Burgess
  Cc: Ulrich Weigand, Andreas Arnez, gdb-patches, Pedro Alves,
	Ilya Leoshkevich

Move setting LOAD_ADDRESS and LOAD_INCREMENT to a separate global
variable.  This eliminates repetition and is useful for sharing with
performance tests.  Also make them unsigned long long in order to
prevent overflows when using a lot of shared libraries.
---
 gdb/testsuite/lib/jit-elf-helpers.exp | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/gdb/testsuite/lib/jit-elf-helpers.exp b/gdb/testsuite/lib/jit-elf-helpers.exp
index b699917f209..7c17178f800 100644
--- a/gdb/testsuite/lib/jit-elf-helpers.exp
+++ b/gdb/testsuite/lib/jit-elf-helpers.exp
@@ -19,6 +19,9 @@
 
 set jit_load_address   0x7000000
 set jit_load_increment 0x1000000
+set jit_compile_options [list \
+    additional_flags=-DLOAD_ADDRESS=${jit_load_address}ull \
+    additional_flags=-DLOAD_INCREMENT=${jit_load_increment}ull]
 
 # Compile jit-elf-main.c as an executable.
 #
@@ -28,12 +31,11 @@ set jit_load_increment 0x1000000
 # On success, return 0.
 # On failure, return -1.
 proc compile_jit_main {main_srcfile main_binfile options} {
-    global jit_load_address jit_load_increment
+    global jit_compile_options
 
     set options [concat \
 	$options \
-	additional_flags=-DLOAD_ADDRESS=$jit_load_address \
-	additional_flags=-DLOAD_INCREMENT=$jit_load_increment \
+	$jit_compile_options \
 	debug]
 
     if { [gdb_compile ${main_srcfile} ${main_binfile} \
@@ -53,12 +55,11 @@ proc compile_jit_main {main_srcfile main_binfile options} {
 # On success, return 0.
 # On failure, return -1.
 proc compile_jit_elf_main_as_so {main_solib_srcfile main_solib_binfile options} {
-    global jit_load_address jit_load_increment
+    global jit_compile_options
 
     set options [concat \
 	$options \
-	additional_flags=-DLOAD_ADDRESS=$jit_load_address \
-	additional_flags=-DLOAD_INCREMENT=$jit_load_increment \
+	$jit_compile_options \
 	debug]
 
     if { [gdb_compile_shlib ${main_solib_srcfile} ${main_solib_binfile} \
-- 
2.35.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 6/7] gdb.base/: Introduce n_jit_so_address
  2022-05-30 22:11 [PATCH v2 0/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
                   ` (4 preceding siblings ...)
  2022-05-30 22:11 ` [PATCH v2 5/7] gdb.base/: Introduce jit_compile_options Ilya Leoshkevich via Gdb-patches
@ 2022-05-30 22:11 ` Ilya Leoshkevich via Gdb-patches
  2022-05-30 22:11 ` [PATCH v2 7/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ilya Leoshkevich via Gdb-patches @ 2022-05-30 22:11 UTC (permalink / raw)
  To: Tom Tromey, Andrew Burgess
  Cc: Ulrich Weigand, Andreas Arnez, gdb-patches, Pedro Alves,
	Ilya Leoshkevich

Move computing shared library load addresses into a separate function
(both in TCL and C).  This eliminates repetition and is useful for
sharing with performance tests.
---
 gdb/testsuite/gdb.base/jit-elf-fork-main.c | 11 +----------
 gdb/testsuite/gdb.base/jit-elf-main.c      | 11 +----------
 gdb/testsuite/gdb.base/jit-elf-util.h      | 17 +++++++++++++++++
 gdb/testsuite/lib/jit-elf-helpers.exp      |  9 +++++++--
 4 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/gdb/testsuite/gdb.base/jit-elf-fork-main.c b/gdb/testsuite/gdb.base/jit-elf-fork-main.c
index 96fadaa57b7..6e1b3db3d5a 100644
--- a/gdb/testsuite/gdb.base/jit-elf-fork-main.c
+++ b/gdb/testsuite/gdb.base/jit-elf-fork-main.c
@@ -39,15 +39,6 @@ usage (void)
   exit (1);
 }
 
-/* Must be defined by .exp file when compiling to know
-   what address to map the ELF binary to.  */
-#ifndef LOAD_ADDRESS
-#error "Must define LOAD_ADDRESS"
-#endif
-#ifndef LOAD_INCREMENT
-#error "Must define LOAD_INCREMENT"
-#endif
-
 int
 main (int argc, char *argv[])
 {
@@ -65,7 +56,7 @@ main (int argc, char *argv[])
   for (i = 1; i < argc; ++i)
     {
       size_t obj_size;
-      void *load_addr = (void *) (size_t) (LOAD_ADDRESS + (i - 1) * LOAD_INCREMENT);
+      void *load_addr = n_jit_so_address (i);
       printf ("Loading %s as JIT at %p\n", argv[i], load_addr);
       void *addr = load_elf (argv[i], &obj_size, load_addr);
 
diff --git a/gdb/testsuite/gdb.base/jit-elf-main.c b/gdb/testsuite/gdb.base/jit-elf-main.c
index 8f482748ee5..604fb07aa8a 100644
--- a/gdb/testsuite/gdb.base/jit-elf-main.c
+++ b/gdb/testsuite/gdb.base/jit-elf-main.c
@@ -48,15 +48,6 @@ usage (void)
 #define MAIN main
 #endif
 
-/* Must be defined by .exp file when compiling to know
-   what address to map the ELF binary to.  */
-#ifndef LOAD_ADDRESS
-#error "Must define LOAD_ADDRESS"
-#endif
-#ifndef LOAD_INCREMENT
-#error "Must define LOAD_INCREMENT"
-#endif
-
 /* Used to spin waiting for GDB.  */
 volatile int wait_for_gdb = ATTACH;
 #define WAIT_FOR_GDB do {} while (wait_for_gdb)
@@ -84,7 +75,7 @@ MAIN (int argc, char *argv[])
   for (i = 1; i < argc; ++i)
     {
       size_t obj_size;
-      void *load_addr = (void *) (size_t) (LOAD_ADDRESS + (i - 1) * LOAD_INCREMENT);
+      void *load_addr = n_jit_so_address (i);
       printf ("Loading %s as JIT at %p\n", argv[i], load_addr);
       void *addr = load_elf (argv[i], &obj_size, load_addr);
 
diff --git a/gdb/testsuite/gdb.base/jit-elf-util.h b/gdb/testsuite/gdb.base/jit-elf-util.h
index 419a781f865..faa1a21204a 100644
--- a/gdb/testsuite/gdb.base/jit-elf-util.h
+++ b/gdb/testsuite/gdb.base/jit-elf-util.h
@@ -117,3 +117,20 @@ load_elf (const char *libname, size_t *size, void *load_addr)
 
   return addr;
 }
+
+/* Must be defined by .exp file when compiling to know
+   what address to map the ELF binary to.  */
+#ifndef LOAD_ADDRESS
+#error "Must define LOAD_ADDRESS"
+#endif
+#ifndef LOAD_INCREMENT
+#error "Must define LOAD_INCREMENT"
+#endif
+
+/* Return the address of the SO_NRth shared library.  The first shared
+   library's SO_NR is 1.  */
+static void *
+n_jit_so_address (int so_nr)
+{
+  return (void *) (size_t) (LOAD_ADDRESS + (so_nr - 1) * LOAD_INCREMENT);
+}
diff --git a/gdb/testsuite/lib/jit-elf-helpers.exp b/gdb/testsuite/lib/jit-elf-helpers.exp
index 7c17178f800..57513de0927 100644
--- a/gdb/testsuite/lib/jit-elf-helpers.exp
+++ b/gdb/testsuite/lib/jit-elf-helpers.exp
@@ -72,13 +72,18 @@ proc compile_jit_elf_main_as_so {main_solib_srcfile main_solib_binfile options}
     return 0
 }
 
+# Return the address of the SO_NRth shared library.
+proc n_jit_so_address {so_nr} {
+    global jit_load_address jit_load_increment
+    return [expr $jit_load_address + $jit_load_increment * [expr $so_nr - 1]]
+}
+
 # Compile jit-elf-solib.c as a shared library in multiple copies and
 # upload them to the target.
 #
 # On success, return a list of target path to the shared libraries.
 # On failure, return -1.
 proc compile_and_download_n_jit_so {jit_solib_basename jit_solib_srcfile count} {
-    global jit_load_address jit_load_increment
     set binfiles_target {}
 
     for {set i 1} {$i <= $count} {incr i} {
@@ -88,7 +93,7 @@ proc compile_and_download_n_jit_so {jit_solib_basename jit_solib_srcfile count}
 	# do symbol renaming by munging on ELF symbol table, and that
 	# wouldn't work for .debug sections.  Also, output for "info
 	# function" changes when debug info is present.
-	set addr [format 0x%x [expr $jit_load_address + $jit_load_increment * [expr $i-1]]]
+	set addr [format 0x%x [n_jit_so_address $i]]
 
 	# Use "text_segment=..." to ask the linker to relocate everything in the
 	# compiled shared library against a fixed base address.  Combined
-- 
2.35.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 7/7] gdb.perf/: Add JIT performance test
  2022-05-30 22:11 [PATCH v2 0/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
                   ` (5 preceding siblings ...)
  2022-05-30 22:11 ` [PATCH v2 6/7] gdb.base/: Introduce n_jit_so_address Ilya Leoshkevich via Gdb-patches
@ 2022-05-30 22:11 ` Ilya Leoshkevich via Gdb-patches
  2022-06-22  8:48 ` [PING] [PATCH v2 0/7] " Ilya Leoshkevich via Gdb-patches
  2022-08-03 10:52 ` [PING^2] " Ilya Leoshkevich via Gdb-patches
  8 siblings, 0 replies; 10+ messages in thread
From: Ilya Leoshkevich via Gdb-patches @ 2022-05-30 22:11 UTC (permalink / raw)
  To: Tom Tromey, Andrew Burgess
  Cc: Ulrich Weigand, Andreas Arnez, gdb-patches, Pedro Alves,
	Ilya Leoshkevich

The test registers and unregisters 500 functions.  The time it takes to
process each function (the more functions there are, the slower it is)
is written into a global array, which is then read and reported by the
GDB script.
---
 gdb/testsuite/gdb.perf/jit-check.exp | 25 ++++++++
 gdb/testsuite/gdb.perf/jit-check.py  | 60 +++++++++++++++++++
 gdb/testsuite/gdb.perf/jit-solib.c   | 27 +++++++++
 gdb/testsuite/gdb.perf/jit.c         | 87 ++++++++++++++++++++++++++++
 gdb/testsuite/gdb.perf/jit.exp       | 79 +++++++++++++++++++++++++
 5 files changed, 278 insertions(+)
 create mode 100644 gdb/testsuite/gdb.perf/jit-check.exp
 create mode 100644 gdb/testsuite/gdb.perf/jit-check.py
 create mode 100644 gdb/testsuite/gdb.perf/jit-solib.c
 create mode 100644 gdb/testsuite/gdb.perf/jit.c
 create mode 100644 gdb/testsuite/gdb.perf/jit.exp

diff --git a/gdb/testsuite/gdb.perf/jit-check.exp b/gdb/testsuite/gdb.perf/jit-check.exp
new file mode 100644
index 00000000000..c124f294f7b
--- /dev/null
+++ b/gdb/testsuite/gdb.perf/jit-check.exp
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Benchmark registering and unregistering JITed code (run part).
+
+load_lib perftest.exp
+load_lib gen-perf-test.exp
+
+if [skip_perf_tests] {
+    return 0
+}
+
+GenPerfTest::standard_run_driver jit.exp make_testcase_config jit-check.py JitCheck
diff --git a/gdb/testsuite/gdb.perf/jit-check.py b/gdb/testsuite/gdb.perf/jit-check.py
new file mode 100644
index 00000000000..c5b46a23ffc
--- /dev/null
+++ b/gdb/testsuite/gdb.perf/jit-check.py
@@ -0,0 +1,60 @@
+# Copyright (C) 2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Benchmark for registering and unregistering JITed code.
+
+import os
+import shlex
+
+from perftest import measure
+from perftest import perftest
+from perftest import testresult
+from perftest import utils
+
+
+class JitCheck(perftest.TestCaseWithBasicMeasurements):
+    def __init__(self, name, run_names, binfile):
+        super(JitCheck, self).__init__(name)
+        self.run_names = run_names
+        self.binfile = binfile
+        self.measurement = measure.MeasurementWallTime(
+            testresult.SingleStatisticTestResult()
+        )
+        self.measure.measurements.append(self.measurement)
+
+    def warm_up(self):
+        pass
+
+    def execute_test(self):
+        for run in self.run_names:
+            exe = "{}-{}".format(self.binfile, utils.convert_spaces(run))
+            utils.select_file(exe)
+
+            # Help the binary find the shared objects.
+            pieces = os.path.join(os.path.dirname(exe), "pieces")
+            gdb.execute("cd {}".format(shlex.quote(pieces)))
+
+            # Measure the total run time.
+            utils.runto_main()
+            gdb.execute("tbreak done_breakpoint")
+            self.measure.measure(lambda: gdb.execute("continue"), run)
+
+            # Extract and record processing times for individual functions.
+            for array_name in ("register_times", "unregister_times"):
+                array_value = gdb.parse_and_eval(array_name)
+                for i in range(*array_value.type.range()):
+                    parameter = "{}:{}:{}".format(run, array_name, i + 1)
+                    result = int(array_value[i]) / 1e6
+                    self.measurement.result.record(parameter, result)
diff --git a/gdb/testsuite/gdb.perf/jit-solib.c b/gdb/testsuite/gdb.perf/jit-solib.c
new file mode 100644
index 00000000000..b2f70fc16e8
--- /dev/null
+++ b/gdb/testsuite/gdb.perf/jit-solib.c
@@ -0,0 +1,27 @@
+/* This test program is part of GDB, the GNU debugger.
+
+   Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Shared object for benchmarking registering and unregistering JITed code.
+   Must be compiled with -DSHLIB=<shared object number>.  */
+
+#define CAT_1(x, y) x##y
+#define CAT(x, y) CAT_1 (x, y)
+int
+CAT (jited_func_, SHLIB) (void)
+{
+  return SHLIB;
+}
diff --git a/gdb/testsuite/gdb.perf/jit.c b/gdb/testsuite/gdb.perf/jit.c
new file mode 100644
index 00000000000..5fb373a753f
--- /dev/null
+++ b/gdb/testsuite/gdb.perf/jit.c
@@ -0,0 +1,87 @@
+/* This test program is part of GDB, the GNU debugger.
+
+   Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Benchmark for registering and unregistering JITed code.
+   Must be compiled with -DTOTAL_NR_SHLIBS=<total number of shared
+   objects>.  */
+
+#include "../gdb.base/jit-elf-util.h"
+#include "../gdb.base/jit-protocol-util.h"
+#include <stdint.h>
+#include <sys/time.h>
+
+static struct jit_code_entry entries[TOTAL_NR_SHLIBS];
+static uint64_t register_times[TOTAL_NR_SHLIBS];
+static uint64_t unregister_times[TOTAL_NR_SHLIBS];
+
+static uint64_t
+time_delta (struct timeval *start_time)
+{
+  struct timeval end_time;
+
+  gettimeofday (&end_time, NULL);
+  return (uint64_t)(end_time.tv_sec - start_time->tv_sec) * 1000000
+	 + (end_time.tv_usec - start_time->tv_usec);
+}
+
+void __attribute__ ((noinline)) done_breakpoint (void) {}
+
+int
+main (void)
+{
+  struct timeval start_time;
+  int i;
+
+  /* Load and register shared libraries.  */
+  for (i = 0; i < TOTAL_NR_SHLIBS; i++)
+    {
+      int (*jited_func) (void);
+      size_t obj_size;
+      char name[32];
+      void *addr;
+
+      sprintf (name, "jit-lib%d.so", i);
+      void *load_addr = n_jit_so_address (i + 1);
+      addr = load_elf (name, &obj_size, load_addr);
+      sprintf (name, "jited_func_%d", i);
+      jited_func = load_symbol (addr, name);
+
+      entries[i].symfile_addr = addr;
+      entries[i].symfile_size = obj_size;
+      gettimeofday (&start_time, NULL);
+      jit_push_back (&entries[i]);
+      register_times[i] = time_delta (&start_time);
+
+      if (jited_func () != i)
+	{
+	  fprintf (stderr, "jited_func_%d () != %d\n", i, i);
+	  return 1;
+	}
+    }
+
+  /* Now unregister them all in reverse order.  */
+  for (i = TOTAL_NR_SHLIBS - 1; i >= 0; i--)
+    {
+      gettimeofday (&start_time, NULL);
+      jit_pop_back ();
+      unregister_times[i] = time_delta (&start_time);
+    }
+
+  done_breakpoint ();
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.perf/jit.exp b/gdb/testsuite/gdb.perf/jit.exp
new file mode 100644
index 00000000000..8423312c07a
--- /dev/null
+++ b/gdb/testsuite/gdb.perf/jit.exp
@@ -0,0 +1,79 @@
+# Copyright (C) 2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Benchmark registering and unregistering JITed code (build part).
+#
+# Usage example:
+#
+#     make build-perf RUNTESTFLAGS='jit.exp SOLIB_COUNT=100'
+#
+# Supported options:
+#
+# - SOLIB_COUNT: How many shared objects to build (default: 500).
+
+load_lib jit-elf-helpers.exp
+load_lib perftest.exp
+load_lib gen-perf-test.exp
+
+if [skip_perf_tests] {
+    return 0
+}
+
+if ![info exists SOLIB_COUNT] {
+    set SOLIB_COUNT 500
+}
+
+# Adjust binary compile options.
+proc jit_binary_adjust_compile_options { options nr_gen_shlibs } {
+    # Specify shared library load addresses.
+    global jit_compile_options
+    set options [concat $options $jit_compile_options]
+
+    # Specify the total number of shared libraries.
+    lappend options additional_flags=-DTOTAL_NR_SHLIBS=$nr_gen_shlibs
+
+    return $options
+}
+
+# Adjust solib compile options.
+proc jit_solib_adjust_compile_options { options so_nr } {
+    # Disable debuginfo (see compile_and_download_n_jit_so for explanations).
+    set debug [lsearch -exact $options debug]
+    if {$debug != -1} {
+	set options [lreplace $options $debug $debug]
+    }
+
+    # Specify a load address for this solib.
+    lappend options text_segment=[format 0x%x [n_jit_so_address $so_nr]]
+
+    return $options
+}
+
+proc make_testcase_config { } {
+    set program_name "jit"
+    array set testcase [GenPerfTest::init_testcase $program_name]
+    set testcase(language) c
+    set testcase(binary_extra_sources) { { jit.c } }
+    set testcase(binary_link_with_shlibs) { false }
+    set testcase(binary_adjust_compile_options) { jit_binary_adjust_compile_options }
+    set testcase(gen_shlib_extra_sources) { { jit-solib.c } }
+    set testcase(gen_shlib_adjust_compile_options) { jit_solib_adjust_compile_options }
+    set name "${::SOLIB_COUNT}-sos"
+    set testcase(run_names) [list $name]
+    set testcase(nr_gen_shlibs) ${::SOLIB_COUNT}
+    return [array get testcase]
+}
+
+GenPerfTest::standard_compile_driver jit.exp make_testcase_config
-- 
2.35.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PING] [PATCH v2 0/7] gdb.perf/: Add JIT performance test
  2022-05-30 22:11 [PATCH v2 0/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
                   ` (6 preceding siblings ...)
  2022-05-30 22:11 ` [PATCH v2 7/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
@ 2022-06-22  8:48 ` Ilya Leoshkevich via Gdb-patches
  2022-08-03 10:52 ` [PING^2] " Ilya Leoshkevich via Gdb-patches
  8 siblings, 0 replies; 10+ messages in thread
From: Ilya Leoshkevich via Gdb-patches @ 2022-06-22  8:48 UTC (permalink / raw)
  To: Tom Tromey, Andrew Burgess, Pedro Alves
  Cc: Ulrich Weigand, Andreas Arnez, gdb-patches

On Tue, 2022-05-31 at 00:11 +0200, Ilya Leoshkevich wrote:
> Hi,
> 
> This series implements a JIT performance test as discussed in [1].
> Patch 1 is a small fix, patches 2-6 are preparations and patch 7 is
> the test itself.
> 
> ChangeLog:
> v1: https://sourceware.org/pipermail/gdb-patches/2022-May/189427.html
> v1 -> v2:
> * Make sure shared objects contain virtual addresses they are loaded
>   at by reusing parts of jit-elf-helpers.exp.  By default, virtual
>   addresses in all shared objects are relative to 0 - this creates a
>   lots of overlaps and forces sort_cmp () to go through the slow
> "Sort
>   on sequence number of the objfile in the chain" path, which is not
> a
>   useful performance testing scenario.
> * Fix DEFAULT_BINARY_LINK_WITH_SHLIBS style (Andrew).
> * Rename SHLIB to TOTAL_NR_SHLIBS (Andrew).
> * Add SOLIB_COUNT (Andrew).
> * Drop "gdb.perf/: Compile the binary with -DSHLIB", it's superseded
> by
>   "Allow adjusting GenPerfTest compile options".
> 
> The test can be used as follows:
> 
> $ make build-perf -j"$(nproc)" RUNTESTFLAGS=jit.exp
> $ make check-perf RUNTESTFLAGS=jit-check.exp GDB_PERFTEST_MODE=run
> 
> The results can be converted to gnuplot-friendly format as follows:
> 
> $ perl -ne 'if (/:register_times:(\d+) (.+)/) { print "$1 $2\n"; }' \
>       <gdb.perf/outputs/jit/pieces/perftest.sum >jit.txt
> 
> I've uploaded the results to [2].  They are similar to the ones from
> Andrew and show that [1] is an improvement.  The third result shown
> on
> the chart is from [3] - with it I can pass the 10k JITed objects mark
> and debug CoreCLR JIT with GDB.  It's still WIP though - the
> testsuite
> shows a couple of failures.
> 
> Best regards,
> Ilya
> 
> [1] https://sourceware.org/pipermail/gdb-patches/2022-May/189341.html
> [2]
> https://github.com/iii-i/binutils-gdb/blob/section-map-20220530-2/gdb/testsuite/jit.png
> [3]
> https://github.com/iii-i/binutils-gdb/commits/section-map-20220530-2
> 
> Ilya Leoshkevich (7):
>   gdb.perf/: Fix tcl_string_list_to_python_list {x}
>   gdb.perf/: Add binary_link_with_shlibs setting to GenPerfTest
>   gdb.perf/: Allow adjusting GenPerfTest compile options
>   gdb.base/: Introduce jit-protocol-util.h
>   gdb.base/: Introduce jit_compile_options
>   gdb.base/: Introduce n_jit_so_address
>   gdb.perf/: Add JIT performance test
> 
>  gdb/testsuite/gdb.base/jit-elf-fork-main.c | 48 ++----------
>  gdb/testsuite/gdb.base/jit-elf-main.c      | 48 ++----------
>  gdb/testsuite/gdb.base/jit-elf-util.h      | 17 +++++
>  gdb/testsuite/gdb.base/jit-protocol-util.h | 74 ++++++++++++++++++
>  gdb/testsuite/gdb.base/jit-reader-host.c   |  8 +-
>  gdb/testsuite/gdb.perf/jit-check.exp       | 25 +++++++
>  gdb/testsuite/gdb.perf/jit-check.py        | 60 +++++++++++++++
>  gdb/testsuite/gdb.perf/jit-solib.c         | 27 +++++++
>  gdb/testsuite/gdb.perf/jit.c               | 87
> ++++++++++++++++++++++
>  gdb/testsuite/gdb.perf/jit.exp             | 79 ++++++++++++++++++++
>  gdb/testsuite/lib/gen-perf-test.exp        | 54 +++++++++++---
>  gdb/testsuite/lib/jit-elf-helpers.exp      | 22 ++++--
>  gdb/testsuite/lib/perftest.exp             |  2 +-
>  13 files changed, 439 insertions(+), 112 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.base/jit-protocol-util.h
>  create mode 100644 gdb/testsuite/gdb.perf/jit-check.exp
>  create mode 100644 gdb/testsuite/gdb.perf/jit-check.py
>  create mode 100644 gdb/testsuite/gdb.perf/jit-solib.c
>  create mode 100644 gdb/testsuite/gdb.perf/jit.c
>  create mode 100644 gdb/testsuite/gdb.perf/jit.exp
> 

Hi,

is there anything else that needs to be adjusted here?

Best regards,
Ilya

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PING^2] [PATCH v2 0/7] gdb.perf/: Add JIT performance test
  2022-05-30 22:11 [PATCH v2 0/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
                   ` (7 preceding siblings ...)
  2022-06-22  8:48 ` [PING] [PATCH v2 0/7] " Ilya Leoshkevich via Gdb-patches
@ 2022-08-03 10:52 ` Ilya Leoshkevich via Gdb-patches
  8 siblings, 0 replies; 10+ messages in thread
From: Ilya Leoshkevich via Gdb-patches @ 2022-08-03 10:52 UTC (permalink / raw)
  To: Tom Tromey, Andrew Burgess
  Cc: Ulrich Weigand, Andreas Arnez, gdb-patches, Pedro Alves

On Tue, 2022-05-31 at 00:11 +0200, Ilya Leoshkevich wrote:
> Hi,
> 
> This series implements a JIT performance test as discussed in [1].
> Patch 1 is a small fix, patches 2-6 are preparations and patch 7 is
> the test itself.
> 
> ChangeLog:
> v1: https://sourceware.org/pipermail/gdb-patches/2022-May/189427.html
> v1 -> v2:
> * Make sure shared objects contain virtual addresses they are loaded
>   at by reusing parts of jit-elf-helpers.exp.  By default, virtual
>   addresses in all shared objects are relative to 0 - this creates a
>   lots of overlaps and forces sort_cmp () to go through the slow
> "Sort
>   on sequence number of the objfile in the chain" path, which is not
> a
>   useful performance testing scenario.
> * Fix DEFAULT_BINARY_LINK_WITH_SHLIBS style (Andrew).
> * Rename SHLIB to TOTAL_NR_SHLIBS (Andrew).
> * Add SOLIB_COUNT (Andrew).
> * Drop "gdb.perf/: Compile the binary with -DSHLIB", it's superseded
> by
>   "Allow adjusting GenPerfTest compile options".
> 
> The test can be used as follows:
> 
> $ make build-perf -j"$(nproc)" RUNTESTFLAGS=jit.exp
> $ make check-perf RUNTESTFLAGS=jit-check.exp GDB_PERFTEST_MODE=run
> 
> The results can be converted to gnuplot-friendly format as follows:
> 
> $ perl -ne 'if (/:register_times:(\d+) (.+)/) { print "$1 $2\n"; }' \
>       <gdb.perf/outputs/jit/pieces/perftest.sum >jit.txt
> 
> I've uploaded the results to [2].  They are similar to the ones from
> Andrew and show that [1] is an improvement.  The third result shown
> on
> the chart is from [3] - with it I can pass the 10k JITed objects mark
> and debug CoreCLR JIT with GDB.  It's still WIP though - the
> testsuite
> shows a couple of failures.
> 
> Best regards,
> Ilya
> 
> [1] https://sourceware.org/pipermail/gdb-patches/2022-May/189341.html
> [2]
> https://github.com/iii-i/binutils-gdb/blob/section-map-20220530-2/gdb/testsuite/jit.png
> [3]
> https://github.com/iii-i/binutils-gdb/commits/section-map-20220530-2
> 
> Ilya Leoshkevich (7):
>   gdb.perf/: Fix tcl_string_list_to_python_list {x}
>   gdb.perf/: Add binary_link_with_shlibs setting to GenPerfTest
>   gdb.perf/: Allow adjusting GenPerfTest compile options
>   gdb.base/: Introduce jit-protocol-util.h
>   gdb.base/: Introduce jit_compile_options
>   gdb.base/: Introduce n_jit_so_address
>   gdb.perf/: Add JIT performance test
> 
>  gdb/testsuite/gdb.base/jit-elf-fork-main.c | 48 ++----------
>  gdb/testsuite/gdb.base/jit-elf-main.c      | 48 ++----------
>  gdb/testsuite/gdb.base/jit-elf-util.h      | 17 +++++
>  gdb/testsuite/gdb.base/jit-protocol-util.h | 74 ++++++++++++++++++
>  gdb/testsuite/gdb.base/jit-reader-host.c   |  8 +-
>  gdb/testsuite/gdb.perf/jit-check.exp       | 25 +++++++
>  gdb/testsuite/gdb.perf/jit-check.py        | 60 +++++++++++++++
>  gdb/testsuite/gdb.perf/jit-solib.c         | 27 +++++++
>  gdb/testsuite/gdb.perf/jit.c               | 87
> ++++++++++++++++++++++
>  gdb/testsuite/gdb.perf/jit.exp             | 79 ++++++++++++++++++++
>  gdb/testsuite/lib/gen-perf-test.exp        | 54 +++++++++++---
>  gdb/testsuite/lib/jit-elf-helpers.exp      | 22 ++++--
>  gdb/testsuite/lib/perftest.exp             |  2 +-
>  13 files changed, 439 insertions(+), 112 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.base/jit-protocol-util.h
>  create mode 100644 gdb/testsuite/gdb.perf/jit-check.exp
>  create mode 100644 gdb/testsuite/gdb.perf/jit-check.py
>  create mode 100644 gdb/testsuite/gdb.perf/jit-solib.c
>  create mode 100644 gdb/testsuite/gdb.perf/jit.c
>  create mode 100644 gdb/testsuite/gdb.perf/jit.exp

Ping.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-08-03 10:53 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-30 22:11 [PATCH v2 0/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` [PATCH v2 1/7] gdb.perf/: Fix tcl_string_list_to_python_list {x} Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` [PATCH v2 2/7] gdb.perf/: Add binary_link_with_shlibs setting to GenPerfTest Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` [PATCH v2 3/7] gdb.perf/: Allow adjusting GenPerfTest compile options Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` [PATCH v2 4/7] gdb.base/: Introduce jit-protocol-util.h Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` [PATCH v2 5/7] gdb.base/: Introduce jit_compile_options Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` [PATCH v2 6/7] gdb.base/: Introduce n_jit_so_address Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` [PATCH v2 7/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
2022-06-22  8:48 ` [PING] [PATCH v2 0/7] " Ilya Leoshkevich via Gdb-patches
2022-08-03 10:52 ` [PING^2] " Ilya Leoshkevich via Gdb-patches

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox