Commit b4e18eee by Andrew Haley Committed by Andrew Haley

expr.c (expand_byte_code): Call cache_this_class_ref() and cache_cpool_data_ref().

2007-02-02  Andrew Haley  <aph@redhat.com>

        * expr.c (expand_byte_code): Call cache_this_class_ref() and
        cache_cpool_data_ref().
        Set TYPE_CPOOL_DATA_REF.
        (cache_cpool_data_ref): New function.
        * constants.c (build_ref_from_constant_pool): Remove special-case
        code for flag_indirect_classes.
        (build_constant_data_ref): Move special-case code for
        flag_indirect_classes here from build_ref_from_constant_pool.
        * decl.c (finish_method): Move class initialization from here to
        cache_this_class_ref.
        * class.c (cache_this_class_ref): New function.
        (build_class_ref): Use this_classdollar for the ouput class.

From-SVN: r121508
parent ad12460b
2007-02-02 Andrew Haley <aph@redhat.com>
* expr.c (expand_byte_code): Call cache_this_class_ref() and
cache_cpool_data_ref().
Set TYPE_CPOOL_DATA_REF.
(cache_cpool_data_ref): New function.
* constants.c (build_ref_from_constant_pool): Remove special-case
code for flag_indirect_classes.
(build_constant_data_ref): Move special-case code for
flag_indirect_classes here from build_ref_from_constant_pool.
* decl.c (finish_method): Move class initialization from here to
cache_this_class_ref.
* class.c (cache_this_class_ref): New function.
(build_class_ref): Use this_classdollar for the ouput class.
2007-02-02 David Daney <ddaney@avtrex.com> 2007-02-02 David Daney <ddaney@avtrex.com>
* class.c (is_compiled_class): Move check to avoid reloading * class.c (is_compiled_class): Move check to avoid reloading
......
...@@ -110,6 +110,10 @@ static GTY(()) tree class_roots[4]; ...@@ -110,6 +110,10 @@ static GTY(()) tree class_roots[4];
static GTY(()) VEC(tree,gc) *registered_class; static GTY(()) VEC(tree,gc) *registered_class;
/* A tree that returns the address of the class$ of the class
currently being compiled. */
static GTY(()) tree this_classdollar;
/* Return the node that most closely represents the class whose name /* Return the node that most closely represents the class whose name
is IDENT. Start the search from NODE (followed by its siblings). is IDENT. Start the search from NODE (followed by its siblings).
Return NULL if an appropriate node does not exist. */ Return NULL if an appropriate node does not exist. */
...@@ -1004,6 +1008,45 @@ build_classdollar_field (tree type) ...@@ -1004,6 +1008,45 @@ build_classdollar_field (tree type)
return decl; return decl;
} }
/* Create a local variable that holds the the current class$. */
void
cache_this_class_ref (tree fndecl)
{
if (optimize)
{
tree classdollar_field;
if (flag_indirect_classes)
classdollar_field = build_classdollar_field (output_class);
else
classdollar_field = build_static_class_ref (output_class);
this_classdollar = build_decl (VAR_DECL, NULL_TREE,
TREE_TYPE (classdollar_field));
java_add_local_var (this_classdollar);
java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (this_classdollar),
this_classdollar, classdollar_field));
}
else
this_classdollar = build_classdollar_field (output_class);
/* Prepend class initialization for static methods reachable from
other classes. */
if (METHOD_STATIC (fndecl)
&& (! METHOD_PRIVATE (fndecl)
|| INNER_CLASS_P (DECL_CONTEXT (fndecl)))
&& ! DECL_CLINIT_P (fndecl)
&& ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl))))
{
tree init = build3 (CALL_EXPR, void_type_node,
build_address_of (soft_initclass_node),
build_tree_list (NULL_TREE, this_classdollar),
NULL_TREE);
java_add_stmt (init);
}
}
/* Build a reference to the class TYPE. /* Build a reference to the class TYPE.
Also handles primitive types and array types. */ Also handles primitive types and array types. */
...@@ -1023,7 +1066,7 @@ build_class_ref (tree type) ...@@ -1023,7 +1066,7 @@ build_class_ref (tree type)
return build_indirect_class_ref (type); return build_indirect_class_ref (type);
if (type == output_class && flag_indirect_classes) if (type == output_class && flag_indirect_classes)
return build_classdollar_field (type); return this_classdollar;
if (TREE_CODE (type) == RECORD_TYPE) if (TREE_CODE (type) == RECORD_TYPE)
return build_static_class_ref (type); return build_static_class_ref (type);
...@@ -2443,7 +2486,7 @@ layout_class_methods (tree this_class) ...@@ -2443,7 +2486,7 @@ layout_class_methods (tree this_class)
if (TYPE_NVIRTUALS (this_class)) if (TYPE_NVIRTUALS (this_class))
return; return;
super_class = CLASSTYPE_SUPER (this_class); super_class = CLASSTYPE_SUPER (this_class);
if (super_class) if (super_class)
......
...@@ -36,7 +36,6 @@ static void set_constant_entry (CPool *, int, int, jword); ...@@ -36,7 +36,6 @@ static void set_constant_entry (CPool *, int, int, jword);
static int find_tree_constant (CPool *, int, tree); static int find_tree_constant (CPool *, int, tree);
static int find_name_and_type_constant (CPool *, tree, tree); static int find_name_and_type_constant (CPool *, tree, tree);
static tree get_tag_node (int); static tree get_tag_node (int);
static tree build_constant_data_ref (void);
/* Set the INDEX'th constant in CPOOL to have the given TAG and VALUE. */ /* Set the INDEX'th constant in CPOOL to have the given TAG and VALUE. */
...@@ -424,14 +423,36 @@ alloc_class_constant (tree clas) ...@@ -424,14 +423,36 @@ alloc_class_constant (tree clas)
/* Return the decl of the data array of the current constant pool. */ /* Return the decl of the data array of the current constant pool. */
static tree tree
build_constant_data_ref (void) build_constant_data_ref (bool indirect)
{ {
tree decl = TYPE_CPOOL_DATA_REF (output_class); if (indirect)
{
tree d;
tree cpool_type = build_array_type (ptr_type_node, NULL_TREE);
tree decl = build_class_ref (output_class);
tree klass = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (decl)),
decl);
tree constants = build3 (COMPONENT_REF,
TREE_TYPE (constants_field_decl_node), klass,
constants_field_decl_node,
NULL_TREE);
tree data = build3 (COMPONENT_REF,
TREE_TYPE (constants_data_field_decl_node),
constants,
constants_data_field_decl_node,
NULL_TREE);
if (decl == NULL_TREE) TREE_THIS_NOTRAP (klass) = 1;
data = fold_convert (build_pointer_type (cpool_type), data);
d = build1 (INDIRECT_REF, cpool_type, data);
TREE_INVARIANT (d) = 1;
return d;
}
else
{ {
tree type; tree type, decl;
tree decl_name = mangled_classname ("_CD_", output_class); tree decl_name = mangled_classname ("_CD_", output_class);
/* Build a type with unspecified bounds. The will make sure /* Build a type with unspecified bounds. The will make sure
...@@ -446,10 +467,9 @@ build_constant_data_ref (void) ...@@ -446,10 +467,9 @@ build_constant_data_ref (void)
decl = build_decl (VAR_DECL, decl_name, type); decl = build_decl (VAR_DECL, decl_name, type);
TREE_STATIC (decl) = 1; TREE_STATIC (decl) = 1;
TYPE_CPOOL_DATA_REF (output_class) = decl;
}
return decl; return decl;
}
} }
/* Get the pointer value at the INDEX'th element of the constant pool. */ /* Get the pointer value at the INDEX'th element of the constant pool. */
...@@ -457,27 +477,13 @@ build_constant_data_ref (void) ...@@ -457,27 +477,13 @@ build_constant_data_ref (void)
tree tree
build_ref_from_constant_pool (int index) build_ref_from_constant_pool (int index)
{ {
tree d = build_constant_data_ref (); tree i;
tree i = build_int_cst (NULL_TREE, index); tree d = TYPE_CPOOL_DATA_REF (output_class);
if (flag_indirect_classes)
{ if (d == NULL_TREE)
tree decl = build_class_ref (output_class); d = build_constant_data_ref (flag_indirect_classes);
tree klass = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (decl)),
decl); i = build_int_cst (NULL_TREE, index);
tree constants = build3 (COMPONENT_REF,
TREE_TYPE (constants_field_decl_node), klass,
constants_field_decl_node,
NULL_TREE);
tree data = build3 (COMPONENT_REF,
TREE_TYPE (constants_data_field_decl_node),
constants,
constants_data_field_decl_node,
NULL_TREE);
data = fold_convert (build_pointer_type (TREE_TYPE (d)), data);
d = build1 (INDIRECT_REF, TREE_TYPE (d), data);
/* FIXME: These should be cached. */
TREE_INVARIANT (d) = 1;
}
d = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i, d = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i,
NULL_TREE, NULL_TREE); NULL_TREE, NULL_TREE);
TREE_INVARIANT (d) = 1; TREE_INVARIANT (d) = 1;
...@@ -557,7 +563,7 @@ build_constants_constructor (void) ...@@ -557,7 +563,7 @@ build_constants_constructor (void)
tags_list = tree_cons (NULL_TREE, get_tag_node (0), tags_list); tags_list = tree_cons (NULL_TREE, get_tag_node (0), tags_list);
data_list = tree_cons (NULL_TREE, null_pointer_node, data_list); data_list = tree_cons (NULL_TREE, null_pointer_node, data_list);
data_decl = build_constant_data_ref (); data_decl = build_constant_data_ref (false);
TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type); TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type);
DECL_INITIAL (data_decl) = build_constructor_from_list DECL_INITIAL (data_decl) = build_constructor_from_list
(TREE_TYPE (data_decl), data_list); (TREE_TYPE (data_decl), data_list);
......
...@@ -1876,22 +1876,6 @@ finish_method (tree fndecl) ...@@ -1876,22 +1876,6 @@ finish_method (tree fndecl)
build2 (TRY_FINALLY_EXPR, void_type_node, *tp, exit)); build2 (TRY_FINALLY_EXPR, void_type_node, *tp, exit));
} }
/* Prepend class initialization for static methods reachable from
other classes. */
if (METHOD_STATIC (fndecl)
&& (! METHOD_PRIVATE (fndecl)
|| INNER_CLASS_P (DECL_CONTEXT (fndecl)))
&& ! DECL_CLINIT_P (fndecl)
&& ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl))))
{
tree clas = DECL_CONTEXT (fndecl);
tree init = build3 (CALL_EXPR, void_type_node,
build_address_of (soft_initclass_node),
build_tree_list (NULL_TREE, build_class_ref (clas)),
NULL_TREE);
*tp = build2 (COMPOUND_EXPR, TREE_TYPE (*tp), init, *tp);
}
/* Convert function tree to GENERIC prior to inlining. */ /* Convert function tree to GENERIC prior to inlining. */
java_genericize (fndecl); java_genericize (fndecl);
......
...@@ -83,6 +83,7 @@ static tree build_java_throw_out_of_bounds_exception (tree); ...@@ -83,6 +83,7 @@ static tree build_java_throw_out_of_bounds_exception (tree);
static tree build_java_check_indexed_type (tree, tree); static tree build_java_check_indexed_type (tree, tree);
static unsigned char peek_opcode_at_pc (struct JCF *, int, int); static unsigned char peek_opcode_at_pc (struct JCF *, int, int);
static void promote_arguments (void); static void promote_arguments (void);
static void cache_cpool_data_ref (void);
static GTY(()) tree operand_type[59]; static GTY(()) tree operand_type[59];
...@@ -3151,6 +3152,8 @@ expand_byte_code (JCF *jcf, tree method) ...@@ -3151,6 +3152,8 @@ expand_byte_code (JCF *jcf, tree method)
return; return;
promote_arguments (); promote_arguments ();
cache_this_class_ref (method);
cache_cpool_data_ref ();
/* Translate bytecodes. */ /* Translate bytecodes. */
linenumber_pointer = linenumber_table; linenumber_pointer = linenumber_table;
...@@ -3223,7 +3226,7 @@ expand_byte_code (JCF *jcf, tree method) ...@@ -3223,7 +3226,7 @@ expand_byte_code (JCF *jcf, tree method)
PC = process_jvm_instruction (PC, byte_ops, length); PC = process_jvm_instruction (PC, byte_ops, length);
maybe_poplevels (PC); maybe_poplevels (PC);
} /* for */ } /* for */
if (dead_code_index != -1) if (dead_code_index != -1)
{ {
/* We've just reached the end of a region of dead code. */ /* We've just reached the end of a region of dead code. */
...@@ -3791,4 +3794,27 @@ promote_arguments (void) ...@@ -3791,4 +3794,27 @@ promote_arguments (void)
} }
} }
/* Create a local variable that points to the constant pool. */
static void
cache_cpool_data_ref (void)
{
if (optimize)
{
tree cpool;
tree d = build_constant_data_ref (flag_indirect_classes);
tree cpool_ptr = build_decl (VAR_DECL, NULL_TREE,
build_pointer_type (TREE_TYPE (d)));
java_add_local_var (cpool_ptr);
TREE_INVARIANT (cpool_ptr) = 1;
TREE_CONSTANT (cpool_ptr) = 1;
java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (cpool_ptr),
cpool_ptr, build_address_of (d)));
cpool = build1 (INDIRECT_REF, TREE_TYPE (d), cpool_ptr);
TREE_THIS_NOTRAP (cpool) = 1;
TYPE_CPOOL_DATA_REF (output_class) = cpool;
}
}
#include "gt-java-expr.h" #include "gt-java-expr.h"
...@@ -1129,10 +1129,12 @@ extern void layout_class (tree); ...@@ -1129,10 +1129,12 @@ extern void layout_class (tree);
extern int get_interface_method_index (tree, tree); extern int get_interface_method_index (tree, tree);
extern tree layout_class_method (tree, tree, tree, tree); extern tree layout_class_method (tree, tree, tree, tree);
extern void layout_class_methods (tree); extern void layout_class_methods (tree);
extern void cache_this_class_ref (tree);
extern tree build_class_ref (tree); extern tree build_class_ref (tree);
extern tree build_dtable_decl (tree); extern tree build_dtable_decl (tree);
extern tree build_internal_class_name (tree); extern tree build_internal_class_name (tree);
extern tree build_constants_constructor (void); extern tree build_constants_constructor (void);
extern tree build_constant_data_ref (bool);
extern tree build_ref_from_constant_pool (int); extern tree build_ref_from_constant_pool (int);
extern tree build_utf8_ref (tree); extern tree build_utf8_ref (tree);
extern tree ident_subst (const char *, int, const char *, int, int, extern tree ident_subst (const char *, int, const char *, int, int,
......
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