Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ci/ciMethodData.java
41161 views
/*1* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324package sun.jvm.hotspot.ci;2526import java.io.*;27import java.util.*;28import sun.jvm.hotspot.debugger.*;29import sun.jvm.hotspot.runtime.*;30import sun.jvm.hotspot.oops.*;31import sun.jvm.hotspot.types.*;32import sun.jvm.hotspot.types.Field;33import sun.jvm.hotspot.utilities.Observable;34import sun.jvm.hotspot.utilities.Observer;3536public class ciMethodData extends ciMetadata implements MethodDataInterface<ciKlass,ciMethod> {37static {38VM.registerVMInitializedObserver(new Observer() {39public void update(Observable o, Object data) {40initialize(VM.getVM().getTypeDataBase());41}42});43}4445private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {46Type type = db.lookupType("ciMethodData");47origField = type.getField("_orig");48currentMileageField = new CIntField(type.getCIntegerField("_current_mileage"), 0);49argReturnedField = new CIntField(type.getCIntegerField("_arg_returned"), 0);50argStackField = new CIntField(type.getCIntegerField("_arg_stack"), 0);51argLocalField = new CIntField(type.getCIntegerField("_arg_local"), 0);52eflagsField = new CIntField(type.getCIntegerField("_eflags"), 0);53hintDiField = new CIntField(type.getCIntegerField("_hint_di"), 0);54currentMileageField = new CIntField(type.getCIntegerField("_current_mileage"), 0);55dataField = type.getAddressField("_data");56extraDataSizeField = new CIntField(type.getCIntegerField("_extra_data_size"), 0);57dataSizeField = new CIntField(type.getCIntegerField("_data_size"), 0);58stateField = new CIntField(type.getCIntegerField("_state"), 0);59Type typeMethodData = db.lookupType("MethodData");60sizeofMethodDataOopDesc = (int)typeMethodData.getSize();61parametersTypeDataDi = new CIntField(typeMethodData.getCIntegerField("_parameters_type_data_di"), 0);62}6364private static Field origField;65private static CIntField currentMileageField;66private static CIntField argReturnedField;67private static CIntField argStackField;68private static CIntField argLocalField;69private static CIntField eflagsField;70private static CIntField hintDiField;71private static AddressField dataField;72private static CIntField extraDataSizeField;73private static CIntField dataSizeField;74private static CIntField stateField;75private static int sizeofMethodDataOopDesc;76private static CIntField parametersTypeDataDi;7778public ciMethodData(Address addr) {79super(addr);80}8182public ciKlass getKlassAtAddress(Address addr) {83return (ciKlass)ciObjectFactory.getMetadata(addr);84}8586public ciMethod getMethodAtAddress(Address addr) {87return (ciMethod)ciObjectFactory.getMetadata(addr);88}8990public void printKlassValueOn(ciKlass klass, PrintStream st) {91klass.printValueOn(st);92}9394public void printMethodValueOn(ciMethod method, PrintStream st) {95method.printValueOn(st);96}9798private byte[] fetchDataAt(Address base, long size) {99byte[] result = new byte[(int)size];100for (int i = 0; i < size; i++) {101result[i] = base.getJByteAt(i);102}103return result;104}105106public byte[] orig() {107// fetch the orig MethodData data between header and dataSize108Address base = getAddress().addOffsetTo(origField.getOffset());109byte[] result = new byte[(int)origField.getType().getSize()];110for (int i = 0; i < result.length; i++) {111result[i] = base.getJByteAt(i);112}113return result;114}115116public long[] data() {117// Read the data as an array of intptr_t elements118Address base = dataField.getValue(getAddress());119int elements = (dataSize() + extraDataSize()) / MethodData.cellSize;120long[] result = new long[elements];121for (int i = 0; i < elements; i++) {122Address value = base.getAddressAt(i * MethodData.cellSize);123if (value != null) {124result[i] = value.minus(null);125}126}127return result;128}129130int dataSize() {131return (int)dataSizeField.getValue(getAddress());132}133134int extraDataSize() {135return (int)extraDataSizeField.getValue(getAddress());136}137138int state() {139return (int)stateField.getValue(getAddress());140}141142int currentMileage() {143return (int)currentMileageField.getValue(getAddress());144}145146boolean outOfBounds(int dataIndex) {147return dataIndex >= dataSize();148}149150ParametersTypeData<ciKlass,ciMethod> parametersTypeData() {151int di = (int)parametersTypeDataDi.getValue(getMetadata().getAddress());152if (di == -1 || di == -2) {153return null;154}155DataLayout dataLayout = new DataLayout(dataField.getValue(getAddress()), di);156return new ParametersTypeData<ciKlass,ciMethod>(this, dataLayout);157}158159ProfileData dataAt(int dataIndex) {160if (outOfBounds(dataIndex)) {161return null;162}163DataLayout dataLayout = new DataLayout(dataField.getValue(getAddress()), dataIndex);164165switch (dataLayout.tag()) {166case DataLayout.noTag:167default:168throw new InternalError();169case DataLayout.bitDataTag:170return new BitData(dataLayout);171case DataLayout.counterDataTag:172return new CounterData(dataLayout);173case DataLayout.jumpDataTag:174return new JumpData(dataLayout);175case DataLayout.receiverTypeDataTag:176return new ReceiverTypeData<ciKlass,ciMethod>(this, dataLayout);177case DataLayout.virtualCallDataTag:178return new VirtualCallData<ciKlass,ciMethod>(this, dataLayout);179case DataLayout.retDataTag:180return new RetData(dataLayout);181case DataLayout.branchDataTag:182return new BranchData(dataLayout);183case DataLayout.multiBranchDataTag:184return new MultiBranchData(dataLayout);185case DataLayout.callTypeDataTag:186return new CallTypeData<ciKlass,ciMethod>(this, dataLayout);187case DataLayout.virtualCallTypeDataTag:188return new VirtualCallTypeData<ciKlass,ciMethod>(this, dataLayout);189case DataLayout.parametersTypeDataTag:190return new ParametersTypeData<ciKlass,ciMethod>(this, dataLayout);191}192}193194int dpToDi(int dp) {195return dp;196}197198int firstDi() { return 0; }199ProfileData firstData() { return dataAt(firstDi()); }200ProfileData nextData(ProfileData current) {201int currentIndex = dpToDi(current.dp());202int nextIndex = currentIndex + current.sizeInBytes();203return dataAt(nextIndex);204}205boolean isValid(ProfileData current) { return current != null; }206207DataLayout limitDataPosition() {208return new DataLayout(dataField.getValue(getAddress()), dataSize());209}210DataLayout extraDataBase() {211return limitDataPosition();212}213DataLayout extraDataLimit() {214return new DataLayout(dataField.getValue(getAddress()), dataSize() + extraDataSize());215}216DataLayout nextExtra(DataLayout dataLayout) {217return new DataLayout(dataField.getValue(getAddress()), dataLayout.dp() + DataLayout.computeSizeInBytes(MethodData.extraNbCells(dataLayout)));218}219220public void printDataOn(PrintStream st) {221if (parametersTypeData() != null) {222parametersTypeData().printDataOn(st);223}224ProfileData data = firstData();225for ( ; isValid(data); data = nextData(data)) {226st.print(dpToDi(data.dp()));227st.print(" ");228// st->fillTo(6);229data.printDataOn(st);230}231st.println("--- Extra data:");232DataLayout dp = extraDataBase();233DataLayout end = extraDataLimit();234for (;; dp = nextExtra(dp)) {235switch(dp.tag()) {236case DataLayout.noTag:237continue;238case DataLayout.bitDataTag:239data = new BitData(dp);240break;241case DataLayout.speculativeTrapDataTag:242data = new SpeculativeTrapData<ciKlass,ciMethod>(this, dp);243break;244case DataLayout.argInfoDataTag:245data = new ArgInfoData(dp);246dp = end; // ArgInfoData is at the end of extra data section.247break;248default:249throw new InternalError("unexpected tag " + dp.tag());250}251st.print(dpToDi(data.dp()));252st.print(" ");253data.printDataOn(st);254if (dp == end) return;255}256}257258int dumpReplayDataTypeHelper(PrintStream out, int round, int count, int index, ProfileData pdata, ciKlass k) {259if (k != null) {260if (round == 0) count++;261else out.print(" " + ((pdata.dp() + pdata.cellOffset(index)) / MethodData.cellSize) + " " + k.name());262}263return count;264}265266int dumpReplayDataReceiverTypeHelper(PrintStream out, int round, int count, ReceiverTypeData<ciKlass,ciMethod> vdata) {267for (int i = 0; i < vdata.rowLimit(); i++) {268ciKlass k = vdata.receiver(i);269count = dumpReplayDataTypeHelper(out, round, count, vdata.receiverCellIndex(i), vdata, k);270}271return count;272}273274int dumpReplayDataCallTypeHelper(PrintStream out, int round, int count, CallTypeDataInterface<ciKlass> callTypeData) {275if (callTypeData.hasArguments()) {276for (int i = 0; i < callTypeData.numberOfArguments(); i++) {277count = dumpReplayDataTypeHelper(out, round, count, callTypeData.argumentTypeIndex(i), (ProfileData)callTypeData, callTypeData.argumentType(i));278}279}280if (callTypeData.hasReturn()) {281count = dumpReplayDataTypeHelper(out, round, count, callTypeData.returnTypeIndex(), (ProfileData)callTypeData, callTypeData.returnType());282}283return count;284}285286int dumpReplayDataExtraDataHelper(PrintStream out, int round, int count) {287DataLayout dp = extraDataBase();288DataLayout end = extraDataLimit();289290for (;dp != end; dp = nextExtra(dp)) {291switch(dp.tag()) {292case DataLayout.noTag:293case DataLayout.argInfoDataTag:294return count;295case DataLayout.bitDataTag:296break;297case DataLayout.speculativeTrapDataTag: {298SpeculativeTrapData<ciKlass,ciMethod> data = new SpeculativeTrapData<ciKlass,ciMethod>(this, dp);299ciMethod m = data.method();300if (m != null) {301if (round == 0) {302count++;303} else {304out.print(" " + (dpToDi(data.dp() + data.cellOffset(SpeculativeTrapData.methodIndex())) / MethodData.cellSize) + " " + m.nameAsAscii());305}306}307break;308}309default:310throw new InternalError("bad tag " + dp.tag());311}312}313return count;314}315316public void dumpReplayData(PrintStream out) {317MethodData mdo = (MethodData)getMetadata();318Method method = mdo.getMethod();319out.print("ciMethodData " +320method.nameAsAscii() + " " +321state() + " " + currentMileage());322byte[] orig = orig();323out.print(" orig " + orig.length);324for (int i = 0; i < orig.length; i++) {325out.print(" " + (orig[i] & 0xff));326}327328long[] data = data();329out.print(" data " + data.length);330for (int i = 0; i < data.length; i++) {331out.print(" 0x" + Long.toHexString(data[i]));332}333int count = 0;334ParametersTypeData<ciKlass,ciMethod> parameters = parametersTypeData();335for (int round = 0; round < 2; round++) {336if (round == 1) out.print(" oops " + count);337ProfileData pdata = firstData();338for ( ; isValid(pdata); pdata = nextData(pdata)) {339if (pdata instanceof ReceiverTypeData) {340@SuppressWarnings("unchecked")341ReceiverTypeData<ciKlass,ciMethod> receiverTypeData = (ReceiverTypeData<ciKlass,ciMethod>)pdata;342count = dumpReplayDataReceiverTypeHelper(out, round, count, receiverTypeData);343}344if (pdata instanceof CallTypeDataInterface) {345@SuppressWarnings("unchecked")346CallTypeDataInterface<ciKlass> callTypeData = (CallTypeDataInterface<ciKlass>)pdata;347count = dumpReplayDataCallTypeHelper(out, round, count, callTypeData);348}349}350if (parameters != null) {351for (int i = 0; i < parameters.numberOfParameters(); i++) {352count = dumpReplayDataTypeHelper(out, round, count, ParametersTypeData.typeIndex(i), parameters, parameters.type(i));353}354}355}356count = 0;357for (int round = 0; round < 2; round++) {358if (round == 1) out.print(" methods " + count);359count = dumpReplayDataExtraDataHelper(out, round, count);360}361out.println();362}363}364365366