decl.c (init_decl_processing): Added new class fields depth',
ancestors', and `idt' to class_type_node.
2000-03-06 Bryce McKinlay <bryce@albatross.co.nz> * decl.c (init_decl_processing): Added new class fields `depth', `ancestors', and `idt' to class_type_node. Use _Jv_LookupInterfaceMethodIdx for soft_lookupinterfacemthod_node. * class.c (make_class_data): Push initial values for new fields. * java-tree.h: Updated prototype for `build_invokeinterface'. * expr.c (build_invokeinterface): Changed parameters to accept `method' tree. Calculate index of `method' in its declaring interface. Build call to _Jv_LookupInterfaceMethodIdx. (expand_invoke): Call `build_invokeinterface' with new parameters. * parse.y (patch_invoke): Call `build_invokeinterface' with new parameters. (This is Bryce McKinlay's implementation of the interfaces constant-time dispatch and type checking techniques designed by Per Bothner.) From-SVN: r32381
This commit is contained in:
parent
f2d2acce60
commit
173f556ccc
6 changed files with 49 additions and 14 deletions
|
@ -1,3 +1,17 @@
|
||||||
|
2000-03-06 Bryce McKinlay <bryce@albatross.co.nz>
|
||||||
|
|
||||||
|
* decl.c (init_decl_processing): Added new class fields `depth',
|
||||||
|
`ancestors', and `idt' to class_type_node. Use
|
||||||
|
_Jv_LookupInterfaceMethodIdx for soft_lookupinterfacemthod_node.
|
||||||
|
* class.c (make_class_data): Push initial values for new fields.
|
||||||
|
* java-tree.h: Updated prototype for `build_invokeinterface'.
|
||||||
|
* expr.c (build_invokeinterface): Changed parameters to accept
|
||||||
|
`method' tree. Calculate index of `method' in its declaring
|
||||||
|
interface. Build call to _Jv_LookupInterfaceMethodIdx.
|
||||||
|
(expand_invoke): Call `build_invokeinterface' with new parameters.
|
||||||
|
* parse.y (patch_invoke): Call `build_invokeinterface' with new
|
||||||
|
parameters.
|
||||||
|
|
||||||
2000-03-06 Bryce McKinlay <bryce@albatross.co.nz>
|
2000-03-06 Bryce McKinlay <bryce@albatross.co.nz>
|
||||||
|
|
||||||
* typeck.c (lookup_do): Search superinterfaces first
|
* typeck.c (lookup_do): Search superinterfaces first
|
||||||
|
|
|
@ -1380,6 +1380,9 @@ make_class_data (type)
|
||||||
PUSH_FIELD_VALUE (cons, "state", integer_zero_node);
|
PUSH_FIELD_VALUE (cons, "state", integer_zero_node);
|
||||||
|
|
||||||
PUSH_FIELD_VALUE (cons, "thread", null_pointer_node);
|
PUSH_FIELD_VALUE (cons, "thread", null_pointer_node);
|
||||||
|
PUSH_FIELD_VALUE (cons, "depth", integer_zero_node);
|
||||||
|
PUSH_FIELD_VALUE (cons, "ancestors", null_pointer_node);
|
||||||
|
PUSH_FIELD_VALUE (cons, "idt", null_pointer_node);
|
||||||
|
|
||||||
FINISH_RECORD_CONSTRUCTOR (cons);
|
FINISH_RECORD_CONSTRUCTOR (cons);
|
||||||
|
|
||||||
|
|
|
@ -661,6 +661,9 @@ init_decl_processing ()
|
||||||
PUSH_FIELD (class_type_node, field, "interface_count", short_type_node);
|
PUSH_FIELD (class_type_node, field, "interface_count", short_type_node);
|
||||||
PUSH_FIELD (class_type_node, field, "state", byte_type_node);
|
PUSH_FIELD (class_type_node, field, "state", byte_type_node);
|
||||||
PUSH_FIELD (class_type_node, field, "thread", ptr_type_node);
|
PUSH_FIELD (class_type_node, field, "thread", ptr_type_node);
|
||||||
|
PUSH_FIELD (class_type_node, field, "depth", short_type_node);
|
||||||
|
PUSH_FIELD (class_type_node, field, "ancestors", ptr_type_node);
|
||||||
|
PUSH_FIELD (class_type_node, field, "idt", ptr_type_node);
|
||||||
for (t = TYPE_FIELDS (class_type_node); t != NULL_TREE; t = TREE_CHAIN (t))
|
for (t = TYPE_FIELDS (class_type_node); t != NULL_TREE; t = TREE_CHAIN (t))
|
||||||
FIELD_PRIVATE (t) = 1;
|
FIELD_PRIVATE (t) = 1;
|
||||||
push_super_field (class_type_node, object_type_node);
|
push_super_field (class_type_node, object_type_node);
|
||||||
|
@ -815,9 +818,9 @@ init_decl_processing ()
|
||||||
0, NOT_BUILT_IN, NULL_PTR);
|
0, NOT_BUILT_IN, NULL_PTR);
|
||||||
t = tree_cons (NULL_TREE, ptr_type_node,
|
t = tree_cons (NULL_TREE, ptr_type_node,
|
||||||
tree_cons (NULL_TREE, ptr_type_node,
|
tree_cons (NULL_TREE, ptr_type_node,
|
||||||
tree_cons (NULL_TREE, ptr_type_node, endlink)));
|
tree_cons (NULL_TREE, int_type_node, endlink)));
|
||||||
soft_lookupinterfacemethod_node
|
soft_lookupinterfacemethod_node
|
||||||
= builtin_function ("_Jv_LookupInterfaceMethod",
|
= builtin_function ("_Jv_LookupInterfaceMethodIdx",
|
||||||
build_function_type (ptr_type_node, t),
|
build_function_type (ptr_type_node, t),
|
||||||
0, NOT_BUILT_IN, NULL_PTR);
|
0, NOT_BUILT_IN, NULL_PTR);
|
||||||
t = tree_cons (NULL_TREE, double_type_node,
|
t = tree_cons (NULL_TREE, double_type_node,
|
||||||
|
|
|
@ -1648,11 +1648,15 @@ build_invokevirtual (dtable, method)
|
||||||
}
|
}
|
||||||
|
|
||||||
tree
|
tree
|
||||||
build_invokeinterface (dtable, method_name, method_signature)
|
build_invokeinterface (dtable, method)
|
||||||
tree dtable, method_name, method_signature;
|
tree dtable, method;
|
||||||
{
|
{
|
||||||
static tree class_ident = NULL_TREE;
|
static tree class_ident = NULL_TREE;
|
||||||
tree lookup_arg;
|
tree lookup_arg;
|
||||||
|
tree interface;
|
||||||
|
tree idx;
|
||||||
|
tree meth;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
|
/* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
|
||||||
ensure that the selected method exists, is public and not
|
ensure that the selected method exists, is public and not
|
||||||
|
@ -1664,14 +1668,25 @@ build_invokeinterface (dtable, method_name, method_signature)
|
||||||
dtable = build1 (INDIRECT_REF, dtable_type, dtable);
|
dtable = build1 (INDIRECT_REF, dtable_type, dtable);
|
||||||
dtable = build (COMPONENT_REF, class_ptr_type, dtable,
|
dtable = build (COMPONENT_REF, class_ptr_type, dtable,
|
||||||
lookup_field (&dtable_type, class_ident));
|
lookup_field (&dtable_type, class_ident));
|
||||||
lookup_arg = build_tree_list (NULL_TREE,
|
|
||||||
(build_utf8_ref
|
interface = DECL_CONTEXT (method);
|
||||||
(unmangle_classname
|
|
||||||
(IDENTIFIER_POINTER(method_signature),
|
i = 1;
|
||||||
IDENTIFIER_LENGTH(method_signature)))));
|
for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
|
||||||
|
{
|
||||||
|
if (meth == method)
|
||||||
|
{
|
||||||
|
idx = build_int_2 (i, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (meth == NULL_TREE)
|
||||||
|
fatal ("internal error in build_invokeinterface");
|
||||||
|
}
|
||||||
|
|
||||||
lookup_arg = tree_cons (NULL_TREE, dtable,
|
lookup_arg = tree_cons (NULL_TREE, dtable,
|
||||||
tree_cons (NULL_TREE, build_utf8_ref (method_name),
|
tree_cons (NULL_TREE, build_class_ref (interface),
|
||||||
lookup_arg));
|
build_tree_list (NULL_TREE, idx)));
|
||||||
|
|
||||||
return build (CALL_EXPR, ptr_type_node,
|
return build (CALL_EXPR, ptr_type_node,
|
||||||
build_address_of (soft_lookupinterfacemethod_node),
|
build_address_of (soft_lookupinterfacemethod_node),
|
||||||
lookup_arg, NULL_TREE);
|
lookup_arg, NULL_TREE);
|
||||||
|
@ -1770,7 +1785,7 @@ expand_invoke (opcode, method_ref_index, nargs)
|
||||||
if (opcode == OPCODE_invokevirtual)
|
if (opcode == OPCODE_invokevirtual)
|
||||||
func = build_invokevirtual (dtable, method);
|
func = build_invokevirtual (dtable, method);
|
||||||
else
|
else
|
||||||
func = build_invokeinterface (dtable, method_name, method_signature);
|
func = build_invokeinterface (dtable, method);
|
||||||
}
|
}
|
||||||
func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
|
func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
|
||||||
call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
|
call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
|
||||||
|
|
|
@ -564,7 +564,7 @@ extern tree lookup_name PARAMS ((tree));
|
||||||
extern tree build_known_method_ref PARAMS ((tree, tree, tree, tree, tree));
|
extern tree build_known_method_ref PARAMS ((tree, tree, tree, tree, tree));
|
||||||
extern tree build_class_init PARAMS ((tree, tree));
|
extern tree build_class_init PARAMS ((tree, tree));
|
||||||
extern tree build_invokevirtual PARAMS ((tree, tree));
|
extern tree build_invokevirtual PARAMS ((tree, tree));
|
||||||
extern tree build_invokeinterface PARAMS ((tree, tree, tree));
|
extern tree build_invokeinterface PARAMS ((tree, tree));
|
||||||
extern tree invoke_build_dtable PARAMS ((int, tree));
|
extern tree invoke_build_dtable PARAMS ((int, tree));
|
||||||
extern tree build_field_ref PARAMS ((tree, tree, tree));
|
extern tree build_field_ref PARAMS ((tree, tree, tree));
|
||||||
extern void pushdecl_force_head PARAMS ((tree));
|
extern void pushdecl_force_head PARAMS ((tree));
|
||||||
|
|
|
@ -7524,7 +7524,7 @@ patch_invoke (patch, method, args)
|
||||||
|
|
||||||
case INVOKE_INTERFACE:
|
case INVOKE_INTERFACE:
|
||||||
dtable = invoke_build_dtable (1, args);
|
dtable = invoke_build_dtable (1, args);
|
||||||
func = build_invokeinterface (dtable, DECL_NAME (method), signature);
|
func = build_invokeinterface (dtable, method);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue