klassVtable.hpp 13.6 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * 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.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29 30 31 32
#ifndef SHARE_VM_OOPS_KLASSVTABLE_HPP
#define SHARE_VM_OOPS_KLASSVTABLE_HPP

#include "memory/allocation.hpp"
#include "oops/oopsHierarchy.hpp"
#include "runtime/handles.hpp"
#include "utilities/growableArray.hpp"

33
// A klassVtable abstracts the variable-length vtable that is embedded in InstanceKlass
34
// and ArrayKlass.  klassVtable objects are used just as convenient transient accessors to the vtable,
D
duke 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
// not to actually hold the vtable data.
// Note: the klassVtable should not be accessed before the class has been verified
// (until that point, the vtable is uninitialized).

// Currently a klassVtable contains a direct reference to the vtable data, and is therefore
// not preserved across GCs.

class vtableEntry;

class klassVtable : public ResourceObj {
  KlassHandle  _klass;            // my klass
  int          _tableOffset;      // offset of start of vtable data within klass
  int          _length;           // length of vtable (number of entries)
#ifndef PRODUCT
  int          _verify_count;     // to make verify faster
#endif

  // Ordering important, so greater_than (>) can be used as an merge operator.
  enum AccessType {
    acc_private         = 0,
    acc_package_private = 1,
    acc_publicprotected = 2
  };

 public:
  klassVtable(KlassHandle h_klass, void* base, int length) : _klass(h_klass) {
    _tableOffset = (address)base - (address)h_klass(); _length = length;
  }

  // accessors
  vtableEntry* table() const      { return (vtableEntry*)(address(_klass()) + _tableOffset); }
  KlassHandle klass() const       { return _klass;  }
  int length() const              { return _length; }
68 69 70
  inline Method* method_at(int i) const;
  inline Method* unchecked_method_at(int i) const;
  inline Method** adr_method_at(int i) const;
D
duke 已提交
71 72

  // searching; all methods return -1 if not found
73
  int index_of(Method* m) const                         { return index_of(m, _length); }
74
  int index_of_miranda(Symbol* name, Symbol* signature);
D
duke 已提交
75 76 77

  void initialize_vtable(bool checkconstraints, TRAPS);   // initialize vtable of a new klass

78 79 80 81 82 83 84 85 86
  // CDS/RedefineClasses support - clear vtables so they can be reinitialized
  // at dump time.  Clearing gives us an easy way to tell if the vtable has
  // already been reinitialized at dump time (see dump.cpp).  Vtables can
  // be initialized at run time by RedefineClasses so dumping the right order
  // is necessary.
  void clear_vtable();
  bool is_initialized();

  // computes vtable length (in words) and the number of miranda methods
87 88 89 90 91
  static void compute_vtable_size_and_num_mirandas(
      int* vtable_length, int* num_new_mirandas,
      GrowableArray<Method*>* all_mirandas, Klass* super,
      Array<Method*>* methods, AccessFlags class_flags, Handle classloader,
      Symbol* classname, Array<Klass*>* local_interfaces, TRAPS);
D
duke 已提交
92

93
#if INCLUDE_JVMTI
D
duke 已提交
94 95 96 97 98 99
  // RedefineClasses() API support:
  // If any entry of this vtable points to any of old_methods,
  // replace it with the corresponding new_method.
  // trace_name_printed is set to true if the current call has
  // printed the klass name so that other routines in the adjust_*
  // group don't print the klass name.
100
  bool adjust_default_method(int vtable_index, Method* old_method, Method* new_method);
101
  void adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed);
102 103 104
  bool check_no_old_or_obsolete_entries();
  void dump_vtable();
#endif // INCLUDE_JVMTI
D
duke 已提交
105 106 107 108 109 110 111 112 113

  // Debugging code
  void print()                                              PRODUCT_RETURN;
  void verify(outputStream* st, bool force = false);
  static void print_statistics()                            PRODUCT_RETURN;

 protected:
  friend class vtableEntry;
 private:
114
  enum { VTABLE_TRANSITIVE_OVERRIDE_VERSION = 51 } ;
D
duke 已提交
115 116
  void copy_vtable_to(vtableEntry* start);
  int  initialize_from_super(KlassHandle super);
117 118 119
  int  index_of(Method* m, int len) const; // same as index_of, but search only up to len
  void put_method_at(Method* m, int index);
  static bool needs_new_vtable_entry(methodHandle m, Klass* super, Handle classloader, Symbol* classname, AccessFlags access_flags, TRAPS);
D
duke 已提交
120

121
  bool update_inherited_vtable(InstanceKlass* klass, methodHandle target_method, int super_vtable_len, int default_index, bool checkconstraints, TRAPS);
122
 InstanceKlass* find_transitive_override(InstanceKlass* initialsuper, methodHandle target_method, int vtable_index,
123
                                         Handle target_loader, Symbol* target_classname, Thread* THREAD);
D
duke 已提交
124 125 126

  // support for miranda methods
  bool is_miranda_entry_at(int i);
127
  int fill_in_mirandas(int initialized);
128 129
  static bool is_miranda(Method* m, Array<Method*>* class_methods,
                         Array<Method*>* default_methods, Klass* super);
130 131 132
  static void add_new_mirandas_to_lists(
      GrowableArray<Method*>* new_mirandas,
      GrowableArray<Method*>* all_mirandas,
133 134 135
      Array<Method*>* current_interface_methods,
      Array<Method*>* class_methods,
      Array<Method*>* default_methods,
136 137 138 139
      Klass* super);
  static void get_mirandas(
      GrowableArray<Method*>* new_mirandas,
      GrowableArray<Method*>* all_mirandas, Klass* super,
140 141 142
      Array<Method*>* class_methods,
      Array<Method*>* default_methods,
      Array<Klass*>* local_interfaces);
D
duke 已提交
143
  void verify_against(outputStream* st, klassVtable* vt, int index);
144
  inline InstanceKlass* ik() const;
145 146 147 148 149 150 151 152 153 154 155 156 157
  // When loading a class from CDS archive at run time, and no class redefintion
  // has happened, it is expected that the class's itable/vtables are
  // laid out exactly the same way as they had been during dump time.
  // Therefore, in klassVtable::initialize_[iv]table, we do not layout the
  // tables again. Instead, we only rerun the process to create/check
  // the class loader constraints. In non-product builds, we add asserts to
  // guarantee that the table's layout would be the same as at dump time.
  //
  // If JVMTI redefines any class, the read-only shared memory are remapped
  // as read-write. A shared class' vtable/itable are re-initialized and
  // might have different layout due to class redefinition of the shared class
  // or its super types.
  bool is_preinitialized_vtable();
D
duke 已提交
158 159 160 161 162 163 164 165 166 167 168 169
};


// private helper class for klassVtable
// description of entry points:
//    destination is interpreted:
//      from_compiled_code_entry_point -> c2iadapter
//      from_interpreter_entry_point   -> interpreter entry point
//    destination is compiled:
//      from_compiled_code_entry_point -> nmethod entry point
//      from_interpreter_entry_point   -> i2cadapter
class vtableEntry VALUE_OBJ_CLASS_SPEC {
170 171
  friend class VMStructs;

D
duke 已提交
172 173 174 175 176 177
 public:
  // size in words
  static int size() {
    return sizeof(vtableEntry) / sizeof(HeapWord);
  }
  static int method_offset_in_bytes() { return offset_of(vtableEntry, _method); }
178
  Method* method() const    { return _method; }
D
duke 已提交
179 180

 private:
181 182
  Method* _method;
  void set(Method* method)  { assert(method != NULL, "use clear"); _method = method; }
D
duke 已提交
183 184 185 186 187 188 189 190
  void clear()                { _method = NULL; }
  void print()                                        PRODUCT_RETURN;
  void verify(klassVtable* vt, outputStream* st);

  friend class klassVtable;
};


191
inline Method* klassVtable::method_at(int i) const {
D
duke 已提交
192 193
  assert(i >= 0 && i < _length, "index out of bounds");
  assert(table()[i].method() != NULL, "should not be null");
194
  assert(((Metadata*)table()[i].method())->is_method(), "should be method");
D
duke 已提交
195 196 197
  return table()[i].method();
}

198
inline Method* klassVtable::unchecked_method_at(int i) const {
D
duke 已提交
199 200 201 202
  assert(i >= 0 && i < _length, "index out of bounds");
  return table()[i].method();
}

203
inline Method** klassVtable::adr_method_at(int i) const {
D
duke 已提交
204 205
  // Allow one past the last entry to be referenced; useful for loop bounds.
  assert(i >= 0 && i <= _length, "index out of bounds");
206
  return (Method**)(address(table() + i) + vtableEntry::method_offset_in_bytes());
D
duke 已提交
207 208 209 210 211 212 213 214
}

// --------------------------------------------------------------------------------
class klassItable;
class itableMethodEntry;

class itableOffsetEntry VALUE_OBJ_CLASS_SPEC {
 private:
215
  Klass* _interface;
D
duke 已提交
216 217
  int      _offset;
 public:
218
  Klass* interface_klass() const { return _interface; }
D
duke 已提交
219 220
  int      offset() const          { return _offset; }

221 222
  static itableMethodEntry* method_entry(Klass* k, int offset) { return (itableMethodEntry*)(((address)k) + offset); }
  itableMethodEntry* first_method_entry(Klass* k)              { return method_entry(k, _offset); }
D
duke 已提交
223

224
  void initialize(Klass* interf, int offset) { _interface = interf; _offset = offset; }
D
duke 已提交
225 226 227 228 229 230 231 232 233 234 235 236

  // Static size and offset accessors
  static int size()                       { return sizeof(itableOffsetEntry) / HeapWordSize; }    // size in words
  static int interface_offset_in_bytes()  { return offset_of(itableOffsetEntry, _interface); }
  static int offset_offset_in_bytes()     { return offset_of(itableOffsetEntry, _offset); }

  friend class klassItable;
};


class itableMethodEntry VALUE_OBJ_CLASS_SPEC {
 private:
237
  Method* _method;
D
duke 已提交
238 239

 public:
240
  Method* method() const { return _method; }
D
duke 已提交
241 242 243

  void clear()             { _method = NULL; }

244
  void initialize(Method* method);
D
duke 已提交
245 246 247 248 249 250 251 252 253 254 255 256

  // Static size and offset accessors
  static int size()                         { return sizeof(itableMethodEntry) / HeapWordSize; }  // size in words
  static int method_offset_in_bytes()       { return offset_of(itableMethodEntry, _method); }

  friend class klassItable;
};

//
// Format of an itable
//
//    ---- offset table ---
257
//    Klass* of interface 1             \
D
duke 已提交
258 259
//    offset to vtable from start of oop  / offset table entry
//    ...
260
//    Klass* of interface n             \
D
duke 已提交
261 262
//    offset to vtable from start of oop  / offset table entry
//    --- vtable for interface 1 ---
263
//    Method*                             \
D
duke 已提交
264 265
//    compiler entry point                / method table entry
//    ...
266
//    Method*                             \
D
duke 已提交
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
//    compiler entry point                / method table entry
//    -- vtable for interface 2 ---
//    ...
//
class klassItable : public ResourceObj {
 private:
  instanceKlassHandle  _klass;             // my klass
  int                  _table_offset;      // offset of start of itable data within klass (in words)
  int                  _size_offset_table; // size of offset table (in itableOffset entries)
  int                  _size_method_table; // size of methodtable (in itableMethodEntry entries)

  void initialize_itable_for_interface(int method_table_offset, KlassHandle interf_h, bool checkconstraints, TRAPS);
 public:
  klassItable(instanceKlassHandle klass);

  itableOffsetEntry* offset_entry(int i) { assert(0 <= i && i <= _size_offset_table, "index out of bounds");
                                           return &((itableOffsetEntry*)vtable_start())[i]; }

  itableMethodEntry* method_entry(int i) { assert(0 <= i && i <= _size_method_table, "index out of bounds");
                                           return &((itableMethodEntry*)method_start())[i]; }

288
  int size_offset_table()                { return _size_offset_table; }
D
duke 已提交
289 290 291 292 293

  // Initialization
  void initialize_itable(bool checkconstraints, TRAPS);

  // Updates
294
  void initialize_with_method(Method* m);
D
duke 已提交
295

296
#if INCLUDE_JVMTI
D
duke 已提交
297 298 299 300 301 302
  // RedefineClasses() API support:
  // if any entry of this itable points to any of old_methods,
  // replace it with the corresponding new_method.
  // trace_name_printed is set to true if the current call has
  // printed the klass name so that other routines in the adjust_*
  // group don't print the klass name.
303
  void adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed);
304 305 306
  bool check_no_old_or_obsolete_entries();
  void dump_itable();
#endif // INCLUDE_JVMTI
D
duke 已提交
307 308

  // Setup of itable
309
  static int assign_itable_indices_for_interface(Klass* klass);
310
  static int method_count_for_interface(Klass* klass);
311
  static int compute_itable_size(Array<Klass*>* transitive_interfaces);
D
duke 已提交
312 313 314
  static void setup_itable_offset_table(instanceKlassHandle klass);

  // Resolving of method to index
315
  static Method* method_for_itable_index(Klass* klass, int itable_index);
D
duke 已提交
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331

  // Debugging/Statistics
  static void print_statistics() PRODUCT_RETURN;
 private:
  intptr_t* vtable_start() const { return ((intptr_t*)_klass()) + _table_offset; }
  intptr_t* method_start() const { return vtable_start() + _size_offset_table * itableOffsetEntry::size(); }

  // Helper methods
  static int  calc_itable_size(int num_interfaces, int num_methods) { return (num_interfaces * itableOffsetEntry::size()) + (num_methods * itableMethodEntry::size()); }

  // Statistics
  NOT_PRODUCT(static int  _total_classes;)   // Total no. of classes with itables
  NOT_PRODUCT(static long _total_size;)      // Total no. of bytes used for itables

  static void update_stats(int size) PRODUCT_RETURN NOT_PRODUCT({ _total_classes++; _total_size += size; })
};
332 333

#endif // SHARE_VM_OOPS_KLASSVTABLE_HPP