< 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 >