# HG changeset patch # User mgerdin # Date 1453201652 -3600 # Node ID d64cf9290fc4cf4ee638bc4f7fe33af154772d27 # Parent 0dbc821628fc9f036fb23cd10fa5e9776948a0f5 8148481: Devirtualize Klass::vtable Summary: Move remainder of vtable related methods to Klass Reviewed-by: cjplummer, coleenp diff -r 0dbc821628fc -r d64cf9290fc4 hotspot/src/share/vm/interpreter/linkResolver.cpp --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Tue Dec 01 10:35:49 2015 +0100 +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Tue Jan 19 12:07:32 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -168,7 +168,7 @@ } else if (!resolved_klass->is_interface()) { // A default or miranda method. Compute the vtable index. ResourceMark rm; - klassVtable* vt = InstanceKlass::cast(resolved_klass)->vtable(); + klassVtable* vt = resolved_klass->vtable(); index = LinkResolver::vtable_index_of_interface_method(resolved_klass, resolved_method); assert(index >= 0 , "we should have valid vtable index at this point"); @@ -1227,8 +1227,7 @@ resolved_method); assert(vtable_index >= 0 , "we should have valid vtable index at this point"); - InstanceKlass* inst = InstanceKlass::cast(recv_klass()); - selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); + selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index)); } else { // at this point we are sure that resolved_method is virtual and not // a default or miranda method; therefore, it must have a valid vtable index. @@ -1243,10 +1242,7 @@ assert(resolved_method->can_be_statically_bound(), "cannot override this method"); selected_method = resolved_method; } else { - // recv_klass might be an arrayKlassOop but all vtables start at - // the same place. The cast is to avoid virtual call and assertion. - InstanceKlass* inst = (InstanceKlass*)recv_klass(); - selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); + selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index)); } } diff -r 0dbc821628fc -r d64cf9290fc4 hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp --- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Tue Dec 01 10:35:49 2015 +0100 +++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Tue Jan 19 12:07:32 2016 +0100 @@ -655,8 +655,7 @@ vtable_index = LinkResolver::vtable_index_of_interface_method(holder_klass, resolved_method); assert(vtable_index >= 0 , "we should have valid vtable index at this point"); - InstanceKlass* inst = InstanceKlass::cast(recv_klass); - selected_method = inst->method_at_vtable(vtable_index); + selected_method = recv_klass->method_at_vtable(vtable_index); } else { // at this point we are sure that resolved_method is virtual and not // a miranda method; therefore, it must have a valid vtable index. @@ -671,10 +670,7 @@ assert(resolved_method->can_be_statically_bound(), "cannot override this method"); selected_method = resolved_method(); } else { - // recv_klass might be an arrayKlassOop but all vtables start at - // the same place. The cast is to avoid virtual call and assertion. - InstanceKlass* inst = (InstanceKlass*)recv_klass; - selected_method = inst->method_at_vtable(vtable_index); + selected_method = recv_klass->method_at_vtable(vtable_index); } } oop result = CompilerToVM::get_jvmci_method(selected_method, CHECK_NULL); diff -r 0dbc821628fc -r d64cf9290fc4 hotspot/src/share/vm/oops/arrayKlass.cpp --- a/hotspot/src/share/vm/oops/arrayKlass.cpp Tue Dec 01 10:35:49 2015 +0100 +++ b/hotspot/src/share/vm/oops/arrayKlass.cpp Tue Jan 19 12:07:32 2016 +0100 @@ -117,19 +117,6 @@ || k == SystemDictionary::Serializable_klass(); } - -inline intptr_t* ArrayKlass::start_of_vtable() const { - // all vtables start at the same place, that's why we use InstanceKlass::header_size here - return ((intptr_t*)this) + InstanceKlass::header_size(); -} - - -klassVtable* ArrayKlass::vtable() const { - KlassHandle kh(Thread::current(), this); - return new klassVtable(kh, start_of_vtable(), vtable_length() / vtableEntry::size()); -} - - objArrayOop ArrayKlass::allocate_arrayArray(int n, int length, TRAPS) { if (length < 0) { THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); diff -r 0dbc821628fc -r d64cf9290fc4 hotspot/src/share/vm/oops/arrayKlass.hpp --- a/hotspot/src/share/vm/oops/arrayKlass.hpp Tue Dec 01 10:35:49 2015 +0100 +++ b/hotspot/src/share/vm/oops/arrayKlass.hpp Tue Jan 19 12:07:32 2016 +0100 @@ -98,7 +98,6 @@ bool compute_is_subtype_of(Klass* k); // Sizing - static int header_size() { return sizeof(ArrayKlass)/wordSize; } static int static_size(int header_size); #if INCLUDE_SERVICES @@ -109,12 +108,6 @@ } #endif - // Java vtable - klassVtable* vtable() const; // return new klassVtable - protected: - inline intptr_t* start_of_vtable() const; - - public: // Iterators void array_klasses_do(void f(Klass* k)); void array_klasses_do(void f(Klass* k, TRAPS), TRAPS); diff -r 0dbc821628fc -r d64cf9290fc4 hotspot/src/share/vm/oops/cpCache.cpp --- a/hotspot/src/share/vm/oops/cpCache.cpp Tue Dec 01 10:35:49 2015 +0100 +++ b/hotspot/src/share/vm/oops/cpCache.cpp Tue Jan 19 12:07:32 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, 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 @@ -394,9 +394,7 @@ int holder_index = cpool->uncached_klass_ref_index_at(constant_pool_index()); if (cpool->tag_at(holder_index).is_klass()) { Klass* klass = cpool->resolved_klass_at(holder_index); - if (!klass->is_instance_klass()) - klass = SystemDictionary::Object_klass(); - return InstanceKlass::cast(klass)->method_at_vtable(f2_as_index()); + return klass->method_at_vtable(f2_as_index()); } } break; diff -r 0dbc821628fc -r d64cf9290fc4 hotspot/src/share/vm/oops/instanceKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlass.cpp Tue Dec 01 10:35:49 2015 +0100 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Tue Jan 19 12:07:32 2016 +0100 @@ -364,10 +364,6 @@ return !is_initialized(); } -klassVtable* InstanceKlass::vtable() const { - return new klassVtable(this, start_of_vtable(), vtable_length() / vtableEntry::size()); -} - klassItable* InstanceKlass::itable() const { return new klassItable(instanceKlassHandle(this)); } @@ -2667,6 +2663,10 @@ } } +static void print_vtable(vtableEntry* start, int len, outputStream* st) { + return print_vtable(reinterpret_cast(start), len, st); +} + void InstanceKlass::print_on(outputStream* st) const { assert(is_klass(), "must be klass"); Klass::print_on(st); diff -r 0dbc821628fc -r d64cf9290fc4 hotspot/src/share/vm/oops/instanceKlass.hpp --- a/hotspot/src/share/vm/oops/instanceKlass.hpp Tue Dec 01 10:35:49 2015 +0100 +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Tue Jan 19 12:07:32 2016 +0100 @@ -944,12 +944,11 @@ virtual void collect_statistics(KlassSizeStats *sz) const; #endif - intptr_t* start_of_vtable() const { return (intptr_t*) ((address)this + in_bytes(vtable_start_offset())); } - intptr_t* start_of_itable() const { return start_of_vtable() + vtable_length(); } + intptr_t* start_of_itable() const { return (intptr_t*)start_of_vtable() + vtable_length(); } + intptr_t* end_of_itable() const { return start_of_itable() + itable_length(); } + int itable_offset_in_words() const { return start_of_itable() - (intptr_t*)this; } - intptr_t* end_of_itable() const { return start_of_itable() + itable_length(); } - address static_field_addr(int offset); OopMapBlock* start_of_nonstatic_oop_maps() const { @@ -997,9 +996,7 @@ return !layout_helper_needs_slow_path(layout_helper()); } - // Java vtable/itable - klassVtable* vtable() const; // return new klassVtable wrapper - inline Method* method_at_vtable(int index); + // Java itable klassItable* itable() const; // return new klassItable wrapper Method* method_at_itable(Klass* holder, int index, TRAPS); @@ -1249,17 +1246,6 @@ void oop_verify_on(oop obj, outputStream* st); }; -inline Method* InstanceKlass::method_at_vtable(int index) { -#ifndef PRODUCT - assert(index >= 0, "valid vtable index"); - if (DebugVtables) { - verify_vtable_index(index); - } -#endif - vtableEntry* ve = (vtableEntry*)start_of_vtable(); - return ve[index].method(); -} - // for adding methods // UNSET_IDNUM return means no more ids available inline u2 InstanceKlass::next_method_idnum() { diff -r 0dbc821628fc -r d64cf9290fc4 hotspot/src/share/vm/oops/klass.cpp --- a/hotspot/src/share/vm/oops/klass.cpp Tue Dec 01 10:35:49 2015 +0100 +++ b/hotspot/src/share/vm/oops/klass.cpp Tue Jan 19 12:07:32 2016 +0100 @@ -659,6 +659,24 @@ guarantee(obj->klass()->is_klass(), "klass field is not a klass"); } +klassVtable* Klass::vtable() const { + return new klassVtable(this, start_of_vtable(), vtable_length() / vtableEntry::size()); +} + +vtableEntry* Klass::start_of_vtable() const { + return (vtableEntry*) ((address)this + in_bytes(vtable_start_offset())); +} + +Method* Klass::method_at_vtable(int index) { +#ifndef PRODUCT + assert(index >= 0, "valid vtable index"); + if (DebugVtables) { + verify_vtable_index(index); + } +#endif + return start_of_vtable()[index].method(); +} + ByteSize Klass::vtable_start_offset() { return in_ByteSize(InstanceKlass::header_size() * wordSize); } diff -r 0dbc821628fc -r d64cf9290fc4 hotspot/src/share/vm/oops/klass.hpp --- a/hotspot/src/share/vm/oops/klass.hpp Tue Dec 01 10:35:49 2015 +0100 +++ b/hotspot/src/share/vm/oops/klass.hpp Tue Jan 19 12:07:32 2016 +0100 @@ -57,6 +57,7 @@ class PSPromotionManager; class KlassSizeStats; class fieldDescriptor; +class vtableEntry; class Klass : public Metadata { friend class VMStructs; @@ -377,7 +378,7 @@ #endif // vtables - virtual klassVtable* vtable() const = 0; + klassVtable* vtable() const; int vtable_length() const { return _vtable_len; } // subclass check @@ -443,7 +444,10 @@ void set_vtable_length(int len) { _vtable_len= len; } + vtableEntry* start_of_vtable() const; public: + Method* method_at_vtable(int index); + static ByteSize vtable_start_offset(); static ByteSize vtable_length_offset() { return byte_offset_of(Klass, _vtable_len); diff -r 0dbc821628fc -r d64cf9290fc4 hotspot/src/share/vm/prims/jni.cpp --- a/hotspot/src/share/vm/prims/jni.cpp Tue Dec 01 10:35:49 2015 +0100 +++ b/hotspot/src/share/vm/prims/jni.cpp Tue Jan 19 12:07:32 2016 +0100 @@ -1131,11 +1131,7 @@ assert(m->valid_vtable_index(), "no valid vtable index"); int vtbl_index = m->vtable_index(); if (vtbl_index != Method::nonvirtual_vtable_index) { - Klass* k = h_recv->klass(); - // k might be an arrayKlassOop but all vtables start at - // the same place. The cast is to avoid virtual call and assertion. - InstanceKlass *ik = (InstanceKlass*)k; - selected_method = ik->method_at_vtable(vtbl_index); + selected_method = h_recv->klass()->method_at_vtable(vtbl_index); } else { // final method selected_method = m; diff -r 0dbc821628fc -r d64cf9290fc4 hotspot/src/share/vm/runtime/reflection.cpp --- a/hotspot/src/share/vm/runtime/reflection.cpp Tue Dec 01 10:35:49 2015 +0100 +++ b/hotspot/src/share/vm/runtime/reflection.cpp Tue Jan 19 12:07:32 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -939,10 +939,7 @@ int index = reflected_method->vtable_index(); method = reflected_method; if (index != Method::nonvirtual_vtable_index) { - // target_klass might be an arrayKlassOop but all vtables start at - // the same place. The cast is to avoid virtual call and assertion. - InstanceKlass* inst = (InstanceKlass*)target_klass(); - method = methodHandle(THREAD, inst->method_at_vtable(index)); + method = methodHandle(THREAD, target_klass->method_at_vtable(index)); } if (!method.is_null()) { // Check for abstract methods as well diff -r 0dbc821628fc -r d64cf9290fc4 hotspot/src/share/vm/utilities/debug.cpp --- a/hotspot/src/share/vm/utilities/debug.cpp Tue Dec 01 10:35:49 2015 +0100 +++ b/hotspot/src/share/vm/utilities/debug.cpp Tue Jan 19 12:07:32 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -461,7 +461,7 @@ extern "C" void dump_vtable(address p) { Command c("dump_vtable"); Klass* k = (Klass*)p; - InstanceKlass::cast(k)->vtable()->print(); + k->vtable()->print(); }