OSDN Git Service

* config/i386/sse.md (xop_pmacsww, xop_pmacssww, xop_pmacsdd,
[pf3gnuchains/gcc-fork.git] / gcc / ggc-common.c
index d1022a1..76a35f7 100644 (file)
@@ -30,6 +30,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "params.h"
 #include "hosthooks.h"
 #include "hosthooks-def.h"
+#include "plugin.h"
+#include "vec.h"
 
 #ifdef HAVE_SYS_RESOURCE_H
 # include <sys/resource.h>
@@ -86,6 +88,63 @@ ggc_htab_delete (void **slot, void *info)
   return 1;
 }
 
+
+/* This extra vector of dynamically registered root_tab-s is used by
+   ggc_mark_roots and gives the ability to dynamically add new GGC root
+   tables, for instance from some plugins; this vector is on the heap
+   since it is used by GGC internally.  */
+typedef const struct ggc_root_tab *const_ggc_root_tab_t;
+DEF_VEC_P(const_ggc_root_tab_t);
+DEF_VEC_ALLOC_P(const_ggc_root_tab_t, heap);
+static VEC(const_ggc_root_tab_t, heap) *extra_root_vec;
+
+/* Dynamically register a new GGC root table RT. This is useful for
+   plugins. */
+
+void 
+ggc_register_root_tab (const struct ggc_root_tab* rt)
+{
+  if (rt)
+    VEC_safe_push (const_ggc_root_tab_t, heap, extra_root_vec, rt);
+}
+
+/* This extra vector of dynamically registered cache_tab-s is used by
+   ggc_mark_roots and gives the ability to dynamically add new GGC cache
+   tables, for instance from some plugins; this vector is on the heap
+   since it is used by GGC internally.  */
+typedef const struct ggc_cache_tab *const_ggc_cache_tab_t;
+DEF_VEC_P(const_ggc_cache_tab_t);
+DEF_VEC_ALLOC_P(const_ggc_cache_tab_t, heap);
+static VEC(const_ggc_cache_tab_t, heap) *extra_cache_vec;
+
+/* Dynamically register a new GGC cache table CT. This is useful for
+   plugins. */
+
+void
+ggc_register_cache_tab (const struct ggc_cache_tab* ct)
+{
+  if (ct)
+    VEC_safe_push (const_ggc_cache_tab_t, heap, extra_cache_vec, ct);
+}
+
+/* Scan a hash table that has objects which are to be deleted if they are not
+   already marked.  */
+
+static void
+ggc_scan_cache_tab (const_ggc_cache_tab_t ctp)
+{
+  const struct ggc_cache_tab *cti;
+
+  for (cti = ctp; cti->base != NULL; cti++)
+    if (*cti->base)
+      {
+        ggc_set_mark (*cti->base);
+        htab_traverse_noresize (*cti->base, ggc_htab_delete,
+                                CONST_CAST (void *, (const void *)cti));
+        ggc_set_mark ((*cti->base)->entries);
+      }
+}
+
 /* Iterate through all registered roots and mark each element.  */
 
 void
@@ -93,8 +152,9 @@ ggc_mark_roots (void)
 {
   const struct ggc_root_tab *const *rt;
   const struct ggc_root_tab *rti;
+  const_ggc_root_tab_t rtp;
   const struct ggc_cache_tab *const *ct;
-  const struct ggc_cache_tab *cti;
+  const_ggc_cache_tab_t ctp;
   size_t i;
 
   for (rt = gt_ggc_deletable_rtab; *rt; rt++)
@@ -104,7 +164,14 @@ ggc_mark_roots (void)
   for (rt = gt_ggc_rtab; *rt; rt++)
     for (rti = *rt; rti->base != NULL; rti++)
       for (i = 0; i < rti->nelt; i++)
-       (*rti->cb)(*(void **)((char *)rti->base + rti->stride * i));
+       (*rti->cb) (*(void **)((char *)rti->base + rti->stride * i));
+
+  for (i = 0; VEC_iterate (const_ggc_root_tab_t, extra_root_vec, i, rtp); i++)
+    {
+      for (rti = rtp; rti->base != NULL; rti++)
+        for (i = 0; i < rti->nelt; i++)
+          (*rti->cb) (*(void **) ((char *)rti->base + rti->stride * i));
+    }
 
   if (ggc_protect_identifiers)
     ggc_mark_stringpool ();
@@ -112,17 +179,16 @@ ggc_mark_roots (void)
   /* Now scan all hash tables that have objects which are to be deleted if
      they are not already marked.  */
   for (ct = gt_ggc_cache_rtab; *ct; ct++)
-    for (cti = *ct; cti->base != NULL; cti++)
-      if (*cti->base)
-       {
-         ggc_set_mark (*cti->base);
-         htab_traverse_noresize (*cti->base, ggc_htab_delete,
-                                 CONST_CAST (void *, (const void *)cti));
-         ggc_set_mark ((*cti->base)->entries);
-       }
+    ggc_scan_cache_tab (*ct);
+
+  for (i = 0; VEC_iterate (const_ggc_cache_tab_t, extra_cache_vec, i, ctp); i++)
+    ggc_scan_cache_tab (ctp);
 
   if (! ggc_protect_identifiers)
     ggc_purge_stringpool ();
+
+  /* Some plugins may call ggc_set_mark from here.  */
+  invoke_plugin_callbacks (PLUGIN_GGC_MARKING, NULL);
 }
 
 /* Allocate a block of memory, then clear it.  */
@@ -638,7 +704,7 @@ mmap_gt_pch_get_address (size_t size, int fd)
   if (ret == (void *) MAP_FAILED)
     ret = NULL;
   else
-    munmap (ret, size);
+    munmap ((caddr_t) ret, size);
 
   return ret;
 }
@@ -662,7 +728,7 @@ mmap_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
   if (size == 0)
     return -1;
 
-  addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
+  addr = mmap ((caddr_t) base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
               fd, offset);
 
   return addr == base ? 1 : -1;
@@ -845,7 +911,7 @@ loc_descriptor (const char *name, int line, const char *function)
   if (!loc_hash)
     loc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
 
-  slot = (struct loc_descriptor **) htab_find_slot (loc_hash, &loc, 1);
+  slot = (struct loc_descriptor **) htab_find_slot (loc_hash, &loc, INSERT);
   if (*slot)
     return *slot;
   *slot = XCNEW (struct loc_descriptor);
@@ -947,7 +1013,7 @@ cmp_statistic (const void *loc1, const void *loc2)
 }
 
 /* Collect array of the descriptors from hashtable.  */
-struct loc_descriptor **loc_array;
+static struct loc_descriptor **loc_array;
 static int
 add_statistics (void **slot, void *b)
 {