< prev index next >
src/share/vm/oops/klassVtable.cpp
Print this page
@@ -224,11 +224,11 @@
}
for (int i = 0; i < len; i++) {
HandleMark hm(THREAD);
assert(default_methods->at(i)->is_method(), "must be a Method*");
methodHandle mh(THREAD, default_methods->at(i));
-
+ assert(!mh()->is_private(), "private interface method in the default method list");
bool needs_new_entry = update_inherited_vtable(ik(), mh, super_vtable_len, i, checkconstraints, CHECK);
// needs new entry
if (needs_new_entry) {
put_method_at(mh(), initialized);
@@ -360,18 +360,20 @@
bool allocate_new = true;
assert(klass->is_instance_klass(), "must be InstanceKlass");
Array<int>* def_vtable_indices = NULL;
bool is_default = false;
- // default methods are concrete methods in superinterfaces which are added to the vtable
- // with their real method_holder
+
+ // default methods are non-private concrete methods in superinterfaces which are added
+ // to the vtable with their real method_holder.
// Since vtable and itable indices share the same storage, don't touch
- // the default method's real vtable/itable index
+ // the default method's real vtable/itable index.
// default_vtable_indices stores the vtable value relative to this inheritor
if (default_index >= 0 ) {
is_default = true;
def_vtable_indices = klass->default_vtable_indices();
+ assert(!target_method()->is_private(), "private interface method flagged as default");
assert(def_vtable_indices != NULL, "def vtable alloc?");
assert(default_index <= def_vtable_indices->length(), "def vtable len?");
} else {
assert(klass == target_method()->method_holder(), "caller resp.");
// Initialize the method's vtable index to "nonvirtual".
@@ -393,16 +395,19 @@
allocate_new = false; // see note below in needs_new_vtable_entry
// An interface never allocates new vtable slots, only inherits old ones.
// This method will either be assigned its own itable index later,
// or be assigned an inherited vtable index in the loop below.
// default methods inherited by classes store their vtable indices
- // in the inheritor's default_vtable_indices
+ // in the inheritor's default_vtable_indices.
// default methods inherited by interfaces may already have a
- // valid itable index, if so, don't change it
- // overpass methods in an interface will be assigned an itable index later
- // by an inheriting class
- if (!is_default || !target_method()->has_itable_index()) {
+ // valid itable index, if so, don't change it.
+ // Overpass methods in an interface will be assigned an itable index later
+ // by an inheriting class.
+ // Private interface methods have no itable index and are always invoked nonvirtually,
+ // so they retain their nonvirtual_vtable_index value, and therefore can_be_statically_bound()
+ // will return true.
+ if ((!is_default || !target_method()->has_itable_index()) && !target_method()->is_private()) {
target_method()->set_vtable_index(Method::pending_itable_index);
}
}
// we need a new entry if there is no superclass
@@ -595,23 +600,23 @@
// Concrete interface methods do not need new entries, they override
// abstract method entries using default inheritance rules
if (target_method()->method_holder() != NULL &&
target_method()->method_holder()->is_interface() &&
- !target_method()->is_abstract() ) {
+ !target_method()->is_abstract()) {
+ assert(target_method()->is_default_method() || target_method()->is_private(),
+ "unexpected interface method type");
return false;
}
// we need a new entry if there is no superclass
if (super == NULL) {
return true;
}
- // private methods in classes always have a new entry in the vtable
- // specification interpretation since classic has
- // private methods not overriding
- // JDK8 adds private methods in interfaces which require invokespecial
+ // private methods in classes always have a new entry in the vtable.
+ // Specification interpretation since classic has private methods not overriding.
if (target_method()->is_private()) {
return true;
}
// Package private methods always need a new entry to root their own
@@ -1086,10 +1091,11 @@
inline bool interface_method_needs_itable_index(Method* m) {
if (m->is_static()) return false; // e.g., Stream.empty
if (m->is_initializer()) return false; // <init> or <clinit>
+ if (m->is_private()) return false; // requires invokeSpecial
// If an interface redeclares a method from java.lang.Object,
// it should already have a vtable index, don't touch it.
// e.g., CharSequence.toString (from initialize_vtable)
// if (m->has_vtable_index()) return false; // NO!
return true;
< prev index next >