--- old/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp 2016-01-22 15:20:54.418584341 +0100 +++ new/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp 2016-01-22 15:20:54.322580391 +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)); @@ -963,7 +963,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(); --- old/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp 2016-01-22 15:20:54.602591914 +0100 +++ new/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp 2016-01-22 15:20:54.506587964 +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(); --- old/src/cpu/ppc/vm/macroAssembler_ppc.cpp 2016-01-22 15:20:54.754598170 +0100 +++ new/src/cpu/ppc/vm/macroAssembler_ppc.cpp 2016-01-22 15:20:54.658594220 +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()) { --- old/src/cpu/ppc/vm/ppc.ad 2016-01-22 15:20:54.950606237 +0100 +++ new/src/cpu/ppc/vm/ppc.ad 2016-01-22 15:20:54.850602122 +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*/); --- old/src/cpu/ppc/vm/templateTable_ppc_64.cpp 2016-01-22 15:20:55.190616115 +0100 +++ new/src/cpu/ppc/vm/templateTable_ppc_64.cpp 2016-01-22 15:20:55.094612165 +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. --- old/src/cpu/ppc/vm/vtableStubs_ppc_64.cpp 2016-01-22 15:20:55.370623524 +0100 +++ new/src/cpu/ppc/vm/vtableStubs_ppc_64.cpp 2016-01-22 15:20:55.274619572 +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; --- old/src/cpu/sparc/vm/macroAssembler_sparc.cpp 2016-01-22 15:20:55.522629780 +0100 +++ new/src/cpu/sparc/vm/macroAssembler_sparc.cpp 2016-01-22 15:20:55.422625664 +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. @@ -2280,7 +2280,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; --- old/src/cpu/sparc/vm/sparc.ad 2016-01-22 15:20:55.718637847 +0100 +++ new/src/cpu/sparc/vm/sparc.ad 2016-01-22 15:20:55.614633567 +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); --- old/src/cpu/sparc/vm/templateTable_sparc.cpp 2016-01-22 15:20:55.962647889 +0100 +++ new/src/cpu/sparc/vm/templateTable_sparc.cpp 2016-01-22 15:20:55.862643773 +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); if (align_object_offset(1) > 1) { __ round_to(Rtemp, align_object_offset(1)); } --- old/src/cpu/sparc/vm/vtableStubs_sparc.cpp 2016-01-22 15:20:56.142655298 +0100 +++ new/src/cpu/sparc/vm/vtableStubs_sparc.cpp 2016-01-22 15:20:56.042651182 +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); --- old/src/cpu/x86/vm/macroAssembler_x86.cpp 2016-01-22 15:20:56.298661718 +0100 +++ new/src/cpu/x86/vm/macroAssembler_x86.cpp 2016-01-22 15:20:56.194657438 +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)); @@ -5870,7 +5870,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, --- old/src/cpu/x86/vm/vtableStubs_x86_32.cpp 2016-01-22 15:20:56.534671432 +0100 +++ new/src/cpu/x86/vm/vtableStubs_x86_32.cpp 2016-01-22 15:20:56.438667480 +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); --- old/src/cpu/x86/vm/vtableStubs_x86_64.cpp 2016-01-22 15:20:56.682677523 +0100 +++ new/src/cpu/x86/vm/vtableStubs_x86_64.cpp 2016-01-22 15:20:56.586673572 +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); --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ArrayKlass.java 2016-01-22 15:20:56.834683780 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ArrayKlass.java 2016-01-22 15:20:56.738679828 +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); } } --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java 2016-01-22 15:20:56.982689871 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java 2016-01-22 15:20:56.886685919 +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 @@ -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; @@ -352,7 +350,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); } @@ -548,7 +545,6 @@ visitor.doCInt(nonstaticOopMapSize, true); visitor.doCInt(isMarkedDependent, true); visitor.doCInt(initState, true); - visitor.doCInt(vtableLen, true); visitor.doCInt(itableLen, true); } --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java 2016-01-22 15:20:57.142696456 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java 2016-01-22 15:20:57.042692340 +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() { --- old/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java 2016-01-22 15:20:57.298702876 +0100 +++ new/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java 2016-01-22 15:20:57.198698760 +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 --- old/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java 2016-01-22 15:20:57.454709297 +0100 +++ new/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java 2016-01-22 15:20:57.358705346 +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; } --- old/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java 2016-01-22 15:20:57.610715717 +0100 +++ new/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java 2016-01-22 15:20:57.514711767 +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*", 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; --- old/src/share/vm/c1/c1_LIRGenerator.cpp 2016-01-22 15:20:57.786722961 +0100 +++ new/src/share/vm/c1/c1_LIRGenerator.cpp 2016-01-22 15:20:57.682718681 +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); } --- old/src/share/vm/jvmci/jvmciCompilerToVM.cpp 2016-01-22 15:20:57.970730534 +0100 +++ new/src/share/vm/jvmci/jvmciCompilerToVM.cpp 2016-01-22 15:20:57.866726254 +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(); --- old/src/share/vm/jvmci/jvmciCompilerToVM.hpp 2016-01-22 15:20:58.130737120 +0100 +++ new/src/share/vm/jvmci/jvmciCompilerToVM.hpp 2016-01-22 15:20:58.034733168 +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; --- old/src/share/vm/jvmci/vmStructs_jvmci.cpp 2016-01-22 15:20:58.270742882 +0100 +++ new/src/share/vm/jvmci/vmStructs_jvmci.cpp 2016-01-22 15:20:58.174738930 +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) \ \ --- old/src/share/vm/oops/arrayKlass.cpp 2016-01-22 15:20:58.426749302 +0100 +++ new/src/share/vm/oops/arrayKlass.cpp 2016-01-22 15:20:58.334745516 +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 @@ -85,10 +85,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); --- old/src/share/vm/oops/arrayKlass.hpp 2016-01-22 15:20:58.578755558 +0100 +++ new/src/share/vm/oops/arrayKlass.hpp 2016-01-22 15:20:58.482751607 +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 @@ -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; --- old/src/share/vm/oops/instanceKlass.cpp 2016-01-22 15:20:58.734761979 +0100 +++ new/src/share/vm/oops/instanceKlass.cpp 2016-01-22 15:20:58.630757698 +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 @@ -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()); --- old/src/share/vm/oops/instanceKlass.hpp 2016-01-22 15:20:58.914769388 +0100 +++ new/src/share/vm/oops/instanceKlass.hpp 2016-01-22 15:20:58.814765271 +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; } @@ -951,9 +946,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() + align_object_offset(vtable_length()); } int itable_offset_in_words() const { return start_of_itable() - (intptr_t*)this; } --- old/src/share/vm/oops/klass.cpp 2016-01-22 15:20:59.078776137 +0100 +++ new/src/share/vm/oops/klass.cpp 2016-01-22 15:20:58.978772021 +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) { --- old/src/share/vm/oops/klass.hpp 2016-01-22 15:20:59.238782722 +0100 +++ new/src/share/vm/oops/klass.hpp 2016-01-22 15:20:59.138778607 +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 @@ -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); --- old/src/share/vm/opto/library_call.cpp 2016-01-22 15:20:59.398789308 +0100 +++ new/src/share/vm/opto/library_call.cpp 2016-01-22 15:20:59.298785192 +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); --- old/src/share/vm/runtime/vmStructs.cpp 2016-01-22 15:20:59.610798033 +0100 +++ new/src/share/vm/runtime/vmStructs.cpp 2016-01-22 15:20:59.506793753 +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*) \ @@ -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*) \ --- old/src/share/vm/shark/sharkTopLevelBlock.cpp 2016-01-22 15:20:59.802805935 +0100 +++ new/src/share/vm/shark/sharkTopLevelBlock.cpp 2016-01-22 15:20:59.698801655 +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 =