changeset 23717:41fa89f93355

removed jdk.vm.ci.hotspot.HotSpotMethodDataAccessor.Tag (JDK-8159613)
author Doug Simon <doug.simon@oracle.com>
date Thu, 30 Jun 2016 22:07:57 +0200
parents 74c4e0459c11
children 0bd91cd9869d
files jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java
diffstat 2 files changed, 225 insertions(+), 278 deletions(-) [+]
line wrap: on
line diff
--- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java	Fri Jul 01 13:31:04 2016 -0700
+++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java	Thu Jun 30 22:07:57 2016 +0200
@@ -30,7 +30,6 @@
 
 import java.util.Arrays;
 
-import jdk.vm.ci.hotspot.HotSpotMethodDataAccessor.Tag;
 import jdk.vm.ci.meta.DeoptimizationReason;
 import jdk.vm.ci.meta.JavaMethodProfile;
 import jdk.vm.ci.meta.JavaMethodProfile.ProfiledMethod;
@@ -42,74 +41,18 @@
 import sun.misc.Unsafe;
 
 /**
- * Access to a HotSpot MethodData structure (defined in methodData.hpp).
+ * Access to a HotSpot {@code MethodData} structure (defined in methodData.hpp).
  */
-public final class HotSpotMethodData {
+final class HotSpotMethodData {
 
     static final HotSpotVMConfig config = config();
-    static final HotSpotMethodDataAccessor NO_DATA_NO_EXCEPTION_ACCESSOR = new NoMethodData(TriState.FALSE);
-    static final HotSpotMethodDataAccessor NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR = new NoMethodData(TriState.UNKNOWN);
-
-    static final int BIT_DATA_SIZE = cellIndexToOffset(0);
-    static final int BIT_DATA_NULL_SEEN_FLAG = 1 << config.bitDataNullSeenFlag;
-
-    static final int BRANCH_DATA_SIZE = cellIndexToOffset(3);
-    static final int NOT_TAKEN_COUNT_OFFSET = cellIndexToOffset(config.branchDataNotTakenOffset);
-
-    static final int ARG_INFO_DATA_SIZE = cellIndexToOffset(1);
-
-    static final int COUNTER_DATA_SIZE = cellIndexToOffset(1);
-    static final int COUNTER_DATA_COUNT_OFFSET = cellIndexToOffset(config.methodDataCountOffset);
-    static final int JUMP_DATA_SIZE = cellIndexToOffset(2);
-    static final int TAKEN_COUNT_OFFSET = cellIndexToOffset(config.jumpDataTakenOffset);
-    static final int TAKEN_DISPLACEMENT_OFFSET = cellIndexToOffset(config.jumpDataDisplacementOffset);
-    static final int TYPE_DATA_ROW_SIZE = cellsToBytes(config.receiverTypeDataReceiverTypeRowCellCount);
-
-    static final int NONPROFILED_COUNT_OFFSET = cellIndexToOffset(config.receiverTypeDataNonprofiledCountOffset);
-    static final int TYPE_DATA_FIRST_TYPE_OFFSET = cellIndexToOffset(config.receiverTypeDataReceiver0Offset);
-    static final int TYPE_DATA_FIRST_TYPE_COUNT_OFFSET = cellIndexToOffset(config.receiverTypeDataCount0Offset);
-    static final int VIRTUAL_CALL_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * (config.typeProfileWidth + config.methodProfileWidth);
-    static final int VIRTUAL_CALL_DATA_FIRST_METHOD_OFFSET = TYPE_DATA_FIRST_TYPE_OFFSET + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
-    static final int VIRTUAL_CALL_DATA_FIRST_METHOD_COUNT_OFFSET = TYPE_DATA_FIRST_TYPE_COUNT_OFFSET + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
-
-    static final int ARRAY_DATA_LENGTH_OFFSET = cellIndexToOffset(config.arrayDataArrayLenOffset);
-    static final int ARRAY_DATA_START_OFFSET = cellIndexToOffset(config.arrayDataArrayStartOffset);
-
-    static final int TYPE_CHECK_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
-
-    static final int RET_DATA_ROW_SIZE = cellsToBytes(3);
-    static final int RET_DATA_SIZE = cellIndexToOffset(1) + RET_DATA_ROW_SIZE * config.bciProfileWidth;
-
-    static final int MULTI_BRANCH_DATA_SIZE = cellIndexToOffset(1);
-    static final int MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS = config.multiBranchDataPerCaseCellCount;
-    static final int MULTI_BRANCH_DATA_ROW_SIZE = cellsToBytes(MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS);
-    static final int MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(0);
-    static final int MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(1);
-
-    // sorted by tag
-    // @formatter:off
-    static final HotSpotMethodDataAccessor[] PROFILE_DATA_ACCESSORS = {
-        null,
-        new BitData(),
-        new CounterData(),
-        new JumpData(),
-        new ReceiverTypeData(),
-        new VirtualCallData(),
-        new RetData(),
-        new BranchData(),
-        new MultiBranchData(),
-        new ArgInfoData(),
-        new UnknownProfileData(Tag.CallTypeData),
-        new VirtualCallTypeData(),
-        new UnknownProfileData(Tag.ParametersTypeData),
-        new UnknownProfileData(Tag.SpeculativeTrapData),
-    };
-    // @formatter:on
+    static final HotSpotMethodDataAccessor NO_DATA_NO_EXCEPTION_ACCESSOR = new NoMethodData(config, config.dataLayoutNoTag, TriState.FALSE);
+    static final HotSpotMethodDataAccessor NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR = new NoMethodData(config, config.dataLayoutNoTag, TriState.UNKNOWN);
 
     /**
      * Reference to the C++ MethodData object.
      */
-    private final long metaspaceMethodData;
+    final long metaspaceMethodData;
     @SuppressWarnings("unused") private final HotSpotResolvedJavaMethodImpl method;
 
     public HotSpotMethodData(long metaspaceMethodData, HotSpotResolvedJavaMethodImpl method) {
@@ -169,10 +112,7 @@
             return null;
         }
 
-        HotSpotMethodDataAccessor result = getData(position);
-        final Tag tag = AbstractMethodData.readTag(this, position);
-        assert result != null : "NO_DATA tag is not allowed " + tag;
-        return result;
+        return getData(position);
     }
 
     public HotSpotMethodDataAccessor getExtraData(int position) {
@@ -196,18 +136,18 @@
 
     private HotSpotMethodDataAccessor getData(int position) {
         assert position >= 0 : "out of bounds";
-        final Tag tag = AbstractMethodData.readTag(this, position);
-        HotSpotMethodDataAccessor accessor = PROFILE_DATA_ACCESSORS[tag.getValue()];
+        final int tag = HotSpotMethodDataAccessor.readTag(config, this, position);
+        HotSpotMethodDataAccessor accessor = PROFILE_DATA_ACCESSORS[tag];
         assert accessor == null || accessor.getTag() == tag : "wrong data accessor " + accessor + " for tag " + tag;
         return accessor;
     }
 
-    private int readUnsignedByte(int position, int offsetInBytes) {
+    int readUnsignedByte(int position, int offsetInBytes) {
         long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
         return UNSAFE.getByte(metaspaceMethodData + fullOffsetInBytes) & 0xFF;
     }
 
-    private int readUnsignedShort(int position, int offsetInBytes) {
+    int readUnsignedShort(int position, int offsetInBytes) {
         long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
         return UNSAFE.getShort(metaspaceMethodData + fullOffsetInBytes) & 0xFFFF;
     }
@@ -305,101 +245,14 @@
         return sb.toString();
     }
 
-    /**
-     * Corresponds to {@code exception_seen_flag}.
-     */
-    static final int EXCEPTIONS_MASK = 1 << config.bitDataExceptionSeenFlag;
     static final int NO_DATA_SIZE = cellIndexToOffset(0);
 
-    private abstract static class AbstractMethodData implements HotSpotMethodDataAccessor {
-
-        private final Tag tag;
-        protected final int staticSize;
-
-        protected AbstractMethodData(Tag tag, int staticSize) {
-            this.tag = tag;
-            this.staticSize = staticSize;
-        }
-
-        public Tag getTag() {
-            return tag;
-        }
-
-        public static Tag readTag(HotSpotMethodData data, int position) {
-            final int tag = data.readUnsignedByte(position, config.dataLayoutTagOffset);
-            return Tag.getEnum(tag);
-        }
-
-        @Override
-        public int getBCI(HotSpotMethodData data, int position) {
-            return data.readUnsignedShort(position, config.dataLayoutBCIOffset);
-        }
-
-        @Override
-        public final int getSize(HotSpotMethodData data, int position) {
-            int size = staticSize + getDynamicSize(data, position);
-            // Sanity check against VM
-            int vmSize = HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position);
-            assert size == vmSize : size + " != " + vmSize;
-            return size;
-        }
-
-        @Override
-        public TriState getExceptionSeen(HotSpotMethodData data, int position) {
-            return TriState.get((getFlags(data, position) & EXCEPTIONS_MASK) != 0);
-        }
-
-        @Override
-        public JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position) {
-            return null;
-        }
-
-        @Override
-        public JavaMethodProfile getMethodProfile(HotSpotMethodData data, int position) {
-            return null;
-        }
-
-        @Override
-        public double getBranchTakenProbability(HotSpotMethodData data, int position) {
-            return -1;
-        }
-
-        @Override
-        public double[] getSwitchProbabilities(HotSpotMethodData data, int position) {
-            return null;
-        }
-
-        @Override
-        public int getExecutionCount(HotSpotMethodData data, int position) {
-            return -1;
-        }
-
-        @Override
-        public TriState getNullSeen(HotSpotMethodData data, int position) {
-            return TriState.UNKNOWN;
-        }
-
-        protected int getFlags(HotSpotMethodData data, int position) {
-            return data.readUnsignedByte(position, config.dataLayoutFlagsOffset);
-        }
-
-        /**
-         * @param data
-         * @param position
-         */
-        protected int getDynamicSize(HotSpotMethodData data, int position) {
-            return 0;
-        }
-
-        public abstract StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos);
-    }
-
-    static class NoMethodData extends AbstractMethodData {
+    static class NoMethodData extends HotSpotMethodDataAccessor {
 
         private final TriState exceptionSeen;
 
-        protected NoMethodData(TriState exceptionSeen) {
-            super(Tag.No, NO_DATA_SIZE);
+        protected NoMethodData(HotSpotVMConfig config, int tag, TriState exceptionSeen) {
+            super(config, tag, NO_DATA_SIZE);
             this.exceptionSeen = exceptionSeen;
         }
 
@@ -419,14 +272,17 @@
         }
     }
 
-    static class BitData extends AbstractMethodData {
+    static final int BIT_DATA_SIZE = cellIndexToOffset(0);
+    static final int BIT_DATA_NULL_SEEN_FLAG = 1 << config.bitDataNullSeenFlag;
 
-        private BitData() {
-            super(Tag.BitData, BIT_DATA_SIZE);
+    static class BitData extends HotSpotMethodDataAccessor {
+
+        private BitData(HotSpotVMConfig config, int tag) {
+            super(config, tag, BIT_DATA_SIZE);
         }
 
-        protected BitData(Tag tag, int staticSize) {
-            super(tag, staticSize);
+        protected BitData(HotSpotVMConfig config, int tag, int staticSize) {
+            super(config, tag, staticSize);
         }
 
         @Override
@@ -440,14 +296,17 @@
         }
     }
 
+    static final int COUNTER_DATA_SIZE = cellIndexToOffset(1);
+    static final int COUNTER_DATA_COUNT_OFFSET = cellIndexToOffset(config.methodDataCountOffset);
+
     static class CounterData extends BitData {
 
-        CounterData() {
-            super(Tag.CounterData, COUNTER_DATA_SIZE);
+        CounterData(HotSpotVMConfig config, int tag) {
+            super(config, tag, COUNTER_DATA_SIZE);
         }
 
-        protected CounterData(Tag tag, int staticSize) {
-            super(tag, staticSize);
+        protected CounterData(HotSpotVMConfig config, int tag, int staticSize) {
+            super(config, tag, staticSize);
         }
 
         @Override
@@ -465,14 +324,18 @@
         }
     }
 
-    static class JumpData extends AbstractMethodData {
+    static final int JUMP_DATA_SIZE = cellIndexToOffset(2);
+    static final int TAKEN_COUNT_OFFSET = cellIndexToOffset(config.jumpDataTakenOffset);
+    static final int TAKEN_DISPLACEMENT_OFFSET = cellIndexToOffset(config.jumpDataDisplacementOffset);
 
-        JumpData() {
-            super(Tag.JumpData, JUMP_DATA_SIZE);
+    static class JumpData extends HotSpotMethodDataAccessor {
+
+        JumpData(HotSpotVMConfig config, int tag) {
+            super(config, tag, JUMP_DATA_SIZE);
         }
 
-        protected JumpData(Tag tag, int staticSize) {
-            super(tag, staticSize);
+        protected JumpData(HotSpotVMConfig config, int tag, int staticSize) {
+            super(config, tag, staticSize);
         }
 
         @Override
@@ -509,10 +372,16 @@
         }
     }
 
+    static final int TYPE_DATA_ROW_SIZE = cellsToBytes(config.receiverTypeDataReceiverTypeRowCellCount);
+
+    static final int NONPROFILED_COUNT_OFFSET = cellIndexToOffset(config.receiverTypeDataNonprofiledCountOffset);
+    static final int TYPE_DATA_FIRST_TYPE_OFFSET = cellIndexToOffset(config.receiverTypeDataReceiver0Offset);
+    static final int TYPE_DATA_FIRST_TYPE_COUNT_OFFSET = cellIndexToOffset(config.receiverTypeDataCount0Offset);
+
     abstract static class AbstractTypeData extends CounterData {
 
-        protected AbstractTypeData(Tag tag, int staticSize) {
-            super(tag, staticSize);
+        protected AbstractTypeData(HotSpotVMConfig config, int tag, int staticSize) {
+            super(config, tag, staticSize);
         }
 
         @Override
@@ -558,7 +427,7 @@
 
         protected abstract long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position);
 
-        private static JavaTypeProfile createTypeProfile(TriState nullSeen, RawItemProfile<ResolvedJavaType> profile) {
+        private JavaTypeProfile createTypeProfile(TriState nullSeen, RawItemProfile<ResolvedJavaType> profile) {
             if (profile.entries <= 0 || profile.totalCount <= 0) {
                 return null;
             }
@@ -602,14 +471,16 @@
         }
     }
 
+    static final int TYPE_CHECK_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
+
     static class ReceiverTypeData extends AbstractTypeData {
 
-        ReceiverTypeData() {
-            super(Tag.ReceiverTypeData, TYPE_CHECK_DATA_SIZE);
+        ReceiverTypeData(HotSpotVMConfig config, int tag) {
+            super(config, tag, TYPE_CHECK_DATA_SIZE);
         }
 
-        protected ReceiverTypeData(Tag tag, int staticSize) {
-            super(tag, staticSize);
+        protected ReceiverTypeData(HotSpotVMConfig config, int tag, int staticSize) {
+            super(config, tag, staticSize);
         }
 
         @Override
@@ -623,14 +494,18 @@
         }
     }
 
+    static final int VIRTUAL_CALL_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * (config.typeProfileWidth + config.methodProfileWidth);
+    static final int VIRTUAL_CALL_DATA_FIRST_METHOD_OFFSET = TYPE_DATA_FIRST_TYPE_OFFSET + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
+    static final int VIRTUAL_CALL_DATA_FIRST_METHOD_COUNT_OFFSET = TYPE_DATA_FIRST_TYPE_COUNT_OFFSET + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
+
     static class VirtualCallData extends ReceiverTypeData {
 
-        VirtualCallData() {
-            super(Tag.VirtualCallData, VIRTUAL_CALL_DATA_SIZE);
+        VirtualCallData(HotSpotVMConfig config, int tag) {
+            super(config, tag, VIRTUAL_CALL_DATA_SIZE);
         }
 
-        protected VirtualCallData(Tag tag, int staticSize) {
-            super(tag, staticSize);
+        protected VirtualCallData(HotSpotVMConfig config, int tag, int staticSize) {
+            super(config, tag, staticSize);
         }
 
         @Override
@@ -660,7 +535,7 @@
             return createMethodProfile(getRawMethodProfile(data, position));
         }
 
-        private static RawItemProfile<ResolvedJavaMethod> getRawMethodProfile(HotSpotMethodData data, int position) {
+        private RawItemProfile<ResolvedJavaMethod> getRawMethodProfile(HotSpotMethodData data, int position) {
             int profileWidth = config.methodProfileWidth;
 
             ResolvedJavaMethod[] methods = new ResolvedJavaMethod[profileWidth];
@@ -684,7 +559,7 @@
             return new RawItemProfile<>(entries, methods, counts, totalCount);
         }
 
-        private static JavaMethodProfile createMethodProfile(RawItemProfile<ResolvedJavaMethod> profile) {
+        private JavaMethodProfile createMethodProfile(RawItemProfile<ResolvedJavaMethod> profile) {
             if (profile.entries <= 0 || profile.totalCount <= 0) {
                 return null;
             }
@@ -727,8 +602,8 @@
 
     static class VirtualCallTypeData extends VirtualCallData {
 
-        VirtualCallTypeData() {
-            super(Tag.VirtualCallTypeData, 0);
+        VirtualCallTypeData(HotSpotVMConfig config, int tag) {
+            super(config, tag, 0);
         }
 
         @Override
@@ -738,17 +613,23 @@
         }
     }
 
+    static final int RET_DATA_ROW_SIZE = cellsToBytes(3);
+    static final int RET_DATA_SIZE = cellIndexToOffset(1) + RET_DATA_ROW_SIZE * config.bciProfileWidth;
+
     static class RetData extends CounterData {
 
-        RetData() {
-            super(Tag.RetData, RET_DATA_SIZE);
+        RetData(HotSpotVMConfig config, int tag) {
+            super(config, tag, RET_DATA_SIZE);
         }
     }
 
+    static final int BRANCH_DATA_SIZE = cellIndexToOffset(3);
+    static final int NOT_TAKEN_COUNT_OFFSET = cellIndexToOffset(config.branchDataNotTakenOffset);
+
     static class BranchData extends JumpData {
 
-        BranchData() {
-            super(Tag.BranchData, BRANCH_DATA_SIZE);
+        BranchData(HotSpotVMConfig config, int tag) {
+            super(config, tag, BRANCH_DATA_SIZE);
         }
 
         @Override
@@ -775,10 +656,13 @@
         }
     }
 
-    static class ArrayData extends AbstractMethodData {
+    static final int ARRAY_DATA_LENGTH_OFFSET = cellIndexToOffset(config.arrayDataArrayLenOffset);
+    static final int ARRAY_DATA_START_OFFSET = cellIndexToOffset(config.arrayDataArrayStartOffset);
 
-        ArrayData(Tag tag, int staticSize) {
-            super(tag, staticSize);
+    static class ArrayData extends HotSpotMethodDataAccessor {
+
+        ArrayData(HotSpotVMConfig config, int tag, int staticSize) {
+            super(config, tag, staticSize);
         }
 
         @Override
@@ -796,10 +680,16 @@
         }
     }
 
+    static final int MULTI_BRANCH_DATA_SIZE = cellIndexToOffset(1);
+    static final int MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS = config.multiBranchDataPerCaseCellCount;
+    static final int MULTI_BRANCH_DATA_ROW_SIZE = cellsToBytes(MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS);
+    static final int MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(0);
+    static final int MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(1);
+
     static class MultiBranchData extends ArrayData {
 
-        MultiBranchData() {
-            super(Tag.MultiBranchData, MULTI_BRANCH_DATA_SIZE);
+        MultiBranchData(HotSpotVMConfig config, int tag) {
+            super(config, tag, MULTI_BRANCH_DATA_SIZE);
         }
 
         @Override
@@ -876,16 +766,18 @@
         }
     }
 
+    static final int ARG_INFO_DATA_SIZE = cellIndexToOffset(1);
+
     static class ArgInfoData extends ArrayData {
 
-        ArgInfoData() {
-            super(Tag.ArgInfoData, ARG_INFO_DATA_SIZE);
+        ArgInfoData(HotSpotVMConfig config, int tag) {
+            super(config, tag, ARG_INFO_DATA_SIZE);
         }
     }
 
-    static class UnknownProfileData extends AbstractMethodData {
-        UnknownProfileData(Tag tag) {
-            super(tag, 0);
+    static class UnknownProfileData extends HotSpotMethodDataAccessor {
+        UnknownProfileData(HotSpotVMConfig config, int tag) {
+            super(config, tag, 0);
         }
 
         @Override
@@ -896,7 +788,6 @@
 
         @Override
         public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) {
-            // TODO Auto-generated method stub
             return null;
         }
     }
@@ -908,4 +799,41 @@
     public int getCompiledIRSize() {
         return UNSAFE.getInt(metaspaceMethodData + config.methodDataIRSizeOffset);
     }
+
+    // sorted by tag
+    // @formatter:off
+    static final HotSpotMethodDataAccessor[] PROFILE_DATA_ACCESSORS = {
+        null,
+        new BitData(config, config.dataLayoutBitDataTag),
+        new CounterData(config, config.dataLayoutCounterDataTag),
+        new JumpData(config, config.dataLayoutJumpDataTag),
+        new ReceiverTypeData(config, config.dataLayoutReceiverTypeDataTag),
+        new VirtualCallData(config, config.dataLayoutVirtualCallDataTag),
+        new RetData(config, config.dataLayoutRetDataTag),
+        new BranchData(config, config.dataLayoutBranchDataTag),
+        new MultiBranchData(config, config.dataLayoutMultiBranchDataTag),
+        new ArgInfoData(config, config.dataLayoutArgInfoDataTag),
+        new UnknownProfileData(config, config.dataLayoutCallTypeDataTag),
+        new VirtualCallTypeData(config, config.dataLayoutVirtualCallTypeDataTag),
+        new UnknownProfileData(config, config.dataLayoutParametersTypeDataTag),
+        new UnknownProfileData(config, config.dataLayoutSpeculativeTrapDataTag),
+    };
+
+    private static boolean checkAccessorTags() {
+        int expectedTag = 0;
+        for (HotSpotMethodDataAccessor accessor : PROFILE_DATA_ACCESSORS) {
+            if (expectedTag ==0 ) {
+                assert accessor == null;
+            } else {
+                assert accessor.tag == expectedTag: expectedTag + " != " + accessor.tag + " " + accessor;
+            }
+            expectedTag++;
+        }
+        return true;
+    }
+
+    static {
+        assert checkAccessorTags();
+    }
+    // @formatter:on
 }
--- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java	Fri Jul 01 13:31:04 2016 -0700
+++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java	Thu Jun 30 22:07:57 2016 +0200
@@ -1,110 +1,129 @@
-/*
- * Copyright (c) 2011, 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
- * 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.
- *
- * 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.
- */
 package jdk.vm.ci.hotspot;
 
-import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
 import jdk.vm.ci.meta.JavaMethodProfile;
 import jdk.vm.ci.meta.JavaTypeProfile;
 import jdk.vm.ci.meta.ProfilingInfo;
 import jdk.vm.ci.meta.TriState;
 
 /**
- * Interface for accessor objects that encapsulate the logic for accessing the different kinds of
- * data in a HotSpot methodDataOop. This interface is similar to the interface {@link ProfilingInfo}
- * , but most methods require a MethodDataObject and the exact position within the methodData.
+ * Base class for accessing the different kinds of data in a HotSpot {@code MethodData}. This is
+ * similar to {@link ProfilingInfo}, but most methods require a {@link HotSpotMethodData} and the
+ * exact position within the method data.
  */
-public interface HotSpotMethodDataAccessor {
+abstract class HotSpotMethodDataAccessor {
 
-    /**
-     * {@code DataLayout} tag values.
-     */
-    enum Tag {
-        No(config().dataLayoutNoTag),
-        BitData(config().dataLayoutBitDataTag),
-        CounterData(config().dataLayoutCounterDataTag),
-        JumpData(config().dataLayoutJumpDataTag),
-        ReceiverTypeData(config().dataLayoutReceiverTypeDataTag),
-        VirtualCallData(config().dataLayoutVirtualCallDataTag),
-        RetData(config().dataLayoutRetDataTag),
-        BranchData(config().dataLayoutBranchDataTag),
-        MultiBranchData(config().dataLayoutMultiBranchDataTag),
-        ArgInfoData(config().dataLayoutArgInfoDataTag),
-        CallTypeData(config().dataLayoutCallTypeDataTag),
-        VirtualCallTypeData(config().dataLayoutVirtualCallTypeDataTag),
-        ParametersTypeData(config().dataLayoutParametersTypeDataTag),
-        SpeculativeTrapData(config().dataLayoutSpeculativeTrapDataTag);
+    final int tag;
+    final int staticSize;
+    final HotSpotVMConfig config;
 
-        private final int value;
-
-        Tag(int value) {
-            this.value = value;
-        }
-
-        public int getValue() {
-            return value;
-        }
-
-        public static Tag getEnum(int value) {
-            Tag result = values()[value];
-            assert value == result.value;
-            return result;
-        }
+    protected HotSpotMethodDataAccessor(HotSpotVMConfig config, int tag, int staticSize) {
+        this.config = config;
+        this.tag = tag;
+        this.staticSize = staticSize;
     }
 
     /**
-     * Returns the {@link Tag} stored in the LayoutData header.
+     * Returns the tag stored in the LayoutData header.
      *
      * @return tag stored in the LayoutData header
      */
-    Tag getTag();
+    int getTag() {
+        return tag;
+    }
+
+    static int readTag(HotSpotVMConfig config, HotSpotMethodData data, int position) {
+        final int tag = data.readUnsignedByte(position, config.dataLayoutTagOffset);
+        assert tag >= config.dataLayoutNoTag && tag <= config.dataLayoutSpeculativeTrapDataTag : "profile data tag out of bounds: " + tag;
+        return tag;
+    }
 
     /**
      * Returns the BCI stored in the LayoutData header.
      *
-     * @return An integer &ge; 0 and &le; Short.MAX_VALUE, or -1 if not supported.
+     * @return an integer between 0 and {@link Short#MAX_VALUE} inclusive, or -1 if not supported
      */
-    int getBCI(HotSpotMethodData data, int position);
+    int getBCI(HotSpotMethodData data, int position) {
+        return data.readUnsignedShort(position, config.dataLayoutBCIOffset);
+    }
 
     /**
      * Computes the size for the specific data at the given position.
      *
-     * @return An integer &gt; 0.
+     * @return a value greater than 0
      */
-    int getSize(HotSpotMethodData data, int position);
+    final int getSize(HotSpotMethodData data, int position) {
+        int size = staticSize + getDynamicSize(data, position);
+        // Sanity check against VM
+        int vmSize = HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position);
+        assert size == vmSize : size + " != " + vmSize;
+        return size;
+    }
+
+    TriState getExceptionSeen(HotSpotMethodData data, int position) {
+        final int exceptionsMask = 1 << config.bitDataExceptionSeenFlag;
+        return TriState.get((getFlags(data, position) & exceptionsMask) != 0);
+    }
 
-    JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position);
+    /**
+     * @param data
+     * @param position
+     */
+    JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position) {
+        return null;
+    }
 
-    JavaMethodProfile getMethodProfile(HotSpotMethodData data, int position);
+    /**
+     * @param data
+     * @param position
+     */
+    JavaMethodProfile getMethodProfile(HotSpotMethodData data, int position) {
+        return null;
+    }
 
-    double getBranchTakenProbability(HotSpotMethodData data, int position);
+    /**
+     * @param data
+     * @param position
+     */
+    double getBranchTakenProbability(HotSpotMethodData data, int position) {
+        return -1;
+    }
 
-    double[] getSwitchProbabilities(HotSpotMethodData data, int position);
+    /**
+     * @param data
+     * @param position
+     */
+    double[] getSwitchProbabilities(HotSpotMethodData data, int position) {
+        return null;
+    }
 
-    TriState getExceptionSeen(HotSpotMethodData data, int position);
+    /**
+     * @param data
+     * @param position
+     */
+    int getExecutionCount(HotSpotMethodData data, int position) {
+        return -1;
+    }
 
-    TriState getNullSeen(HotSpotMethodData data, int position);
+    /**
+     * @param data
+     * @param position
+     */
+    TriState getNullSeen(HotSpotMethodData data, int position) {
+        return TriState.UNKNOWN;
+    }
+
+    protected int getFlags(HotSpotMethodData data, int position) {
+        return data.readUnsignedByte(position, config.dataLayoutFlagsOffset);
+    }
 
-    int getExecutionCount(HotSpotMethodData data, int position);
+    /**
+     * @param data
+     * @param position
+     */
+    protected int getDynamicSize(HotSpotMethodData data, int position) {
+        return 0;
+    }
 
-    StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos);
+    abstract StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos);
+
 }