< prev index next >

src/hotspot/share/opto/doCall.cpp

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -503,19 +503,28 @@
                                       receiver_type, is_virtual,
                                       call_does_dispatch, vtable_index);  // out-parameters
     speculative_receiver_type = receiver_type != NULL ? receiver_type->speculative_type() : NULL;
   }
 
-  // invoke-super-special
+  // Additional receiver subtype checks for interface calls via invokespecial or invokeinterface.
+  ciKlass* receiver_constraint = NULL;
   if (iter().cur_bc_raw() == Bytecodes::_invokespecial && !orig_callee->is_object_initializer()) {
     ciInstanceKlass* calling_klass = method()->holder();
     ciInstanceKlass* sender_klass =
         calling_klass->is_anonymous() ? calling_klass->host_klass() :
                                         calling_klass;
     if (sender_klass->is_interface()) {
+      receiver_constraint = sender_klass;
+    }
+  } else if (iter().cur_bc_raw() == Bytecodes::_invokeinterface && orig_callee->is_private()) {
+    assert(holder->is_interface(), "How did we get a non-interface method here!");
+    receiver_constraint = holder;
+  }
+
+  if (receiver_constraint != NULL) {
       Node* receiver_node = stack(sp() - nargs);
-      Node* cls_node = makecon(TypeKlassPtr::make(sender_klass));
+    Node* cls_node = makecon(TypeKlassPtr::make(receiver_constraint));
       Node* bad_type_ctrl = NULL;
       Node* casted_receiver = gen_checkcast(receiver_node, cls_node, &bad_type_ctrl);
       if (bad_type_ctrl != NULL) {
         PreserveJVMState pjvms(this);
         set_control(bad_type_ctrl);

@@ -525,11 +534,10 @@
       if (stopped()) {
         return; // MUST uncommon-trap?
       }
       set_stack(sp() - nargs, casted_receiver);
     }
-  }
 
   // Note:  It's OK to try to inline a virtual call.
   // The call generator will not attempt to inline a polymorphic call
   // unless it knows how to optimize the receiver dispatch.
   bool try_inline = (C->do_inlining() || InlineAccessors);
< prev index next >