8148047: Move the vtable length field to Klass
authormgerdin
Tue, 01 Dec 2015 10:35:49 +0100
changeset 35899 0dbc821628fc
parent 35898 ddc274f0052f
child 35900 d64cf9290fc4
8148047: Move the vtable length field to Klass Reviewed-by: cjplummer, twisti, coleenp, kbarrett
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp
hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp
hotspot/src/cpu/ppc/vm/ppc.ad
hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp
hotspot/src/cpu/ppc/vm/vtableStubs_ppc_64.cpp
hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
hotspot/src/cpu/sparc/vm/sparc.ad
hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp
hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp
hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ArrayKlass.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java
hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp
hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp
hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp
hotspot/src/share/vm/oops/arrayKlass.cpp
hotspot/src/share/vm/oops/arrayKlass.hpp
hotspot/src/share/vm/oops/instanceKlass.cpp
hotspot/src/share/vm/oops/instanceKlass.hpp
hotspot/src/share/vm/oops/klass.cpp
hotspot/src/share/vm/oops/klass.hpp
hotspot/src/share/vm/opto/library_call.cpp
hotspot/src/share/vm/runtime/vmStructs.cpp
hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -898,13 +898,13 @@
          "caller must use same register for non-constant itable index as for method");
 
   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
-  int vtable_base = in_bytes(InstanceKlass::vtable_start_offset());
+  int vtable_base = in_bytes(Klass::vtable_start_offset());
   int itentry_off = itableMethodEntry::method_offset_in_bytes();
   int scan_step   = itableOffsetEntry::size() * wordSize;
   int vte_size    = vtableEntry::size_in_bytes();
   assert(vte_size == wordSize, "else adjust times_vte_scale");
 
-  ldrw(scan_temp, Address(recv_klass, InstanceKlass::vtable_length_offset()));
+  ldrw(scan_temp, Address(recv_klass, Klass::vtable_length_offset()));
 
   // %%% Could store the aligned, prescaled offset in the klassoop.
   // lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
@@ -958,7 +958,7 @@
 void MacroAssembler::lookup_virtual_method(Register recv_klass,
                                            RegisterOrConstant vtable_index,
                                            Register method_result) {
-  const int base = in_bytes(InstanceKlass::vtable_start_offset());
+  const int base = in_bytes(Klass::vtable_start_offset());
   assert(vtableEntry::size() * wordSize == 8,
          "adjust the scaling in the code below");
   int vtable_offset_in_bytes = base + vtableEntry::method_offset_in_bytes();
--- a/hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -73,7 +73,7 @@
   if (DebugVtables) {
     Label L;
     // check offset vs vtable length
-    __ ldrw(rscratch1, Address(r19, InstanceKlass::vtable_length_offset()));
+    __ ldrw(rscratch1, Address(r19, Klass::vtable_length_offset()));
     __ cmpw(rscratch1, vtable_index * vtableEntry::size());
     __ br(Assembler::GT, L);
     __ enter();
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -1583,13 +1583,13 @@
          "caller must use same register for non-constant itable index as for method");
 
   // Compute start of first itableOffsetEntry (which is at the end of the vtable).
-  int vtable_base = in_bytes(InstanceKlass::vtable_start_offset());
+  int vtable_base = in_bytes(Klass::vtable_start_offset());
   int itentry_off = itableMethodEntry::method_offset_in_bytes();
   int logMEsize   = exact_log2(itableMethodEntry::size() * wordSize);
   int scan_step   = itableOffsetEntry::size() * wordSize;
   int log_vte_size= exact_log2(vtableEntry::size_in_bytes());
 
-  lwz(scan_temp, in_bytes(InstanceKlass::vtable_length_offset()), recv_klass);
+  lwz(scan_temp, in_bytes(Klass::vtable_length_offset()), recv_klass);
   // %%% We should store the aligned, prescaled offset in the klassoop.
   // Then the next several instructions would fold away.
 
@@ -1657,7 +1657,7 @@
 
   assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg());
 
-  const int base = in_bytes(InstanceKlass::vtable_start_offset());
+  const int base = in_bytes(Klass::vtable_start_offset());
   assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
 
   if (vtable_index.is_register()) {
--- a/hotspot/src/cpu/ppc/vm/ppc.ad	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad	Tue Dec 01 10:35:49 2015 +0100
@@ -3562,7 +3562,7 @@
 
       __ load_klass(R11_scratch1, R3);
 
-      int entry_offset = in_bytes(InstanceKlass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes();
+      int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes();
       int v_off = entry_offset + vtableEntry::method_offset_in_bytes();
       __ li(R19_method, v_off);
       __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/);
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -3282,7 +3282,7 @@
   const Register Rtarget_method = Rindex;
 
   // Get target method & entry point.
-  const int base = in_bytes(InstanceKlass::vtable_start_offset());
+  const int base = in_bytes(Klass::vtable_start_offset());
   // Calc vtable addr scale the vtable index by 8.
   __ sldi(Rindex, Rindex, exact_log2(vtableEntry::size_in_bytes()));
   // Load target.
--- a/hotspot/src/cpu/ppc/vm/vtableStubs_ppc_64.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/cpu/ppc/vm/vtableStubs_ppc_64.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -80,14 +80,14 @@
   __ load_klass(rcvr_klass, R3);
 
  // Set method (in case of interpreted method), and destination address.
-  int entry_offset = in_bytes(InstanceKlass::vtable_start_offset()) + vtable_index*vtableEntry::size_in_bytes();
+  int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index*vtableEntry::size_in_bytes();
 
 #ifndef PRODUCT
   if (DebugVtables) {
     Label L;
     // Check offset vs vtable length.
     const Register vtable_len = R12_scratch2;
-    __ lwz(vtable_len, in_bytes(InstanceKlass::vtable_length_offset()), rcvr_klass);
+    __ lwz(vtable_len, in_bytes(Klass::vtable_length_offset()), rcvr_klass);
     __ cmpwi(CCR0, vtable_len, vtable_index*vtableEntry::size());
     __ bge(CCR0, L);
     __ li(R12_scratch2, vtable_index);
@@ -163,13 +163,13 @@
   __ load_klass(rcvr_klass, R3_ARG1);
 
   BLOCK_COMMENT("Load start of itable entries into itable_entry.");
-  __ lwz(vtable_len, in_bytes(InstanceKlass::vtable_length_offset()), rcvr_klass);
+  __ lwz(vtable_len, in_bytes(Klass::vtable_length_offset()), rcvr_klass);
   __ slwi(vtable_len, vtable_len, exact_log2(vtableEntry::size_in_bytes()));
   __ add(itable_entry_addr, vtable_len, rcvr_klass);
 
   // Loop over all itable entries until desired interfaceOop(Rinterface) found.
   BLOCK_COMMENT("Increment itable_entry_addr in loop.");
-  const int vtable_base_offset = in_bytes(InstanceKlass::vtable_start_offset());
+  const int vtable_base_offset = in_bytes(Klass::vtable_start_offset());
   __ addi(itable_entry_addr, itable_entry_addr, vtable_base_offset + itableOffsetEntry::interface_offset_in_bytes());
 
   const int itable_offset_search_inc = itableOffsetEntry::size() * wordSize;
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -2188,11 +2188,11 @@
   }
 
   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
-  int vtable_base = in_bytes(InstanceKlass::vtable_start_offset());
+  int vtable_base = in_bytes(Klass::vtable_start_offset());
   int scan_step   = itableOffsetEntry::size() * wordSize;
   int vte_size    = vtableEntry::size_in_bytes();
 
-  lduw(recv_klass, in_bytes(InstanceKlass::vtable_length_offset()), scan_temp);
+  lduw(recv_klass, in_bytes(Klass::vtable_length_offset()), scan_temp);
   // %%% We should store the aligned, prescaled offset in the klassoop.
   // Then the next several instructions would fold away.
 
@@ -2268,7 +2268,7 @@
                                            Register method_result) {
   assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg());
   Register sethi_temp = method_result;
-  const int base = in_bytes(InstanceKlass::vtable_start_offset()) +
+  const int base = in_bytes(Klass::vtable_start_offset()) +
                    // method pointer offset within the vtable entry:
                    vtableEntry::method_offset_in_bytes();
   RegisterOrConstant vtable_offset = vtable_index;
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Tue Dec 01 10:35:49 2015 +0100
@@ -601,7 +601,7 @@
            NativeCall::instruction_size);  // sethi; setlo; call; delay slot
   } else {
     assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
-    int entry_offset = in_bytes(InstanceKlass::vtable_start_offset()) + vtable_index*vtableEntry::size_in_bytes();
+    int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index*vtableEntry::size_in_bytes();
     int v_off = entry_offset + vtableEntry::method_offset_in_bytes();
     int klass_load_size;
     if (UseCompressedClassPointers) {
@@ -2658,7 +2658,7 @@
       } else {
         klass_load_size = 1*BytesPerInstWord;
       }
-      int entry_offset = in_bytes(InstanceKlass::vtable_start_offset()) + vtable_index*vtableEntry::size_in_bytes();
+      int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index*vtableEntry::size_in_bytes();
       int v_off = entry_offset + vtableEntry::method_offset_in_bytes();
       if (Assembler::is_simm13(v_off)) {
         __ ld_ptr(G3, v_off, G5_method);
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -3153,11 +3153,11 @@
   //
 
   // compute start of first itableOffsetEntry (which is at end of vtable)
-  const int base = in_bytes(InstanceKlass::vtable_start_offset());
+  const int base = in_bytes(Klass::vtable_start_offset());
   Label search;
   Register Rtemp = O1_flags;
 
-  __ ld(O2_Klass, in_bytes(InstanceKlass::vtable_length_offset()), Rtemp);
+  __ ld(O2_Klass, in_bytes(Klass::vtable_length_offset()), Rtemp);
   __ sll(Rtemp, LogBytesPerWord, Rtemp);   // Rscratch *= 4;
   if (Assembler::is_simm13(base)) {
     __ add(Rtemp, base, Rtemp);
--- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -78,7 +78,7 @@
   if (DebugVtables) {
     Label L;
     // check offset vs vtable length
-    __ ld(G3_scratch, in_bytes(InstanceKlass::vtable_length_offset()), G5);
+    __ ld(G3_scratch, in_bytes(Klass::vtable_length_offset()), G5);
     __ cmp_and_br_short(G5, vtable_index*vtableEntry::size(), Assembler::greaterUnsigned, Assembler::pt, L);
     __ set(vtable_index, O2);
     __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), O0, O2);
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -5807,14 +5807,14 @@
          "caller must use same register for non-constant itable index as for method");
 
   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
-  int vtable_base = in_bytes(InstanceKlass::vtable_start_offset());
+  int vtable_base = in_bytes(Klass::vtable_start_offset());
   int itentry_off = itableMethodEntry::method_offset_in_bytes();
   int scan_step   = itableOffsetEntry::size() * wordSize;
   int vte_size    = vtableEntry::size_in_bytes();
   Address::ScaleFactor times_vte_scale = Address::times_ptr;
   assert(vte_size == wordSize, "else adjust times_vte_scale");
 
-  movl(scan_temp, Address(recv_klass, InstanceKlass::vtable_length_offset()));
+  movl(scan_temp, Address(recv_klass, Klass::vtable_length_offset()));
 
   // %%% Could store the aligned, prescaled offset in the klassoop.
   lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
@@ -5865,7 +5865,7 @@
 void MacroAssembler::lookup_virtual_method(Register recv_klass,
                                            RegisterOrConstant vtable_index,
                                            Register method_result) {
-  const int base = in_bytes(InstanceKlass::vtable_start_offset());
+  const int base = in_bytes(Klass::vtable_start_offset());
   assert(vtableEntry::size() * wordSize == wordSize, "else adjust the scaling in the code below");
   Address vtable_entry_addr(recv_klass,
                             vtable_index, Address::times_ptr,
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -85,7 +85,7 @@
   if (DebugVtables) {
     Label L;
     // check offset vs vtable length
-    __ cmpl(Address(rax, InstanceKlass::vtable_length_offset()), vtable_index*vtableEntry::size());
+    __ cmpl(Address(rax, Klass::vtable_length_offset()), vtable_index*vtableEntry::size());
     __ jcc(Assembler::greater, L);
     __ movl(rbx, vtable_index);
     __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), rcx, rbx);
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -77,7 +77,7 @@
   if (DebugVtables) {
     Label L;
     // check offset vs vtable length
-    __ cmpl(Address(rax, InstanceKlass::vtable_length_offset()),
+    __ cmpl(Address(rax, Klass::vtable_length_offset()),
             vtable_index * vtableEntry::size());
     __ jcc(Assembler::greater, L);
     __ movl(rbx, vtable_index);
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ArrayKlass.java	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ArrayKlass.java	Tue Dec 01 10:35:49 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -48,7 +48,6 @@
     dimension          = new CIntField(type.getCIntegerField("_dimension"), 0);
     higherDimension    = new MetadataField(type.getAddressField("_higher_dimension"), 0);
     lowerDimension     = new MetadataField(type.getAddressField("_lower_dimension"), 0);
-    vtableLen          = new CIntField(type.getCIntegerField("_vtable_len"), 0);
     javaLangCloneableName = null;
     javaLangObjectName = null;
     javaIoSerializableName = null;
@@ -61,7 +60,6 @@
   private static CIntField dimension;
   private static MetadataField  higherDimension;
   private static MetadataField  lowerDimension;
-  private static CIntField vtableLen;
 
   public Klass getJavaSuper() {
     SystemDictionary sysDict = VM.getVM().getSystemDictionary();
@@ -71,7 +69,6 @@
   public long  getDimension()       { return         dimension.getValue(this); }
   public Klass getHigherDimension() { return (Klass) higherDimension.getValue(this); }
   public Klass getLowerDimension()  { return (Klass) lowerDimension.getValue(this); }
-  public long  getVtableLen()       { return         vtableLen.getValue(this); }
 
   // constant class names - javaLangCloneable, javaIoSerializable, javaLangObject
   // Initialized lazily to avoid initialization ordering dependencies between ArrayKlass and SymbolTable
@@ -140,6 +137,5 @@
       visitor.doCInt(dimension, true);
     visitor.doMetadata(higherDimension, true);
     visitor.doMetadata(lowerDimension, true);
-      visitor.doCInt(vtableLen, true);
     }
   }
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Tue Dec 01 10:35:49 2015 +0100
@@ -84,7 +84,6 @@
     nonstaticOopMapSize  = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), 0);
     isMarkedDependent    = new CIntField(type.getCIntegerField("_is_marked_dependent"), 0);
     initState            = new CIntField(type.getCIntegerField("_init_state"), 0);
-    vtableLen            = new CIntField(type.getCIntegerField("_vtable_len"), 0);
     itableLen            = new CIntField(type.getCIntegerField("_itable_len"), 0);
     breakpoints          = type.getAddressField("_breakpoints");
     genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"), 0);
@@ -143,7 +142,6 @@
   private static CIntField nonstaticOopMapSize;
   private static CIntField isMarkedDependent;
   private static CIntField initState;
-  private static CIntField vtableLen;
   private static CIntField itableLen;
   private static AddressField breakpoints;
   private static CIntField genericSignatureIndex;
@@ -351,7 +349,6 @@
   public long      getStaticOopFieldCount() { return                staticOopFieldCount.getValue(this); }
   public long      getNonstaticOopMapSize() { return                nonstaticOopMapSize.getValue(this); }
   public boolean   getIsMarkedDependent()   { return                isMarkedDependent.getValue(this) != 0; }
-  public long      getVtableLen()           { return                vtableLen.getValue(this); }
   public long      getItableLen()           { return                itableLen.getValue(this); }
   public long      majorVersion()           { return                majorVersion.getValue(this); }
   public long      minorVersion()           { return                minorVersion.getValue(this); }
@@ -547,7 +544,6 @@
       visitor.doCInt(nonstaticOopMapSize, true);
       visitor.doCInt(isMarkedDependent, true);
       visitor.doCInt(initState, true);
-      visitor.doCInt(vtableLen, true);
       visitor.doCInt(itableLen, true);
     }
 
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java	Tue Dec 01 10:35:49 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -61,6 +61,7 @@
     }
     subklass     = new MetadataField(type.getAddressField("_subklass"), 0);
     nextSibling  = new MetadataField(type.getAddressField("_next_sibling"), 0);
+    vtableLen    = new CIntField(type.getCIntegerField("_vtable_len"), 0);
 
     LH_INSTANCE_SLOW_PATH_BIT  = db.lookupIntConstant("Klass::_lh_instance_slow_path_bit").intValue();
     LH_LOG2_ELEMENT_SIZE_SHIFT = db.lookupIntConstant("Klass::_lh_log2_element_size_shift").intValue();
@@ -71,6 +72,7 @@
     LH_ARRAY_TAG_OBJ_VALUE     = db.lookupIntConstant("Klass::_lh_array_tag_obj_value").intValue();
   }
 
+
   public Klass(Address addr) {
     super(addr);
   }
@@ -91,6 +93,7 @@
   private static MetadataField  subklass;
   private static MetadataField  nextSibling;
   private static sun.jvm.hotspot.types.Field traceIDField;
+  private static CIntField vtableLen;
 
   private Address getValue(AddressField field) {
     return addr.getAddressAt(field.getOffset());
@@ -111,6 +114,7 @@
   public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags());      }
   public Klass    getSubklassKlass()    { return (Klass)    subklass.getValue(this);     }
   public Klass    getNextSiblingKlass() { return (Klass)    nextSibling.getValue(this);  }
+  public long     getVtableLen()        { return            vtableLen.getValue(this); }
 
   public long traceID() {
     if (traceIDField == null) return 0;
@@ -179,6 +183,7 @@
       visitor.doCInt(accessFlags, true);
     visitor.doMetadata(subklass, true);
     visitor.doMetadata(nextSibling, true);
+    visitor.doCInt(vtableLen, true);
     }
 
   public long getObjectSize() {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Tue Dec 01 10:35:49 2015 +0100
@@ -597,7 +597,7 @@
         }
         HotSpotVMConfig config = config();
         final int vtableIndex = getVtableIndex((HotSpotResolvedObjectTypeImpl) resolved);
-        return config.instanceKlassVtableStartOffset + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset;
+        return config.klassVtableStartOffset + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset;
     }
 
     @Override
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Tue Dec 01 10:35:49 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -482,8 +482,8 @@
             /* Everything has the core vtable of java.lang.Object */
             return config.baseVtableLength();
         }
-        int result = UNSAFE.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize);
-        assert result >= config.baseVtableLength() : UNSAFE.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) + " " + config.vtableEntrySize;
+        int result = UNSAFE.getInt(getMetaspaceKlass() + config.klassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize);
+        assert result >= config.baseVtableLength() : UNSAFE.getInt(getMetaspaceKlass() + config.klassVtableLengthOffset) + " " + config.vtableEntrySize;
         return result;
     }
 
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Tue Dec 01 10:35:49 2015 +0100
@@ -1030,8 +1030,8 @@
     @HotSpotVMField(name = "InstanceKlass::_init_state", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassInitStateOffset;
     @HotSpotVMField(name = "InstanceKlass::_constants", type = "ConstantPool*", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassConstantsOffset;
     @HotSpotVMField(name = "InstanceKlass::_fields", type = "Array<u2>*", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassFieldsOffset;
-    @HotSpotVMField(name = "CompilerToVM::Data::InstanceKlass_vtable_start_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int instanceKlassVtableStartOffset;
-    @HotSpotVMField(name = "CompilerToVM::Data::InstanceKlass_vtable_length_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int instanceKlassVtableLengthOffset;
+    @HotSpotVMField(name = "CompilerToVM::Data::Klass_vtable_start_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int klassVtableStartOffset;
+    @HotSpotVMField(name = "CompilerToVM::Data::Klass_vtable_length_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int klassVtableLengthOffset;
 
     @HotSpotVMConstant(name = "InstanceKlass::linked") @Stable public int instanceKlassStateLinked;
     @HotSpotVMConstant(name = "InstanceKlass::fully_initialized") @Stable public int instanceKlassStateFullyInitialized;
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -2972,7 +2972,7 @@
                           SharedRuntime::get_resolve_virtual_call_stub(),
                           arg_list, info);
       } else {
-        int entry_offset = in_bytes(InstanceKlass::vtable_start_offset()) + x->vtable_index() * vtableEntry::size_in_bytes();
+        int entry_offset = in_bytes(Klass::vtable_start_offset()) + x->vtable_index() * vtableEntry::size_in_bytes();
         int vtable_offset = entry_offset + vtableEntry::method_offset_in_bytes();
         __ call_virtual(target, receiver, result_register, vtable_offset, arg_list, info);
       }
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -121,8 +121,8 @@
 extern uint64_t jvmciHotSpotVMAddressEntryArrayStride;
 }
 
-int CompilerToVM::Data::InstanceKlass_vtable_start_offset;
-int CompilerToVM::Data::InstanceKlass_vtable_length_offset;
+int CompilerToVM::Data::Klass_vtable_start_offset;
+int CompilerToVM::Data::Klass_vtable_length_offset;
 
 int CompilerToVM::Data::Method_extra_stack_entries;
 
@@ -151,8 +151,8 @@
 int CompilerToVM::Data::cardtable_shift;
 
 void CompilerToVM::Data::initialize() {
-  InstanceKlass_vtable_start_offset = in_bytes(InstanceKlass::vtable_start_offset());
-  InstanceKlass_vtable_length_offset = in_bytes(InstanceKlass::vtable_length_offset());
+  Klass_vtable_start_offset = in_bytes(Klass::vtable_start_offset());
+  Klass_vtable_length_offset = in_bytes(Klass::vtable_length_offset());
 
   Method_extra_stack_entries = Method::extra_stack_entries();
 
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp	Tue Dec 01 10:35:49 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -34,8 +34,8 @@
     friend class JVMCIVMStructs;
 
    private:
-    static int InstanceKlass_vtable_start_offset;
-    static int InstanceKlass_vtable_length_offset;
+    static int Klass_vtable_start_offset;
+    static int Klass_vtable_length_offset;
 
     static int Method_extra_stack_entries;
 
--- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -45,8 +45,8 @@
 
 
 #define VM_STRUCTS(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field) \
-  static_field(CompilerToVM::Data,             InstanceKlass_vtable_start_offset,      int)                                          \
-  static_field(CompilerToVM::Data,             InstanceKlass_vtable_length_offset,     int)                                          \
+  static_field(CompilerToVM::Data,             Klass_vtable_start_offset,              int)                                          \
+  static_field(CompilerToVM::Data,             Klass_vtable_length_offset,             int)                                          \
                                                                                                                                      \
   static_field(CompilerToVM::Data,             Method_extra_stack_entries,             int)                                          \
                                                                                                                                      \
--- a/hotspot/src/share/vm/oops/arrayKlass.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/share/vm/oops/arrayKlass.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -81,10 +81,10 @@
 ArrayKlass::ArrayKlass(Symbol* name) :
   _dimension(1),
   _higher_dimension(NULL),
-  _lower_dimension(NULL),
-  // Arrays don't add any new methods, so their vtable is the same size as
-  // the vtable of klass Object.
-  _vtable_len(Universe::base_vtable_size()) {
+  _lower_dimension(NULL) {
+    // Arrays don't add any new methods, so their vtable is the same size as
+    // the vtable of klass Object.
+    set_vtable_length(Universe::base_vtable_size());
     set_name(name);
     set_super(Universe::is_bootstrapping() ? (Klass*)NULL : SystemDictionary::Object_klass());
     set_layout_helper(Klass::_lh_neutral_value);
--- a/hotspot/src/share/vm/oops/arrayKlass.hpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/share/vm/oops/arrayKlass.hpp	Tue Dec 01 10:35:49 2015 +0100
@@ -39,7 +39,6 @@
   int      _dimension;         // This is n'th-dimensional array.
   Klass* volatile _higher_dimension;  // Refers the (n+1)'th-dimensional array (if present).
   Klass* volatile _lower_dimension;   // Refers the (n-1)'th-dimensional array (if present).
-  int      _vtable_len;        // size of vtable for this klass
 
  protected:
   // Constructors
@@ -112,9 +111,6 @@
 
   // Java vtable
   klassVtable* vtable() const;             // return new klassVtable
-  int  vtable_length() const               { return _vtable_len; }
-  static int base_vtable_length()          { return Universe::base_vtable_size(); }
-  void set_vtable_length(int len)          { assert(len == base_vtable_length(), "bad length"); _vtable_len = len; }
  protected:
   inline intptr_t* start_of_vtable() const;
 
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -211,9 +211,9 @@
 InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind) :
   _static_field_size(parser.static_field_size()),
   _nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())),
-  _vtable_len(parser.vtable_size()),
   _itable_len(parser.itable_size()),
   _reference_type(parser.reference_type()) {
+    set_vtable_length(parser.vtable_size());
     set_kind(kind);
     set_access_flags(parser.access_flags());
     set_is_anonymous(parser.is_anonymous());
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Tue Dec 01 10:35:49 2015 +0100
@@ -178,6 +178,7 @@
   u2              _java_fields_count;    // The number of declared Java fields
   int             _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
 
+  int             _itable_len;           // length of Java itable (in words)
   // _is_marked_dependent can be set concurrently, thus cannot be part of the
   // _misc_flags.
   bool            _is_marked_dependent;  // used for marking during flushing and deoptimization
@@ -211,8 +212,6 @@
   u2              _minor_version;        // minor version number of class file
   u2              _major_version;        // major version number of class file
   Thread*         _init_thread;          // Pointer to current thread doing initialization (to handle recusive initialization)
-  int             _vtable_len;           // length of Java vtable (in words)
-  int             _itable_len;           // length of Java itable (in words)
   OopMapCache*    volatile _oop_map_cache;   // OopMapCache for all methods in the klass (allocated lazily)
   MemberNameTable* _member_names;        // Member names
   JNIid*          _jni_ids;              // First JNI identifier for static fields in this class
@@ -311,10 +310,6 @@
   int static_oop_field_count() const       { return (int)_static_oop_field_count; }
   void set_static_oop_field_count(u2 size) { _static_oop_field_count = size; }
 
-  // Java vtable
-  int  vtable_length() const               { return _vtable_len; }
-  void set_vtable_length(int len)          { _vtable_len = len; }
-
   // Java itable
   int  itable_length() const               { return _itable_len; }
   void set_itable_length(int len)          { _itable_len = len; }
@@ -949,9 +944,6 @@
   virtual void collect_statistics(KlassSizeStats *sz) const;
 #endif
 
-  static ByteSize vtable_start_offset()    { return in_ByteSize(header_size() * wordSize); }
-  static ByteSize vtable_length_offset()   { return byte_offset_of(InstanceKlass, _vtable_len); }
-
   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(); }
   int  itable_offset_in_words() const { return start_of_itable() - (intptr_t*)this; }
--- a/hotspot/src/share/vm/oops/klass.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/share/vm/oops/klass.cpp	Tue Dec 01 10:35:49 2015 +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
@@ -659,6 +659,10 @@
   guarantee(obj->klass()->is_klass(), "klass field is not a klass");
 }
 
+ByteSize Klass::vtable_start_offset() {
+  return in_ByteSize(InstanceKlass::header_size() * wordSize);
+}
+
 #ifndef PRODUCT
 
 bool Klass::verify_vtable_index(int i) {
--- a/hotspot/src/share/vm/oops/klass.hpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/share/vm/oops/klass.hpp	Tue Dec 01 10:35:49 2015 +0100
@@ -131,13 +131,16 @@
   jint        _modifier_flags;  // Processed access flags, for use by Class.getModifiers.
   AccessFlags _access_flags;    // Access flags. The class/interface distinction is stored here.
 
+  TRACE_DEFINE_KLASS_TRACE_ID;
+
   // Biased locking implementation and statistics
   // (the 64-bit chunk goes first, to avoid some fragmentation)
   jlong    _last_biased_lock_bulk_revocation_time;
   markOop  _prototype_header;   // Used when biased locking is both enabled and disabled for this type
   jint     _biased_lock_revocation_count;
 
-  TRACE_DEFINE_KLASS_TRACE_ID;
+  // vtable length
+  int _vtable_len;
 
   // Remembered sets support for the oops in the klasses.
   jbyte _modified_oops;             // Card Table Equivalent (YC/CMS support)
@@ -375,7 +378,7 @@
 
   // vtables
   virtual klassVtable* vtable() const = 0;
-  virtual int vtable_length() const = 0;
+  int vtable_length() const { return _vtable_len; }
 
   // subclass check
   bool is_subclass_of(const Klass* k) const;
@@ -438,7 +441,14 @@
   virtual Klass* array_klass_impl(bool or_null, int rank, TRAPS);
   virtual Klass* array_klass_impl(bool or_null, TRAPS);
 
+  void set_vtable_length(int len) { _vtable_len= len; }
+
  public:
+  static ByteSize vtable_start_offset();
+  static ByteSize vtable_length_offset() {
+    return byte_offset_of(Klass, _vtable_len);
+  }
+
   // CDS support - remove and restore oops from metadata. Oops are not shared.
   virtual void remove_unshareable_info();
   virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
--- a/hotspot/src/share/vm/opto/library_call.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -3828,7 +3828,7 @@
   assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index,
          "bad index %d", vtable_index);
   // Get the Method* out of the appropriate vtable entry.
-  int entry_offset  = in_bytes(InstanceKlass::vtable_start_offset()) +
+  int entry_offset  = in_bytes(Klass::vtable_start_offset()) +
                      vtable_index*vtableEntry::size_in_bytes() +
                      vtableEntry::method_offset_in_bytes();
   Node* entry_addr  = basic_plus_adr(obj_klass, entry_offset);
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -298,7 +298,6 @@
   nonstatic_field(ArrayKlass,                  _dimension,                                    int)                                   \
   volatile_nonstatic_field(ArrayKlass,         _higher_dimension,                             Klass*)                                \
   volatile_nonstatic_field(ArrayKlass,         _lower_dimension,                              Klass*)                                \
-  nonstatic_field(ArrayKlass,                  _vtable_len,                                   int)                                   \
   nonstatic_field(CompiledICHolder,            _holder_method,                                Method*)                               \
   nonstatic_field(CompiledICHolder,            _holder_klass,                                 Klass*)                                \
   nonstatic_field(ConstantPool,                _tags,                                         Array<u1>*)                            \
@@ -332,7 +331,6 @@
   nonstatic_field(InstanceKlass,               _major_version,                                u2)                                    \
   nonstatic_field(InstanceKlass,               _init_state,                                   u1)                                    \
   nonstatic_field(InstanceKlass,               _init_thread,                                  Thread*)                               \
-  nonstatic_field(InstanceKlass,               _vtable_len,                                   int)                                   \
   nonstatic_field(InstanceKlass,               _itable_len,                                   int)                                   \
   nonstatic_field(InstanceKlass,               _reference_type,                               u1)                                    \
   volatile_nonstatic_field(InstanceKlass,      _oop_map_cache,                                OopMapCache*)                          \
@@ -358,6 +356,7 @@
   nonstatic_field(Klass,                       _access_flags,                                 AccessFlags)                           \
   nonstatic_field(Klass,                       _prototype_header,                             markOop)                               \
   nonstatic_field(Klass,                       _next_sibling,                                 Klass*)                                \
+  nonstatic_field(Klass,                       _vtable_len,                                   int)                                \
   nonstatic_field(vtableEntry,                 _method,                                       Method*)                               \
   nonstatic_field(MethodData,                  _size,                                         int)                                   \
   nonstatic_field(MethodData,                  _method,                                       Method*)                               \
--- a/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp	Sat Jan 30 11:02:29 2016 -0500
+++ b/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp	Tue Dec 01 10:35:49 2015 +0100
@@ -1144,7 +1144,7 @@
       klass,
       SharkType::Method_type(),
       vtableEntry::size_in_bytes(),
-      InstanceKlass::vtable_start_offset(),
+      Klass::vtable_start_offset(),
       LLVMValue::intptr_constant(vtable_index)),
     "callee");
 }
@@ -1166,12 +1166,12 @@
   Value *vtable_start = builder()->CreateAdd(
     builder()->CreatePtrToInt(object_klass, SharkType::intptr_type()),
     LLVMValue::intptr_constant(
-      in_bytes(InstanceKlass::vtable_start_offset())),
+      in_bytes(Klass::vtable_start_offset())),
     "vtable_start");
 
   Value *vtable_length = builder()->CreateValueOfStructEntry(
     object_klass,
-    InstanceKlass::vtable_length_offset(),
+    Klass::vtable_length_offset(),
     SharkType::jint_type(),
     "vtable_length");
   vtable_length =