From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16520 invoked by alias); 20 Feb 2012 20:42:45 -0000 Received: (qmail 16510 invoked by uid 22791); 20 Feb 2012 20:42:44 -0000 X-SWARE-Spam-Status: No, hits=-6.9 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_BJ,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 20 Feb 2012 20:42:30 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q1KKgUoi031650 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 20 Feb 2012 15:42:30 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q1KKgU0w020451; Mon, 20 Feb 2012 15:42:30 -0500 Received: from barimba (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id q1KKgS3P005936; Mon, 20 Feb 2012 15:42:29 -0500 From: Tom Tromey To: gdb-patches@sourceware.org Subject: FYI: fix some performance bugs with .gdb_index Date: Mon, 20 Feb 2012 20:44:00 -0000 Message-ID: <87pqd9uthn.fsf@fleche.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.93 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-02/txt/msg00414.txt.bz2 I'm checking this in. PR 13498 concerns gdb performance problems with DWARF 4 and also with .gdb_index. This patch fixes the index-related problems. The .so I used for the test (libooxlo.so from LibreOffice) has 262 CUs and 16597 TUs. The bug reporter indicated that the problem was that we were redundantly revisiting file names, and some local profiling confirmed this. The fix is to keep track of which file names we have already visited. This works because multiple TUs will share the same file name table. I don't think this will drastically impact smaller test cases. The overhead of the hash table isn't very big. Built and regtested on x86-64 Fedora 16. Tom 2012-02-20 Tom Tromey PR gdb/13498: * dwarf2read.c (dw2_expand_symtabs_matching): Only visit a particular set of file names once. (dw2_map_symbol_filenames): Likewise. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 0576def..5892a64 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -2707,32 +2707,63 @@ dw2_expand_symtabs_matching index = dwarf2_per_objfile->index_table; if (file_matcher != NULL) - for (i = 0; i < (dwarf2_per_objfile->n_comp_units - + dwarf2_per_objfile->n_type_units); ++i) - { - int j; - struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); - struct quick_file_names *file_data; + { + struct cleanup *cleanup; + htab_t visited_found, visited_not_found; - per_cu->v.quick->mark = 0; + visited_found = htab_create_alloc (10, + htab_hash_pointer, htab_eq_pointer, + NULL, xcalloc, xfree); + cleanup = make_cleanup_htab_delete (visited_found); + visited_not_found = htab_create_alloc (10, + htab_hash_pointer, htab_eq_pointer, + NULL, xcalloc, xfree); + make_cleanup_htab_delete (visited_not_found); - /* We only need to look at symtabs not already expanded. */ - if (per_cu->v.quick->symtab) - continue; + for (i = 0; i < (dwarf2_per_objfile->n_comp_units + + dwarf2_per_objfile->n_type_units); ++i) + { + int j; + struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); + struct quick_file_names *file_data; + void **slot; - file_data = dw2_get_file_names (objfile, per_cu); - if (file_data == NULL) - continue; + per_cu->v.quick->mark = 0; - for (j = 0; j < file_data->num_file_names; ++j) - { - if (file_matcher (file_data->file_names[j], data)) - { - per_cu->v.quick->mark = 1; - break; - } - } - } + /* We only need to look at symtabs not already expanded. */ + if (per_cu->v.quick->symtab) + continue; + + file_data = dw2_get_file_names (objfile, per_cu); + if (file_data == NULL) + continue; + + if (htab_find (visited_not_found, file_data) != NULL) + continue; + else if (htab_find (visited_found, file_data) != NULL) + { + per_cu->v.quick->mark = 1; + continue; + } + + for (j = 0; j < file_data->num_file_names; ++j) + { + if (file_matcher (file_data->file_names[j], data)) + { + per_cu->v.quick->mark = 1; + break; + } + } + + slot = htab_find_slot (per_cu->v.quick->mark + ? visited_found + : visited_not_found, + file_data, INSERT); + *slot = file_data; + } + + do_cleanups (cleanup); + } for (iter = 0; iter < index->symbol_table_slots; ++iter) { @@ -2794,15 +2825,35 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun, void *data, int need_fullname) { int i; + struct cleanup *cleanup; + htab_t visited = htab_create_alloc (10, htab_hash_pointer, htab_eq_pointer, + NULL, xcalloc, xfree); + cleanup = make_cleanup_htab_delete (visited); dw2_setup (objfile); + /* We can ignore file names coming from already-expanded CUs. */ + for (i = 0; i < (dwarf2_per_objfile->n_comp_units + + dwarf2_per_objfile->n_type_units); ++i) + { + struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); + + if (per_cu->v.quick->symtab) + { + void **slot = htab_find_slot (visited, per_cu->v.quick->file_names, + INSERT); + + *slot = per_cu->v.quick->file_names; + } + } + for (i = 0; i < (dwarf2_per_objfile->n_comp_units + dwarf2_per_objfile->n_type_units); ++i) { int j; struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); struct quick_file_names *file_data; + void **slot; /* We only need to look at symtabs not already expanded. */ if (per_cu->v.quick->symtab) @@ -2812,6 +2863,14 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun, if (file_data == NULL) continue; + slot = htab_find_slot (visited, file_data, INSERT); + if (*slot) + { + /* Already visited. */ + continue; + } + *slot = file_data; + for (j = 0; j < file_data->num_file_names; ++j) { const char *this_real_name; @@ -2823,6 +2882,8 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun, (*fun) (file_data->file_names[j], this_real_name, data); } } + + do_cleanups (cleanup); } static int