This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] GC for objective C (take 2)
On Mon, Apr 10, 2000 at 10:58:12AM -0700, Richard Henderson wrote:
> On Mon, Apr 10, 2000 at 06:33:25PM +0100, grahams wrote:
> > If a proper tree node objc_one_node is created and
> > registered as a gcc-root then all uses of (tree)1
> > can be replaced by objc_one_node.
>
> This is the correct solution, IMO.
>
Here is an updated patch:
Besides introducing objc_ellipsis_node it also changes most of the
objc-act.c's static tree variables into objc_global_trees, so it can be
registered with GC all at once (like it is done in c-common).
With this patch gcc bootstrapped and passed objc testsuite with 3 failures
(before it did not bootstrap and did not pass any testsuite tests for ages).
I'll send another patch to fix the remaining 3 failures shortly.
Ok to commit?
2000-04-11 Jakub Jelinek <jakub@redhat.com>
* objc/objc-act.c: Include ggc.h.
(objc_tree_index, objc_global_trees): Convert most of the
static tree variables into a static array with previous names
as defines.
(objc_ellipsis_node): New variable.
(lang_init): Call objc_act_parse_init and c_parse_init.
Create objc_ellipsis_node.
(build_selector_translation_table): Use objc_ellipsis_node instead
of (tree)1.
(hack_method_prototype): Likewise.
(get_arg_type_list): Likewise.
(start_method_def): Likewise.
(continue_method_def): Likewise.
(gen_method_decl): Likewise.
(ggc_mark_imp_list): New function.
(ggc_mark_hash_table): New function.
(objc_act_parse_init): New function.
* objc/objc-act.h (objc_ellipsis_node): Add extern variable.
* c-parse.in (c_parse_init): For objc add roots of objc specific
local tree variables.
* objc/objc-parse.y: Rebuilt.
* objc/objc-parse.c: Rebuilt.
(opt_parm_list): Use objc_ellipsis_node instead of (tree)1.
* Object.m (strlen): Provide prototype on all 64bit platforms,
not only alpha.
* sarray.c (memcpy): Likewise.
* encoding.c (objc_layout_finish_structure): Don't use
ROUND_TYPE_ALIGN on sparc.
--- gcc/objc/objc-act.c.jj Mon Mar 27 12:20:07 2000
+++ gcc/objc/objc-act.c Tue Apr 11 09:04:11 2000
@@ -51,6 +51,7 @@ Boston, MA 02111-1307, USA. */
#include "function.h"
#include "output.h"
#include "toplev.h"
+#include "ggc.h"
#if USE_CPPLIB
#include "cpplib.h"
@@ -134,12 +135,6 @@ static struct obstack util_obstack;
so we can free the whole contents. */
char *util_firstobj;
-/* List of classes with list of their static instances. */
-static tree objc_static_instances = NULL_TREE;
-
-/* The declaration of the array administrating the static instances. */
-static tree static_instances_decl = NULL_TREE;
-
/* for encode_method_def */
#include "rtl.h"
#include "c-parse.h"
@@ -345,6 +340,7 @@ static void generate_classref_translatio
static void handle_class_ref PARAMS ((tree));
static void generate_struct_by_value_array PARAMS ((void))
ATTRIBUTE_NORETURN;
+static void objc_act_parse_init PARAMS ((void));
/*** Private Interface (data) ***/
@@ -388,16 +384,102 @@ static const char *TAG_EXECCLASS;
#define TYPED_OBJECT(type) \
(TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
-/* Some commonly used instances of "identifier_node". */
+tree objc_ellipsis_node;
-static tree self_id, ucmd_id;
-static tree unused_list;
+enum objc_tree_index
+{
+ OCTI_STATIC_NST,
+ OCTI_STATIC_NST_DECL,
+ OCTI_SELF_ID,
+ OCTI_UCMD_ID,
+ OCTI_UNUSED_LIST,
+ OCTI_SELF_DECL,
+ OCTI_UMSG_DECL,
+ OCTI_UMSG_SUPER_DECL,
+ OCTI_GET_CLASS_DECL,
+ OCTI_GET_MCLASS_DECL,
+ OCTI_SUPER_TYPE,
+ OCTI_SEL_TYPE,
+ OCTI_ID_TYPE,
+ OCTI_CLS_TYPE,
+ OCTI_NST_TYPE,
+ OCTI_PROTO_TYPE,
+
+ OCTI_CLS_CHAIN,
+ OCTI_ALIAS_CHAIN,
+ OCTI_INTF_CHAIN,
+ OCTI_PROTO_CHAIN,
+ OCTI_CLS_REF_CHAIN,
+ OCTI_SEL_REF_CHAIN,
+ OCTI_CLS_NAMES_CHAIN,
+ OCTI_METH_VAR_NAMES_CHAIN,
+ OCTI_METH_VAR_TYPES_CHAIN,
+
+ OCTI_SYMBOLS_DECL,
+ OCTI_NST_VAR_DECL,
+ OCTI_CLS_VAR_DECL,
+ OCTI_NST_METH_DECL,
+ OCTI_CLS_METH_DECL,
+ OCTI_CLS_DECL,
+ OCTI_MCLS_DECL,
+ OCTI_SEL_TABLE_DECL,
+ OCTI_MODULES_DECL,
+ OCTI_STRG_DECL,
+
+ OCTI_IMPL_CTX,
+ OCTI_IMPL_TEMPL,
+
+ OCTI_CLS_TEMPL,
+ OCTI_CAT_TEMPL,
+ OCTI_UPRIV_REC,
+ OCTI_PROTO_TEMPL,
+ OCTI_SEL_TEMPL,
+ OCTI_UCLS_SUPER_REF,
+ OCTI_UUCLS_SUPER_REF,
+ OCTI_METH_TEMPL,
+ OCTI_IVAR_TEMPL,
+ OCTI_SYMTAB_TEMPL,
+ OCTI_MODULE_TEMPL,
+ OCTI_SUPER_TEMPL,
+ OCTI_OBJ_REF,
+ OCTI_OBJ_ID,
+ OCTI_CLS_ID,
+ OCTI_ID_ID,
+ OCTI_CNST_STR_ID,
+ OCTI_CNST_STR_TYPE,
+ OCTI_SUPER_DECL,
+ OCTI_METH_CTX,
-static tree self_decl, umsg_decl, umsg_super_decl;
-static tree objc_get_class_decl, objc_get_meta_class_decl;
+ OCTI_MAX
+};
-static tree super_type, selector_type, id_type, objc_class_type;
-static tree instance_type, protocol_type;
+static tree objc_global_trees[OCTI_MAX];
+
+/* List of classes with list of their static instances. */
+#define objc_static_instances objc_global_trees[OCTI_STATIC_NST]
+
+/* The declaration of the array administrating the static instances. */
+#define static_instances_decl objc_global_trees[OCTI_STATIC_NST_DECL]
+
+/* Some commonly used instances of "identifier_node". */
+
+#define self_id objc_global_trees[OCTI_SELF_ID]
+#define ucmd_id objc_global_trees[OCTI_UCMD_ID]
+#define unused_list objc_global_trees[OCTI_UNUSED_LIST]
+
+#define self_decl objc_global_trees[OCTI_SELF_DECL]
+#define umsg_decl objc_global_trees[OCTI_UMSG_DECL]
+#define umsg_super_decl objc_global_trees[OCTI_UMSG_SUPER_DECL]
+#define objc_get_class_decl objc_global_trees[OCTI_GET_CLASS_DECL]
+#define objc_get_meta_class_decl \
+ objc_global_trees[OCTI_GET_MCLASS_DECL]
+
+#define super_type objc_global_trees[OCTI_SUPER_TYPE]
+#define selector_type objc_global_trees[OCTI_SEL_TYPE]
+#define id_type objc_global_trees[OCTI_ID_TYPE]
+#define objc_class_type objc_global_trees[OCTI_CLS_TYPE]
+#define instance_type objc_global_trees[OCTI_NST_TYPE]
+#define protocol_type objc_global_trees[OCTI_PROTO_TYPE]
/* Type checking macros. */
@@ -408,22 +490,22 @@ static tree instance_type, protocol_type
#define IS_SUPER(TYPE) \
(super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
-static tree class_chain = NULL_TREE;
-static tree alias_chain = NULL_TREE;
-static tree interface_chain = NULL_TREE;
-static tree protocol_chain = NULL_TREE;
+#define class_chain objc_global_trees[OCTI_CLS_CHAIN]
+#define alias_chain objc_global_trees[OCTI_ALIAS_CHAIN]
+#define interface_chain objc_global_trees[OCTI_INTF_CHAIN]
+#define protocol_chain objc_global_trees[OCTI_PROTO_CHAIN]
/* Chains to manage selectors that are referenced and defined in the
module. */
-static tree cls_ref_chain = NULL_TREE; /* Classes referenced. */
-static tree sel_ref_chain = NULL_TREE; /* Selectors referenced. */
+#define cls_ref_chain objc_global_trees[OCTI_CLS_REF_CHAIN] /* Classes referenced. */
+#define sel_ref_chain objc_global_trees[OCTI_SEL_REF_CHAIN] /* Selectors referenced. */
/* Chains to manage uniquing of strings. */
-static tree class_names_chain = NULL_TREE;
-static tree meth_var_names_chain = NULL_TREE;
-static tree meth_var_types_chain = NULL_TREE;
+#define class_names_chain objc_global_trees[OCTI_CLS_NAMES_CHAIN]
+#define meth_var_names_chain objc_global_trees[OCTI_METH_VAR_NAMES_CHAIN]
+#define meth_var_types_chain objc_global_trees[OCTI_METH_VAR_TYPES_CHAIN]
/* Hash tables to manage the global pool of method prototypes. */
@@ -432,21 +514,24 @@ static hash *cls_method_hash_list = 0;
/* Backend data declarations. */
-static tree UOBJC_SYMBOLS_decl;
-static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl;
-static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl;
-static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl;
-static tree UOBJC_SELECTOR_TABLE_decl;
-static tree UOBJC_MODULES_decl;
-static tree UOBJC_STRINGS_decl;
+#define UOBJC_SYMBOLS_decl objc_global_trees[OCTI_SYMBOLS_DECL]
+#define UOBJC_INSTANCE_VARIABLES_decl objc_global_trees[OCTI_NST_VAR_DECL]
+#define UOBJC_CLASS_VARIABLES_decl objc_global_trees[OCTI_CLS_VAR_DECL]
+#define UOBJC_INSTANCE_METHODS_decl objc_global_trees[OCTI_NST_METH_DECL]
+#define UOBJC_CLASS_METHODS_decl objc_global_trees[OCTI_CLS_METH_DECL]
+#define UOBJC_CLASS_decl objc_global_trees[OCTI_CLS_DECL]
+#define UOBJC_METACLASS_decl objc_global_trees[OCTI_MCLS_DECL]
+#define UOBJC_SELECTOR_TABLE_decl objc_global_trees[OCTI_SEL_TABLE_DECL]
+#define UOBJC_MODULES_decl objc_global_trees[OCTI_MODULES_DECL]
+#define UOBJC_STRINGS_decl objc_global_trees[OCTI_STRG_DECL]
/* The following are used when compiling a class implementation.
implementation_template will normally be an interface, however if
none exists this will be equal to implementation_context...it is
set in start_class. */
-static tree implementation_context = NULL_TREE;
-static tree implementation_template = NULL_TREE;
+#define implementation_context objc_global_trees[OCTI_IMPL_CTX]
+#define implementation_template objc_global_trees[OCTI_IMPL_TEMPL]
struct imp_entry
{
@@ -463,20 +548,29 @@ static struct imp_entry *imp_list = 0;
static int imp_count = 0; /* `@implementation' */
static int cat_count = 0; /* `@category' */
-static tree objc_class_template, objc_category_template, uprivate_record;
-static tree objc_protocol_template, objc_selector_template;
-static tree ucls_super_ref, uucls_super_ref;
-
-static tree objc_method_template, objc_ivar_template;
-static tree objc_symtab_template, objc_module_template;
-static tree objc_super_template, objc_object_reference;
-
-static tree objc_object_id, objc_class_id, objc_id_id;
-static tree constant_string_id;
-static tree constant_string_type;
-static tree UOBJC_SUPER_decl;
+#define objc_class_template objc_global_trees[OCTI_CLS_TEMPL]
+#define objc_category_template objc_global_trees[OCTI_CAT_TEMPL]
+#define uprivate_record objc_global_trees[OCTI_UPRIV_REC]
+#define objc_protocol_template objc_global_trees[OCTI_PROTO_TEMPL]
+#define objc_selector_template objc_global_trees[OCTI_SEL_TEMPL]
+#define ucls_super_ref objc_global_trees[OCTI_UCLS_SUPER_REF]
+#define uucls_super_ref objc_global_trees[OCTI_UUCLS_SUPER_REF]
+
+#define objc_method_template objc_global_trees[OCTI_METH_TEMPL]
+#define objc_ivar_template objc_global_trees[OCTI_IVAR_TEMPL]
+#define objc_symtab_template objc_global_trees[OCTI_SYMTAB_TEMPL]
+#define objc_module_template objc_global_trees[OCTI_MODULE_TEMPL]
+#define objc_super_template objc_global_trees[OCTI_SUPER_TEMPL]
+#define objc_object_reference objc_global_trees[OCTI_OBJ_REF]
+
+#define objc_object_id objc_global_trees[OCTI_OBJ_ID]
+#define objc_class_id objc_global_trees[OCTI_CLS_ID]
+#define objc_id_id objc_global_trees[OCTI_ID_ID]
+#define constant_string_id objc_global_trees[OCTI_CNST_STR_ID]
+#define constant_string_type objc_global_trees[OCTI_CNST_STR_TYPE]
+#define UOBJC_SUPER_decl objc_global_trees[OCTI_SUPER_DECL]
-static tree method_context = NULL_TREE;
+#define method_context objc_global_trees[OCTI_METH_CTX]
static int method_slot = 0; /* Used by start_method_def, */
#define BUFSIZE 1024
@@ -656,11 +750,16 @@ lang_init ()
flag_typed_selectors = 1;
}
+ objc_ellipsis_node = make_node (ERROR_MARK);
+
if (doing_objc_thang)
init_objc ();
if (print_struct_values)
generate_struct_by_value_array ();
+
+ objc_act_parse_init ();
+ c_parse_init ();
}
static void
@@ -2109,7 +2208,7 @@ build_selector_translation_table ()
TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
/* NULL terminate the list and fix the decl for output. */
initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
- DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1;
+ DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
nreverse (initlist));
finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
@@ -3013,7 +3112,7 @@ hack_method_prototype (nst_methods, tmp_
start_method_def (nst_methods);
TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
- if (METHOD_ADD_ARGS (nst_methods) == (tree) 1)
+ if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
parms = get_parm_info (0); /* we have a `, ...' */
else
parms = get_parm_info (1); /* place a `void_at_end' */
@@ -4751,7 +4850,7 @@ get_arg_type_list (meth, context, superf
chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl)));
}
- if (METHOD_ADD_ARGS (meth) == (tree)1)
+ if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
/* We have a `, ...' immediately following the selector,
finalize the arglist...simulate get_parm_info (0). */
;
@@ -6971,7 +7070,8 @@ start_method_def (method)
while (arglist);
}
- if (METHOD_ADD_ARGS (method) > (tree)1)
+ if (METHOD_ADD_ARGS (method) != NULL_TREE
+ && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
{
/* We have a variable length selector - in "prototype" format. */
tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
@@ -7151,7 +7251,7 @@ continue_method_def ()
{
tree parmlist;
- if (METHOD_ADD_ARGS (method_context) == (tree)1)
+ if (METHOD_ADD_ARGS (method_context) == objc_ellipsis_node)
/* We have a `, ...' immediately following the selector. */
parmlist = get_parm_info (0);
else
@@ -7946,7 +8046,7 @@ gen_method_decl (method, buf)
}
while (chain);
- if (METHOD_ADD_ARGS (method) == (tree)1)
+ if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
strcat (buf, ", ...");
else if (METHOD_ADD_ARGS (method))
{
@@ -8470,4 +8570,50 @@ objc_debug (fp)
void
print_lang_statistics ()
{
+}
+
+static void
+ggc_mark_imp_list (arg)
+ void *arg;
+{
+ struct imp_entry *impent;
+
+ for (impent = *(struct imp_entry **)arg; impent; impent = impent->next)
+ {
+ ggc_mark_tree (impent->imp_context);
+ ggc_mark_tree (impent->imp_template);
+ ggc_mark_tree (impent->class_decl);
+ ggc_mark_tree (impent->meta_decl);
+ }
+}
+
+static void
+ggc_mark_hash_table (arg)
+ void *arg;
+{
+ hash *hash_table = *(hash **)arg;
+ hash hst;
+ attr list;
+ int i;
+
+ if (hash_table == NULL)
+ return;
+ for (i = 0; i < SIZEHASHTABLE; i++)
+ for (hst = hash_table [i]; hst; hst = hst->next)
+ {
+ ggc_mark_tree (hst->key);
+ for (list = hst->list; list; list = list->next)
+ ggc_mark_tree (list->value);
+ }
+}
+
+/* Add GC roots for variables local to this file. */
+static void
+objc_act_parse_init ()
+{
+ ggc_add_tree_root (&objc_ellipsis_node, 1);
+ ggc_add_tree_root (objc_global_trees, OCTI_MAX);
+ ggc_add_root (&imp_list, 1, sizeof imp_list, ggc_mark_imp_list);
+ ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table);
+ ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table);
}
--- gcc/objc/objc-act.h.jj Tue Jan 18 22:33:19 2000
+++ gcc/objc/objc-act.h Tue Apr 11 09:05:14 2000
@@ -55,6 +55,7 @@ tree build_objc_string_object PARAMS (
extern tree objc_ivar_chain;
extern tree objc_method_context;
+extern tree objc_ellipsis_node;
void objc_declare_alias PARAMS ((tree, tree));
void objc_declare_class PARAMS ((tree));
--- gcc/c-parse.in.jj Fri Mar 31 09:00:59 2000
+++ gcc/c-parse.in Tue Apr 11 09:10:43 2000
@@ -266,6 +266,13 @@ c_parse_init ()
ggc_add_tree_root (&declspec_stack, 1);
ggc_add_tree_root (¤t_declspecs, 1);
ggc_add_tree_root (&prefix_attributes, 1);
+ifobjc
+ ggc_add_tree_root (&objc_interface_context, 1);
+ ggc_add_tree_root (&objc_implementation_context, 1);
+ ggc_add_tree_root (&objc_method_context, 1);
+ ggc_add_tree_root (&objc_ivar_chain, 1);
+ ggc_add_tree_root (&objc_ivar_context, 1);
+end ifobjc
}
%}
@@ -2876,7 +2883,7 @@ optparmlist:
| ',' ELLIPSIS
{
/* oh what a kludge! */
- $$ = (tree)1;
+ $$ = objc_ellipsis_node;
}
| ','
{
--- gcc/objc/objc-parse.y.jj Fri Mar 31 09:01:02 2000
+++ gcc/objc/objc-parse.y Tue Apr 11 09:11:36 2000
@@ -251,6 +251,11 @@ c_parse_init ()
ggc_add_tree_root (&declspec_stack, 1);
ggc_add_tree_root (¤t_declspecs, 1);
ggc_add_tree_root (&prefix_attributes, 1);
+ ggc_add_tree_root (&objc_interface_context, 1);
+ ggc_add_tree_root (&objc_implementation_context, 1);
+ ggc_add_tree_root (&objc_method_context, 1);
+ ggc_add_tree_root (&objc_ivar_chain, 1);
+ ggc_add_tree_root (&objc_ivar_context, 1);
}
%}
@@ -2808,7 +2813,7 @@ optparmlist:
| ',' ELLIPSIS
{
/* oh what a kludge! */
- $$ = (tree)1;
+ $$ = objc_ellipsis_node;
}
| ','
{
--- gcc/objc/objc-parse.c.jj Fri Mar 31 09:01:02 2000
+++ gcc/objc/objc-parse.c Tue Apr 11 09:11:51 2000
@@ -160,6 +160,11 @@ c_parse_init ()
ggc_add_tree_root (&declspec_stack, 1);
ggc_add_tree_root (¤t_declspecs, 1);
ggc_add_tree_root (&prefix_attributes, 1);
+ ggc_add_tree_root (&objc_interface_context, 1);
+ ggc_add_tree_root (&objc_implementation_context, 1);
+ ggc_add_tree_root (&objc_method_context, 1);
+ ggc_add_tree_root (&objc_ivar_chain, 1);
+ ggc_add_tree_root (&objc_ivar_context, 1);
}
#include <stdio.h>
@@ -4881,7 +4886,7 @@ case 515:
#line 2809 "objc-parse.y"
{
/* oh what a kludge! */
- yyval.ttype = (tree)1;
+ yyval.ttype = objc_ellipsis_node;
;
break;}
case 516:
--- libobjc/Object.m.jj Sat Sep 4 17:09:19 1999
+++ libobjc/Object.m Mon Apr 10 23:24:40 2000
@@ -320,7 +320,7 @@ extern int errno;
object_get_class_name(self), sel_get_name(aSel)];
}
-#ifdef __alpha__
+#if defined(__alpha__) || (defined(__sparc__) && (defined(__sparcv9) || defined(__arch64__))) || (defined(__ia64__) && defined(__LP64__))
extern size_t strlen(const char*);
#endif
--- libobjc/sarray.c.jj Wed Sep 30 04:13:12 1998
+++ libobjc/sarray.c Mon Apr 10 23:24:40 2000
@@ -44,7 +44,7 @@ const char* __objc_sparse2_id = "2 level
const char* __objc_sparse3_id = "3 level sparse indices";
#endif
-#ifdef __alpha__
+#if defined(__alpha__) || (defined(__sparc__) && (defined(__sparcv9) || defined(__arch64__))) || (defined(__ia64__) && defined(__LP64__))
const void *memcpy (void*, const void*, size_t);
#endif
--- libobjc/encoding.c.jj Sat Oct 17 00:19:21 1998
+++ libobjc/encoding.c Tue Apr 11 11:42:57 2000
@@ -868,7 +868,7 @@ void objc_layout_finish_structure (struc
in the record type. Round it up to a multiple of the record's
alignment. */
-#ifdef ROUND_TYPE_ALIGN
+#if defined(ROUND_TYPE_ALIGN) && !defined(__sparc__)
layout->record_align = ROUND_TYPE_ALIGN (layout->original_type,
1,
layout->record_align);
Jakub