# HG changeset patch # User Christian Haeubl # Date 1327019375 28800 # Node ID f7251c729b311fb6345332bb34f307654f8db4df # Parent 2bc254976621b3f28de3532be3612f12a9c6c9ce profiling info first try diff -r 2bc254976621 -r f7251c729b31 graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiProfilingInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiProfilingInfo.java Thu Jan 19 16:29:35 2012 -0800 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2009, 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 com.oracle.max.cri.ri; + + +/** + * Represents profiling information for one specific method. + */ +public interface RiProfilingInfo { + // iterating the profiling information + boolean setBCI(int bci); + int currentBCI(); + boolean next(); + boolean isAtValidData(); + + // invokevirtual/invokeinterface + RiResolvedType[] getTypes(); + double[] getTypeProbabilities(); + + // branches + double getBranchTakenProbability(); + double[] getSwitchProbabilities(); + + // exceptions + boolean hasExceptionOccurred(); +} diff -r 2bc254976621 -r f7251c729b31 graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedMethod.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedMethod.java Tue Jan 17 20:35:49 2012 +0100 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedMethod.java Thu Jan 19 16:29:35 2012 -0800 @@ -159,29 +159,10 @@ int invocationCount(); /** - * Returns an estimate of hot often an exception was seen at the given bytecode. - * @return The estimate in percent (0-100), with 0 meaning never and 100 meaning always, or -1 if this information isn't available. - */ - int exceptionProbability(int bci); - - /** - * Returns the type profile of the instruction at the given byte code index. - * @return The RiTypeProfile information, or null if it isn't available. + * Returns an object that provides access to the method's profiling information. + * @return The profiling information recorded for this method. */ - RiTypeProfile typeProfile(int bci); - - /** - * Returns an estimate of how often the branch at the given byte code was taken. - * @return The estimated probability, with 0.0 meaning never and 1.0 meaning always, or -1 if this information isn't available. - */ - double branchProbability(int bci); - - /** - * Returns an estimate of how often the branches of the switch at the given byte code were taken. - * @return The estimated probability, with 0.0 meaning never and 1.0 meaning always, or NULL if this information isn't available. - * The default case is specified at the last index. - */ - double[] switchProbability(int bci); + RiProfilingInfo profilingInfo(); /** * Returns a map that the compiler can use to store objects that should survive the current compilation. diff -r 2bc254976621 -r f7251c729b31 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotVMConfig.java Tue Jan 17 20:35:49 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotVMConfig.java Thu Jan 19 16:29:35 2012 -0800 @@ -30,7 +30,7 @@ public final class HotSpotVMConfig extends CompilerObject { /** - * + * */ private static final long serialVersionUID = -4744897993263044184L; @@ -72,6 +72,17 @@ public int klassOopOffset; public int nmethodEntryOffset; + // methodData information + public int methodDataDataOffset; + public int dataLayoutHeaderSizeInBytes; + public int dataLayoutTagOffset; + public int dataLayoutFlagsOffset; + public int dataLayoutBCIOffset; + public int dataLayoutCellsOffset; + public int dataLayoutCellSize; + public int bciProfileWidth; + public int typeProfileWidth; + // runtime stubs public long debugStub; public long instanceofStub; diff -r 2bc254976621 -r f7251c729b31 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java Tue Jan 17 20:35:49 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java Thu Jan 19 16:29:35 2012 -0800 @@ -49,13 +49,7 @@ int RiMethod_invocationCount(HotSpotMethodResolved method); - int RiMethod_exceptionProbability(HotSpotMethodResolved method, int bci); - - RiTypeProfile RiMethod_typeProfile(HotSpotMethodResolved method, int bci); - - double RiMethod_branchProbability(HotSpotMethodResolved method, int bci); - - double[] RiMethod_switchProbability(HotSpotMethodResolved method, int bci); + HotSpotMethodData RiMethod_methodData(HotSpotMethodResolved method); RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass); diff -r 2bc254976621 -r f7251c729b31 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java Tue Jan 17 20:35:49 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java Thu Jan 19 16:29:35 2012 -0800 @@ -60,18 +60,6 @@ public native int RiMethod_invocationCount(HotSpotMethodResolved method); @Override - public native int RiMethod_exceptionProbability(HotSpotMethodResolved method, int bci); - - @Override - public native RiTypeProfile RiMethod_typeProfile(HotSpotMethodResolved method, int bci); - - @Override - public native double RiMethod_branchProbability(HotSpotMethodResolved method, int bci); - - @Override - public native double[] RiMethod_switchProbability(HotSpotMethodResolved method, int bci); - - @Override public native RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass); @Override @@ -123,6 +111,9 @@ public native boolean RiType_isInitialized(HotSpotTypeResolved klass); @Override + public native RiProfilingInfo RiMethod_profilingInfo(HotSpotMethodResolved method); + + @Override public native RiType getType(Class javaClass); @Override diff -r 2bc254976621 -r f7251c729b31 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HOTSPOTMETHODDATAACCESSOR.JAVA --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HOTSPOTMETHODDATAACCESSOR.JAVA Thu Jan 19 16:29:35 2012 -0800 @@ -0,0 +1,39 @@ +/* + * 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 com.oracle.max.graal.hotspot.ri; + +import com.oracle.max.cri.ri.*; + +public interface HotSpotMethodDataAccessor { + int getTag(); + int getBCI(HotSpotMethodData data, int position); + int getSize(HotSpotMethodData data, int position); + boolean hasExceptionOccurred(HotSpotMethodData data, int position); + long getExecutionCount(HotSpotMethodDataAccessor data, int position); + + RiResolvedType[] getTypes(HotSpotMethodData data, int position); + double[] getTypeProbabilities(HotSpotMethodData data, int position); + + double getBranchTakenProbability(HotSpotMethodData data, int position); + double[] getSwitchProbabilities(HotSpotMethodData data, int position); +} diff -r 2bc254976621 -r f7251c729b31 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HOTSPOTPROFILINGINFOIMPL.JAVA --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HOTSPOTPROFILINGINFOIMPL.JAVA Thu Jan 19 16:29:35 2012 -0800 @@ -0,0 +1,104 @@ +/* + * 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 com.oracle.max.graal.hotspot.ri; + +import com.oracle.max.cri.ri.*; +import com.oracle.max.graal.hotspot.*; +import com.oracle.max.graal.hotspot.Compiler; + + +public final class HotSpotProfilingInfoImpl extends CompilerObject implements RiProfilingInfo { + + /** + * + */ + private static final long serialVersionUID = -8307682725047864875L; + + private boolean atValidData; + private int position; + private HotSpotMethodDataAccessor dataAccessor; + private HotSpotMethodData methodData; + + public HotSpotProfilingInfoImpl(Compiler compiler, HotSpotMethodData methodData) { + super(compiler); + this.methodData = methodData; + setBCI(0); + } + + public boolean setBCI(int value) { + assert value >= 0 : "invalid BCI"; + + seek(0); + while (atValidData && currentBCI() < value) { + next(); + } + + return atValidData; + } + + @Override + public int currentBCI() { + return dataAccessor.getBCI(methodData, position); + } + + @Override + public boolean isAtValidData() { + return atValidData; + } + + @Override + public boolean next() { + return seek(position + dataAccessor.getSize(methodData, position)); + } + + @Override + public RiResolvedType[] getTypes() { + return dataAccessor.getTypes(methodData, position); + } + + @Override + public double[] getTypeProbabilities() { + return dataAccessor.getTypeProbabilities(methodData, position); + } + + @Override + public double getBranchTakenProbability() { + return dataAccessor.getBranchTakenProbability(methodData, position); + } + + @Override + public double[] getSwitchProbabilities() { + return dataAccessor.getSwitchProbabilities(methodData, position); + } + + @Override + public boolean hasExceptionOccurred() { + return dataAccessor.hasExceptionOccurred(methodData, position); + } + + private boolean seek(int value) { + position = value; + dataAccessor = methodData.getDataAccessor(position); + return dataAccessor != null; + } +} diff -r 2bc254976621 -r f7251c729b31 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodData.java Thu Jan 19 16:29:35 2012 -0800 @@ -0,0 +1,432 @@ +/* + * 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 com.oracle.max.graal.hotspot.ri; + +import sun.misc.*; + +import com.oracle.max.cri.ri.*; +import com.oracle.max.graal.hotspot.*; +import com.oracle.max.graal.hotspot.Compiler; + + +public final class HotSpotMethodData extends CompilerObject { + + /** + * + */ + private static final long serialVersionUID = -8873133496591225071L; + // TODO (ch) use same logic as in NodeClass? + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final HotSpotMethodDataAccessor[] PROFILE_DATA_ACCESSORS = { + null, new BitData(), new CounterData(), new JumpData(), + new TypeCheckData(), new VirtualCallData(), new RetData(), + new BranchData(), new MultiBranchData(), new ArgInfoData() + }; + + private Object javaMirror; + private int dataSize; + + private HotSpotMethodData(Compiler compiler) { + super(compiler); + javaMirror = null; + dataSize = 0; + throw new IllegalStateException("this constructor is never actually called, because the objects are allocated from within the VM"); + } + + public HotSpotMethodDataAccessor getDataAccessor(int position) { + if (position < 0 || position >= dataSize) { + return null; + } + + int tag = AbstractMethodDataAccessor.readTag(this, position); + assert tag > 0 && tag < PROFILE_DATA_ACCESSORS.length : "illegal tag"; + return PROFILE_DATA_ACCESSORS[tag]; + } + + private int readUnsignedByte(int position, int offsetInCells) { + long fullOffset = computeFullOffset(position, offsetInCells); + return unsafe.getByte(javaMirror, fullOffset) & 0xFF; + } + + private int readUnsignedShort(int position, int offsetInCells) { + long fullOffset = computeFullOffset(position, offsetInCells); + return unsafe.getShort(javaMirror, fullOffset) & 0xFFFF; + } + + private long readUnsignedInt(int position, int offsetInCells) { + long fullOffset = computeFullOffset(position, offsetInCells); + return unsafe.getInt(javaMirror, fullOffset) & 0xFFFFFFFFL; + } + + private int readInt(int position, int offsetInCells) { + long fullOffset = computeFullOffset(position, offsetInCells); + return unsafe.getInt(javaMirror, fullOffset); + } + + private static int computeFullOffset(int position, int offsetInCells) { + HotSpotVMConfig config = getHotSpotVMConfig(); + return config.methodDataDataOffset + position + offsetInCells * config.dataLayoutCellSize; + } + + private static HotSpotVMConfig getHotSpotVMConfig() { + // TODO: implement, cache config somewhere? + return null; + } + + private abstract static class AbstractMethodDataAccessor implements HotSpotMethodDataAccessor { + private final int tag; + private final int staticCellCount; + + protected AbstractMethodDataAccessor(int tag, int staticCellCount) { + this.tag = tag; + this.staticCellCount = staticCellCount; + } + + @Override + public int getTag() { + return tag; + } + + public static int readTag(HotSpotMethodData data, int position) { + HotSpotVMConfig config = getHotSpotVMConfig(); + return data.readUnsignedByte(position, config.dataLayoutTagOffset); + } + + @Override + public int getBCI(HotSpotMethodData data, int position) { + HotSpotVMConfig config = getHotSpotVMConfig(); + return data.readUnsignedShort(position, config.dataLayoutBCIOffset); + } + + @Override + public int getSize(HotSpotMethodData data, int position) { + HotSpotVMConfig config = getHotSpotVMConfig(); + return config.dataLayoutHeaderSizeInBytes + (staticCellCount + getDynamicCellCount(data, position)) * config.dataLayoutCellSize; + } + + @Override + public boolean hasExceptionOccurred(HotSpotMethodData data, int position) { + return false; + } + + @Override + public RiResolvedType[] getTypes(HotSpotMethodData data, int position) { + throw new IllegalStateException("not supported by current method data"); + } + + @Override + public double[] getTypeProbabilities(HotSpotMethodData data, int position) { + throw new IllegalStateException("not supported by current method data"); + } + + @Override + public double getBranchTakenProbability(HotSpotMethodData data, int position) { + throw new IllegalStateException("not supported by current method data"); + } + + @Override + public double[] getSwitchProbabilities(HotSpotMethodData data, int position) { + throw new IllegalStateException("not supported by current method data"); + } + + @Override + public long getExecutionCount(HotSpotMethodData data, int position) { + throw new IllegalStateException("not supported by current method data"); + } + + protected int getDynamicCellCount(HotSpotMethodData data, int position) { + return 0; + } + } + + private static class BitData extends AbstractMethodDataAccessor { + private static final int BIT_DATA_TAG = 1; + private static final int BIT_DATA_CELLS = 0; + + private BitData() { + super(BIT_DATA_TAG, BIT_DATA_CELLS); + } + + protected BitData(int tag, int staticCellCount) { + super(tag, staticCellCount); + } + } + + private static class CounterData extends BitData { + private static final int COUNTER_DATA_TAG = 2; + private static final int COUNTER_DATA_CELLS = 1; + private static final int COUNTER_DATA_COUNT_OFFSET = 0; + + public CounterData() { + super(COUNTER_DATA_TAG, COUNTER_DATA_CELLS); + } + + protected CounterData(int tag, int staticCellCount) { + super(tag, staticCellCount); + } + + @Override + public long getExecutionCount(HotSpotMethodData data, int position) { + return getCounterValue(data, position); + } + + protected long getCounterValue(HotSpotMethodData data, int position) { + return data.readUnsignedInt(position, COUNTER_DATA_COUNT_OFFSET); + } + } + + private static class JumpData extends AbstractMethodDataAccessor { + private static final int JUMP_DATA_TAG = 3; + private static final int JUMP_DATA_CELLS = 2; + protected static final int TAKEN_COUNT_OFFSET = 0; + protected static final int TAKEN_DISPLACEMENT_OFFSET = 1; + + public JumpData() { + super(JUMP_DATA_TAG, JUMP_DATA_CELLS); + } + + protected JumpData(int tag, int staticCellCount) { + super(tag, staticCellCount); + } + + @Override + public double getBranchTakenProbability(HotSpotMethodData data, int position) { + return 1; + } + + @Override + public long getExecutionCount(HotSpotMethodData data, int position) { + return data.readUnsignedInt(position, TAKEN_COUNT_OFFSET); + } + + public int getDisplacement(HotSpotMethodData data, int position) { + return data.readInt(position, TAKEN_DISPLACEMENT_OFFSET); + } + } + + private static class AbstractTypeData extends CounterData { + private static final int RECEIVER_TYPE_DATA_ROW_CELL_COUNT = 2; + private static final int RECEIVER_TYPE_DATA_FIRST_RECEIVER_OFFSET = 1; + private static final int RECEIVER_TYPE_DATA_FIRST_COUNT_OFFSET = 2; + + protected AbstractTypeData(int tag, int staticCellCount) { + super(tag, staticCellCount); + } + + @Override + public double[] getTypeProbabilities(HotSpotMethodData data, int position) { + HotSpotVMConfig config = getHotSpotVMConfig(); + int typeProfileWidth = config.typeProfileWidth; + + long total = 0; + double[] result = new double[typeProfileWidth]; + + for (int i = 0; i < typeProfileWidth; i++) { + long count = data.readUnsignedInt(position, getCountOffset(i)); + total += count; + result[i] = count; + } + + if (total != 0) { + for (int i = 0; i < typeProfileWidth; i++) { + result[i] = result[i] / total; + } + } + return result; + } + + @Override + public RiResolvedType[] getTypes(HotSpotMethodData data, int position) { + // TODO: seems to require a native call... + return null; + } + + @Override + protected int getDynamicCellCount(HotSpotMethodData data, int position) { + HotSpotVMConfig config = getHotSpotVMConfig(); + return config.typeProfileWidth * RECEIVER_TYPE_DATA_ROW_CELL_COUNT; + } + + private static int getReceiverOffset(int row) { + return RECEIVER_TYPE_DATA_FIRST_RECEIVER_OFFSET + row * RECEIVER_TYPE_DATA_ROW_CELL_COUNT; + } + + protected static int getCountOffset(int row) { + return RECEIVER_TYPE_DATA_FIRST_COUNT_OFFSET + row * RECEIVER_TYPE_DATA_ROW_CELL_COUNT; + } + } + + private static class TypeCheckData extends AbstractTypeData { + private static final int RECEIVER_TYPE_DATA_TAG = 4; + private static final int RECEIVER_TYPE_DATA_CELLS = 1; + + public TypeCheckData() { + super(RECEIVER_TYPE_DATA_TAG, RECEIVER_TYPE_DATA_CELLS); + } + + @Override + public long getExecutionCount(HotSpotMethodData data, int position) { + throw new IllegalStateException("not supported by current method data"); + } + + public long getTypeCheckFailedCount(HotSpotMethodData data, int position) { + return super.getCounterValue(data, position); + } + } + + private static class VirtualCallData extends AbstractTypeData { + private static final int VIRTUAL_CALL_DATA_TAG = 5; + private static final int VIRTUAL_CALL_DATA_CELLS = 1; + + public VirtualCallData() { + super(VIRTUAL_CALL_DATA_TAG, VIRTUAL_CALL_DATA_CELLS); + } + + @Override + public long getExecutionCount(HotSpotMethodData data, int position) { + HotSpotVMConfig config = getHotSpotVMConfig(); + int typeProfileWidth = config.typeProfileWidth; + + long total = 0; + for (int i = 0; i < typeProfileWidth; i++) { + total += data.readUnsignedInt(position, getCountOffset(i)); + } + + return total + getCounterValue(data, position); + } + } + + private static class RetData extends CounterData { + private static final int RET_DATA_TAG = 6; + private static final int RET_DATA_CELLS = 1; + private static final int RET_DATA_ROW_CELL_COUNT = 3; + + public RetData() { + super(RET_DATA_TAG, RET_DATA_CELLS); + } + + @Override + protected int getDynamicCellCount(HotSpotMethodData data, int position) { + HotSpotVMConfig config = getHotSpotVMConfig(); + return config.bciProfileWidth * RET_DATA_ROW_CELL_COUNT; + } + } + + private static class BranchData extends JumpData { + private static final int BRANCH_DATA_TAG = 7; + private static final int BRANCH_DATA_CELLS = 3; + private static final int NOT_TAKEN_COUNT_OFFSET = 2; + + public BranchData() { + super(BRANCH_DATA_TAG, BRANCH_DATA_CELLS); + } + + @Override + public double getBranchTakenProbability(HotSpotMethodData data, int position) { + long takenCount = data.readUnsignedInt(position, TAKEN_COUNT_OFFSET); + long notTakenCount = data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET); + double total = takenCount + notTakenCount; + return takenCount / total; + } + } + + private static class ArrayData extends AbstractMethodDataAccessor { + private static final int ARRAY_DATA_LENGTH_OFFSET = 0; + private static final int ARRAY_DATA_START_OFFSET = 1; + + public ArrayData(int tag, int staticCellCount) { + super(tag, staticCellCount); + } + + @Override + protected int getDynamicCellCount(HotSpotMethodData data, int position) { + return getLength(data, position); + } + + protected static int getLength(HotSpotMethodData data, int position) { + return data.readInt(position, ARRAY_DATA_LENGTH_OFFSET); + } + + protected static int getElementOffset(int index) { + return ARRAY_DATA_START_OFFSET + index; + } + } + + private static class MultiBranchData extends ArrayData { + private static final int MULTI_BRANCH_DATA_TAG = 8; + private static final int MULTI_BRANCH_DATA_CELLS = 1; + private static final int MULTI_BRANCH_DATA_COUNT_OFFSET = 0; + private static final int MULTI_BRANCH_DATA_DISPLACEMENT_OFFSET = 1; + + public MultiBranchData() { + super(MULTI_BRANCH_DATA_TAG, MULTI_BRANCH_DATA_CELLS); + } + + @Override + public double[] getSwitchProbabilities(HotSpotMethodData data, int position) { + int length = getLength(data, position); + long total = 0; + double[] result = new double[length]; + + for (int i = 0; i < length; i++) { + int offset = getCountOffset(i); + long count = data.readUnsignedInt(position, offset); + total += count; + result[i] = count; + } + + if (total != 0) { + for (int i = 0; i < length; i++) { + result[i] = result[i] / total; + } + } + return result; + } + + @Override + public long getExecutionCount(HotSpotMethodData data, int position) { + int length = getLength(data, position); + long total = 0; + + for (int i = 0; i < length; i++) { + int offset = getCountOffset(i); + total += data.readUnsignedInt(position, offset); + } + + return total; + } + + private static int getCountOffset(int index) { + return getElementOffset(index + MULTI_BRANCH_DATA_COUNT_OFFSET); + } + } + + private static class ArgInfoData extends ArrayData { + private static final int ARG_INFO_DATA_TAG = 9; + private static final int ARG_INFO_DATA_CELLS = 1; + + public ArgInfoData() { + super(ARG_INFO_DATA_TAG, ARG_INFO_DATA_CELLS); + } + } +} diff -r 2bc254976621 -r f7251c729b31 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java Tue Jan 17 20:35:49 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java Thu Jan 19 16:29:35 2012 -0800 @@ -55,6 +55,7 @@ private Boolean hasBalancedMonitors; private Map compilerStorage; private RiResolvedType holder; + private HotSpotMethodData methodData; private byte[] code; private HotSpotMethodResolvedImpl() { @@ -189,24 +190,17 @@ return null; } + @Override public int invocationCount() { return compiler.getVMEntries().RiMethod_invocationCount(this); } - public int exceptionProbability(int bci) { - return compiler.getVMEntries().RiMethod_exceptionProbability(this, bci); - } - - public RiTypeProfile typeProfile(int bci) { - return compiler.getVMEntries().RiMethod_typeProfile(this, bci); - } - - public double branchProbability(int bci) { - return compiler.getVMEntries().RiMethod_branchProbability(this, bci); - } - - public double[] switchProbability(int bci) { - return compiler.getVMEntries().RiMethod_switchProbability(this, bci); + @Override + public RiProfilingInfo profilingInfo() { + if (methodData == null) { + methodData = compiler.getVMEntries().RiMethod_methodData(this); + } + return new HotSpotProfilingInfoImpl(compiler, methodData); } @Override diff -r 2bc254976621 -r f7251c729b31 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Tue Jan 17 20:35:49 2012 +0100 +++ b/src/share/vm/classfile/systemDictionary.hpp Thu Jan 19 16:29:35 2012 -0800 @@ -223,7 +223,7 @@ template(RiType_klass, com_oracle_max_cri_ri_RiType, Opt) \ template(RiResolvedField_klass, com_oracle_max_cri_ri_RiResolvedField, Opt) \ template(RiExceptionHandler_klass, com_oracle_max_cri_ri_RiExceptionHandler, Opt) \ - template(RiTypeProfile_klass, com_oracle_max_cri_ri_RiTypeProfile, Opt) \ + template(RiProfilingInfo_klass, com_oracle_max_cri_ri_RiProfilingInfo, Opt) \ /*end*/ diff -r 2bc254976621 -r f7251c729b31 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Tue Jan 17 20:35:49 2012 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Thu Jan 19 16:29:35 2012 -0800 @@ -284,7 +284,7 @@ template(com_oracle_max_cri_ri_RiMethod, "com/oracle/max/cri/ri/RiMethod") \ template(com_oracle_max_cri_ri_RiResolvedField, "com/oracle/max/cri/ri/RiResolvedField") \ template(com_oracle_max_cri_ri_RiType, "com/oracle/max/cri/ri/RiType") \ - template(com_oracle_max_cri_ri_RiTypeProfile, "com/oracle/max/cri/ri/RiTypeProfile") \ + template(com_oracle_max_cri_ri_RiProfilingInfo, "com/oracle/max/cri/ri/RiProfilingInfo") \ template(com_oracle_max_cri_ri_RiConstantPool, "com/oracle/max/cri/ri/RiConstantPool") \ template(com_oracle_max_cri_ri_RiExceptionHandler, "com/oracle/max/cri/ri/RiExceptionHandler") \ template(com_oracle_max_cri_ci_CiAssumptions, "com/oracle/max/cri/ci/CiAssumptions") \ diff -r 2bc254976621 -r f7251c729b31 src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Tue Jan 17 20:35:49 2012 +0100 +++ b/src/share/vm/graal/graalCompiler.cpp Thu Jan 19 16:29:35 2012 -0800 @@ -272,7 +272,24 @@ HotSpotMethodResolved::set_maxStackSize(obj, method->max_stack()); method->set_graal_mirror(obj()); - return obj(); + return obj; +} + +Handle GraalCompiler::createHotSpotProfilingInfo(methodDataHandle method_data, TRAPS) { + if(method_data->graal_mirror() != NULL) { + assert(method_data->graal_mirror()->is_a(HotSpotProfilingInfo::klass()), "unexpected class"); + return method_data->graal_mirror(); + } + + instanceKlass::cast(HotSpotProfilingInfo::klass())->initialize(CHECK_NULL); + Handle obj = instanceKlass::cast(HotSpotProfilingInfo::klass())->allocate_instance(CHECK_NULL); + assert(obj.not_null, "must be"); + + HotSpotProfilingInfo::set_compiler(obj, VMToCompiler::compilerInstance()()); + HotSpotProfilingInfo::set_javaMirror(obj, method_data()); + + method_data->set_graal_mirror(obj()); + return obj; } BasicType GraalCompiler::kindToBasicType(jchar ch) { diff -r 2bc254976621 -r f7251c729b31 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Tue Jan 17 20:35:49 2012 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Thu Jan 19 16:29:35 2012 -0800 @@ -873,6 +873,7 @@ set_int(env, config, "threadExceptionPcOffset", in_bytes(JavaThread::exception_pc_offset())); set_int(env, config, "threadMultiNewArrayStorage", in_bytes(JavaThread::graal_multinewarray_storage_offset())); set_int(env, config, "classMirrorOffset", klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes()); + set_int(env, config, "methodDataDataOffset", in_bytes(methodDataOopDesc::data_offset)); set_long(env, config, "debugStub", VmIds::addStub((address)warning)); set_long(env, config, "instanceofStub", VmIds::addStub(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); @@ -985,7 +986,7 @@ #define METHOD "Lcom/oracle/max/cri/ri/RiMethod;" #define RESOLVED_METHOD "Lcom/oracle/max/graal/hotspot/ri/HotSpotMethodResolved;" #define REFLECT_METHOD "Ljava/lang/reflect/Method;" -#define TYPE_PROFILE "Lcom/oracle/max/cri/ri/RiTypeProfile;" +#define PROFILING_INFO "Lcom/oracle/max/cri/ri/RiProfilingInfo;" #define SIGNATURE "Lcom/oracle/max/cri/ri/RiSignature;" #define FIELD "Lcom/oracle/max/cri/ri/RiField;" #define RESOLVED_FIELD "Lcom/oracle/max/cri/ri/RiResolvedField;" diff -r 2bc254976621 -r f7251c729b31 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Tue Jan 17 20:35:49 2012 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Thu Jan 19 16:29:35 2012 -0800 @@ -68,6 +68,10 @@ int_field(HotSpotMethodResolved, maxLocals) \ int_field(HotSpotMethodResolved, maxStackSize) \ end_class \ + start_class(HotSpotProfilingInfo) \ + oop_field(HotSpotProfilingInfo, compiler, "Lcom/oracle/max/graal/hotspot/Compiler;") \ + oop_field(HotSpotProfilingInfo, javaMirror, "Ljava/lang/Object;") \ + end_class \ start_class(HotSpotType) \ oop_field(HotSpotType, name, "Ljava/lang/String;") \ end_class \ @@ -226,12 +230,6 @@ oop_field(CiMonitorValue, lockData, "Lcom/oracle/max/cri/ci/CiValue;") \ boolean_field(CiMonitorValue, eliminated) \ end_class \ - start_class(RiTypeProfile) \ - int_field(RiTypeProfile, count) \ - int_field(RiTypeProfile, morphism) \ - oop_field(RiTypeProfile, probabilities, "[F") \ - oop_field(RiTypeProfile, types, "[Lcom/oracle/max/cri/ri/RiResolvedType;") \ - end_class \ /* end*/ #define START_CLASS(name) \ diff -r 2bc254976621 -r f7251c729b31 src/share/vm/oops/methodDataKlass.cpp --- a/src/share/vm/oops/methodDataKlass.cpp Tue Jan 17 20:35:49 2012 +0100 +++ b/src/share/vm/oops/methodDataKlass.cpp Thu Jan 19 16:29:35 2012 -0800 @@ -84,6 +84,7 @@ obj->follow_header(); MarkSweep::mark_and_push(m->adr_method()); + MarkSweep::mark_and_push(m->adr_graal_mirror()); ResourceMark rm; for (ProfileData* data = m->first_data(); m->is_valid(data); @@ -100,6 +101,7 @@ obj->follow_header(cm); PSParallelCompact::mark_and_push(cm, m->adr_method()); + PSParallelCompact::mark_and_push(cm, m->adr_graal_mirror()); ResourceMark rm; for (ProfileData* data = m->first_data(); m->is_valid(data); @@ -119,6 +121,7 @@ obj->oop_iterate_header(blk); blk->do_oop(m->adr_method()); + blk->do_oop(m->adr_graal_mirror()); ResourceMark rm; for (ProfileData* data = m->first_data(); m->is_valid(data); @@ -140,6 +143,11 @@ if (mr.contains(adr)) { blk->do_oop(m->adr_method()); } + adr = m->adr_graal_mirror(); + if(mr.contains(adr)) { + blk->do_oop(m->adr_graal_mirror()); + } + ResourceMark rm; for (ProfileData* data = m->first_data(); m->is_valid(data); @@ -158,6 +166,7 @@ obj->adjust_header(); MarkSweep::adjust_pointer(m->adr_method()); + MarkSweep::adjust_pointer(m->adr_graal_mirror()); ResourceMark rm; ProfileData* data; for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) { @@ -173,6 +182,11 @@ methodDataOop m = methodDataOop(obj); // This should never point into the young gen. assert(!PSScavenge::should_scavenge(m->adr_method()), "Sanity"); + + oop* adr = m->adr_graal_mirror(); + if(PSScavenge::should_scavenge(adr)) { + pm->claim_or_forward_depth(adr); + } } int methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { @@ -180,6 +194,7 @@ methodDataOop m = methodDataOop(obj); PSParallelCompact::adjust_pointer(m->adr_method()); + PSParallelCompact::adjust_pointer(m->adr_graal_mirror()); ResourceMark rm; ProfileData* data; diff -r 2bc254976621 -r f7251c729b31 src/share/vm/oops/methodDataOop.cpp --- a/src/share/vm/oops/methodDataOop.cpp Tue Jan 17 20:35:49 2012 +0100 +++ b/src/share/vm/oops/methodDataOop.cpp Thu Jan 19 16:29:35 2012 -0800 @@ -749,6 +749,7 @@ ResourceMark rm; // Set the method back-pointer. _method = method(); + _graal_mirror = NULL; if (TieredCompilation) { _invocation_counter.init(); diff -r 2bc254976621 -r f7251c729b31 src/share/vm/oops/methodDataOop.hpp --- a/src/share/vm/oops/methodDataOop.hpp Tue Jan 17 20:35:49 2012 +0100 +++ b/src/share/vm/oops/methodDataOop.hpp Thu Jan 19 16:29:35 2012 -0800 @@ -1194,6 +1194,9 @@ // Back pointer to the methodOop methodOop _method; + // com/oracle/max/graal/hotspot/HotSpotProfilingInfo mirroring this method + oop _graal_mirror; + // Size of this oop in bytes int _size; @@ -1423,6 +1426,10 @@ // Accessors methodOop method() { return _method; } + // graal mirror + oop graal_mirror() const { return _graal_mirror; } + void set_graal_mirror(oop m) { oop_store((oop*) &_graal_mirror, m); } + // Get the data at an arbitrary (sort of) data index. ProfileData* data_at(int data_index); @@ -1520,6 +1527,7 @@ // GC support oop* adr_method() const { return (oop*)&_method; } + oop* adr_graal_mirror() const { return (oop*)&_graal_mirror; } bool object_is_parsable() const { return _size != 0; } void set_object_is_parsable(int object_size_in_bytes) { _size = object_size_in_bytes; }