comparison src/share/vm/oops/cpCache.cpp @ 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 a1ebd310d5c1
children 190899198332
comparison
equal deleted inserted replaced
12261:2c98370f2611 12264:b2e698d2276c
138 } 138 }
139 guarantee(parameter_size() == value, 139 guarantee(parameter_size() == value,
140 err_msg("size must not change: parameter_size=%d, value=%d", parameter_size(), value)); 140 err_msg("size must not change: parameter_size=%d, value=%d", parameter_size(), value));
141 } 141 }
142 142
143 void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, 143 void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code,
144 methodHandle method, 144 methodHandle method,
145 int vtable_index) { 145 int vtable_index) {
146 bool is_vtable_call = (vtable_index >= 0); // FIXME: split this method on this boolean
146 assert(method->interpreter_entry() != NULL, "should have been set at this point"); 147 assert(method->interpreter_entry() != NULL, "should have been set at this point");
147 assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); 148 assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache");
148 149
149 int byte_no = -1; 150 int byte_no = -1;
150 bool change_to_virtual = false; 151 bool change_to_virtual = false;
158 change_to_virtual = true; 159 change_to_virtual = true;
159 160
160 // ...and fall through as if we were handling invokevirtual: 161 // ...and fall through as if we were handling invokevirtual:
161 case Bytecodes::_invokevirtual: 162 case Bytecodes::_invokevirtual:
162 { 163 {
163 if (method->can_be_statically_bound()) { 164 if (!is_vtable_call) {
165 assert(method->can_be_statically_bound(), "");
164 // set_f2_as_vfinal_method checks if is_vfinal flag is true. 166 // set_f2_as_vfinal_method checks if is_vfinal flag is true.
165 set_method_flags(as_TosState(method->result_type()), 167 set_method_flags(as_TosState(method->result_type()),
166 ( 1 << is_vfinal_shift) | 168 ( 1 << is_vfinal_shift) |
167 ((method->is_final_method() ? 1 : 0) << is_final_shift) | 169 ((method->is_final_method() ? 1 : 0) << is_final_shift) |
168 ((change_to_virtual ? 1 : 0) << is_forced_virtual_shift), 170 ((change_to_virtual ? 1 : 0) << is_forced_virtual_shift),
169 method()->size_of_parameters()); 171 method()->size_of_parameters());
170 set_f2_as_vfinal_method(method()); 172 set_f2_as_vfinal_method(method());
171 } else { 173 } else {
174 assert(!method->can_be_statically_bound(), "");
172 assert(vtable_index >= 0, "valid index"); 175 assert(vtable_index >= 0, "valid index");
173 assert(!method->is_final_method(), "sanity"); 176 assert(!method->is_final_method(), "sanity");
174 set_method_flags(as_TosState(method->result_type()), 177 set_method_flags(as_TosState(method->result_type()),
175 ((change_to_virtual ? 1 : 0) << is_forced_virtual_shift), 178 ((change_to_virtual ? 1 : 0) << is_forced_virtual_shift),
176 method()->size_of_parameters()); 179 method()->size_of_parameters());
180 break; 183 break;
181 } 184 }
182 185
183 case Bytecodes::_invokespecial: 186 case Bytecodes::_invokespecial:
184 case Bytecodes::_invokestatic: 187 case Bytecodes::_invokestatic:
188 assert(!is_vtable_call, "");
185 // Note: Read and preserve the value of the is_vfinal flag on any 189 // Note: Read and preserve the value of the is_vfinal flag on any
186 // invokevirtual bytecode shared with this constant pool cache entry. 190 // invokevirtual bytecode shared with this constant pool cache entry.
187 // It is cheap and safe to consult is_vfinal() at all times. 191 // It is cheap and safe to consult is_vfinal() at all times.
188 // Once is_vfinal is set, it must stay that way, lest we get a dangling oop. 192 // Once is_vfinal is set, it must stay that way, lest we get a dangling oop.
189 set_method_flags(as_TosState(method->result_type()), 193 set_method_flags(as_TosState(method->result_type()),
230 ShouldNotReachHere(); 234 ShouldNotReachHere();
231 } 235 }
232 NOT_PRODUCT(verify(tty)); 236 NOT_PRODUCT(verify(tty));
233 } 237 }
234 238
235 239 void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, methodHandle method) {
236 void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index) { 240 int index = Method::nonvirtual_vtable_index;
241 // index < 0; FIXME: inline and customize set_direct_or_vtable_call
242 set_direct_or_vtable_call(invoke_code, method, index);
243 }
244
245 void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
246 // either the method is a miranda or its holder should accept the given index
247 assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), "");
248 // index >= 0; FIXME: inline and customize set_direct_or_vtable_call
249 set_direct_or_vtable_call(invoke_code, method, index);
250 }
251
252 void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
253 assert(method->method_holder()->verify_itable_index(index), "");
254 assert(invoke_code == Bytecodes::_invokeinterface, "");
237 InstanceKlass* interf = method->method_holder(); 255 InstanceKlass* interf = method->method_holder();
238 assert(interf->is_interface(), "must be an interface"); 256 assert(interf->is_interface(), "must be an interface");
239 assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here"); 257 assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here");
240 set_f1(interf); 258 set_f1(interf);
241 set_f2(index); 259 set_f2(index);