Commit 3ff9925c by Anthony Green Committed by Anthony Green

expr.c (build_class_init): Mark the decl to be ignored by check_init.

2000-02-25  Anthony Green  <green@cygnus.com>

	* expr.c (build_class_init): Mark the decl to be ignored by
	check_init.
	* java-tree.h (DECL_BIT_INDEX): Move definition from check-init.c
	* check-init.c: Move DECL_BIT_INDEX to java-tree.h
	* class.c (init_test_hash_newfunc): New function.
	(decl_hash): New function.
	(decl_compare): New function.
	* decl.c (emit_init_test_initialization): New function.
	(complete_start_java_method): Traverse the init test hashtable,
	calling emit_init_test_initialization.
	(always_initialize_class_p): Define.
	* expr.c (build_class_init): Use initialization tests when
	emitting class initialization code.
	(always_initialize_class_p): Declare.
	* jcf-parse.c (parse_class_file): Set always_initialize_class_p to
	1.
	* java-tree.h: Include hash.h.
	(DECL_FUNCTION_INIT_TEST_TABLE): Define.
	(struct lang_decl): Add init_test_table field.
	(init_test_hash_entry): Define.

From-SVN: r32166
parent 985dae7c
2000-02-25 Anthony Green <green@cygnus.com>
* expr.c (build_class_init): Mark the decl to be ignored by
check_init.
* java-tree.h (DECL_BIT_INDEX): Move definition from check-init.c
* check-init.c: Move DECL_BIT_INDEX to java-tree.h
* class.c (init_test_hash_newfunc): New function.
(decl_hash): New function.
(decl_compare): New function.
* decl.c (emit_init_test_initialization): New function.
(complete_start_java_method): Traverse the init test hashtable,
calling emit_init_test_initialization.
(always_initialize_class_p): Define.
* expr.c (build_class_init): Use initialization tests when
emitting class initialization code.
(always_initialize_class_p): Declare.
* jcf-parse.c (parse_class_file): Set always_initialize_class_p to
1.
* java-tree.h: Include hash.h.
(DECL_FUNCTION_INIT_TEST_TABLE): Define.
(struct lang_decl): Add init_test_table field.
(init_test_hash_entry): Define.
Fri Feb 25 18:41:31 2000 Alexandre Petit-Bianco <apbianco@cygnus.com>
* gjavah.c (main): Avoid using `argi' to report unimplemented
......
......@@ -39,11 +39,6 @@ typedef unsigned int word;
/* Pointer to a bitstring. */
typedef word *words;
/* For a local VAR_DECL, holds the index into a words bitstring that
specifies if this decl is definitively assigned.
A DECL_BIT_INDEX of -1 means we no longer care. */
#define DECL_BIT_INDEX(DECL) DECL_FIELD_SIZE(DECL)
/* Number of locals variables currently active. */
int num_current_locals = 0;
......
......@@ -389,7 +389,7 @@ set_super_info (access_flags, this_class, super_class, interfaces_count)
CLASS_HAS_SUPER (this_class) = 1;
}
pop_obstacks ();
if (access_flags & ACC_PUBLIC) CLASS_PUBLIC (class_decl) = 1;
if (access_flags & ACC_FINAL) CLASS_FINAL (class_decl) = 1;
if (access_flags & ACC_SUPER) CLASS_SUPER (class_decl) = 1;
......@@ -548,6 +548,40 @@ build_java_method_type (fntype, this_class, access_flags)
return build_method_type (CLASS_TO_HANDLE_TYPE (this_class), fntype);
}
static struct hash_entry *
init_test_hash_newfunc (entry, table, string)
struct hash_entry *entry;
struct hash_table *table;
hash_table_key string ATTRIBUTE_UNUSED;
{
struct init_test_hash_entry *ret = (struct init_test_hash_entry *) entry;
if (ret == NULL)
{
ret = ((struct init_test_hash_entry *)
hash_allocate (table, sizeof (struct init_test_hash_entry)));
if (ret == NULL)
return NULL;
}
ret->init_test_decl = 0;
return (struct hash_entry *) ret;
}
static unsigned long
decl_hash (k)
hash_table_key k;
{
return (long) k;
}
static boolean
decl_compare (k1, k2)
hash_table_key k1;
hash_table_key k2;
{
return ((char*) k1 == (char*) k2);
}
tree
add_method_1 (handle_class, access_flags, name, function_type)
tree handle_class;
......@@ -568,6 +602,11 @@ add_method_1 (handle_class, access_flags, name, function_type)
= (struct lang_decl *) permalloc (sizeof (struct lang_decl));
bzero ((PTR) DECL_LANG_SPECIFIC (fndecl), sizeof (struct lang_decl));
/* Initialize the static initializer test table. */
hash_table_init (&DECL_FUNCTION_INIT_TEST_TABLE (fndecl),
init_test_hash_newfunc, decl_hash,
decl_compare);
TREE_CHAIN (fndecl) = TYPE_METHODS (handle_class);
TYPE_METHODS (handle_class) = fndecl;
pop_obstacks ();
......
......@@ -48,6 +48,10 @@ static tree lookup_name_current_level PARAMS ((tree));
static tree push_promoted_type PARAMS ((const char *, tree));
static struct binding_level *make_binding_level PARAMS ((void));
/* Set to non-zero value in order to emit class initilization code
before static field references. */
extern int always_initialize_class_p;
#ifndef INT_TYPE_SIZE
#define INT_TYPE_SIZE BITS_PER_WORD
#endif
......@@ -1623,6 +1627,24 @@ build_result_decl (fndecl)
return (DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, restype));
}
/* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE in order
to emit initialization code for each test flag. */
static boolean
emit_init_test_initialization (entry, key)
struct hash_entry *entry;
hash_table_key key;
{
struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry;
expand_decl (ite->init_test_decl);
expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node,
ite->init_test_decl, boolean_false_node));
return true;
}
void
complete_start_java_method (fndecl)
tree fndecl;
......@@ -1634,6 +1656,11 @@ complete_start_java_method (fndecl)
/* Set up parameters and prepare for return, for the function. */
expand_function_start (fndecl, 0);
/* Emit initialization code for test flags. */
if (! always_initialize_class_p)
hash_traverse (&DECL_FUNCTION_INIT_TEST_TABLE (fndecl),
emit_init_test_initialization, 0);
}
/* Allocate further tree nodes temporarily during compilation
......
......@@ -83,6 +83,10 @@ static tree case_identity PARAMS ((tree, tree));
static tree operand_type[59];
extern struct obstack permanent_obstack;
/* Set to non-zero value in order to emit class initilization code
before static field references. */
int always_initialize_class_p;
void
init_expr_processing()
{
......@@ -1490,14 +1494,48 @@ tree
build_class_init (clas, expr)
tree clas, expr;
{
tree init;
tree init, call;
struct init_test_hash_entry *ite;
if (inherits_from_p (current_class, clas))
return expr;
init = build (CALL_EXPR, void_type_node,
build_address_of (soft_initclass_node),
build_tree_list (NULL_TREE, build_class_ref (clas)),
NULL_TREE);
TREE_SIDE_EFFECTS (init) = 1;
if (always_initialize_class_p)
{
init = build (CALL_EXPR, void_type_node,
build_address_of (soft_initclass_node),
build_tree_list (NULL_TREE, build_class_ref (clas)),
NULL_TREE);
TREE_SIDE_EFFECTS (init) = 1;
}
else
{
ite = (struct init_test_hash_entry *)
hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
(const hash_table_key) clas,
TRUE, NULL);
if (ite->init_test_decl == 0)
ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
boolean_type_node);
/* Tell the check-init code to ignore this decl. */
DECL_BIT_INDEX(ite->init_test_decl) = -1;
init = build (CALL_EXPR, void_type_node,
build_address_of (soft_initclass_node),
build_tree_list (NULL_TREE, build_class_ref (clas)),
NULL_TREE);
TREE_SIDE_EFFECTS (init) = 1;
call = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
build (MODIFY_EXPR, boolean_type_node,
ite->init_test_decl, boolean_true_node));
TREE_SIDE_EFFECTS (call) = 1;
init = build (COND_EXPR, void_type_node,
build (EQ_EXPR, boolean_type_node,
ite->init_test_decl, boolean_false_node),
call, integer_zero_node);
TREE_SIDE_EFFECTS (init) = 1;
}
if (expr != NULL_TREE)
{
expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
......
......@@ -25,6 +25,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
/* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
#include "hash.h"
/* Java language-specific tree codes. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,
enum java_tree_code {
......@@ -368,6 +370,12 @@ struct lang_identifier
/* How specific the function is (for method selection - Java source
code front-end */
#define DECL_SPECIFIC_COUNT(DECL) DECL_ARG_SLOT_COUNT(DECL)
/* For each function decl, init_test_table contains a hash table whose
entries are keyed on class names, and whose values are local
boolean decls. The variables are intended to be TRUE when the
class has been initialized in this function, and FALSE otherwise. */
#define DECL_FUNCTION_INIT_TEST_TABLE(DECL) \
(DECL_LANG_SPECIFIC(DECL)->init_test_table)
/* In a LABEL_DECL, a TREE_VEC that saves the type_map at that point. */
#define LABEL_TYPE_STATE(NODE) (DECL_INITIAL (NODE))
......@@ -429,6 +437,11 @@ struct lang_identifier
#define DECL_LOCAL_SLOT_CHAIN(NODE) \
(((struct lang_decl_var*)DECL_LANG_SPECIFIC(NODE))->slot_chain)
/* For a local VAR_DECL, holds the index into a words bitstring that
specifies if this decl is definitively assigned.
A DECL_BIT_INDEX of -1 means we no longer care. */
#define DECL_BIT_INDEX(DECL) DECL_FIELD_SIZE(DECL)
/* DECL_LANG_SPECIFIC for FUNCTION_DECLs. */
struct lang_decl
{
......@@ -443,8 +456,18 @@ struct lang_decl
tree function_decl_body; /* Hold all function's statements */
tree called_constructor; /* When decl is a constructor, the
list of other constructor it calls. */
struct hash_table init_test_table;
/* Class initialization test variables. */
};
/* init_test_table hash table entry structure. */
struct init_test_hash_entry
{
struct hash_entry root;
tree init_test_decl;
};
/* DECL_LANG_SPECIFIC for VAR_DECL and PARM_DECL. */
struct lang_decl_var
{
......
......@@ -57,6 +57,10 @@ extern struct obstack *saveable_obstack;
extern struct obstack temporary_obstack;
extern struct obstack permanent_obstack;
/* Set to non-zero value in order to emit class initilization code
before static field references. */
extern int always_initialize_class_p;
/* The class we are currently processing. */
tree current_class = NULL_TREE;
......@@ -646,6 +650,10 @@ parse_class_file ()
debug_start_source_file (input_filename);
init_outgoing_cpool ();
/* Currently we always have to emit calls to _Jv_InitClass when
compiling from class files. */
always_initialize_class_p = 1;
for ( method = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (current_class));
method != NULL_TREE; method = TREE_CHAIN (method))
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment