]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/alloc-pool.h
* doc/extend.texi (Common Function Attributes): Clarify
[thirdparty/gcc.git] / gcc / alloc-pool.h
index 404b558e027e08a699fb159e59668d3e00320405..d32081003163872a0bc880f1b751837ea2adaf96 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions to support a pool of allocatable objects
-   Copyright (C) 1997-2015 Free Software Foundation, Inc.
+   Copyright (C) 1997-2019 Free Software Foundation, Inc.
    Contributed by Daniel Berlin <dan@cgsoftware.com>
 
 This file is part of GCC.
@@ -25,6 +25,9 @@ along with GCC; see the file COPYING3.  If not see
 
 extern void dump_alloc_pool_statistics (void);
 
+/* Flag indicates whether memory statistics are gathered any longer.  */
+extern bool after_memory_report;
+
 typedef unsigned long ALLOC_POOL_ID_TYPE;
 
 /* Last used ID.  */
@@ -60,12 +63,16 @@ struct pool_usage: public mem_usage
   {
     char *location_string = loc->to_string ();
 
-    fprintf (stderr, "%-32s%-48s %6li%10li:%5.1f%%%10li%10li:%5.1f%%%12li\n",
-            m_pool_name, location_string, (long)m_instances,
-            (long)m_allocated, get_percent (m_allocated, total.m_allocated),
-            (long)m_peak, (long)m_times,
+    fprintf (stderr, "%-32s%-48s " PRsa(5) PRsa(9) ":%5.1f%%"
+            PRsa(9) PRsa(9) ":%5.1f%%%12" PRIu64 "\n",
+            m_pool_name, location_string,
+            SIZE_AMOUNT (m_instances),
+            SIZE_AMOUNT (m_allocated),
+            get_percent (m_allocated, total.m_allocated),
+            SIZE_AMOUNT (m_peak),
+            SIZE_AMOUNT (m_times),
             get_percent (m_times, total.m_times),
-            (long)m_element_size);
+            (uint64_t)m_element_size);
 
     free (location_string);
   }
@@ -76,17 +83,14 @@ struct pool_usage: public mem_usage
   {
     fprintf (stderr, "%-32s%-48s %6s%11s%16s%17s%12s\n", "Pool name", name,
             "Pools", "Leak", "Peak", "Times", "Elt size");
-    print_dash_line ();
   }
 
   /* Dump footer.  */
   inline void
   dump_footer ()
   {
-    print_dash_line ();
-    fprintf (stderr, "%s%82li%10li\n", "Total", (long)m_instances,
-            (long)m_allocated);
-    print_dash_line ();
+    fprintf (stderr, "%s" PRsa(82) PRsa(10) "\n", "Total",
+            SIZE_AMOUNT (m_instances), SIZE_AMOUNT (m_allocated));
   }
 
   /* Element size.  */
@@ -156,8 +160,10 @@ private:
 
   struct allocation_object
   {
+#if CHECKING_P
     /* The ID of alloc pool which the object was allocated from.  */
     ALLOC_POOL_ID_TYPE id;
+#endif
 
     union
       {
@@ -172,6 +178,7 @@ private:
        int64_t align_i;
       } u;
 
+#if CHECKING_P
     static inline allocation_object*
     get_instance (void *data_ptr)
     {
@@ -179,6 +186,7 @@ private:
                                      - offsetof (allocation_object,
                                                  u.data));
     }
+#endif
 
     static inline void*
     get_data (void *instance_ptr)
@@ -233,8 +241,9 @@ base_pool_allocator <TBlockAllocator>::base_pool_allocator (
                                const char *name, size_t size MEM_STAT_DECL):
   m_name (name), m_id (0), m_elts_per_block (0), m_returned_free_list (NULL),
   m_virgin_free_list (NULL), m_virgin_elts_remaining (0), m_elts_allocated (0),
-  m_elts_free (0), m_blocks_allocated (0), m_block_list (NULL), m_size (size),
-  m_initialized (false), m_location (ALLOC_POOL_ORIGIN, false PASS_MEM_STAT) {}
+  m_elts_free (0), m_blocks_allocated (0), m_block_list (NULL), m_elt_size (0),
+  m_size (size), m_initialized (false),
+  m_location (ALLOC_POOL_ORIGIN, false PASS_MEM_STAT) {}
 
 /* Initialize a pool allocator.  */
 
@@ -248,6 +257,7 @@ base_pool_allocator <TBlockAllocator>::initialize ()
   size_t size = m_size;
 
   gcc_checking_assert (m_name);
+  gcc_checking_assert (m_size);
 
   /* Make size large enough to store the list header.  */
   if (size < sizeof (allocation_pool_list*))
@@ -302,7 +312,7 @@ base_pool_allocator <TBlockAllocator>::release ()
       TBlockAllocator::release (block);
     }
 
-  if (GATHER_STATISTICS)
+  if (GATHER_STATISTICS && !after_memory_report)
     {
       pool_allocator_usage.release_instance_overhead
        (this, (m_elts_allocated - m_elts_free) * m_elt_size);
@@ -363,7 +373,7 @@ base_pool_allocator <TBlockAllocator>::allocate ()
 
          /* Make the block.  */
          block = reinterpret_cast<char *> (TBlockAllocator::allocate ());
-         block_header = (allocation_pool_list*) block;
+         block_header = new (block) allocation_pool_list;
          block += align_eight (sizeof (allocation_pool_list));
 
          /* Throw it on the block list.  */
@@ -388,7 +398,9 @@ base_pool_allocator <TBlockAllocator>::allocate ()
       header->next = NULL;
 
       /* Mark the element to be free.  */
+#if CHECKING_P
       ((allocation_object*) block)->id = 0;
+#endif
       VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS (header,size));
       m_returned_free_list = header;
       m_virgin_free_list += m_elt_size;
@@ -403,7 +415,9 @@ base_pool_allocator <TBlockAllocator>::allocate ()
   m_elts_free--;
 
   /* Set the ID for element.  */
+#if CHECKING_P
   allocation_object::get_instance (header)->id = m_id;
+#endif
   VALGRIND_DISCARD (VALGRIND_MAKE_MEM_UNDEFINED (header, size));
 
   return (void *)(header);
@@ -414,23 +428,28 @@ template <typename TBlockAllocator>
 inline void
 base_pool_allocator <TBlockAllocator>::remove (void *object)
 {
+  int size = m_elt_size - offsetof (allocation_object, u.data);
+
   if (flag_checking)
     {
       gcc_assert (m_initialized);
       gcc_assert (object
-             /* Check if we free more than we allocated, which is Bad (TM).  */
-             && m_elts_free < m_elts_allocated
-             /* Check whether the PTR was allocated from POOL.  */
-             && m_id == allocation_object::get_instance (object)->id);
+                 /* Check if we free more than we allocated.  */
+                 && m_elts_free < m_elts_allocated);
+#if CHECKING_P
+      /* Check whether the PTR was allocated from POOL.  */
+      gcc_assert (m_id == allocation_object::get_instance (object)->id);
+#endif
 
-      int size = m_elt_size - offsetof (allocation_object, u.data);
       memset (object, 0xaf, size);
     }
 
+#if CHECKING_P 
   /* Mark the element to be free.  */
   allocation_object::get_instance (object)->id = 0;
+#endif
 
-  allocation_pool_list *header = (allocation_pool_list*) object;
+  allocation_pool_list *header = new (object) allocation_pool_list;
   header->next = m_returned_free_list;
   m_returned_free_list = header;
   VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS (object, size));
@@ -476,10 +495,23 @@ public:
     m_allocator.release_if_empty ();
   }
 
+
+  /* Allocate memory for instance of type T and call a default constructor.  */
+
   inline T *
   allocate () ATTRIBUTE_MALLOC
   {
-    return ::new (m_allocator.allocate ()) T ();
+    return ::new (m_allocator.allocate ()) T;
+  }
+
+  /* Allocate memory for instance of type T and return void * that
+     could be used in situations where a default constructor is not provided
+     by the class T.  */
+
+  inline void *
+  allocate_raw () ATTRIBUTE_MALLOC
+  {
+    return m_allocator.allocate ();
   }
 
   inline void
@@ -527,7 +559,7 @@ template <typename T>
 inline void *
 operator new (size_t, object_allocator<T> &a)
 {
-  return a.allocate ();
+  return a.allocate_raw ();
 }
 
 /* Hashtable mapping alloc_pool names to descriptors.  */