From patchwork Thu May 15 19:08:47 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Evans X-Patchwork-Id: 951 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx23.g.dreamhost.com (mx2.sub5.homie.mail.dreamhost.com [208.113.200.128]) by wilcox.dreamhost.com (Postfix) with ESMTP id 183D2360098 for ; Thu, 15 May 2014 12:08:55 -0700 (PDT) Received: by homiemail-mx23.g.dreamhost.com (Postfix, from userid 14314964) id B8A6A63D0951E; Thu, 15 May 2014 12:08:54 -0700 (PDT) X-Original-To: gdb@patchwork.siddhesh.in Delivered-To: x14314964@homiemail-mx23.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx23.g.dreamhost.com (Postfix) with ESMTPS id 818D263D09518 for ; Thu, 15 May 2014 12:08:54 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:mime-version :content-type; q=dns; s=default; b=t/dnCxLC4eAIBdbcXaT0fXx58N8Vk tNkUqil/r7gi6aqfzMofy2JV3lh8IRMj0s7n4ikH5tx3MSaPTq+JzZsX6b2AcN7e NSFrT+GM/PuJIcXr/R5GHXK/iRo5CGBaLKooEvfWsyDrgM72aUR0aj7HxvYZ+xdk bn//hngT9aUPjE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:mime-version :content-type; s=default; bh=Xsv3RHBbUIaNQRH5QNgoMEgYtZM=; b=PzE BJlD2jIu3+MwzAxiBhqwo9iGXzPCujv58/a2djJ6IospUA/IVYwcTxR9SOa2AHCs a+dsGkgyjy/rRkeAh6P+SJi5Jq6ooLBP9zSCiyBhsrZilXAyLXFA6WnGjrL0l6s5 5gTTivH3zxoTfcXVC7sRuaQR4msYLtQ7JbHOA8kw= Received: (qmail 1502 invoked by alias); 15 May 2014 19:08:52 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 1484 invoked by uid 89); 15 May 2014 19:08:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-ie0-f202.google.com Received: from mail-ie0-f202.google.com (HELO mail-ie0-f202.google.com) (209.85.223.202) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Thu, 15 May 2014 19:08:49 +0000 Received: by mail-ie0-f202.google.com with SMTP id ar20so321452iec.5 for ; Thu, 15 May 2014 12:08:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-type; bh=OQTFaIIAFHSgZjs6OszKsz6JtnmYuoAhO+BRpd1B9k8=; b=doJ9cBSDI1oIUplXIUVgWLf/8vVBnfEDD8Rgc9rs+ulocgvKFULToTM9+46hVoxHqX m7HIreMcQazhxZch18mw6Seu4t5OLu8dZM9cyx8yHvi7w96fA9/36iJkkpwFJgwBMTbQ n6QuM+9rVbc4WUTVnnRkNz6Lh7bgXq8hRL6o86rTLnIIo8ODF79Jon5mB12tHj1U6r2p 2/syD4BOUPHPQt6R9HvU6Z9jKLXJ9rusgvhZYSb7WfyWcGuw+j/MRRIow3URNJQDLji6 PK/zDlZDwIfBAFl7DKmVGbACBA+b/KEM1JjMneD4aN6ifnQD7ds75TWUlyyVICcghizF TcmA== X-Gm-Message-State: ALoCoQkVTz5wBxaBridsVnQHkyafCKDFZ796RzBUW3vfnex4Xn1CVpCvz+QoTT0OU4Gsb7B5X3UxVXT8hlfUY4szhD5QZDYRPDn1MGlO/3fBqKBSCGp/GwcmbVsqAzHZsaqP7KbSlRWn X-Received: by 10.182.227.131 with SMTP id sa3mr5868662obc.38.1400180927966; Thu, 15 May 2014 12:08:47 -0700 (PDT) Received: from corp2gmr1-2.hot.corp.google.com (corp2gmr1-2.hot.corp.google.com [172.24.189.93]) by gmr-mx.google.com with ESMTPS id n43si36561yhe.1.2014.05.15.12.08.47 for (version=TLSv1.1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 15 May 2014 12:08:47 -0700 (PDT) Received: from ruffy.mtv.corp.google.com (ruffy.mtv.corp.google.com [172.17.128.44]) by corp2gmr1-2.hot.corp.google.com (Postfix) with ESMTP id 8F28D5A427D for ; Thu, 15 May 2014 12:08:47 -0700 (PDT) From: Doug Evans To: gdb-patches@sourceware.org Subject: [PATCH] Move dwarf2read.c:build_type_unit_groups closer to only user. Date: Thu, 15 May 2014 12:08:47 -0700 Message-ID: MIME-Version: 1.0 X-IsSubscribed: yes X-DH-Original-To: gdb@patchwork.siddhesh.in Hi. This is another cleanup patch. There is only one caller of build_type_unit_groups now. This patch moves it closer to its only user and renames it. 2014-05-15 Doug Evans * dwarf2read.c (build_type_psymtabs_1): Renamed from build_type_unit_groups and moved closer to only caller. Remove arguments. All references updated. Remove outdated .gdb_index comment. (struct tu_abbrev_offset, sort_tu_by_abbrev_offset): Move with build_type_psymtabs_1. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index dfa2caf..43ba985 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -5731,162 +5731,6 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list) return tu_group; } - -/* Struct used to sort TUs by their abbreviation table offset. */ - -struct tu_abbrev_offset -{ - struct signatured_type *sig_type; - sect_offset abbrev_offset; -}; - -/* Helper routine for build_type_unit_groups, passed to qsort. */ - -static int -sort_tu_by_abbrev_offset (const void *ap, const void *bp) -{ - const struct tu_abbrev_offset * const *a = ap; - const struct tu_abbrev_offset * const *b = bp; - unsigned int aoff = (*a)->abbrev_offset.sect_off; - unsigned int boff = (*b)->abbrev_offset.sect_off; - - return (aoff > boff) - (aoff < boff); -} - -/* Efficiently read all the type units, calling init_cutu_and_read_dies on - each one passing FUNC,DATA. - - The efficiency is because we sort TUs by the abbrev table they use and - only read each abbrev table once. In one program there are 200K TUs - sharing 8K abbrev tables. - - The main purpose of this function is to support building the - dwarf2_per_objfile->type_unit_groups table. - TUs typically share the DW_AT_stmt_list of the CU they came from, so we - can collapse the search space by grouping them by stmt_list. - The savings can be significant, in the same program from above the 200K TUs - share 8K stmt_list tables. - - FUNC is expected to call get_type_unit_group, which will create the - struct type_unit_group if necessary and add it to - dwarf2_per_objfile->type_unit_groups. */ - -static void -build_type_unit_groups (die_reader_func_ftype *func, void *data) -{ - struct objfile *objfile = dwarf2_per_objfile->objfile; - struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats; - struct cleanup *cleanups; - struct abbrev_table *abbrev_table; - sect_offset abbrev_offset; - struct tu_abbrev_offset *sorted_by_abbrev; - struct type_unit_group **iter; - int i; - - /* It's up to the caller to not call us multiple times. */ - gdb_assert (dwarf2_per_objfile->type_unit_groups == NULL); - - if (dwarf2_per_objfile->n_type_units == 0) - return; - - /* TUs typically share abbrev tables, and there can be way more TUs than - abbrev tables. Sort by abbrev table to reduce the number of times we - read each abbrev table in. - Alternatives are to punt or to maintain a cache of abbrev tables. - This is simpler and efficient enough for now. - - Later we group TUs by their DW_AT_stmt_list value (as this defines the - symtab to use). Typically TUs with the same abbrev offset have the same - stmt_list value too so in practice this should work well. - - The basic algorithm here is: - - sort TUs by abbrev table - for each TU with same abbrev table: - read abbrev table if first user - read TU top level DIE - [IWBN if DWO skeletons had DW_AT_stmt_list] - call FUNC */ - - if (dwarf2_read_debug) - fprintf_unfiltered (gdb_stdlog, "Building type unit groups ...\n"); - - /* Sort in a separate table to maintain the order of all_type_units - for .gdb_index: TU indices directly index all_type_units. */ - sorted_by_abbrev = XNEWVEC (struct tu_abbrev_offset, - dwarf2_per_objfile->n_type_units); - for (i = 0; i < dwarf2_per_objfile->n_type_units; ++i) - { - struct signatured_type *sig_type = dwarf2_per_objfile->all_type_units[i]; - - sorted_by_abbrev[i].sig_type = sig_type; - sorted_by_abbrev[i].abbrev_offset = - read_abbrev_offset (sig_type->per_cu.section, - sig_type->per_cu.offset); - } - cleanups = make_cleanup (xfree, sorted_by_abbrev); - qsort (sorted_by_abbrev, dwarf2_per_objfile->n_type_units, - sizeof (struct tu_abbrev_offset), sort_tu_by_abbrev_offset); - - /* Note: In the .gdb_index case, get_type_unit_group may have already been - called any number of times, so we don't reset tu_stats here. */ - - abbrev_offset.sect_off = ~(unsigned) 0; - abbrev_table = NULL; - make_cleanup (abbrev_table_free_cleanup, &abbrev_table); - - for (i = 0; i < dwarf2_per_objfile->n_type_units; ++i) - { - const struct tu_abbrev_offset *tu = &sorted_by_abbrev[i]; - - /* Switch to the next abbrev table if necessary. */ - if (abbrev_table == NULL - || tu->abbrev_offset.sect_off != abbrev_offset.sect_off) - { - if (abbrev_table != NULL) - { - abbrev_table_free (abbrev_table); - /* Reset to NULL in case abbrev_table_read_table throws - an error: abbrev_table_free_cleanup will get called. */ - abbrev_table = NULL; - } - abbrev_offset = tu->abbrev_offset; - abbrev_table = - abbrev_table_read_table (&dwarf2_per_objfile->abbrev, - abbrev_offset); - ++tu_stats->nr_uniq_abbrev_tables; - } - - init_cutu_and_read_dies (&tu->sig_type->per_cu, abbrev_table, 0, 0, - func, data); - } - - /* type_unit_groups can be NULL if there is an error in the debug info. - Just create an empty table so the rest of gdb doesn't have to watch - for this error case. */ - if (dwarf2_per_objfile->type_unit_groups == NULL) - { - dwarf2_per_objfile->type_unit_groups = - allocate_type_unit_groups_table (); - } - - do_cleanups (cleanups); - - if (dwarf2_read_debug) - { - fprintf_unfiltered (gdb_stdlog, "Done building type unit groups:\n"); - fprintf_unfiltered (gdb_stdlog, " %d TUs\n", - dwarf2_per_objfile->n_type_units); - fprintf_unfiltered (gdb_stdlog, " %d uniq abbrev tables\n", - tu_stats->nr_uniq_abbrev_tables); - fprintf_unfiltered (gdb_stdlog, " %d symtabs from stmt_list entries\n", - tu_stats->nr_symtabs); - fprintf_unfiltered (gdb_stdlog, " %d symtab sharers\n", - tu_stats->nr_symtab_sharers); - fprintf_unfiltered (gdb_stdlog, " %d type units without a stmt_list\n", - tu_stats->nr_stmt_less_type_units); - } -} /* Partial symbol tables. */ @@ -6144,6 +5988,159 @@ build_type_psymtabs_reader (const struct die_reader_specs *reader, sort_pst_symbols (objfile, pst); } +/* Struct used to sort TUs by their abbreviation table offset. */ + +struct tu_abbrev_offset +{ + struct signatured_type *sig_type; + sect_offset abbrev_offset; +}; + +/* Helper routine for build_type_psymtabs_1, passed to qsort. */ + +static int +sort_tu_by_abbrev_offset (const void *ap, const void *bp) +{ + const struct tu_abbrev_offset * const *a = ap; + const struct tu_abbrev_offset * const *b = bp; + unsigned int aoff = (*a)->abbrev_offset.sect_off; + unsigned int boff = (*b)->abbrev_offset.sect_off; + + return (aoff > boff) - (aoff < boff); +} + +/* Efficiently read all the type units. + This does the bulk of the work for build_type_psymtabs. + + The efficiency is because we sort TUs by the abbrev table they use and + only read each abbrev table once. In one program there are 200K TUs + sharing 8K abbrev tables. + + The main purpose of this function is to support building the + dwarf2_per_objfile->type_unit_groups table. + TUs typically share the DW_AT_stmt_list of the CU they came from, so we + can collapse the search space by grouping them by stmt_list. + The savings can be significant, in the same program from above the 200K TUs + share 8K stmt_list tables. + + FUNC is expected to call get_type_unit_group, which will create the + struct type_unit_group if necessary and add it to + dwarf2_per_objfile->type_unit_groups. */ + +static void +build_type_psymtabs_1 (void) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats; + struct cleanup *cleanups; + struct abbrev_table *abbrev_table; + sect_offset abbrev_offset; + struct tu_abbrev_offset *sorted_by_abbrev; + struct type_unit_group **iter; + int i; + + /* It's up to the caller to not call us multiple times. */ + gdb_assert (dwarf2_per_objfile->type_unit_groups == NULL); + + if (dwarf2_per_objfile->n_type_units == 0) + return; + + /* TUs typically share abbrev tables, and there can be way more TUs than + abbrev tables. Sort by abbrev table to reduce the number of times we + read each abbrev table in. + Alternatives are to punt or to maintain a cache of abbrev tables. + This is simpler and efficient enough for now. + + Later we group TUs by their DW_AT_stmt_list value (as this defines the + symtab to use). Typically TUs with the same abbrev offset have the same + stmt_list value too so in practice this should work well. + + The basic algorithm here is: + + sort TUs by abbrev table + for each TU with same abbrev table: + read abbrev table if first user + read TU top level DIE + [IWBN if DWO skeletons had DW_AT_stmt_list] + call FUNC */ + + if (dwarf2_read_debug) + fprintf_unfiltered (gdb_stdlog, "Building type unit groups ...\n"); + + /* Sort in a separate table to maintain the order of all_type_units + for .gdb_index: TU indices directly index all_type_units. */ + sorted_by_abbrev = XNEWVEC (struct tu_abbrev_offset, + dwarf2_per_objfile->n_type_units); + for (i = 0; i < dwarf2_per_objfile->n_type_units; ++i) + { + struct signatured_type *sig_type = dwarf2_per_objfile->all_type_units[i]; + + sorted_by_abbrev[i].sig_type = sig_type; + sorted_by_abbrev[i].abbrev_offset = + read_abbrev_offset (sig_type->per_cu.section, + sig_type->per_cu.offset); + } + cleanups = make_cleanup (xfree, sorted_by_abbrev); + qsort (sorted_by_abbrev, dwarf2_per_objfile->n_type_units, + sizeof (struct tu_abbrev_offset), sort_tu_by_abbrev_offset); + + abbrev_offset.sect_off = ~(unsigned) 0; + abbrev_table = NULL; + make_cleanup (abbrev_table_free_cleanup, &abbrev_table); + + for (i = 0; i < dwarf2_per_objfile->n_type_units; ++i) + { + const struct tu_abbrev_offset *tu = &sorted_by_abbrev[i]; + + /* Switch to the next abbrev table if necessary. */ + if (abbrev_table == NULL + || tu->abbrev_offset.sect_off != abbrev_offset.sect_off) + { + if (abbrev_table != NULL) + { + abbrev_table_free (abbrev_table); + /* Reset to NULL in case abbrev_table_read_table throws + an error: abbrev_table_free_cleanup will get called. */ + abbrev_table = NULL; + } + abbrev_offset = tu->abbrev_offset; + abbrev_table = + abbrev_table_read_table (&dwarf2_per_objfile->abbrev, + abbrev_offset); + ++tu_stats->nr_uniq_abbrev_tables; + } + + init_cutu_and_read_dies (&tu->sig_type->per_cu, abbrev_table, 0, 0, + build_type_psymtabs_reader, NULL); + } + + /* type_unit_groups can be NULL if there is an error in the debug info. + Just create an empty table so the rest of gdb doesn't have to watch + for this error case. */ + if (dwarf2_per_objfile->type_unit_groups == NULL) + { + dwarf2_per_objfile->type_unit_groups = + allocate_type_unit_groups_table (); + } + + do_cleanups (cleanups); + + if (dwarf2_read_debug) + { + fprintf_unfiltered (gdb_stdlog, "Done building type unit groups:\n"); + fprintf_unfiltered (gdb_stdlog, " %d TUs\n", + dwarf2_per_objfile->n_type_units); + fprintf_unfiltered (gdb_stdlog, " %d uniq abbrev tables\n", + tu_stats->nr_uniq_abbrev_tables); + fprintf_unfiltered (gdb_stdlog, " %d symtabs from stmt_list entries\n", + tu_stats->nr_symtabs); + fprintf_unfiltered (gdb_stdlog, " %d symtab sharers\n", + tu_stats->nr_symtab_sharers); + fprintf_unfiltered (gdb_stdlog, " %d type units without a stmt_list\n", + tu_stats->nr_stmt_less_type_units); + } +} + /* Traversal function for build_type_psymtabs. */ static int @@ -6186,7 +6183,7 @@ build_type_psymtabs (struct objfile *objfile) if (! create_all_type_units (objfile)) return; - build_type_unit_groups (build_type_psymtabs_reader, NULL); + build_type_psymtabs_1 (); /* Now that all TUs have been processed we can fill in the dependencies. */ htab_traverse_noresize (dwarf2_per_objfile->type_unit_groups, @@ -14974,7 +14971,7 @@ abbrev_table_free (struct abbrev_table *abbrev_table) /* Same as abbrev_table_free but as a cleanup. We pass in a pointer to the pointer to the table so that we can set the pointer to NULL when we're done. It also simplifies - build_type_unit_groups. */ + build_type_psymtabs_1. */ static void abbrev_table_free_cleanup (void *table_ptr)