hotspot/src/share/vm/oops/cpCache.cpp
changeset 20017 81eba62e9048
parent 17858 c292f8791cca
child 20282 7f9cbdf89af2
--- a/hotspot/src/share/vm/oops/cpCache.cpp	Tue Sep 17 23:12:27 2013 +0200
+++ b/hotspot/src/share/vm/oops/cpCache.cpp	Fri Sep 13 22:38:02 2013 -0400
@@ -140,9 +140,10 @@
             err_msg("size must not change: parameter_size=%d, value=%d", parameter_size(), value));
 }
 
-void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
-                                        methodHandle method,
-                                        int vtable_index) {
+void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code,
+                                                       methodHandle method,
+                                                       int vtable_index) {
+  bool is_vtable_call = (vtable_index >= 0);  // FIXME: split this method on this boolean
   assert(method->interpreter_entry() != NULL, "should have been set at this point");
   assert(!method->is_obsolete(),  "attempt to write obsolete method to cpCache");
 
@@ -160,7 +161,8 @@
       // ...and fall through as if we were handling invokevirtual:
     case Bytecodes::_invokevirtual:
       {
-        if (method->can_be_statically_bound()) {
+        if (!is_vtable_call) {
+          assert(method->can_be_statically_bound(), "");
           // set_f2_as_vfinal_method checks if is_vfinal flag is true.
           set_method_flags(as_TosState(method->result_type()),
                            (                             1      << is_vfinal_shift) |
@@ -169,6 +171,7 @@
                            method()->size_of_parameters());
           set_f2_as_vfinal_method(method());
         } else {
+          assert(!method->can_be_statically_bound(), "");
           assert(vtable_index >= 0, "valid index");
           assert(!method->is_final_method(), "sanity");
           set_method_flags(as_TosState(method->result_type()),
@@ -182,6 +185,7 @@
 
     case Bytecodes::_invokespecial:
     case Bytecodes::_invokestatic:
+      assert(!is_vtable_call, "");
       // Note:  Read and preserve the value of the is_vfinal flag on any
       // invokevirtual bytecode shared with this constant pool cache entry.
       // It is cheap and safe to consult is_vfinal() at all times.
@@ -232,8 +236,22 @@
   NOT_PRODUCT(verify(tty));
 }
 
+void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, methodHandle method) {
+  int index = Method::nonvirtual_vtable_index;
+  // index < 0; FIXME: inline and customize set_direct_or_vtable_call
+  set_direct_or_vtable_call(invoke_code, method, index);
+}
 
-void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index) {
+void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
+  // either the method is a miranda or its holder should accept the given index
+  assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), "");
+  // index >= 0; FIXME: inline and customize set_direct_or_vtable_call
+  set_direct_or_vtable_call(invoke_code, method, index);
+}
+
+void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
+  assert(method->method_holder()->verify_itable_index(index), "");
+  assert(invoke_code == Bytecodes::_invokeinterface, "");
   InstanceKlass* interf = method->method_holder();
   assert(interf->is_interface(), "must be an interface");
   assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here");