remove gengtype support for param_is use_param, if_marked and splay tree allocators
gcc/ * plugin.c, plugin.def, ggc.h, ggc-common.c, gengtype.h, gengtype.c, gengtype-state.c, gengtype-parse.c, gentype-lex.l, gcc-plugin.h, doc/plugins.texi, doc/gty.texi: Remove support for if_marked and param_is. include/ * hashtab.h, splay-tree.h: Remove GTY markers. From-SVN: r218558
This commit is contained in:
parent
59bce71381
commit
63f5d5b818
16 changed files with 100 additions and 936 deletions
|
@ -1,3 +1,10 @@
|
|||
2014-12-09 Trevor Saunders <tsaunders@mozilla.com>
|
||||
|
||||
* plugin.c, plugin.def, ggc.h, ggc-common.c, gengtype.h, gengtype.c,
|
||||
gengtype-state.c, gengtype-parse.c, gentype-lex.l, gcc-plugin.h,
|
||||
doc/plugins.texi, doc/gty.texi: Remove support for if_marked and
|
||||
param_is.
|
||||
|
||||
2014-12-10 Oleg Endo <olegendo@gcc.gnu.org>
|
||||
|
||||
PR target/53513
|
||||
|
|
|
@ -245,54 +245,6 @@ The @code{desc} and @code{tag} options can also be used for inheritance
|
|||
to denote which subclass an instance is. See @ref{Inheritance and GTY}
|
||||
for more information.
|
||||
|
||||
@findex param_is
|
||||
@findex use_param
|
||||
@item param_is (@var{type})
|
||||
@itemx use_param
|
||||
|
||||
Sometimes it's convenient to define some data structure to work on
|
||||
generic pointers (that is, @code{PTR}) and then use it with a specific
|
||||
type. @code{param_is} specifies the real type pointed to, and
|
||||
@code{use_param} says where in the generic data structure that type
|
||||
should be put.
|
||||
|
||||
For instance, to have a @code{htab_t} that points to trees, one would
|
||||
write the definition of @code{htab_t} like this:
|
||||
@smallexample
|
||||
typedef struct GTY(()) @{
|
||||
@dots{}
|
||||
void ** GTY ((use_param, @dots{})) entries;
|
||||
@dots{}
|
||||
@} htab_t;
|
||||
@end smallexample
|
||||
and then declare variables like this:
|
||||
@smallexample
|
||||
static htab_t GTY ((param_is (union tree_node))) ict;
|
||||
@end smallexample
|
||||
|
||||
@findex param@var{n}_is
|
||||
@findex use_param@var{n}
|
||||
@item param@var{n}_is (@var{type})
|
||||
@itemx use_param@var{n}
|
||||
|
||||
In more complicated cases, the data structure might need to work on
|
||||
several different types, which might not necessarily all be pointers.
|
||||
For this, @code{param1_is} through @code{param9_is} may be used to
|
||||
specify the real type of a field identified by @code{use_param1} through
|
||||
@code{use_param9}.
|
||||
|
||||
@findex use_params
|
||||
@item use_params
|
||||
|
||||
When a structure contains another structure that is parameterized,
|
||||
there's no need to do anything special, the inner structure inherits the
|
||||
parameters of the outer one. When a structure contains a pointer to a
|
||||
parameterized structure, the type machinery won't automatically detect
|
||||
this (it could, it just doesn't yet), so it's necessary to tell it that
|
||||
the pointed-to structure should use the same parameters as the outer
|
||||
structure. This is done by marking the pointer with the
|
||||
@code{use_params} option.
|
||||
|
||||
@findex cache
|
||||
@item cache
|
||||
|
||||
|
@ -309,23 +261,6 @@ garbage collection runs, there's no need to mark anything pointed to
|
|||
by this variable, it can just be set to @code{NULL} instead. This is used
|
||||
to keep a list of free structures around for re-use.
|
||||
|
||||
@findex if_marked
|
||||
@item if_marked ("@var{expression}")
|
||||
|
||||
Suppose you want some kinds of object to be unique, and so you put them
|
||||
in a hash table. If garbage collection marks the hash table, these
|
||||
objects will never be freed, even if the last other reference to them
|
||||
goes away. GGC has special handling to deal with this: if you use the
|
||||
@code{if_marked} option on a global hash table, GGC will call the
|
||||
routine whose name is the parameter to the option on each hash table
|
||||
entry. If the routine returns nonzero, the hash table entry will
|
||||
be marked as usual. If the routine returns zero, the hash table entry
|
||||
will be deleted.
|
||||
|
||||
The routine @code{ggc_marked_p} can be used to determine if an element
|
||||
has been marked already; in fact, the usual case is to use
|
||||
@code{if_marked ("ggc_marked_p")}.
|
||||
|
||||
@findex mark_hook
|
||||
@item mark_hook ("@var{hook-routine-name}")
|
||||
|
||||
|
|
|
@ -185,7 +185,6 @@ enum plugin_event
|
|||
PLUGIN_GGC_MARKING, /* Extend the GGC marking. */
|
||||
PLUGIN_GGC_END, /* Called at end of GGC. */
|
||||
PLUGIN_REGISTER_GGC_ROOTS, /* Register an extra GGC root table. */
|
||||
PLUGIN_REGISTER_GGC_CACHES, /* Register an extra GGC cache table. */
|
||||
PLUGIN_ATTRIBUTES, /* Called during attribute registration */
|
||||
PLUGIN_START_UNIT, /* Called before processing a translation unit. */
|
||||
PLUGIN_PRAGMAS, /* Called during pragma registration. */
|
||||
|
@ -233,10 +232,9 @@ the arguments:
|
|||
@item @code{void *user_data}: Pointer to plugin-specific data.
|
||||
@end itemize
|
||||
|
||||
For the @i{PLUGIN_PASS_MANAGER_SETUP}, @i{PLUGIN_INFO},
|
||||
@i{PLUGIN_REGISTER_GGC_ROOTS} and @i{PLUGIN_REGISTER_GGC_CACHES}
|
||||
pseudo-events the @code{callback} should be null, and the
|
||||
@code{user_data} is specific.
|
||||
For the @i{PLUGIN_PASS_MANAGER_SETUP}, @i{PLUGIN_INFO}, and
|
||||
@i{PLUGIN_REGISTER_GGC_ROOTS} pseudo-events the @code{callback} should be null,
|
||||
and the @code{user_data} is specific.
|
||||
|
||||
When the @i{PLUGIN_PRAGMAS} event is triggered (with a null pointer as
|
||||
data from GCC), plugins may register their own pragmas. Notice that
|
||||
|
@ -321,21 +319,22 @@ done by registering a callback (called with a null @code{gcc_data})
|
|||
for the @code{PLUGIN_GGC_MARKING} event. Such callbacks can call the
|
||||
@code{ggc_set_mark} routine, preferably through the @code{ggc_mark} macro
|
||||
(and conversely, these routines should usually not be used in plugins
|
||||
outside of the @code{PLUGIN_GGC_MARKING} event).
|
||||
outside of the @code{PLUGIN_GGC_MARKING} event). Plugins that wish to hold
|
||||
weak references to gc data may also use this event to drop weak references when
|
||||
the object is about to be collected. The @code{ggc_marked_p} function can be
|
||||
used to tell if an object is marked, or is about to be collected. The
|
||||
@code{gt_clear_cache} overloads which some types define may also be of use in
|
||||
managing weak references.
|
||||
|
||||
Some plugins may need to add extra GGC root tables, e.g. to handle their own
|
||||
@code{GTY}-ed data. This can be done with the @code{PLUGIN_REGISTER_GGC_ROOTS}
|
||||
pseudo-event with a null callback and the extra root table (of type @code{struct
|
||||
ggc_root_tab*}) as @code{user_data}. Plugins that want to use the
|
||||
@code{if_marked} hash table option can add the extra GGC cache tables generated
|
||||
by @code{gengtype} using the @code{PLUGIN_REGISTER_GGC_CACHES} pseudo-event with
|
||||
a null callback and the extra cache table (of type @code{struct ggc_cache_tab*})
|
||||
as @code{user_data}. Running the @code{gengtype -p @var{source-dir}
|
||||
@var{file-list} @var{plugin*.c} ...} utility generates these extra root tables.
|
||||
ggc_root_tab*}) as @code{user_data}. Running the
|
||||
@code{gengtype -p @var{source-dir} @var{file-list} @var{plugin*.c} ...}
|
||||
utility generates these extra root tables.
|
||||
|
||||
You should understand the details of memory management inside GCC
|
||||
before using @code{PLUGIN_GGC_MARKING}, @code{PLUGIN_REGISTER_GGC_ROOTS}
|
||||
or @code{PLUGIN_REGISTER_GGC_CACHES}.
|
||||
before using @code{PLUGIN_GGC_MARKING} or @code{PLUGIN_REGISTER_GGC_ROOTS}.
|
||||
|
||||
|
||||
@node Plugins description
|
||||
|
|
|
@ -150,8 +150,8 @@ extern int get_event_last (void);
|
|||
int get_named_event_id (const char *name, enum insert_option insert);
|
||||
|
||||
/* This is also called without a callback routine for the
|
||||
PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS and
|
||||
PLUGIN_REGISTER_GGC_CACHES pseudo-events, with a specific user_data.
|
||||
PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO and PLUGIN_REGISTER_GGC_ROOTS
|
||||
pseudo-events, with a specific user_data.
|
||||
*/
|
||||
|
||||
extern void register_callback (const char *plugin_name,
|
||||
|
|
|
@ -126,10 +126,6 @@ CXX_KEYWORD inline|public:|private:|protected:|template|operator|friend|static
|
|||
"nested_ptr"/{EOID} { return NESTED_PTR; }
|
||||
"user"/{EOID} { return USER_GTY; }
|
||||
[0-9]+ { return NUM; }
|
||||
"param"[0-9]*"_is"/{EOID} {
|
||||
*yylval = XDUPVAR (const char, yytext, yyleng, yyleng+1);
|
||||
return PARAM_IS;
|
||||
}
|
||||
|
||||
{IWORD}({WS}{IWORD})*/{EOID} |
|
||||
"ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" {
|
||||
|
|
|
@ -538,7 +538,6 @@ nestedptr_optvalue (options_p prev)
|
|||
/* One GTY(()) option:
|
||||
ID str_optvalue_opt
|
||||
| PTR_ALIAS type_optvalue
|
||||
| PARAM_IS type_optvalue
|
||||
| NESTED_PTR nestedptr_optvalue
|
||||
*/
|
||||
static options_p
|
||||
|
@ -553,9 +552,6 @@ option (options_p prev)
|
|||
advance ();
|
||||
return type_optvalue (prev, "ptr_alias");
|
||||
|
||||
case PARAM_IS:
|
||||
return type_optvalue (prev, advance ());
|
||||
|
||||
case NESTED_PTR:
|
||||
advance ();
|
||||
return nestedptr_optvalue (prev);
|
||||
|
|
|
@ -54,8 +54,6 @@ type_lineloc (const_type_p ty)
|
|||
case TYPE_USER_STRUCT:
|
||||
case TYPE_UNDEFINED:
|
||||
return CONST_CAST (struct fileloc*, &ty->u.s.line);
|
||||
case TYPE_PARAM_STRUCT:
|
||||
return CONST_CAST (struct fileloc*, &ty->u.param_struct.line);
|
||||
case TYPE_SCALAR:
|
||||
case TYPE_STRING:
|
||||
case TYPE_POINTER:
|
||||
|
@ -180,7 +178,6 @@ private:
|
|||
void write_state_user_struct_type (type_p current);
|
||||
void write_state_union_type (type_p current);
|
||||
void write_state_lang_struct_type (type_p current);
|
||||
void write_state_param_struct_type (type_p current);
|
||||
void write_state_pointer_type (type_p current);
|
||||
void write_state_array_type (type_p current);
|
||||
void write_state_gc_used (enum gc_used_enum gus);
|
||||
|
@ -190,7 +187,6 @@ private:
|
|||
int write_state_pair_list (pair_p list);
|
||||
void write_state_typedefs (void);
|
||||
void write_state_structures (void);
|
||||
void write_state_param_structs (void);
|
||||
void write_state_variables (void);
|
||||
void write_state_srcdir (void);
|
||||
void write_state_files_list (void);
|
||||
|
@ -635,7 +631,6 @@ state_token_is_name (struct state_token_st *p, const char *name)
|
|||
* We want to serialize :
|
||||
* - typedefs list
|
||||
* - structures list
|
||||
* - param_structs list
|
||||
* - variables list
|
||||
*
|
||||
* So, we have one routine for each kind of data. The main writing
|
||||
|
@ -1023,29 +1018,6 @@ state_writer::write_state_lang_struct_type (type_p current)
|
|||
end_s_expr ();
|
||||
}
|
||||
|
||||
/* Write a parametrized structure GTY type. */
|
||||
void
|
||||
state_writer::write_state_param_struct_type (type_p current)
|
||||
{
|
||||
int i;
|
||||
|
||||
write_any_indent (0);
|
||||
fprintf (state_file, "param_struct ");
|
||||
write_state_common_type_content (current);
|
||||
write_state_type (current->u.param_struct.stru);
|
||||
for (i = 0; i < NUM_PARAM; i++)
|
||||
{
|
||||
if (current->u.param_struct.param[i] != NULL)
|
||||
write_state_type (current->u.param_struct.param[i]);
|
||||
else
|
||||
{
|
||||
write_any_indent (0);
|
||||
fprintf (state_file, "nil ");
|
||||
}
|
||||
}
|
||||
write_state_fileloc (¤t->u.param_struct.line);
|
||||
}
|
||||
|
||||
/* Write a pointer type. */
|
||||
void
|
||||
state_writer::write_state_pointer_type (type_p current)
|
||||
|
@ -1166,9 +1138,6 @@ state_writer::write_state_type (type_p current)
|
|||
case TYPE_LANG_STRUCT:
|
||||
write_state_lang_struct_type (current);
|
||||
break;
|
||||
case TYPE_PARAM_STRUCT:
|
||||
write_state_param_struct_type (current);
|
||||
break;
|
||||
case TYPE_SCALAR:
|
||||
write_state_scalar_type (current);
|
||||
break;
|
||||
|
@ -1225,10 +1194,9 @@ state_writer::write_state_pair_list (pair_p list)
|
|||
|
||||
}
|
||||
|
||||
/* When writing imported linked lists, like typedefs, structures,
|
||||
param_structs, ... we count their length first and write it. These
|
||||
eases the reading, and enables an extra verification on the number
|
||||
of actually read items. */
|
||||
/* When writing imported linked lists, like typedefs, structures, ... we count
|
||||
their length first and write it. This eases the reading, and enables an
|
||||
extra verification on the number of actually read items. */
|
||||
|
||||
/* Write our typedefs. */
|
||||
void
|
||||
|
@ -1270,25 +1238,6 @@ state_writer::write_state_structures (void)
|
|||
printf ("%s wrote %d structures in state\n", progname, nbstruct);
|
||||
}
|
||||
|
||||
/* Write our param_struct-s. */
|
||||
void
|
||||
state_writer::write_state_param_structs (void)
|
||||
{
|
||||
int nbparamstruct = 0;
|
||||
type_p current;
|
||||
|
||||
for (current = param_structs; current != NULL; current = current->next)
|
||||
nbparamstruct++;
|
||||
|
||||
begin_s_expr ("param_structs");
|
||||
fprintf (state_file, "%d", nbparamstruct);
|
||||
|
||||
for (current = param_structs; current != NULL; current = current->next)
|
||||
write_state_type (current);
|
||||
|
||||
end_s_expr ();
|
||||
}
|
||||
|
||||
/* Write our variables. */
|
||||
void
|
||||
state_writer::write_state_variables (void)
|
||||
|
@ -1425,7 +1374,6 @@ write_state (const char *state_path)
|
|||
sw.write_state_files_list ();
|
||||
sw.write_state_structures ();
|
||||
sw.write_state_typedefs ();
|
||||
sw.write_state_param_structs ();
|
||||
sw.write_state_variables ();
|
||||
write_state_trailer ();
|
||||
statelen = ftell (state_file);
|
||||
|
@ -1810,34 +1758,6 @@ read_state_lang_struct_type (type_p type)
|
|||
}
|
||||
|
||||
|
||||
/* Read a param_struct type for GTY parametrized structures. */
|
||||
static void
|
||||
read_state_param_struct_type (type_p type)
|
||||
{
|
||||
int i;
|
||||
struct state_token_st *t0;
|
||||
|
||||
type->kind = TYPE_PARAM_STRUCT;
|
||||
read_state_common_type_content (type);
|
||||
DBGPRINTF ("read param_struct type @%p #%d",
|
||||
(void *) type, type->state_number);
|
||||
read_state_type (&(type->u.param_struct.stru));
|
||||
|
||||
for (i = 0; i < NUM_PARAM; i++)
|
||||
{
|
||||
t0 = peek_state_token (0);
|
||||
if (state_token_is_name (t0, "nil"))
|
||||
{
|
||||
type->u.param_struct.param[i] = NULL;
|
||||
next_state_tokens (1);
|
||||
}
|
||||
else
|
||||
read_state_type (&(type->u.param_struct.param[i]));
|
||||
}
|
||||
read_state_fileloc (&(type->u.param_struct.line));
|
||||
}
|
||||
|
||||
|
||||
/* Read the gc used information. */
|
||||
static void
|
||||
read_state_gc_used (enum gc_used_enum *pgus)
|
||||
|
@ -1939,12 +1859,6 @@ read_state_type (type_p *current)
|
|||
next_state_tokens (1);
|
||||
read_state_lang_struct_type (*current);
|
||||
}
|
||||
else if (state_token_is_name (t0, "param_struct"))
|
||||
{
|
||||
*current = XCNEW (struct type);
|
||||
next_state_tokens (1);
|
||||
read_state_param_struct_type (*current);
|
||||
}
|
||||
else if (state_token_is_name (t0, "pointer"))
|
||||
{
|
||||
*current = XCNEW (struct type);
|
||||
|
@ -2440,58 +2354,6 @@ read_state_structures (type_p *structures)
|
|||
}
|
||||
|
||||
|
||||
/* Read the param_struct-s. */
|
||||
static void
|
||||
read_state_param_structs (type_p *param_structs)
|
||||
{
|
||||
int nbparamstructs = 0;
|
||||
int countparamstructs = 0;
|
||||
type_p head = NULL;
|
||||
type_p previous = NULL;
|
||||
type_p tmp;
|
||||
struct state_token_st *t0 = peek_state_token (0);
|
||||
struct state_token_st *t1 = peek_state_token (1);
|
||||
struct state_token_st *t2 = peek_state_token (2);
|
||||
|
||||
if (state_token_kind (t0) == STOK_LEFTPAR
|
||||
&& state_token_is_name (t1, "!param_structs")
|
||||
&& state_token_kind (t2) == STOK_INTEGER)
|
||||
{
|
||||
nbparamstructs = t2->stok_un.stok_num;
|
||||
next_state_tokens (3);
|
||||
t0 = t1 = t2 = NULL;
|
||||
t0 = peek_state_token (0);
|
||||
while (state_token_kind (t0) != STOK_RIGHTPAR)
|
||||
{
|
||||
tmp = NULL;
|
||||
read_state_type (&tmp);
|
||||
if (head == NULL)
|
||||
{
|
||||
head = tmp;
|
||||
previous = head;
|
||||
}
|
||||
else
|
||||
{
|
||||
previous->next = tmp;
|
||||
previous = tmp;
|
||||
}
|
||||
t0 = peek_state_token (0);
|
||||
countparamstructs++;
|
||||
}
|
||||
next_state_tokens (1);
|
||||
}
|
||||
else
|
||||
fatal_reading_state (t0, "Bad param_structs syntax");
|
||||
t0 = peek_state_token (0);
|
||||
if (countparamstructs != nbparamstructs)
|
||||
fatal_reading_state_printf
|
||||
(t0,
|
||||
"invalid number of param_structs expected %d got %d",
|
||||
nbparamstructs, countparamstructs);
|
||||
*param_structs = head;
|
||||
}
|
||||
|
||||
|
||||
/* Read the variables. */
|
||||
static void
|
||||
read_state_variables (pair_p *variables)
|
||||
|
@ -2738,7 +2600,6 @@ read_state (const char *path)
|
|||
(NULL_STATE_TOKEN, "input error while reading state [%s]",
|
||||
xstrerror (errno));
|
||||
read_state_typedefs (&typedefs);
|
||||
read_state_param_structs (¶m_structs);
|
||||
read_state_variables (&variables);
|
||||
read_state_trailer ();
|
||||
|
||||
|
|
592
gcc/gengtype.c
592
gcc/gengtype.c
File diff suppressed because it is too large
Load diff
|
@ -124,7 +124,6 @@ extern struct fileloc lexer_line;
|
|||
gengtype.c & in gengtype-state.c files. */
|
||||
extern pair_p typedefs;
|
||||
extern type_p structures;
|
||||
extern type_p param_structs;
|
||||
extern pair_p variables;
|
||||
|
||||
/* An enum for distinguishing GGC vs PCH. */
|
||||
|
@ -153,11 +152,6 @@ enum typekind {
|
|||
TYPE_LANG_STRUCT, /* GCC front-end language specific structs.
|
||||
Various languages may have homonymous but
|
||||
different structs. */
|
||||
TYPE_PARAM_STRUCT, /* Type for parametrized structs, e.g. hash_t
|
||||
hash-tables, ... See (param_is, use_param,
|
||||
param1_is, param2_is,... use_param1,
|
||||
use_param_2,... use_params) GTY
|
||||
options. */
|
||||
TYPE_USER_STRUCT /* User defined type. Walkers and markers for
|
||||
this type are assumed to be provided by the
|
||||
user. */
|
||||
|
@ -246,20 +240,16 @@ enum gc_used_enum {
|
|||
GC_POINTED_TO
|
||||
};
|
||||
|
||||
/* We can have at most ten type parameters in parameterized structures. */
|
||||
#define NUM_PARAM 10
|
||||
|
||||
/* Our type structure describes all types handled by gengtype. */
|
||||
struct type {
|
||||
/* Discriminating kind, cannot be TYPE_NONE. */
|
||||
enum typekind kind;
|
||||
|
||||
/* For top-level structs or unions, the 'next' field links the
|
||||
global list 'structures' or 'param_structs'; for lang_structs,
|
||||
their homonymous structs are linked using this 'next' field. The
|
||||
homonymous list starts at the s.lang_struct field of the
|
||||
lang_struct. See the new_structure function for details. This is
|
||||
tricky! */
|
||||
global list 'structures'; for lang_structs, their homonymous structs are
|
||||
linked using this 'next' field. The homonymous list starts at the
|
||||
s.lang_struct field of the lang_struct. See the new_structure function
|
||||
for details. This is tricky! */
|
||||
type_p next;
|
||||
|
||||
/* State number used when writing & reading the persistent state. A
|
||||
|
@ -325,14 +315,6 @@ struct type {
|
|||
const char *len; /* The string if any giving its length. */
|
||||
} a;
|
||||
|
||||
/* When TYPE_PARAM_STRUCT for (param_is, use_param, param1_is,
|
||||
param2_is, ... use_param1, use_param_2, ... use_params) GTY
|
||||
options. */
|
||||
struct {
|
||||
type_p stru; /* The generic GTY-ed type. */
|
||||
type_p param[NUM_PARAM]; /* The actual parameter types. */
|
||||
struct fileloc line; /* The source location. */
|
||||
} param_struct;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -376,8 +358,6 @@ type_fileloc (type_p t)
|
|||
return NULL;
|
||||
if (union_or_struct_p (t))
|
||||
return &t->u.s.line;
|
||||
if (t->kind == TYPE_PARAM_STRUCT)
|
||||
return &t->u.param_struct.line;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -488,7 +468,6 @@ enum gty_token
|
|||
PTR_ALIAS,
|
||||
NESTED_PTR,
|
||||
USER_GTY,
|
||||
PARAM_IS,
|
||||
NUM,
|
||||
SCALAR,
|
||||
ID,
|
||||
|
@ -499,7 +478,7 @@ enum gty_token
|
|||
|
||||
/* print_token assumes that any token >= FIRST_TOKEN_WITH_VALUE may have
|
||||
a meaningful value to be printed. */
|
||||
FIRST_TOKEN_WITH_VALUE = PARAM_IS
|
||||
FIRST_TOKEN_WITH_VALUE = USER_GTY
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ static ggc_statistics *ggc_stats;
|
|||
|
||||
struct traversal_state;
|
||||
|
||||
static int ggc_htab_delete (void **, void *);
|
||||
static int compare_ptr_data (const void *, const void *);
|
||||
static void relocate_ptrs (void *, void *);
|
||||
static void write_pch_globals (const struct ggc_root_tab * const *tab,
|
||||
|
@ -53,22 +52,6 @@ static void write_pch_globals (const struct ggc_root_tab * const *tab,
|
|||
|
||||
/* Maintain global roots that are preserved during GC. */
|
||||
|
||||
/* Process a slot of an htab by deleting it if it has not been marked. */
|
||||
|
||||
static int
|
||||
ggc_htab_delete (void **slot, void *info)
|
||||
{
|
||||
const struct ggc_cache_tab *r = (const struct ggc_cache_tab *) info;
|
||||
|
||||
if (! (*r->marked_p) (*slot))
|
||||
htab_clear_slot (*r->base, slot);
|
||||
else
|
||||
(*r->cb) (*slot);
|
||||
|
||||
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
|
||||
|
@ -86,41 +69,6 @@ ggc_register_root_tab (const struct ggc_root_tab* rt)
|
|||
extra_root_vec.safe_push (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;
|
||||
static vec<const_ggc_cache_tab_t> 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)
|
||||
extra_cache_vec.safe_push (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);
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark all the roots in the table RT. */
|
||||
|
||||
static void
|
||||
|
@ -140,8 +88,6 @@ ggc_mark_roots (void)
|
|||
{
|
||||
const struct ggc_root_tab *const *rt;
|
||||
const_ggc_root_tab_t rtp, rti;
|
||||
const struct ggc_cache_tab *const *ct;
|
||||
const_ggc_cache_tab_t ctp;
|
||||
size_t i;
|
||||
|
||||
for (rt = gt_ggc_deletable_rtab; *rt; rt++)
|
||||
|
@ -157,16 +103,8 @@ ggc_mark_roots (void)
|
|||
if (ggc_protect_identifiers)
|
||||
ggc_mark_stringpool ();
|
||||
|
||||
/* 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++)
|
||||
ggc_scan_cache_tab (*ct);
|
||||
|
||||
gt_clear_caches ();
|
||||
|
||||
FOR_EACH_VEC_ELT (extra_cache_vec, i, ctp)
|
||||
ggc_scan_cache_tab (ctp);
|
||||
|
||||
if (! ggc_protect_identifiers)
|
||||
ggc_purge_stringpool ();
|
||||
|
||||
|
@ -503,11 +441,6 @@ gt_pch_save (FILE *f)
|
|||
for (i = 0; i < rti->nelt; i++)
|
||||
(*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i));
|
||||
|
||||
for (rt = gt_pch_cache_rtab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
for (i = 0; i < rti->nelt; i++)
|
||||
(*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i));
|
||||
|
||||
/* Prepare the objects for writing, determine addresses and such. */
|
||||
state.f = f;
|
||||
state.d = init_ggc_pch ();
|
||||
|
@ -543,7 +476,6 @@ gt_pch_save (FILE *f)
|
|||
|
||||
/* Write out all the global pointers, after translation. */
|
||||
write_pch_globals (gt_ggc_rtab, &state);
|
||||
write_pch_globals (gt_pch_cache_rtab, &state);
|
||||
|
||||
/* Pad the PCH file so that the mmapped area starts on an allocation
|
||||
granularity (usually page) boundary. */
|
||||
|
@ -693,13 +625,6 @@ gt_pch_restore (FILE *f)
|
|||
sizeof (void *), 1, f) != 1)
|
||||
fatal_error ("can%'t read PCH file: %m");
|
||||
|
||||
for (rt = gt_pch_cache_rtab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
for (i = 0; i < rti->nelt; i++)
|
||||
if (fread ((char *)rti->base + rti->stride * i,
|
||||
sizeof (void *), 1, f) != 1)
|
||||
fatal_error ("can%'t read PCH file: %m");
|
||||
|
||||
if (fread (&mmi, sizeof (mmi), 1, f) != 1)
|
||||
fatal_error ("can%'t read PCH file: %m");
|
||||
|
||||
|
|
40
gcc/ggc.h
40
gcc/ggc.h
|
@ -73,23 +73,8 @@ struct ggc_root_tab {
|
|||
/* Pointers to arrays of ggc_root_tab, terminated by NULL. */
|
||||
extern const struct ggc_root_tab * const gt_ggc_rtab[];
|
||||
extern const struct ggc_root_tab * const gt_ggc_deletable_rtab[];
|
||||
extern const struct ggc_root_tab * const gt_pch_cache_rtab[];
|
||||
extern const struct ggc_root_tab * const gt_pch_scalar_rtab[];
|
||||
|
||||
/* Structure for hash table cache marking. */
|
||||
struct htab;
|
||||
struct ggc_cache_tab {
|
||||
struct htab * *base;
|
||||
size_t nelt;
|
||||
size_t stride;
|
||||
gt_pointer_walker cb;
|
||||
gt_pointer_walker pchw;
|
||||
int (*marked_p) (const void *);
|
||||
};
|
||||
#define LAST_GGC_CACHE_TAB { NULL, 0, 0, NULL, NULL, NULL }
|
||||
/* Pointers to arrays of ggc_cache_tab, terminated by NULL. */
|
||||
extern const struct ggc_cache_tab * const gt_ggc_cache_rtab[];
|
||||
|
||||
/* If EXPR is not NULL and previously unmarked, mark it and evaluate
|
||||
to true. Otherwise evaluate to false. */
|
||||
#define ggc_test_and_set_mark(EXPR) \
|
||||
|
@ -251,27 +236,6 @@ ggc_alloc_atomic (size_t s CXX_MEM_STAT_INFO)
|
|||
return ggc_internal_alloc (s PASS_MEM_STAT);
|
||||
}
|
||||
|
||||
extern void *ggc_cleared_alloc_htab_ignore_args (size_t, size_t)
|
||||
ATTRIBUTE_MALLOC;
|
||||
|
||||
extern void *ggc_cleared_alloc_ptr_array_two_args (size_t, size_t)
|
||||
ATTRIBUTE_MALLOC;
|
||||
|
||||
#define htab_create_ggc(SIZE, HASH, EQ, DEL) \
|
||||
htab_create_typed_alloc (SIZE, HASH, EQ, DEL, \
|
||||
ggc_cleared_alloc_htab_ignore_args, \
|
||||
ggc_cleared_alloc_ptr_array_two_args, \
|
||||
ggc_free)
|
||||
|
||||
#define splay_tree_new_ggc(COMPARE, ALLOC_TREE, ALLOC_NODE) \
|
||||
splay_tree_new_typed_alloc (COMPARE, NULL, NULL, &ALLOC_TREE, &ALLOC_NODE, \
|
||||
&ggc_splay_dont_free, NULL)
|
||||
|
||||
extern void *ggc_splay_alloc (int, void *)
|
||||
ATTRIBUTE_MALLOC;
|
||||
|
||||
extern void ggc_splay_dont_free (void *, void *);
|
||||
|
||||
/* Allocate a gc-able string, and fill it with LENGTH bytes from CONTENTS.
|
||||
If LENGTH is -1, then CONTENTS is assumed to be a
|
||||
null-terminated string and the memory sized accordingly. */
|
||||
|
@ -292,10 +256,6 @@ extern void ggc_grow (void);
|
|||
plugins. Does nothing if the passed pointer is NULL. */
|
||||
extern void ggc_register_root_tab (const struct ggc_root_tab *);
|
||||
|
||||
/* Register an additional cache table. This can be useful for some
|
||||
plugins. Does nothing if the passed pointer is NULL. */
|
||||
extern void ggc_register_cache_tab (const struct ggc_cache_tab *);
|
||||
|
||||
/* Read objects previously saved with gt_pch_save from F. */
|
||||
extern void gt_pch_restore (FILE *f);
|
||||
|
||||
|
|
|
@ -420,10 +420,6 @@ register_callback (const char *plugin_name,
|
|||
gcc_assert (!callback);
|
||||
ggc_register_root_tab ((const struct ggc_root_tab*) user_data);
|
||||
break;
|
||||
case PLUGIN_REGISTER_GGC_CACHES:
|
||||
gcc_assert (!callback);
|
||||
ggc_register_cache_tab ((const struct ggc_cache_tab*) user_data);
|
||||
break;
|
||||
case PLUGIN_EVENT_FIRST_DYNAMIC:
|
||||
default:
|
||||
if (event < PLUGIN_EVENT_FIRST_DYNAMIC || event >= event_last)
|
||||
|
@ -546,7 +542,6 @@ invoke_plugin_callbacks_full (int event, void *gcc_data)
|
|||
|
||||
case PLUGIN_PASS_MANAGER_SETUP:
|
||||
case PLUGIN_REGISTER_GGC_ROOTS:
|
||||
case PLUGIN_REGISTER_GGC_CACHES:
|
||||
gcc_assert (false);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,9 +51,6 @@ DEFEVENT (PLUGIN_GGC_END)
|
|||
/* Register an extra GGC root table. */
|
||||
DEFEVENT (PLUGIN_REGISTER_GGC_ROOTS)
|
||||
|
||||
/* Register an extra GGC cache table. */
|
||||
DEFEVENT (PLUGIN_REGISTER_GGC_CACHES)
|
||||
|
||||
/* Called during attribute registration. */
|
||||
DEFEVENT (PLUGIN_ATTRIBUTES)
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2014-12-09 Trevor Saunders <tsaunders@mozilla.com>
|
||||
|
||||
* hashtab.h, splay-tree.h: Remove GTY markers.
|
||||
|
||||
2014-12-08 Mark Wielaard <mjw@redhat.com>
|
||||
|
||||
PR debug/60782
|
||||
|
|
|
@ -39,10 +39,6 @@ extern "C" {
|
|||
|
||||
#include "ansidecl.h"
|
||||
|
||||
#ifndef GTY
|
||||
#define GTY(X)
|
||||
#endif
|
||||
|
||||
/* The type for a hash code. */
|
||||
typedef unsigned int hashval_t;
|
||||
|
||||
|
@ -97,7 +93,7 @@ typedef void (*htab_free_with_arg) (void *, void *);
|
|||
functions mentioned below. The size of this structure is subject to
|
||||
change. */
|
||||
|
||||
struct GTY(()) htab {
|
||||
struct htab {
|
||||
/* Pointer to hash function. */
|
||||
htab_hash hash_f;
|
||||
|
||||
|
@ -108,7 +104,7 @@ struct GTY(()) htab {
|
|||
htab_del del_f;
|
||||
|
||||
/* Table itself. */
|
||||
void ** GTY ((use_param, length ("%h.size"))) entries;
|
||||
void **entries;
|
||||
|
||||
/* Current size (in entries) of the hash table. */
|
||||
size_t size;
|
||||
|
@ -132,7 +128,7 @@ struct GTY(()) htab {
|
|||
htab_free free_f;
|
||||
|
||||
/* Alternate allocate/free functions, which take an extra argument. */
|
||||
void * GTY((skip)) alloc_arg;
|
||||
void *alloc_arg;
|
||||
htab_alloc_with_arg alloc_with_arg_f;
|
||||
htab_free_with_arg free_with_arg_f;
|
||||
|
||||
|
|
|
@ -44,10 +44,6 @@ extern "C" {
|
|||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#ifndef GTY
|
||||
#define GTY(X)
|
||||
#endif
|
||||
|
||||
/* Use typedefs for the key and data types to facilitate changing
|
||||
these types, if necessary. These types should be sufficiently wide
|
||||
that any pointer or scalar can be cast to these types, and then
|
||||
|
@ -86,22 +82,22 @@ typedef void *(*splay_tree_allocate_fn) (int, void *);
|
|||
typedef void (*splay_tree_deallocate_fn) (void *, void *);
|
||||
|
||||
/* The nodes in the splay tree. */
|
||||
struct GTY(()) splay_tree_node_s {
|
||||
struct splay_tree_node_s {
|
||||
/* The key. */
|
||||
splay_tree_key GTY ((use_param1)) key;
|
||||
splay_tree_key key;
|
||||
|
||||
/* The value. */
|
||||
splay_tree_value GTY ((use_param2)) value;
|
||||
splay_tree_value value;
|
||||
|
||||
/* The left and right children, respectively. */
|
||||
splay_tree_node GTY ((use_params)) left;
|
||||
splay_tree_node GTY ((use_params)) right;
|
||||
splay_tree_node left;
|
||||
splay_tree_node right;
|
||||
};
|
||||
|
||||
/* The splay tree itself. */
|
||||
struct GTY(()) splay_tree_s {
|
||||
struct splay_tree_s {
|
||||
/* The root of the tree. */
|
||||
splay_tree_node GTY ((use_params)) root;
|
||||
splay_tree_node root;
|
||||
|
||||
/* The comparision function. */
|
||||
splay_tree_compare_fn comp;
|
||||
|
@ -119,7 +115,7 @@ struct GTY(()) splay_tree_s {
|
|||
splay_tree_deallocate_fn deallocate;
|
||||
|
||||
/* Parameter for allocate/free functions. */
|
||||
void * GTY((skip)) allocate_data;
|
||||
void *allocate_data;
|
||||
};
|
||||
|
||||
typedef struct splay_tree_s *splay_tree;
|
||||
|
|
Loading…
Add table
Reference in a new issue