#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>
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 a heap one
+ [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)
+ return;
+ if (!extra_root_vec)
+ {
+ int vlen = 32;
+ extra_root_vec = VEC_alloc (const_ggc_root_tab_t, heap, vlen);
+ }
+ VEC_safe_push (const_ggc_root_tab_t, heap, extra_root_vec, rt);
+}
+
+
/* Iterate through all registered roots and mark each element. */
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));
+
+ if (extra_root_vec
+ && VEC_length(const_ggc_root_tab_t,extra_root_vec) > 0)
+ {
+ const_ggc_root_tab_t rtp = NULL;
+ 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 ();
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. */
if (ret == (void *) MAP_FAILED)
ret = NULL;
else
- munmap (ret, size);
+ munmap ((caddr_t) ret, size);
return ret;
}
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;
static hashval_t
hash_descriptor (const void *p)
{
- const struct loc_descriptor *const d = p;
+ const struct loc_descriptor *const d = (const struct loc_descriptor *) p;
return htab_hash_pointer (d->function) | d->line;
}
static int
eq_descriptor (const void *p1, const void *p2)
{
- const struct loc_descriptor *const d = p1;
- const struct loc_descriptor *const d2 = p2;
+ const struct loc_descriptor *const d = (const struct loc_descriptor *) p1;
+ const struct loc_descriptor *const d2 = (const struct loc_descriptor *) p2;
return (d->file == d2->file && d->line == d2->line
&& d->function == d2->function);
static hashval_t
hash_ptr (const void *p)
{
- const struct ptr_hash_entry *const d = p;
+ const struct ptr_hash_entry *const d = (const struct ptr_hash_entry *) p;
return htab_hash_pointer (d->ptr);
}
static int
eq_ptr (const void *p1, const void *p2)
{
- const struct ptr_hash_entry *const p = p1;
+ const struct ptr_hash_entry *const p = (const struct ptr_hash_entry *) p1;
return (p->ptr == p2);
}
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 = xcalloc (sizeof (**slot), 1);
+ *slot = XCNEW (struct loc_descriptor);
(*slot)->file = name;
(*slot)->line = line;
(*slot)->function = function;
static int
ggc_prune_ptr (void **slot, void *b ATTRIBUTE_UNUSED)
{
- struct ptr_hash_entry *p = *slot;
+ struct ptr_hash_entry *p = (struct ptr_hash_entry *) *slot;
if (!ggc_marked_p (p->ptr))
{
p->loc->collected += p->size;
{
PTR *slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr),
NO_INSERT);
- struct ptr_hash_entry *p = *slot;
+ struct ptr_hash_entry *p = (struct ptr_hash_entry *) *slot;
p->loc->freed += p->size;
htab_clear_slot (ptr_hash, slot);
free (p);
static int
final_cmp_statistic (const void *loc1, const void *loc2)
{
- struct loc_descriptor *l1 = *(struct loc_descriptor **) loc1;
- struct loc_descriptor *l2 = *(struct loc_descriptor **) loc2;
+ const struct loc_descriptor *const l1 =
+ *(const struct loc_descriptor *const *) loc1;
+ const struct loc_descriptor *const l2 =
+ *(const struct loc_descriptor *const *) loc2;
long diff;
diff = ((long)(l1->allocated + l1->overhead - l1->freed) -
(l2->allocated + l2->overhead - l2->freed));
static int
cmp_statistic (const void *loc1, const void *loc2)
{
- struct loc_descriptor *l1 = *(struct loc_descriptor **) loc1;
- struct loc_descriptor *l2 = *(struct loc_descriptor **) loc2;
+ const struct loc_descriptor *const l1 =
+ *(const struct loc_descriptor *const *) loc1;
+ const struct loc_descriptor *const l2 =
+ *(const struct loc_descriptor *const *) loc2;
long diff;
diff = ((long)(l1->allocated + l1->overhead - l1->freed - l1->collected) -
}
/* 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)
{
ggc_force_collect = true;
ggc_collect ();
- loc_array = xcalloc (sizeof (*loc_array), loc_hash->n_elements);
+ loc_array = XCNEWVEC (struct loc_descriptor *, loc_hash->n_elements);
fprintf (stderr, "-------------------------------------------------------\n");
fprintf (stderr, "\n%-48s %10s %10s %10s %10s %10s\n",
"source location", "Garbage", "Freed", "Leak", "Overhead", "Times");