LCOV - code coverage report
Current view: top level - gcc - stringpool.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 60 74 81.1 %
Date: 2020-03-28 11:57:23 Functions: 16 21 76.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* String pool for GCC.
       2                 :            :    Copyright (C) 2000-2020 Free Software Foundation, Inc.
       3                 :            : 
       4                 :            : This file is part of GCC.
       5                 :            : 
       6                 :            : GCC is free software; you can redistribute it and/or modify it under
       7                 :            : the terms of the GNU General Public License as published by the Free
       8                 :            : Software Foundation; either version 3, or (at your option) any later
       9                 :            : version.
      10                 :            : 
      11                 :            : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12                 :            : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13                 :            : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14                 :            : for more details.
      15                 :            : 
      16                 :            : You should have received a copy of the GNU General Public License
      17                 :            : along with GCC; see the file COPYING3.  If not see
      18                 :            : <http://www.gnu.org/licenses/>.  */
      19                 :            : 
      20                 :            : /* String text, identifier text and identifier node allocator.
      21                 :            :    Identifiers are uniquely stored in a hash table.
      22                 :            : 
      23                 :            :    We use cpplib's hash table implementation.  libiberty's
      24                 :            :    hashtab.c is not used because it requires 100% average space
      25                 :            :    overhead per string, which is unacceptable.  Also, this algorithm
      26                 :            :    is faster.  */
      27                 :            : 
      28                 :            : #include "config.h"
      29                 :            : #include "system.h"
      30                 :            : #include "coretypes.h"
      31                 :            : #include "tree.h"
      32                 :            : 
      33                 :            : struct ht *ident_hash;
      34                 :            : 
      35                 :            : static hashnode alloc_node (cpp_hash_table *);
      36                 :            : static int mark_ident (struct cpp_reader *, hashnode, const void *);
      37                 :            : 
      38                 :            : static void *
      39                 :  881393000 : stringpool_ggc_alloc (size_t x)
      40                 :            : {
      41                 :  881393000 :   return ggc_alloc_atomic (x);
      42                 :            : }
      43                 :            : 
      44                 :            : /* Initialize the string pool.  */
      45                 :            : void
      46                 :     200540 : init_stringpool (void)
      47                 :            : {
      48                 :            :   /* Clean up if we're called more than once.
      49                 :            :      (We can't make this idempotent since identifiers contain state) */
      50                 :     200540 :   if (ident_hash)
      51                 :        818 :     ht_destroy (ident_hash);
      52                 :            : 
      53                 :            :   /* Create with 16K (2^14) entries.  */
      54                 :     200540 :   ident_hash = ht_create (14);
      55                 :     200540 :   ident_hash->alloc_node = alloc_node;
      56                 :     200540 :   ident_hash->alloc_subobject = stringpool_ggc_alloc;
      57                 :     200540 : }
      58                 :            : 
      59                 :            : /* Allocate a hash node.  */
      60                 :            : static hashnode
      61                 :  788294000 : alloc_node (cpp_hash_table *table ATTRIBUTE_UNUSED)
      62                 :            : {
      63                 :  788294000 :   return GCC_IDENT_TO_HT_IDENT (make_node (IDENTIFIER_NODE));
      64                 :            : }
      65                 :            : 
      66                 :            : /* Allocate and return a string constant of length LENGTH, containing
      67                 :            :    CONTENTS.  If LENGTH is -1, CONTENTS is assumed to be a
      68                 :            :    nul-terminated string, and the length is calculated using strlen.  */
      69                 :            : 
      70                 :            : const char *
      71                 :  112549000 : ggc_alloc_string (const char *contents, int length MEM_STAT_DECL)
      72                 :            : {
      73                 :  112549000 :   if (length == -1)
      74                 :  112420000 :     length = strlen (contents);
      75                 :            : 
      76                 :  112549000 :   if (!length)
      77                 :            :     return "";
      78                 :            : 
      79                 :  112401000 :   char *result = (char *) ggc_alloc_atomic (length + 1);
      80                 :  112401000 :   memcpy (result, contents, length);
      81                 :  112401000 :   result[length] = '\0';
      82                 :            : 
      83                 :  112401000 :   return (const char *) result;
      84                 :            : }
      85                 :            : 
      86                 :            : /* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string).
      87                 :            :    If an identifier with that name has previously been referred to,
      88                 :            :    the same node is returned this time.  */
      89                 :            : 
      90                 :            : #undef get_identifier
      91                 :            : 
      92                 :            : tree
      93                 :  757838000 : get_identifier (const char *text)
      94                 :            : {
      95                 :  757838000 :   hashnode ht_node = ht_lookup (ident_hash,
      96                 :            :                                 (const unsigned char *) text,
      97                 :            :                                 strlen (text), HT_ALLOC);
      98                 :            : 
      99                 :            :   /* ht_node can't be NULL here.  */
     100                 :  757838000 :   return HT_IDENT_TO_GCC_IDENT (ht_node);
     101                 :            : }
     102                 :            : 
     103                 :            : /* Identical to get_identifier, except that the length is assumed
     104                 :            :    known.  */
     105                 :            : 
     106                 :            : tree
     107                 :  906338000 : get_identifier_with_length (const char *text, size_t length)
     108                 :            : {
     109                 :  906338000 :   hashnode ht_node = ht_lookup (ident_hash,
     110                 :            :                                 (const unsigned char *) text,
     111                 :            :                                 length, HT_ALLOC);
     112                 :            : 
     113                 :            :   /* ht_node can't be NULL here.  */
     114                 :  906338000 :   return HT_IDENT_TO_GCC_IDENT (ht_node);
     115                 :            : }
     116                 :            : 
     117                 :            : /* If an identifier with the name TEXT (a null-terminated string) has
     118                 :            :    previously been referred to, return that node; otherwise return
     119                 :            :    NULL_TREE.  */
     120                 :            : 
     121                 :            : tree
     122                 :  192584000 : maybe_get_identifier (const char *text)
     123                 :            : {
     124                 :  192584000 :   hashnode ht_node;
     125                 :            : 
     126                 :  192584000 :   ht_node = ht_lookup (ident_hash, (const unsigned char *) text,
     127                 :            :                        strlen (text), HT_NO_INSERT);
     128                 :  192584000 :   if (ht_node)
     129                 :   25119400 :     return HT_IDENT_TO_GCC_IDENT (ht_node);
     130                 :            : 
     131                 :            :   return NULL_TREE;
     132                 :            : }
     133                 :            : 
     134                 :            : /* Report some basic statistics about the string pool.  */
     135                 :            : 
     136                 :            : void
     137                 :          0 : stringpool_statistics (void)
     138                 :            : {
     139                 :          0 :   ht_dump_statistics (ident_hash);
     140                 :          0 : }
     141                 :            : 
     142                 :            : /* Mark an identifier for GC.  */
     143                 :            : 
     144                 :            : static int
     145                 :  462484000 : mark_ident (struct cpp_reader *pfile ATTRIBUTE_UNUSED, hashnode h,
     146                 :            :             const void *v ATTRIBUTE_UNUSED)
     147                 :            : {
     148                 :  462484000 :   gt_ggc_m_9tree_node (HT_IDENT_TO_GCC_IDENT (h));
     149                 :  462484000 :   return 1;
     150                 :            : }
     151                 :            : 
     152                 :            : /* Return true if an identifier should be removed from the table.  */
     153                 :            : 
     154                 :            : static int
     155                 :  236572000 : maybe_delete_ident (struct cpp_reader *pfile ATTRIBUTE_UNUSED, hashnode h,
     156                 :            :                     const void *v ATTRIBUTE_UNUSED)
     157                 :            : {
     158                 :  236572000 :   return !ggc_marked_p (HT_IDENT_TO_GCC_IDENT (h));
     159                 :            : }
     160                 :            : 
     161                 :            : /* Mark the trees hanging off the identifier node for GGC.  These are
     162                 :            :    handled specially (not using gengtype) because identifiers are only
     163                 :            :    roots during one part of compilation.  */
     164                 :            : 
     165                 :            : void
     166                 :      55380 : ggc_mark_stringpool (void)
     167                 :            : {
     168                 :      55380 :   ht_forall (ident_hash, mark_ident, NULL);
     169                 :      55380 : }
     170                 :            : 
     171                 :            : /* Purge the identifier hash of identifiers which are no longer
     172                 :            :    referenced.  */
     173                 :            : 
     174                 :            : void
     175                 :     358881 : ggc_purge_stringpool (void)
     176                 :            : {
     177                 :     358881 :   ht_purge (ident_hash, maybe_delete_ident, NULL);
     178                 :     358881 : }
     179                 :            : 
     180                 :            : /* Pointer-walking routine for strings (not very interesting, since
     181                 :            :    strings don't contain pointers).  */
     182                 :            : 
     183                 :            : void
     184                 :    1280100 : gt_pch_p_S (void *obj ATTRIBUTE_UNUSED, void *x ATTRIBUTE_UNUSED,
     185                 :            :             gt_pointer_operator op ATTRIBUTE_UNUSED,
     186                 :            :             void *cookie ATTRIBUTE_UNUSED)
     187                 :            : {
     188                 :    1280100 : }
     189                 :            : 
     190                 :            : /* PCH pointer-walking routine for strings.  */
     191                 :            : 
     192                 :            : void
     193                 :    1727630 : gt_pch_n_S (const void *x)
     194                 :            : {
     195                 :    1727630 :   gt_pch_note_object (CONST_CAST (void *, x), CONST_CAST (void *, x),
     196                 :            :                       &gt_pch_p_S);
     197                 :    1727630 : }
     198                 :            : 
     199                 :            : 
     200                 :            : /* User-callable entry point for marking string X.  */
     201                 :            : 
     202                 :            : void
     203                 :          0 : gt_pch_nx (const char *& x)
     204                 :            : {
     205                 :          0 :   gt_pch_n_S (x);
     206                 :          0 : }
     207                 :            : 
     208                 :            : void
     209                 :          0 : gt_pch_nx (unsigned char *& x)
     210                 :            : {
     211                 :          0 :   gt_pch_n_S (x);
     212                 :          0 : }
     213                 :            : 
     214                 :            : void
     215                 :          0 : gt_pch_nx (unsigned char& x ATTRIBUTE_UNUSED)
     216                 :            : {
     217                 :          0 : }
     218                 :            : 
     219                 :            : void
     220                 :          0 : gt_pch_nx (unsigned char *x, gt_pointer_operator op, void *cookie)
     221                 :            : {
     222                 :          0 :   op (x, cookie);
     223                 :          0 : }
     224                 :            : 
     225                 :            : /* Handle saving and restoring the string pool for PCH.  */
     226                 :            : 
     227                 :            : /* SPD is saved in the PCH file and holds the information needed
     228                 :            :    to restore the string pool.  */
     229                 :            : 
     230                 :            : struct GTY(()) string_pool_data {
     231                 :            :   ht_identifier_ptr *
     232                 :            :     GTY((length ("%h.nslots"),
     233                 :            :          nested_ptr (union tree_node, "%h ? GCC_IDENT_TO_HT_IDENT (%h) : NULL",
     234                 :            :                      "%h ? HT_IDENT_TO_GCC_IDENT (%h) : NULL")))
     235                 :            :     entries;
     236                 :            :   unsigned int nslots;
     237                 :            :   unsigned int nelements;
     238                 :            : };
     239                 :            : 
     240                 :            : static GTY(()) struct string_pool_data * spd;
     241                 :            : 
     242                 :            : /* Save the stringpool data in SPD.  */
     243                 :            : 
     244                 :            : void
     245                 :        346 : gt_pch_save_stringpool (void)
     246                 :            : {
     247                 :        346 :   spd = ggc_alloc<string_pool_data> ();
     248                 :        346 :   spd->nslots = ident_hash->nslots;
     249                 :        346 :   spd->nelements = ident_hash->nelements;
     250                 :        346 :   spd->entries = ggc_vec_alloc<ht_identifier_ptr> (spd->nslots);
     251                 :        346 :   memcpy (spd->entries, ident_hash->entries,
     252                 :        346 :           spd->nslots * sizeof (spd->entries[0]));
     253                 :        346 : }
     254                 :            : 
     255                 :            : /* Return the stringpool to its state before gt_pch_save_stringpool
     256                 :            :    was called.  */
     257                 :            : 
     258                 :            : void
     259                 :        346 : gt_pch_fixup_stringpool (void)
     260                 :            : {
     261                 :        346 : }
     262                 :            : 
     263                 :            : /* A PCH file has been restored, which loaded SPD; fill the real hash table
     264                 :            :    from SPD.  */
     265                 :            : 
     266                 :            : void
     267                 :       6399 : gt_pch_restore_stringpool (void)
     268                 :            : {
     269                 :       6399 :   ht_load (ident_hash, spd->entries, spd->nslots, spd->nelements, false);
     270                 :       6399 :   spd = NULL;
     271                 :       6399 : }
     272                 :            : 
     273                 :            : #include "gt-stringpool.h"

Generated by: LCOV version 1.0

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto --enable-host-shared. GCC test suite is run with the built compiler.