Mercurial > hg > truffle
view graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodResolvedImpl.java @ 5335:439ca5ecc7dc
types profiles are now sorted in descending order of each profiled type's probability
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 02 May 2012 14:39:45 +0200 |
parents | b5cd7bc05695 |
children | f47c770756e6 |
line wrap: on
line source
/* * 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.graal.hotspot.ri; import java.lang.annotation.*; import java.lang.reflect.*; import java.util.*; import java.util.concurrent.*; import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; import com.oracle.max.cri.ri.RiTypeProfile.ProfiledType; import com.oracle.max.criutils.*; import com.oracle.graal.compiler.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.counters.*; import com.oracle.graal.java.bytecode.*; /** * Implementation of RiMethod for resolved HotSpot methods. */ public final class HotSpotMethodResolvedImpl extends HotSpotMethod implements HotSpotMethodResolved { private static final long serialVersionUID = -5486975070147586588L; /** DO NOT USE IN JAVA CODE! */ @SuppressWarnings("unused") @Deprecated private Object javaMirror; // cached values private final int codeSize; private final int accessFlags; private final int maxLocals; private final int maxStackSize; private RiSignature signature; private Boolean hasBalancedMonitors; private Map<Object, Object> compilerStorage; private RiResolvedType holder; private HotSpotMethodData methodData; private byte[] code; private boolean canBeInlined; private int compilationComplexity; private CompilationTask currentTask; private HotSpotMethodResolvedImpl() { super(null); throw new IllegalStateException("this constructor is never actually called, because the objects are allocated from within the VM"); } @Override public RiResolvedType holder() { return holder; } @Override public int accessFlags() { return accessFlags; } @Override public boolean canBeStaticallyBound() { return isLeafMethod() || Modifier.isStatic(accessFlags()); } @Override public byte[] code() { if (code == null) { code = compiler.getCompilerToVM().RiMethod_code(this); assert code.length == codeSize : "expected: " + codeSize + ", actual: " + code.length; } return code; } @Override public int codeSize() { return codeSize; } @Override public RiExceptionHandler[] exceptionHandlers() { return compiler.getCompilerToVM().RiMethod_exceptionHandlers(this); } @Override public boolean hasBalancedMonitors() { if (hasBalancedMonitors == null) { hasBalancedMonitors = compiler.getCompilerToVM().RiMethod_hasBalancedMonitors(this); } return hasBalancedMonitors; } @Override public boolean isClassInitializer() { return "<clinit>".equals(name) && Modifier.isStatic(accessFlags()); } @Override public boolean isConstructor() { return "<init>".equals(name) && !Modifier.isStatic(accessFlags()); } @Override public boolean isLeafMethod() { return Modifier.isFinal(accessFlags()) || Modifier.isPrivate(accessFlags()); } @Override public boolean isOverridden() { throw new UnsupportedOperationException("isOverridden"); } @Override public boolean noSafepointPolls() { return false; } @Override public String jniSymbol() { throw new UnsupportedOperationException("jniSymbol"); } public CiBitMap[] livenessMap() { return null; } @Override public int maxLocals() { return maxLocals; } @Override public int maxStackSize() { return maxStackSize; } @Override public StackTraceElement toStackTraceElement(int bci) { if (bci < 0 || bci >= codeSize) { // HotSpot code can only construct stack trace elements for valid bcis StackTraceElement ste = compiler.getCompilerToVM().RiMethod_toStackTraceElement(this, 0); return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1); } return compiler.getCompilerToVM().RiMethod_toStackTraceElement(this, bci); } @Override public RiResolvedMethod uniqueConcreteMethod() { return (RiResolvedMethod) compiler.getCompilerToVM().RiMethod_uniqueConcreteMethod(this); } @Override public RiSignature signature() { if (signature == null) { signature = new HotSpotSignature(compiler, compiler.getCompilerToVM().RiMethod_signature(this)); } return signature; } @Override public String toString() { return "HotSpotMethod<" + CiUtil.format("%h.%n", this) + ">"; } public boolean hasCompiledCode() { return compiler.getCompilerToVM().RiMethod_hasCompiledCode(this); } public int compiledCodeSize() { int result = compiler.getCompilerToVM().RiMethod_getCompiledCodeSize(this); if (result > 0) { assert result > MethodEntryCounters.getCodeSize(); result = result - MethodEntryCounters.getCodeSize(); } return result; } @Override public RiResolvedType accessor() { return null; } @Override public String intrinsic() { return null; } @Override public int invocationCount() { return compiler.getCompilerToVM().RiMethod_invocationCount(this); } @Override public int compilationComplexity() { if (compilationComplexity <= 0 && codeSize() > 0) { BytecodeStream s = new BytecodeStream(code()); int result = 0; int currentBC; while ((currentBC = s.currentBC()) != Bytecodes.END) { result += Bytecodes.compilationComplexity(currentBC); s.next(); } assert result > 0; compilationComplexity = result; } return compilationComplexity; } @Override public RiProfilingInfo profilingInfo() { if (GraalOptions.UseProfilingInformation && methodData == null) { methodData = compiler.getCompilerToVM().RiMethod_methodData(this); } if (methodData == null) { // Be optimistic and return false for exceptionSeen. A methodDataOop is allocated in case of a deoptimization. return BaseProfilingInfo.get(RiExceptionSeen.FALSE); } else { return new HotSpotProfilingInfo(compiler, methodData); } } @Override public Map<Object, Object> compilerStorage() { if (compilerStorage == null) { compilerStorage = new ConcurrentHashMap<>(); } return compilerStorage; } @Override public RiConstantPool getConstantPool() { return ((HotSpotTypeResolvedImpl) holder()).constantPool(); } @Override public void dumpProfile() { TTY.println("profile info for %s", this); TTY.println("canBeStaticallyBound: " + canBeStaticallyBound()); TTY.println("invocationCount: " + invocationCount()); RiProfilingInfo profilingInfo = this.profilingInfo(); for (int i = 0; i < codeSize(); i++) { if (profilingInfo.getExecutionCount(i) != -1) { TTY.println(" executionCount@%d: %d", i, profilingInfo.getExecutionCount(i)); } if (profilingInfo.getBranchTakenProbability(i) != -1) { TTY.println(" branchProbability@%d: %.3f", i, profilingInfo.getBranchTakenProbability(i)); } double[] switchProbabilities = profilingInfo.getSwitchProbabilities(i); if (switchProbabilities != null) { TTY.print(" switchProbabilities@%d:", i); for (int j = 0; j < switchProbabilities.length; j++) { TTY.print(" %.3f", switchProbabilities[j]); } TTY.println(); } if (profilingInfo.getExceptionSeen(i) != RiExceptionSeen.FALSE) { TTY.println(" exceptionSeen@%d: %s", i, profilingInfo.getExceptionSeen(i).name()); } RiTypeProfile typeProfile = profilingInfo.getTypeProfile(i); if (typeProfile != null) { ProfiledType[] ptypes = typeProfile.getTypes(); if (ptypes != null) { TTY.println(" types@%d:", i); for (int j = 0; j < ptypes.length; j++) { ProfiledType ptype = ptypes[j]; TTY.println(" %.3f %s", ptype.probability, ptype.type); } TTY.println(" %.3f <not recorded>", typeProfile.getNotRecordedProbability()); } } } boolean firstDeoptReason = true; for (RiDeoptReason reason: RiDeoptReason.values()) { int count = profilingInfo.getDeoptimizationCount(reason); if (count > 0) { if (firstDeoptReason) { TTY.println("Deopt History"); firstDeoptReason = false; } TTY.println(" %s: %d", reason.name(), count); } } } @Override public Annotation[][] getParameterAnnotations() { if (isConstructor()) { Constructor javaConstructor = toJavaConstructor(); return javaConstructor == null ? null : javaConstructor.getParameterAnnotations(); } Method javaMethod = toJava(); return javaMethod == null ? null : javaMethod.getParameterAnnotations(); } @Override public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { if (isConstructor()) { Constructor<?> javaConstructor = toJavaConstructor(); return javaConstructor == null ? null : javaConstructor.getAnnotation(annotationClass); } Method javaMethod = toJava(); return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass); } @Override public Type getGenericReturnType() { if (isConstructor()) { return void.class; } Method javaMethod = toJava(); return javaMethod == null ? null : javaMethod.getGenericReturnType(); } @Override public Type[] getGenericParameterTypes() { if (isConstructor()) { Constructor javaConstructor = toJavaConstructor(); return javaConstructor == null ? null : javaConstructor.getGenericParameterTypes(); } Method javaMethod = toJava(); return javaMethod == null ? null : javaMethod.getGenericParameterTypes(); } private Method toJava() { try { return holder.toJava().getDeclaredMethod(name, CiUtil.signatureToTypes(signature(), holder)); } catch (NoSuchMethodException e) { return null; } } private Constructor toJavaConstructor() { try { return holder.toJava().getDeclaredConstructor(CiUtil.signatureToTypes(signature(), holder)); } catch (NoSuchMethodException e) { return null; } } @Override public boolean canBeInlined() { return canBeInlined; } @Override public int vtableEntryOffset() { return compiler.getCompilerToVM().RiMethod_vtableEntryOffset(this); } @Override public void setCurrentTask(CompilationTask task) { currentTask = task; } @Override public CompilationTask currentTask() { return currentTask; } }