comparison src/share/vm/interpreter/linkResolver.hpp @ 12264:b2e698d2276c

8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation Summary: Enhance method resolution and resulting data structures, plus some refactoring. Reviewed-by: twisti, acorn, jrose
author drchase
date Fri, 13 Sep 2013 22:38:02 -0400
parents f6b0eb4e44cf
children 359f7e70ae7f ac9cb1d5a202
comparison
equal deleted inserted replaced
12261:2c98370f2611 12264:b2e698d2276c
1 /* 1 /*
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
28 #include "oops/method.hpp" 28 #include "oops/method.hpp"
29 #include "utilities/top.hpp" 29 #include "utilities/top.hpp"
30 30
31 // All the necessary definitions for run-time link resolution. 31 // All the necessary definitions for run-time link resolution.
32 32
33 // LinkInfo & its subclasses provide all the information gathered 33 // CallInfo provides all the information gathered for a particular
34 // for a particular link after resolving it. A link is any reference 34 // linked call site after resolving it. A link is any reference
35 // made from within the bytecodes of a method to an object outside of 35 // made from within the bytecodes of a method to an object outside of
36 // that method. If the info is invalid, the link has not been resolved 36 // that method. If the info is invalid, the link has not been resolved
37 // successfully. 37 // successfully.
38 38
39 class LinkInfo VALUE_OBJ_CLASS_SPEC { 39 class CallInfo VALUE_OBJ_CLASS_SPEC {
40 };
41
42
43 // Link information for getfield/putfield & getstatic/putstatic bytecodes.
44
45 class FieldAccessInfo: public LinkInfo {
46 protected:
47 KlassHandle _klass;
48 Symbol* _name;
49 AccessFlags _access_flags;
50 int _field_index; // original index in the klass
51 int _field_offset;
52 BasicType _field_type;
53
54 public: 40 public:
55 void set(KlassHandle klass, Symbol* name, int field_index, int field_offset, 41 // Ways that a method call might be selected (or not) based on receiver type.
56 BasicType field_type, AccessFlags access_flags); 42 // Note that an invokevirtual instruction might be linked with no_dispatch,
57 KlassHandle klass() const { return _klass; } 43 // and an invokeinterface instruction might be linked with any of the three options
58 Symbol* name() const { return _name; } 44 enum CallKind {
59 int field_index() const { return _field_index; } 45 direct_call, // jump into resolved_method (must be concrete)
60 int field_offset() const { return _field_offset; } 46 vtable_call, // select recv.klass.method_at_vtable(index)
61 BasicType field_type() const { return _field_type; } 47 itable_call, // select recv.klass.method_at_itable(resolved_method.holder, index)
62 AccessFlags access_flags() const { return _access_flags; } 48 unknown_kind = -1
63 49 };
64 // debugging
65 void print() PRODUCT_RETURN;
66 };
67
68
69 // Link information for all calls.
70
71 class CallInfo: public LinkInfo {
72 private: 50 private:
73 KlassHandle _resolved_klass; // static receiver klass 51 KlassHandle _resolved_klass; // static receiver klass, resolved from a symbolic reference
74 KlassHandle _selected_klass; // dynamic receiver class (same as static, or subklass) 52 KlassHandle _selected_klass; // dynamic receiver class (same as static, or subklass)
75 methodHandle _resolved_method; // static target method 53 methodHandle _resolved_method; // static target method
76 methodHandle _selected_method; // dynamic (actual) target method 54 methodHandle _selected_method; // dynamic (actual) target method
77 int _vtable_index; // vtable index of selected method 55 CallKind _call_kind; // kind of call (static(=bytecode static/special +
56 // others inferred), vtable, itable)
57 int _call_index; // vtable or itable index of selected class method (if any)
78 Handle _resolved_appendix; // extra argument in constant pool (if CPCE::has_appendix) 58 Handle _resolved_appendix; // extra argument in constant pool (if CPCE::has_appendix)
79 Handle _resolved_method_type; // MethodType (for invokedynamic and invokehandle call sites) 59 Handle _resolved_method_type; // MethodType (for invokedynamic and invokehandle call sites)
80 60
81 void set_static( KlassHandle resolved_klass, methodHandle resolved_method , TRAPS); 61 void set_static( KlassHandle resolved_klass, methodHandle resolved_method , TRAPS);
82 void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method , TRAPS); 62 void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index , TRAPS);
83 void set_virtual( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS); 63 void set_virtual( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS);
84 void set_handle( methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS); 64 void set_handle( methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS);
85 void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS); 65 void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, CallKind kind, int index, TRAPS);
86 66
87 friend class LinkResolver; 67 friend class LinkResolver;
88 68
89 public: 69 public:
70 CallInfo() {
71 #ifndef PRODUCT
72 _call_kind = CallInfo::unknown_kind;
73 _call_index = Method::garbage_vtable_index;
74 #endif //PRODUCT
75 }
76
77 // utility to extract an effective CallInfo from a method and an optional receiver limit
78 // does not queue the method for compilation
79 CallInfo(Method* resolved_method, Klass* resolved_klass = NULL);
80
90 KlassHandle resolved_klass() const { return _resolved_klass; } 81 KlassHandle resolved_klass() const { return _resolved_klass; }
91 KlassHandle selected_klass() const { return _selected_klass; } 82 KlassHandle selected_klass() const { return _selected_klass; }
92 methodHandle resolved_method() const { return _resolved_method; } 83 methodHandle resolved_method() const { return _resolved_method; }
93 methodHandle selected_method() const { return _selected_method; } 84 methodHandle selected_method() const { return _selected_method; }
94 Handle resolved_appendix() const { return _resolved_appendix; } 85 Handle resolved_appendix() const { return _resolved_appendix; }
95 Handle resolved_method_type() const { return _resolved_method_type; } 86 Handle resolved_method_type() const { return _resolved_method_type; }
96 87
97 BasicType result_type() const { return selected_method()->result_type(); } 88 BasicType result_type() const { return selected_method()->result_type(); }
98 bool has_vtable_index() const { return _vtable_index >= 0; } 89 CallKind call_kind() const { return _call_kind; }
99 bool is_statically_bound() const { return _vtable_index == Method::nonvirtual_vtable_index; } 90 int call_index() const { return _call_index; }
100 int vtable_index() const { 91 int vtable_index() const {
101 // Even for interface calls the vtable index could be non-negative. 92 // Even for interface calls the vtable index could be non-negative.
102 // See CallInfo::set_interface. 93 // See CallInfo::set_interface.
103 assert(has_vtable_index() || is_statically_bound(), ""); 94 assert(has_vtable_index() || is_statically_bound(), "");
104 return _vtable_index; 95 assert(call_kind() == vtable_call || call_kind() == direct_call, "");
105 } 96 // The returned value is < 0 if the call is statically bound.
97 // But, the returned value may be >= 0 even if the kind is direct_call.
98 // It is up to the caller to decide which way to go.
99 return _call_index;
100 }
101 int itable_index() const {
102 assert(call_kind() == itable_call, "");
103 // The returned value is always >= 0, a valid itable index.
104 return _call_index;
105 }
106
107 // debugging
108 #ifdef ASSERT
109 bool has_vtable_index() const { return _call_index >= 0 && _call_kind != CallInfo::itable_call; }
110 bool is_statically_bound() const { return _call_index == Method::nonvirtual_vtable_index; }
111 #endif //ASSERT
112 void verify() PRODUCT_RETURN;
113 void print() PRODUCT_RETURN;
106 }; 114 };
107 115
116 // Link information for getfield/putfield & getstatic/putstatic bytecodes
117 // is represented using a fieldDescriptor.
108 118
109 // The LinkResolver is used to resolve constant-pool references at run-time. 119 // The LinkResolver is used to resolve constant-pool references at run-time.
110 // It does all necessary link-time checks & throws exceptions if necessary. 120 // It does all necessary link-time checks & throws exceptions if necessary.
111 121
112 class LinkResolver: AllStatic { 122 class LinkResolver: AllStatic {
123 friend class klassVtable;
124 friend class klassItable;
125
113 private: 126 private:
114 static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); 127 static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
115 static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); 128 static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
116 static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); 129 static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
117 static void lookup_polymorphic_method (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, 130 static void lookup_polymorphic_method (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature,
118 KlassHandle current_klass, Handle *appendix_result_or_null, Handle *method_type_result, TRAPS); 131 KlassHandle current_klass, Handle *appendix_result_or_null, Handle *method_type_result, TRAPS);
119 132
120 static int vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); 133 static int vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
121 134
122 static void resolve_klass (KlassHandle& result, constantPoolHandle pool, int index, TRAPS); 135 static void resolve_klass (KlassHandle& result, constantPoolHandle pool, int index, TRAPS);
123 static void resolve_klass_no_update (KlassHandle& result, constantPoolHandle pool, int index, TRAPS); // no update of constantPool entry
124 136
125 static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS); 137 static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS);
126 138
127 static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); 139 static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
128 static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); 140 static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
146 // static resolving calls (will not run any Java code); used only from Bytecode_invoke::static_target 158 // static resolving calls (will not run any Java code); used only from Bytecode_invoke::static_target
147 static void resolve_method_statically(methodHandle& method_result, KlassHandle& klass_result, 159 static void resolve_method_statically(methodHandle& method_result, KlassHandle& klass_result,
148 Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS); 160 Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS);
149 161
150 // runtime/static resolving for fields 162 // runtime/static resolving for fields
151 static void resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS); 163 static void resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS);
152 // takes an extra bool argument "update_pool" to decide whether to update the constantPool during klass resolution. 164 static void resolve_field(fieldDescriptor& result, KlassHandle resolved_klass, Symbol* field_name, Symbol* field_signature,
153 static void resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS); 165 KlassHandle current_klass, Bytecodes::Code access_kind, bool check_access, bool initialize_class, TRAPS);
166
167 // source of access_kind codes:
168 static Bytecodes::Code field_access_kind(bool is_static, bool is_put) {
169 return (is_static
170 ? (is_put ? Bytecodes::_putstatic : Bytecodes::_getstatic)
171 : (is_put ? Bytecodes::_putfield : Bytecodes::_getfield ));
172 }
154 173
155 // runtime resolving: 174 // runtime resolving:
156 // resolved_klass = specified class (i.e., static receiver class) 175 // resolved_klass = specified class (i.e., static receiver class)
157 // current_klass = sending method holder (i.e., class containing the method containing the call being resolved) 176 // current_klass = sending method holder (i.e., class containing the method containing the call being resolved)
158 static void resolve_static_call (CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool initialize_klass, TRAPS); 177 static void resolve_static_call (CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool initialize_klass, TRAPS);