< prev index next >
src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2011, 2014, 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.
--- 1,7 ----
/*
! * Copyright (c) 2011, 2015, 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.
*** 20,52 ****
* 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.HotSpotJVMCIRuntime.*;
! import static jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl.Options.*;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
! import java.lang.annotation.*;
! import java.lang.reflect.*;
! import java.util.*;
!
! import jdk.vm.ci.common.*;
! import jdk.vm.ci.meta.*;
! import jdk.vm.ci.options.*;
/**
* Implementation of {@link JavaMethod} for resolved HotSpot methods.
*/
! public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, MetaspaceWrapperObject {
!
! public static class Options {
! // @formatter:off
! @Option(help = "", type = OptionType.Debug)
! public static final OptionValue<Boolean> UseProfilingInformation = new OptionValue<>(true);
! // @formatter:on
! }
/**
* Reference to metaspace Method object.
*/
private final long metaspaceMethod;
--- 20,70 ----
* 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.CompilerToVM.compilerToVM;
! import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
! import static jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod.Options.UseProfilingInformation;
! import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
! import java.lang.annotation.Annotation;
! import java.lang.reflect.Executable;
! import java.lang.reflect.InvocationTargetException;
! import java.lang.reflect.Method;
! import java.lang.reflect.Modifier;
! import java.lang.reflect.Type;
! import java.util.HashMap;
! import java.util.Map;
!
! import jdk.vm.ci.common.JVMCIError;
! import jdk.vm.ci.meta.Constant;
! import jdk.vm.ci.meta.ConstantPool;
! import jdk.vm.ci.meta.DefaultProfilingInfo;
! import jdk.vm.ci.meta.ExceptionHandler;
! import jdk.vm.ci.meta.JavaConstant;
! import jdk.vm.ci.meta.JavaMethod;
! import jdk.vm.ci.meta.JavaType;
! import jdk.vm.ci.meta.LineNumberTable;
! import jdk.vm.ci.meta.LineNumberTableImpl;
! import jdk.vm.ci.meta.Local;
! import jdk.vm.ci.meta.LocalImpl;
! import jdk.vm.ci.meta.LocalVariableTable;
! import jdk.vm.ci.meta.LocalVariableTableImpl;
! import jdk.vm.ci.meta.ModifiersProvider;
! import jdk.vm.ci.meta.ProfilingInfo;
! import jdk.vm.ci.meta.ResolvedJavaMethod;
! import jdk.vm.ci.meta.ResolvedJavaType;
! import jdk.vm.ci.meta.Signature;
! import jdk.vm.ci.meta.SpeculationLog;
! import jdk.vm.ci.meta.TriState;
/**
* Implementation of {@link JavaMethod} for resolved HotSpot methods.
*/
! final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, MetaspaceWrapperObject {
/**
* Reference to metaspace Method object.
*/
private final long metaspaceMethod;
*** 54,77 ****
private final HotSpotResolvedObjectTypeImpl holder;
private final HotSpotConstantPool constantPool;
private final HotSpotSignature signature;
private HotSpotMethodData methodData;
private byte[] code;
! private Member toJavaCache;
/**
* Gets the holder of a HotSpot metaspace method native object.
*
* @param metaspaceMethod a metaspace Method object
* @return the {@link ResolvedJavaType} corresponding to the holder of the
* {@code metaspaceMethod}
*/
private static HotSpotResolvedObjectTypeImpl getHolder(long metaspaceMethod) {
! HotSpotVMConfig config = runtime().getConfig();
final long metaspaceConstMethod = UNSAFE.getAddress(metaspaceMethod + config.methodConstMethodOffset);
final long metaspaceConstantPool = UNSAFE.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset);
! return runtime().getCompilerToVM().getResolvedJavaType(null, metaspaceConstantPool + config.constantPoolHolderOffset, false);
}
/**
* Gets the JVMCI mirror from a HotSpot method. The VM is responsible for ensuring that the
* Method* is kept alive for the duration of this call and the
--- 72,95 ----
private final HotSpotResolvedObjectTypeImpl holder;
private final HotSpotConstantPool constantPool;
private final HotSpotSignature signature;
private HotSpotMethodData methodData;
private byte[] code;
! private Executable toJavaCache;
/**
* Gets the holder of a HotSpot metaspace method native object.
*
* @param metaspaceMethod a metaspace Method object
* @return the {@link ResolvedJavaType} corresponding to the holder of the
* {@code metaspaceMethod}
*/
private static HotSpotResolvedObjectTypeImpl getHolder(long metaspaceMethod) {
! HotSpotVMConfig config = config();
final long metaspaceConstMethod = UNSAFE.getAddress(metaspaceMethod + config.methodConstMethodOffset);
final long metaspaceConstantPool = UNSAFE.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset);
! return compilerToVM().getResolvedJavaType(null, metaspaceConstantPool + config.constantPoolHolderOffset, false);
}
/**
* Gets the JVMCI mirror from a HotSpot method. The VM is responsible for ensuring that the
* Method* is kept alive for the duration of this call and the
*** 92,102 ****
// It would be too much work to get the method name here so we fill it in later.
super(null);
this.metaspaceMethod = metaspaceMethod;
this.holder = holder;
! HotSpotVMConfig config = runtime().getConfig();
final long constMethod = getConstMethod();
/*
* Get the constant pool from the metaspace method. Some methods (e.g. intrinsics for
* signature-polymorphic method handle methods) have their own constant pool instead of the
--- 110,120 ----
// It would be too much work to get the method name here so we fill it in later.
super(null);
this.metaspaceMethod = metaspaceMethod;
this.holder = holder;
! HotSpotVMConfig config = config();
final long constMethod = getConstMethod();
/*
* Get the constant pool from the metaspace method. Some methods (e.g. intrinsics for
* signature-polymorphic method handle methods) have their own constant pool instead of the
*** 104,114 ****
*/
final long metaspaceConstantPool = UNSAFE.getAddress(constMethod + config.constMethodConstantsOffset);
if (metaspaceConstantPool == holder.getConstantPool().getMetaspaceConstantPool()) {
this.constantPool = holder.getConstantPool();
} else {
! this.constantPool = runtime().getCompilerToVM().getConstantPool(null, constMethod + config.constMethodConstantsOffset);
}
final int nameIndex = UNSAFE.getChar(constMethod + config.constMethodNameIndexOffset);
this.name = constantPool.lookupUtf8(nameIndex);
--- 122,132 ----
*/
final long metaspaceConstantPool = UNSAFE.getAddress(constMethod + config.constMethodConstantsOffset);
if (metaspaceConstantPool == holder.getConstantPool().getMetaspaceConstantPool()) {
this.constantPool = holder.getConstantPool();
} else {
! this.constantPool = compilerToVM().getConstantPool(null, constMethod + config.constMethodConstantsOffset);
}
final int nameIndex = UNSAFE.getChar(constMethod + config.constMethodNameIndexOffset);
this.name = constantPool.lookupUtf8(nameIndex);
*** 124,134 ****
*
* @return pointer to this method's ConstMethod
*/
private long getConstMethod() {
assert metaspaceMethod != 0;
! return UNSAFE.getAddress(metaspaceMethod + runtime().getConfig().methodConstMethodOffset);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
--- 142,152 ----
*
* @return pointer to this method's ConstMethod
*/
private long getConstMethod() {
assert metaspaceMethod != 0;
! return UNSAFE.getAddress(metaspaceMethod + config().methodConstMethodOffset);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
*** 150,202 ****
* Returns this method's flags ({@code Method::_flags}).
*
* @return flags of this method
*/
private int getFlags() {
! return UNSAFE.getByte(metaspaceMethod + runtime().getConfig().methodFlagsOffset);
}
/**
* Returns this method's constant method flags ({@code ConstMethod::_flags}).
*
* @return flags of this method's ConstMethod
*/
private int getConstMethodFlags() {
! return UNSAFE.getChar(getConstMethod() + runtime().getConfig().constMethodFlagsOffset);
}
@Override
public HotSpotResolvedObjectTypeImpl getDeclaringClass() {
return holder;
}
/**
* Gets the address of the C++ Method object for this method.
*/
! public JavaConstant getMetaspaceMethodConstant() {
! return HotSpotMetaspaceConstantImpl.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this, false);
! }
!
! public long getMetaspaceMethod() {
! return metaspaceMethod;
}
public long getMetaspacePointer() {
! return getMetaspaceMethod();
}
@Override
! public JavaConstant getEncoding() {
return getMetaspaceMethodConstant();
}
/**
* Gets the complete set of modifiers for this method which includes the JVM specification
* modifiers as well as the HotSpot internal modifiers.
*/
public int getAllModifiers() {
! return UNSAFE.getInt(metaspaceMethod + runtime().getConfig().methodAccessFlagsOffset);
}
@Override
public int getModifiers() {
return getAllModifiers() & ModifiersProvider.jvmMethodModifiers();
--- 168,216 ----
* Returns this method's flags ({@code Method::_flags}).
*
* @return flags of this method
*/
private int getFlags() {
! return UNSAFE.getByte(metaspaceMethod + config().methodFlagsOffset);
}
/**
* Returns this method's constant method flags ({@code ConstMethod::_flags}).
*
* @return flags of this method's ConstMethod
*/
private int getConstMethodFlags() {
! return UNSAFE.getChar(getConstMethod() + config().constMethodFlagsOffset);
}
@Override
public HotSpotResolvedObjectTypeImpl getDeclaringClass() {
return holder;
}
/**
* Gets the address of the C++ Method object for this method.
*/
! public Constant getMetaspaceMethodConstant() {
! return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false);
}
public long getMetaspacePointer() {
! return metaspaceMethod;
}
@Override
! public Constant getEncoding() {
return getMetaspaceMethodConstant();
}
/**
* Gets the complete set of modifiers for this method which includes the JVM specification
* modifiers as well as the HotSpot internal modifiers.
*/
public int getAllModifiers() {
! return UNSAFE.getInt(metaspaceMethod + config().methodAccessFlagsOffset);
}
@Override
public int getModifiers() {
return getAllModifiers() & ModifiersProvider.jvmMethodModifiers();
*** 211,242 ****
public byte[] getCode() {
if (getCodeSize() == 0) {
return null;
}
if (code == null && holder.isLinked()) {
! code = runtime().getCompilerToVM().getBytecode(this);
assert code.length == getCodeSize() : "expected: " + getCodeSize() + ", actual: " + code.length;
}
return code;
}
@Override
public int getCodeSize() {
! return UNSAFE.getChar(getConstMethod() + runtime().getConfig().constMethodCodeSizeOffset);
}
@Override
public ExceptionHandler[] getExceptionHandlers() {
! final boolean hasExceptionTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasExceptionTable) != 0;
if (!hasExceptionTable) {
return new ExceptionHandler[0];
}
! HotSpotVMConfig config = runtime().getConfig();
! final int exceptionTableLength = runtime().getCompilerToVM().getExceptionTableLength(this);
ExceptionHandler[] handlers = new ExceptionHandler[exceptionTableLength];
! long exceptionTableElement = runtime().getCompilerToVM().getExceptionTableStart(this);
for (int i = 0; i < exceptionTableLength; i++) {
final int startPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementStartPcOffset);
final int endPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementEndPcOffset);
final int handlerPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementHandlerPcOffset);
--- 225,256 ----
public byte[] getCode() {
if (getCodeSize() == 0) {
return null;
}
if (code == null && holder.isLinked()) {
! code = compilerToVM().getBytecode(this);
assert code.length == getCodeSize() : "expected: " + getCodeSize() + ", actual: " + code.length;
}
return code;
}
@Override
public int getCodeSize() {
! return UNSAFE.getChar(getConstMethod() + config().constMethodCodeSizeOffset);
}
@Override
public ExceptionHandler[] getExceptionHandlers() {
! final boolean hasExceptionTable = (getConstMethodFlags() & config().constMethodHasExceptionTable) != 0;
if (!hasExceptionTable) {
return new ExceptionHandler[0];
}
! HotSpotVMConfig config = config();
! final int exceptionTableLength = compilerToVM().getExceptionTableLength(this);
ExceptionHandler[] handlers = new ExceptionHandler[exceptionTableLength];
! long exceptionTableElement = compilerToVM().getExceptionTableStart(this);
for (int i = 0; i < exceptionTableLength; i++) {
final int startPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementStartPcOffset);
final int endPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementEndPcOffset);
final int handlerPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementHandlerPcOffset);
*** 271,316 ****
* Returns true if this method has a {@code CallerSensitive} annotation.
*
* @return true if CallerSensitive annotation present, false otherwise
*/
public boolean isCallerSensitive() {
! return (getFlags() & runtime().getConfig().methodFlagsCallerSensitive) != 0;
}
/**
* Returns true if this method has a {@code ForceInline} annotation.
*
* @return true if ForceInline annotation present, false otherwise
*/
public boolean isForceInline() {
! return (getFlags() & runtime().getConfig().methodFlagsForceInline) != 0;
}
/**
* Returns true if this method has a {@code DontInline} annotation.
*
* @return true if DontInline annotation present, false otherwise
*/
public boolean isDontInline() {
! return (getFlags() & runtime().getConfig().methodFlagsDontInline) != 0;
}
/**
* Manually adds a DontInline annotation to this method.
*/
public void setNotInlineable() {
! runtime().getCompilerToVM().doNotInlineOrCompile(this);
}
/**
* Returns true if this method is one of the special methods that is ignored by security stack
* walks.
*
* @return true if special method ignored by security stack walks, false otherwise
*/
public boolean ignoredBySecurityStackWalk() {
! return runtime().getCompilerToVM().methodIsIgnoredBySecurityStackWalk(this);
}
@Override
public boolean isClassInitializer() {
return "<clinit>".equals(name) && isStatic();
--- 285,330 ----
* Returns true if this method has a {@code CallerSensitive} annotation.
*
* @return true if CallerSensitive annotation present, false otherwise
*/
public boolean isCallerSensitive() {
! return (getFlags() & config().methodFlagsCallerSensitive) != 0;
}
/**
* Returns true if this method has a {@code ForceInline} annotation.
*
* @return true if ForceInline annotation present, false otherwise
*/
public boolean isForceInline() {
! return (getFlags() & config().methodFlagsForceInline) != 0;
}
/**
* Returns true if this method has a {@code DontInline} annotation.
*
* @return true if DontInline annotation present, false otherwise
*/
public boolean isDontInline() {
! return (getFlags() & config().methodFlagsDontInline) != 0;
}
/**
* Manually adds a DontInline annotation to this method.
*/
public void setNotInlineable() {
! compilerToVM().doNotInlineOrCompile(this);
}
/**
* Returns true if this method is one of the special methods that is ignored by security stack
* walks.
*
* @return true if special method ignored by security stack walks, false otherwise
*/
public boolean ignoredBySecurityStackWalk() {
! return compilerToVM().methodIsIgnoredBySecurityStackWalk(this);
}
@Override
public boolean isClassInitializer() {
return "<clinit>".equals(name) && isStatic();
*** 324,354 ****
@Override
public int getMaxLocals() {
if (isAbstract() || isNative()) {
return 0;
}
! HotSpotVMConfig config = runtime().getConfig();
return UNSAFE.getChar(getConstMethod() + config.methodMaxLocalsOffset);
}
@Override
public int getMaxStackSize() {
if (isAbstract() || isNative()) {
return 0;
}
! HotSpotVMConfig config = runtime().getConfig();
return config.extraStackEntries + UNSAFE.getChar(getConstMethod() + config.constMethodMaxStackOffset);
}
@Override
public StackTraceElement asStackTraceElement(int bci) {
if (bci < 0 || bci >= getCodeSize()) {
// HotSpot code can only construct stack trace elements for valid bcis
! StackTraceElement ste = runtime().getCompilerToVM().getStackTraceElement(this, 0);
return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1);
}
! return runtime().getCompilerToVM().getStackTraceElement(this, bci);
}
public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver) {
if (receiver.isInterface()) {
// Cannot trust interfaces. Because of:
--- 338,368 ----
@Override
public int getMaxLocals() {
if (isAbstract() || isNative()) {
return 0;
}
! HotSpotVMConfig config = config();
return UNSAFE.getChar(getConstMethod() + config.methodMaxLocalsOffset);
}
@Override
public int getMaxStackSize() {
if (isAbstract() || isNative()) {
return 0;
}
! HotSpotVMConfig config = config();
return config.extraStackEntries + UNSAFE.getChar(getConstMethod() + config.constMethodMaxStackOffset);
}
@Override
public StackTraceElement asStackTraceElement(int bci) {
if (bci < 0 || bci >= getCodeSize()) {
// HotSpot code can only construct stack trace elements for valid bcis
! StackTraceElement ste = compilerToVM().getStackTraceElement(this, 0);
return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1);
}
! return compilerToVM().getStackTraceElement(this, bci);
}
public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver) {
if (receiver.isInterface()) {
// Cannot trust interfaces. Because of:
*** 359,369 ****
// class D extends B { }
// Would lead to identify C.foo() as the unique concrete method for I.foo() without
// seeing A.foo().
return null;
}
! return runtime().getCompilerToVM().findUniqueConcreteMethod(((HotSpotResolvedObjectTypeImpl) receiver), this);
}
@Override
public HotSpotSignature getSignature() {
return signature;
--- 373,387 ----
// class D extends B { }
// Would lead to identify C.foo() as the unique concrete method for I.foo() without
// seeing A.foo().
return null;
}
! if (this.isDefault()) {
! // CHA for default methods doesn't work and may crash the VM
! return null;
! }
! return compilerToVM().findUniqueConcreteMethod(((HotSpotResolvedObjectTypeImpl) receiver), this);
}
@Override
public HotSpotSignature getSignature() {
return signature;
*** 373,383 ****
* Gets the value of {@code Method::_code}.
*
* @return the value of {@code Method::_code}
*/
private long getCompiledCode() {
! HotSpotVMConfig config = runtime().getConfig();
return UNSAFE.getAddress(metaspaceMethod + config.methodCodeOffset);
}
/**
* Returns whether this method has compiled code.
--- 391,401 ----
* Gets the value of {@code Method::_code}.
*
* @return the value of {@code Method::_code}
*/
private long getCompiledCode() {
! HotSpotVMConfig config = config();
return UNSAFE.getAddress(metaspaceMethod + config.methodCodeOffset);
}
/**
* Returns whether this method has compiled code.
*** 393,403 ****
* @return true if the currently installed code was generated at {@code level}.
*/
public boolean hasCompiledCodeAtLevel(int level) {
long compiledCode = getCompiledCode();
if (compiledCode != 0) {
! return UNSAFE.getInt(compiledCode + runtime().getConfig().nmethodCompLevelOffset) == level;
}
return false;
}
private static final String TraceMethodDataFilter = System.getProperty("jvmci.traceMethodDataFilter");
--- 411,421 ----
* @return true if the currently installed code was generated at {@code level}.
*/
public boolean hasCompiledCodeAtLevel(int level) {
long compiledCode = getCompiledCode();
if (compiledCode != 0) {
! return UNSAFE.getInt(compiledCode + config().nmethodCompLevelOffset) == level;
}
return false;
}
private static final String TraceMethodDataFilter = System.getProperty("jvmci.traceMethodDataFilter");
*** 405,415 ****
@Override
public ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) {
ProfilingInfo info;
if (UseProfilingInformation.getValue() && methodData == null) {
! long metaspaceMethodData = UNSAFE.getAddress(metaspaceMethod + runtime().getConfig().methodDataOffset);
if (metaspaceMethodData != 0) {
methodData = new HotSpotMethodData(metaspaceMethodData, this);
if (TraceMethodDataFilter != null && this.format("%H.%n").contains(TraceMethodDataFilter)) {
System.out.println("Raw method data for " + this.format("%H.%n(%p)") + ":");
System.out.println(methodData.toString());
--- 423,433 ----
@Override
public ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) {
ProfilingInfo info;
if (UseProfilingInformation.getValue() && methodData == null) {
! long metaspaceMethodData = UNSAFE.getAddress(metaspaceMethod + config().methodDataOffset);
if (metaspaceMethodData != 0) {
methodData = new HotSpotMethodData(metaspaceMethodData, this);
if (TraceMethodDataFilter != null && this.format("%H.%n").contains(TraceMethodDataFilter)) {
System.out.println("Raw method data for " + this.format("%H.%n(%p)") + ":");
System.out.println(methodData.toString());
*** 427,471 ****
return info;
}
@Override
public void reprofile() {
! runtime().getCompilerToVM().reprofile(this);
}
@Override
public ConstantPool getConstantPool() {
return constantPool;
}
@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 Annotation[] getAnnotations() {
! if (isConstructor()) {
! Constructor<?> javaConstructor = toJavaConstructor();
! return javaConstructor == null ? new Annotation[0] : javaConstructor.getAnnotations();
! }
! Method javaMethod = toJava();
return javaMethod == null ? new Annotation[0] : javaMethod.getAnnotations();
}
@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);
}
public boolean isDefault() {
if (isConstructor()) {
--- 445,477 ----
return info;
}
@Override
public void reprofile() {
! compilerToVM().reprofile(this);
}
@Override
public ConstantPool getConstantPool() {
return constantPool;
}
@Override
public Annotation[][] getParameterAnnotations() {
! Executable javaMethod = toJava();
return javaMethod == null ? null : javaMethod.getParameterAnnotations();
}
@Override
public Annotation[] getAnnotations() {
! Executable javaMethod = toJava();
return javaMethod == null ? new Annotation[0] : javaMethod.getAnnotations();
}
@Override
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
! Executable javaMethod = toJava();
return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass);
}
public boolean isDefault() {
if (isConstructor()) {
*** 476,490 ****
return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface();
}
@Override
public Type[] getGenericParameterTypes() {
! if (isConstructor()) {
! Constructor<?> javaConstructor = toJavaConstructor();
! return javaConstructor == null ? null : javaConstructor.getGenericParameterTypes();
! }
! Method javaMethod = toJava();
return javaMethod == null ? null : javaMethod.getGenericParameterTypes();
}
public Class<?>[] signatureToTypes() {
Signature sig = getSignature();
--- 482,492 ----
return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface();
}
@Override
public Type[] getGenericParameterTypes() {
! Executable javaMethod = toJava();
return javaMethod == null ? null : javaMethod.getGenericParameterTypes();
}
public Class<?>[] signatureToTypes() {
Signature sig = getSignature();
*** 496,524 ****
result[i] = resolvedParameterType.mirror();
}
return result;
}
! private Method toJava() {
! if (toJavaCache != null) {
! return (Method) toJavaCache;
! }
! try {
! Method result = holder.mirror().getDeclaredMethod(name, signatureToTypes());
! toJavaCache = result;
! return result;
! } catch (NoSuchMethodException | NoClassDefFoundError e) {
! return null;
! }
! }
!
! private Constructor<?> toJavaConstructor() {
if (toJavaCache != null) {
! return (Constructor<?>) toJavaCache;
}
try {
! Constructor<?> result = holder.mirror().getDeclaredConstructor(signatureToTypes());
toJavaCache = result;
return result;
} catch (NoSuchMethodException | NoClassDefFoundError e) {
return null;
}
--- 498,514 ----
result[i] = resolvedParameterType.mirror();
}
return result;
}
! private Executable toJava() {
if (toJavaCache != null) {
! return toJavaCache;
}
try {
! Class<?>[] parameterTypes = signatureToTypes();
! Executable result = isConstructor() ? holder.mirror().getDeclaredConstructor(parameterTypes) : holder.mirror().getDeclaredMethod(name, parameterTypes);
toJavaCache = result;
return result;
} catch (NoSuchMethodException | NoClassDefFoundError e) {
return null;
}
*** 527,555 ****
@Override
public boolean canBeInlined() {
if (isDontInline()) {
return false;
}
! return runtime().getCompilerToVM().canInlineMethod(this);
}
@Override
public boolean shouldBeInlined() {
if (isForceInline()) {
return true;
}
! return runtime().getCompilerToVM().shouldInlineMethod(this);
}
@Override
public LineNumberTable getLineNumberTable() {
! final boolean hasLineNumberTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasLineNumberTable) != 0;
if (!hasLineNumberTable) {
return null;
}
! long[] values = runtime().getCompilerToVM().getLineNumberTable(this);
if (values == null || values.length == 0) {
// Empty table so treat is as non-existent
return null;
}
assert values.length % 2 == 0;
--- 517,545 ----
@Override
public boolean canBeInlined() {
if (isDontInline()) {
return false;
}
! return compilerToVM().canInlineMethod(this);
}
@Override
public boolean shouldBeInlined() {
if (isForceInline()) {
return true;
}
! return compilerToVM().shouldInlineMethod(this);
}
@Override
public LineNumberTable getLineNumberTable() {
! final boolean hasLineNumberTable = (getConstMethodFlags() & config().constMethodHasLineNumberTable) != 0;
if (!hasLineNumberTable) {
return null;
}
! long[] values = compilerToVM().getLineNumberTable(this);
if (values == null || values.length == 0) {
// Empty table so treat is as non-existent
return null;
}
assert values.length % 2 == 0;
*** 564,581 ****
return new LineNumberTableImpl(line, bci);
}
@Override
public LocalVariableTable getLocalVariableTable() {
! final boolean hasLocalVariableTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasLocalVariableTable) != 0;
if (!hasLocalVariableTable) {
return null;
}
! HotSpotVMConfig config = runtime().getConfig();
! long localVariableTableElement = runtime().getCompilerToVM().getLocalVariableTableStart(this);
! final int localVariableTableLength = runtime().getCompilerToVM().getLocalVariableTableLength(this);
Local[] locals = new Local[localVariableTableLength];
for (int i = 0; i < localVariableTableLength; i++) {
final int startBci = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementStartBciOffset);
final int endBci = startBci + UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementLengthOffset);
--- 554,571 ----
return new LineNumberTableImpl(line, bci);
}
@Override
public LocalVariableTable getLocalVariableTable() {
! final boolean hasLocalVariableTable = (getConstMethodFlags() & config().constMethodHasLocalVariableTable) != 0;
if (!hasLocalVariableTable) {
return null;
}
! HotSpotVMConfig config = config();
! long localVariableTableElement = compilerToVM().getLocalVariableTableStart(this);
! final int localVariableTableLength = compilerToVM().getLocalVariableTableLength(this);
Local[] locals = new Local[localVariableTableLength];
for (int i = 0; i < localVariableTableLength; i++) {
final int startBci = UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementStartBciOffset);
final int endBci = startBci + UNSAFE.getChar(localVariableTableElement + config.localVariableTableElementLengthOffset);
*** 604,614 ****
*/
public int vtableEntryOffset(ResolvedJavaType resolved) {
if (!isInVirtualMethodTable(resolved)) {
throw new JVMCIError("%s does not have a vtable entry in type %s", this, resolved);
}
! HotSpotVMConfig config = runtime().getConfig();
final int vtableIndex = getVtableIndex((HotSpotResolvedObjectTypeImpl) resolved);
return config.instanceKlassVtableStartOffset() + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset;
}
@Override
--- 594,604 ----
*/
public int vtableEntryOffset(ResolvedJavaType resolved) {
if (!isInVirtualMethodTable(resolved)) {
throw new JVMCIError("%s does not have a vtable entry in type %s", this, resolved);
}
! HotSpotVMConfig config = config();
final int vtableIndex = getVtableIndex((HotSpotResolvedObjectTypeImpl) resolved);
return config.instanceKlassVtableStartOffset() + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset;
}
@Override
*** 621,635 ****
return false;
}
private int getVtableIndex(HotSpotResolvedObjectTypeImpl resolved) {
if (!holder.isLinked()) {
! return runtime().getConfig().invalidVtableIndex;
}
if (holder.isInterface()) {
if (resolved.isInterface()) {
! return runtime().getConfig().invalidVtableIndex;
}
return getVtableIndexForInterfaceMethod(resolved);
}
return getVtableIndex();
}
--- 611,625 ----
return false;
}
private int getVtableIndex(HotSpotResolvedObjectTypeImpl resolved) {
if (!holder.isLinked()) {
! return config().invalidVtableIndex;
}
if (holder.isInterface()) {
if (resolved.isInterface()) {
! return config().invalidVtableIndex;
}
return getVtableIndexForInterfaceMethod(resolved);
}
return getVtableIndex();
}
*** 638,657 ****
* Returns this method's virtual table index.
*
* @return virtual table index
*/
private int getVtableIndex() {
! assert!holder.isInterface();
! HotSpotVMConfig config = runtime().getConfig();
int result = UNSAFE.getInt(metaspaceMethod + config.methodVtableIndexOffset);
assert result >= config.nonvirtualVtableIndex : "must be linked";
return result;
}
private int getVtableIndexForInterfaceMethod(ResolvedJavaType resolved) {
HotSpotResolvedObjectTypeImpl hotspotType = (HotSpotResolvedObjectTypeImpl) resolved;
! return runtime().getCompilerToVM().getVtableIndexForInterfaceMethod(hotspotType, this);
}
/**
* The {@link SpeculationLog} for methods compiled by JVMCI hang off this per-declaring-type
* {@link ClassValue}. The raw Method* value is safe to use as a key in the map as a) it is
--- 628,647 ----
* Returns this method's virtual table index.
*
* @return virtual table index
*/
private int getVtableIndex() {
! assert !holder.isInterface();
! HotSpotVMConfig config = config();
int result = UNSAFE.getInt(metaspaceMethod + config.methodVtableIndexOffset);
assert result >= config.nonvirtualVtableIndex : "must be linked";
return result;
}
private int getVtableIndexForInterfaceMethod(ResolvedJavaType resolved) {
HotSpotResolvedObjectTypeImpl hotspotType = (HotSpotResolvedObjectTypeImpl) resolved;
! return compilerToVM().getVtableIndexForInterfaceMethod(hotspotType, this);
}
/**
* The {@link SpeculationLog} for methods compiled by JVMCI hang off this per-declaring-type
* {@link ClassValue}. The raw Method* value is safe to use as a key in the map as a) it is
*** 680,697 ****
return log;
}
}
public int intrinsicId() {
! HotSpotVMConfig config = runtime().getConfig();
return UNSAFE.getChar(metaspaceMethod + config.methodIntrinsicIdOffset);
}
@Override
public JavaConstant invoke(JavaConstant receiver, JavaConstant[] arguments) {
! assert!isConstructor();
! Method javaMethod = toJava();
javaMethod.setAccessible(true);
Object[] objArguments = new Object[arguments.length];
for (int i = 0; i < arguments.length; i++) {
objArguments[i] = HotSpotObjectConstantImpl.asBoxedValue(arguments[i]);
--- 670,687 ----
return log;
}
}
public int intrinsicId() {
! HotSpotVMConfig config = config();
return UNSAFE.getChar(metaspaceMethod + config.methodIntrinsicIdOffset);
}
@Override
public JavaConstant invoke(JavaConstant receiver, JavaConstant[] arguments) {
! assert !isConstructor();
! Method javaMethod = (Method) toJava();
javaMethod.setAccessible(true);
Object[] objArguments = new Object[arguments.length];
for (int i = 0; i < arguments.length; i++) {
objArguments[i] = HotSpotObjectConstantImpl.asBoxedValue(arguments[i]);
*** 712,726 ****
*
* @param entryBCI entry bci
* @return compile id
*/
public int allocateCompileId(int entryBCI) {
! return runtime().getCompilerToVM().allocateCompileId(this, entryBCI);
}
public boolean hasCodeAtLevel(int entryBCI, int level) {
! if (entryBCI == runtime().getConfig().invocationEntryBci) {
return hasCompiledCodeAtLevel(level);
}
! return runtime().getCompilerToVM().hasCompiledCodeForOSR(this, entryBCI, level);
}
}
--- 702,716 ----
*
* @param entryBCI entry bci
* @return compile id
*/
public int allocateCompileId(int entryBCI) {
! return compilerToVM().allocateCompileId(this, entryBCI);
}
public boolean hasCodeAtLevel(int entryBCI, int level) {
! if (entryBCI == config().invocationEntryBci) {
return hasCompiledCodeAtLevel(level);
}
! return compilerToVM().hasCompiledCodeForOSR(this, entryBCI, level);
}
}
< prev index next >