< prev index next >

src/hotspot/share/oops/cpCache.cpp

Print this page
rev 50604 : imported patch jep181-rev1


 157   // bother trying to update it once it's nonzero but always make
 158   // sure that the final parameter size agrees with what was passed.
 159   if (_flags == 0) {
 160     intx newflags = (value & parameter_size_mask);
 161     Atomic::cmpxchg(newflags, &_flags, (intx)0);
 162   }
 163   guarantee(parameter_size() == value,
 164             "size must not change: parameter_size=%d, value=%d", parameter_size(), value);
 165 }
 166 
 167 void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code,
 168                                                        const methodHandle& method,
 169                                                        int vtable_index,
 170                                                        bool sender_is_interface) {
 171   bool is_vtable_call = (vtable_index >= 0);  // FIXME: split this method on this boolean
 172   assert(method->interpreter_entry() != NULL, "should have been set at this point");
 173   assert(!method->is_obsolete(),  "attempt to write obsolete method to cpCache");
 174 
 175   int byte_no = -1;
 176   bool change_to_virtual = false;
 177 
 178   switch (invoke_code) {
 179     case Bytecodes::_invokeinterface:
















 180       // We get here from InterpreterRuntime::resolve_invoke when an invokeinterface
 181       // instruction somehow links to a non-interface method (in Object).


 182       // In that case, the method has no itable index and must be invoked as a virtual.
 183       // Set a flag to keep track of this corner case.

 184       assert(method->is_public(), "Calling non-public method in Object with invokeinterface");
 185       change_to_virtual = true;
 186 
 187       // ...and fall through as if we were handling invokevirtual:

 188     case Bytecodes::_invokevirtual:
 189       {
 190         if (!is_vtable_call) {
 191           assert(method->can_be_statically_bound(), "");
 192           // set_f2_as_vfinal_method checks if is_vfinal flag is true.
 193           set_method_flags(as_TosState(method->result_type()),
 194                            (                             1      << is_vfinal_shift) |
 195                            ((method->is_final_method() ? 1 : 0) << is_final_shift)  |
 196                            ((change_to_virtual         ? 1 : 0) << is_forced_virtual_shift),
 197                            method()->size_of_parameters());
 198           set_f2_as_vfinal_method(method());
 199         } else {
 200           assert(!method->can_be_statically_bound(), "");
 201           assert(vtable_index >= 0, "valid index");
 202           assert(!method->is_final_method(), "sanity");
 203           set_method_flags(as_TosState(method->result_type()),
 204                            ((change_to_virtual ? 1 : 0) << is_forced_virtual_shift),
 205                            method()->size_of_parameters());
 206           set_f2(vtable_index);
 207         }


 240     set_bytecode_1(invoke_code);
 241     }
 242   } else if (byte_no == 2)  {
 243     if (change_to_virtual) {
 244       assert(invoke_code == Bytecodes::_invokeinterface, "");
 245       // NOTE: THIS IS A HACK - BE VERY CAREFUL!!!
 246       //
 247       // Workaround for the case where we encounter an invokeinterface, but we
 248       // should really have an _invokevirtual since the resolved method is a
 249       // virtual method in java.lang.Object. This is a corner case in the spec
 250       // but is presumably legal. javac does not generate this code.
 251       //
 252       // We do not set bytecode_1() to _invokeinterface, because that is the
 253       // bytecode # used by the interpreter to see if it is resolved.  In this
 254       // case, the method gets reresolved with caller for each interface call
 255       // because the actual selected method may not be public.
 256       //
 257       // We set bytecode_2() to _invokevirtual.
 258       // See also interpreterRuntime.cpp. (8/25/2000)
 259     } else {
 260       assert(invoke_code == Bytecodes::_invokevirtual, "");











 261     }
 262     // set up for invokevirtual, even if linking for invokeinterface also:
 263     set_bytecode_2(Bytecodes::_invokevirtual);
 264   } else {
 265     ShouldNotReachHere();
 266   }
 267   NOT_PRODUCT(verify(tty));
 268 }
 269 
 270 void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, const methodHandle& method,
 271                                              bool sender_is_interface) {
 272   int index = Method::nonvirtual_vtable_index;
 273   // index < 0; FIXME: inline and customize set_direct_or_vtable_call
 274   set_direct_or_vtable_call(invoke_code, method, index, sender_is_interface);
 275 }
 276 
 277 void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, const methodHandle& method, int index) {
 278   // either the method is a miranda or its holder should accept the given index
 279   assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), "");
 280   // index >= 0; FIXME: inline and customize set_direct_or_vtable_call




 157   // bother trying to update it once it's nonzero but always make
 158   // sure that the final parameter size agrees with what was passed.
 159   if (_flags == 0) {
 160     intx newflags = (value & parameter_size_mask);
 161     Atomic::cmpxchg(newflags, &_flags, (intx)0);
 162   }
 163   guarantee(parameter_size() == value,
 164             "size must not change: parameter_size=%d, value=%d", parameter_size(), value);
 165 }
 166 
 167 void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code,
 168                                                        const methodHandle& method,
 169                                                        int vtable_index,
 170                                                        bool sender_is_interface) {
 171   bool is_vtable_call = (vtable_index >= 0);  // FIXME: split this method on this boolean
 172   assert(method->interpreter_entry() != NULL, "should have been set at this point");
 173   assert(!method->is_obsolete(),  "attempt to write obsolete method to cpCache");
 174 
 175   int byte_no = -1;
 176   bool change_to_virtual = false;
 177   InstanceKlass* holder = NULL;  // have to declare this outside the switch
 178   switch (invoke_code) {
 179     case Bytecodes::_invokeinterface:
 180       holder = method->method_holder();
 181       // check for private interface method invocations
 182       if (vtable_index == Method::nonvirtual_vtable_index && holder->is_interface() ) {
 183         assert(method->is_private(), "unexpected non-private method");
 184         assert(method->can_be_statically_bound(), "unexpected non-statically-bound method");
 185         // set_f2_as_vfinal_method checks if is_vfinal flag is true.
 186         set_method_flags(as_TosState(method->result_type()),
 187                          (                             1      << is_vfinal_shift) |
 188                          ((method->is_final_method() ? 1 : 0) << is_final_shift),
 189                          method()->size_of_parameters());
 190         set_f2_as_vfinal_method(method());
 191         byte_no = 2;
 192         set_f1(holder); // interface klass*
 193         break;
 194       }
 195       else {
 196         // We get here from InterpreterRuntime::resolve_invoke when an invokeinterface
 197         // instruction links to a non-interface method (in Object). This can happen when
 198         // an interface redeclares an Object method (like CharSequence declaring toString())
 199         // or when invokeinterface is used explicitly.
 200         // In that case, the method has no itable index and must be invoked as a virtual.
 201         // Set a flag to keep track of this corner case.
 202         assert(holder->is_interface() || holder == SystemDictionary::Object_klass(), "unexpected holder class");
 203         assert(method->is_public(), "Calling non-public method in Object with invokeinterface");
 204         change_to_virtual = true;
 205 
 206         // ...and fall through as if we were handling invokevirtual:
 207       }
 208     case Bytecodes::_invokevirtual:
 209       {
 210         if (!is_vtable_call) {
 211           assert(method->can_be_statically_bound(), "");
 212           // set_f2_as_vfinal_method checks if is_vfinal flag is true.
 213           set_method_flags(as_TosState(method->result_type()),
 214                            (                             1      << is_vfinal_shift) |
 215                            ((method->is_final_method() ? 1 : 0) << is_final_shift)  |
 216                            ((change_to_virtual         ? 1 : 0) << is_forced_virtual_shift),
 217                            method()->size_of_parameters());
 218           set_f2_as_vfinal_method(method());
 219         } else {
 220           assert(!method->can_be_statically_bound(), "");
 221           assert(vtable_index >= 0, "valid index");
 222           assert(!method->is_final_method(), "sanity");
 223           set_method_flags(as_TosState(method->result_type()),
 224                            ((change_to_virtual ? 1 : 0) << is_forced_virtual_shift),
 225                            method()->size_of_parameters());
 226           set_f2(vtable_index);
 227         }


 260       set_bytecode_1(invoke_code);
 261     }
 262   } else if (byte_no == 2)  {
 263     if (change_to_virtual) {
 264       assert(invoke_code == Bytecodes::_invokeinterface, "");
 265       // NOTE: THIS IS A HACK - BE VERY CAREFUL!!!
 266       //
 267       // Workaround for the case where we encounter an invokeinterface, but we
 268       // should really have an _invokevirtual since the resolved method is a
 269       // virtual method in java.lang.Object. This is a corner case in the spec
 270       // but is presumably legal. javac does not generate this code.
 271       //
 272       // We do not set bytecode_1() to _invokeinterface, because that is the
 273       // bytecode # used by the interpreter to see if it is resolved.  In this
 274       // case, the method gets reresolved with caller for each interface call
 275       // because the actual selected method may not be public.
 276       //
 277       // We set bytecode_2() to _invokevirtual.
 278       // See also interpreterRuntime.cpp. (8/25/2000)
 279     } else {
 280       assert(invoke_code == Bytecodes::_invokevirtual ||
 281              (invoke_code == Bytecodes::_invokeinterface &&
 282               ((method->is_private() ||
 283                 (method->is_final() && method->method_holder() == SystemDictionary::Object_klass())))),
 284              "unexpected invocation mode");
 285       if (invoke_code == Bytecodes::_invokeinterface &&
 286           (method->is_private() || method->is_final())) {
 287         // We set bytecode_1() to _invokeinterface, because that is the
 288         // bytecode # used by the interpreter to see if it is resolved.
 289         // We set bytecode_2() to _invokevirtual.
 290         set_bytecode_1(invoke_code);
 291       }
 292     }
 293     // set up for invokevirtual, even if linking for invokeinterface also:
 294     set_bytecode_2(Bytecodes::_invokevirtual);
 295   } else {
 296     ShouldNotReachHere();
 297   }
 298   NOT_PRODUCT(verify(tty));
 299 }
 300 
 301 void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, const methodHandle& method,
 302                                              bool sender_is_interface) {
 303   int index = Method::nonvirtual_vtable_index;
 304   // index < 0; FIXME: inline and customize set_direct_or_vtable_call
 305   set_direct_or_vtable_call(invoke_code, method, index, sender_is_interface);
 306 }
 307 
 308 void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, const methodHandle& method, int index) {
 309   // either the method is a miranda or its holder should accept the given index
 310   assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), "");
 311   // index >= 0; FIXME: inline and customize set_direct_or_vtable_call


< prev index next >