src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java
Index
Unified diffs
Context diffs
Sdiffs
Frames
Patch
New
Old
Previous File
Next File
open Cdiff src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java
src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2011, 2018, 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, 2019, 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.
*** 33,44 ****
import java.lang.annotation.Annotation;
import java.lang.reflect.Executable;
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.hotspot.HotSpotJVMCIRuntime.Option;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.ConstantPool;
--- 33,42 ----
*** 56,121 ****
import jdk.vm.ci.meta.TriState;
/**
* Implementation of {@link JavaMethod} for resolved HotSpot methods.
*/
! final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, MetaspaceWrapperObject {
/**
! * Reference to metaspace Method object.
*/
! private final long metaspaceMethod;
private final HotSpotResolvedObjectTypeImpl holder;
private final HotSpotConstantPool constantPool;
! private final HotSpotSignature signature;
private HotSpotMethodData methodData;
private byte[] code;
/**
! * Cache for {@link #toJava()}.
*/
! private volatile Executable toJavaCache;
/**
* Only 30% of {@link HotSpotResolvedJavaMethodImpl}s have their name accessed so compute it
* lazily and cache it.
*/
private String nameCache;
/**
* 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
! * {@link HotSpotJVMCIMetaAccessContext} keeps it alive after that.
! *
* Called from the VM.
*
! * @param metaspaceMethod a metaspace Method object
* @return the {@link ResolvedJavaMethod} corresponding to {@code metaspaceMethod}
*/
@SuppressWarnings("unused")
! private static HotSpotResolvedJavaMethod fromMetaspace(long metaspaceMethod) {
! HotSpotResolvedObjectTypeImpl holder = getHolder(metaspaceMethod);
! return holder.createMethod(metaspaceMethod);
}
! HotSpotResolvedJavaMethodImpl(HotSpotResolvedObjectTypeImpl holder, long metaspaceMethod) {
! this.metaspaceMethod = metaspaceMethod;
this.holder = holder;
HotSpotVMConfig config = config();
final long constMethod = getConstMethod();
--- 54,125 ----
import jdk.vm.ci.meta.TriState;
/**
* Implementation of {@link JavaMethod} for resolved HotSpot methods.
*/
! final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, MetaspaceHandleObject {
/**
! * Handle to the metaspace {@code Method} object. The handle is in
! * {@code JVMCI::_metadata_handles}.
*/
! private final long metadataHandle;
private final HotSpotResolvedObjectTypeImpl holder;
private final HotSpotConstantPool constantPool;
! final HotSpotSignature signature;
private HotSpotMethodData methodData;
private byte[] code;
/**
! * Cache for {@link HotSpotJDKReflection#getMethod}.
*/
! volatile Executable toJavaCache;
/**
* Only 30% of {@link HotSpotResolvedJavaMethodImpl}s have their name accessed so compute it
* lazily and cache it.
*/
private String nameCache;
/**
* Gets the holder of a HotSpot metaspace method native object.
*
! * @param metaspaceHandle a handle to a metaspace Method object
* @return the {@link ResolvedJavaType} corresponding to the holder of the
* {@code metaspaceMethod}
*/
! private static HotSpotResolvedObjectTypeImpl getHolder(long metaspaceHandle) {
HotSpotVMConfig config = config();
+ long metaspaceMethod = UNSAFE.getLong(metaspaceHandle);
+ assert metaspaceMethod != 0 : metaspaceHandle;
final long metaspaceConstMethod = UNSAFE.getAddress(metaspaceMethod + config.methodConstMethodOffset);
final long metaspaceConstantPool = UNSAFE.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset);
! HotSpotResolvedObjectTypeImpl result = compilerToVM().getResolvedJavaType(metaspaceConstantPool + config.constantPoolHolderOffset, false);
! assert result != null;
! return result;
}
/**
* 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 {@link HotSpotJVMCIRuntime} keeps
! * it alive after that.
! * <p>
* Called from the VM.
*
! * @param metaspaceHandle a handle to metaspace Method object
* @return the {@link ResolvedJavaMethod} corresponding to {@code metaspaceMethod}
*/
@SuppressWarnings("unused")
! @VMEntryPoint
! private static HotSpotResolvedJavaMethod fromMetaspace(long metaspaceHandle) {
! HotSpotResolvedObjectTypeImpl holder = getHolder(metaspaceHandle);
! return holder.createMethod(metaspaceHandle);
}
! HotSpotResolvedJavaMethodImpl(HotSpotResolvedObjectTypeImpl holder, long metaspaceHandle) {
! this.metadataHandle = metaspaceHandle;
this.holder = holder;
HotSpotVMConfig config = config();
final long constMethod = getConstMethod();
*** 131,140 ****
--- 135,145 ----
this.constantPool = compilerToVM().getConstantPool(this);
}
final int signatureIndex = UNSAFE.getChar(constMethod + config.constMethodSignatureIndexOffset);
this.signature = (HotSpotSignature) constantPool.lookupSignature(signatureIndex);
+ HandleCleaner.create(this, metaspaceHandle);
}
/**
* Returns a pointer to this method's constant method data structure (
* {@code Method::_constMethod}). This pointer isn't wrapped since it should be safe to use it
*** 142,153 ****
* are kept alive as a pair.
*
* @return pointer to this method's ConstMethod
*/
private long getConstMethod() {
! assert metaspaceMethod != 0;
! return UNSAFE.getAddress(metaspaceMethod + config().methodConstMethodOffset);
}
@Override
public String getName() {
if (nameCache == null) {
--- 147,157 ----
* are kept alive as a pair.
*
* @return pointer to this method's ConstMethod
*/
private long getConstMethod() {
! return UNSAFE.getAddress(getMetaspaceMethod() + config().methodConstMethodOffset);
}
@Override
public String getName() {
if (nameCache == null) {
*** 162,188 ****
if (this == obj) {
return true;
}
if (obj instanceof HotSpotResolvedJavaMethodImpl) {
HotSpotResolvedJavaMethodImpl that = (HotSpotResolvedJavaMethodImpl) obj;
! return that.metaspaceMethod == metaspaceMethod;
}
return false;
}
@Override
public int hashCode() {
! return (int) metaspaceMethod;
}
/**
* Returns this method's flags ({@code Method::_flags}).
*
* @return flags of this method
*/
private int getFlags() {
! return UNSAFE.getShort(metaspaceMethod + config().methodFlagsOffset);
}
/**
* Returns this method's constant method flags ({@code ConstMethod::_flags}).
*
--- 166,192 ----
if (this == obj) {
return true;
}
if (obj instanceof HotSpotResolvedJavaMethodImpl) {
HotSpotResolvedJavaMethodImpl that = (HotSpotResolvedJavaMethodImpl) obj;
! return that.getMetaspaceMethod() == getMetaspaceMethod();
}
return false;
}
@Override
public int hashCode() {
! return (int) getMetaspaceMethod();
}
/**
* Returns this method's flags ({@code Method::_flags}).
*
* @return flags of this method
*/
private int getFlags() {
! return UNSAFE.getShort(getMetaspaceMethod() + config().methodFlagsOffset);
}
/**
* Returns this method's constant method flags ({@code ConstMethod::_flags}).
*
*** 202,214 ****
*/
public Constant getMetaspaceMethodConstant() {
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false);
}
@Override
! public long getMetaspacePointer() {
! return metaspaceMethod;
}
@Override
public Constant getEncoding() {
return getMetaspaceMethodConstant();
--- 206,226 ----
*/
public Constant getMetaspaceMethodConstant() {
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false);
}
+ long getMetaspaceMethod() {
+ long metaspacePointer = getMetaspacePointer();
+ if (metaspacePointer == 0) {
+ throw new NullPointerException("Method* is null");
+ }
+ return metaspacePointer;
+ }
+
@Override
! public long getMetadataHandle() {
! return metadataHandle;
}
@Override
public Constant getEncoding() {
return getMetaspaceMethodConstant();
*** 217,227 ****
/**
* 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() & jvmMethodModifiers();
--- 229,239 ----
/**
* 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(getMetaspaceMethod() + config().methodAccessFlagsOffset);
}
@Override
public int getModifiers() {
return getAllModifiers() & jvmMethodModifiers();
*** 275,285 ****
catchType = constantPool.lookupType(catchTypeIndex, opcode);
// Check for Throwable which catches everything.
if (catchType instanceof HotSpotResolvedObjectTypeImpl) {
HotSpotResolvedObjectTypeImpl resolvedType = (HotSpotResolvedObjectTypeImpl) catchType;
! if (resolvedType.mirror() == Throwable.class) {
catchTypeIndex = 0;
catchType = null;
}
}
}
--- 287,297 ----
catchType = constantPool.lookupType(catchTypeIndex, opcode);
// Check for Throwable which catches everything.
if (catchType instanceof HotSpotResolvedObjectTypeImpl) {
HotSpotResolvedObjectTypeImpl resolvedType = (HotSpotResolvedObjectTypeImpl) catchType;
! if (resolvedType.equals(runtime().getJavaLangThrowable())) {
catchTypeIndex = 0;
catchType = null;
}
}
}
*** 422,432 ****
*
* @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.
*
--- 434,444 ----
*
* @return the value of {@code Method::_code}
*/
private long getCompiledCode() {
HotSpotVMConfig config = config();
! return UNSAFE.getAddress(getMetaspaceMethod() + config.methodCodeOffset);
}
/**
* Returns whether this method has compiled code.
*
*** 453,463 ****
@Override
public ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) {
ProfilingInfo info;
if (Option.UseProfilingInformation.getBoolean() && methodData == null) {
! long metaspaceMethodData = UNSAFE.getAddress(metaspaceMethod + config().methodDataOffset);
if (metaspaceMethodData != 0) {
methodData = new HotSpotMethodData(metaspaceMethodData, this);
String methodDataFilter = Option.TraceMethodDataFilter.getString();
if (methodDataFilter != null && this.format("%H.%n").contains(methodDataFilter)) {
System.out.println(methodData.toString());
--- 465,475 ----
@Override
public ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) {
ProfilingInfo info;
if (Option.UseProfilingInformation.getBoolean() && methodData == null) {
! long metaspaceMethodData = UNSAFE.getAddress(getMetaspaceMethod() + config().methodDataOffset);
if (metaspaceMethodData != 0) {
methodData = new HotSpotMethodData(metaspaceMethodData, this);
String methodDataFilter = Option.TraceMethodDataFilter.getString();
if (methodDataFilter != null && this.format("%H.%n").contains(methodDataFilter)) {
System.out.println(methodData.toString());
*** 488,537 ****
@Override
public Parameter[] getParameters() {
if (signature.getParameterCount(false) == 0) {
return new ResolvedJavaMethod.Parameter[0];
}
! java.lang.reflect.Parameter[] javaParameters = toJava().getParameters();
! Parameter[] res = new Parameter[javaParameters.length];
! for (int i = 0; i < res.length; i++) {
! java.lang.reflect.Parameter src = javaParameters[i];
! String paramName = src.isNamePresent() ? src.getName() : null;
! res[i] = new Parameter(paramName, src.getModifiers(), this, i);
! }
! return res;
}
@Override
public Annotation[][] getParameterAnnotations() {
if ((getConstMethodFlags() & config().constMethodHasParameterAnnotations) == 0) {
return new Annotation[signature.getParameterCount(false)][0];
}
! return toJava().getParameterAnnotations();
}
@Override
public Annotation[] getAnnotations() {
if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0) {
return new Annotation[0];
}
! return toJava().getAnnotations();
}
@Override
public Annotation[] getDeclaredAnnotations() {
if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0) {
return new Annotation[0];
}
! return toJava().getDeclaredAnnotations();
}
@Override
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0) {
return null;
}
! return toJava().getAnnotation(annotationClass);
}
@Override
public boolean isBridge() {
return (BRIDGE & getModifiers()) != 0;
--- 500,542 ----
@Override
public Parameter[] getParameters() {
if (signature.getParameterCount(false) == 0) {
return new ResolvedJavaMethod.Parameter[0];
}
! return runtime().reflection.getParameters(this);
}
@Override
public Annotation[][] getParameterAnnotations() {
if ((getConstMethodFlags() & config().constMethodHasParameterAnnotations) == 0) {
return new Annotation[signature.getParameterCount(false)][0];
}
! return runtime().reflection.getParameterAnnotations(this);
}
@Override
public Annotation[] getAnnotations() {
if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0) {
return new Annotation[0];
}
! return runtime().reflection.getMethodAnnotations(this);
}
@Override
public Annotation[] getDeclaredAnnotations() {
if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0) {
return new Annotation[0];
}
! return runtime().reflection.getMethodDeclaredAnnotations(this);
}
@Override
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0) {
return null;
}
! return runtime().reflection.getMethodAnnotation(this, annotationClass);
}
@Override
public boolean isBridge() {
return (BRIDGE & getModifiers()) != 0;
*** 557,579 ****
@Override
public Type[] getGenericParameterTypes() {
if (isClassInitializer()) {
return new Type[0];
}
! return toJava().getGenericParameterTypes();
! }
!
! private Executable toJava() {
! if (toJavaCache == null) {
! assert !isClassInitializer() : this;
! synchronized (this) {
! if (toJavaCache == null) {
! toJavaCache = compilerToVM().asReflectionExecutable(this);
! }
! }
! }
! return toJavaCache;
}
@Override
public boolean canBeInlined() {
if (hasNeverInlineDirective()) {
--- 562,572 ----
@Override
public Type[] getGenericParameterTypes() {
if (isClassInitializer()) {
return new Type[0];
}
! return runtime().reflection.getGenericParameterTypes(this);
}
@Override
public boolean canBeInlined() {
if (hasNeverInlineDirective()) {
*** 696,749 ****
* @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
- * never moves and b) we never read from it.
- * <p>
- * One implication is that we will preserve {@link SpeculationLog}s for methods that have been
- * redefined via class redefinition. It's tempting to periodically flush such logs but we cannot
- * read the JVM_ACC_IS_OBSOLETE bit (or anything else) via the raw pointer as obsoleted methods
- * are subject to clean up and deletion (see InstanceKlass::purge_previous_versions_internal).
- */
- private static final ClassValue<Map<Long, SpeculationLog>> SpeculationLogs = new ClassValue<>() {
- @Override
- protected Map<Long, SpeculationLog> computeValue(java.lang.Class<?> type) {
- return new HashMap<>(4);
- }
- };
-
@Override
public SpeculationLog getSpeculationLog() {
! Map<Long, SpeculationLog> map = SpeculationLogs.get(holder.mirror());
! synchronized (map) {
! SpeculationLog log = map.get(this.metaspaceMethod);
! if (log == null) {
! log = new HotSpotSpeculationLog();
! map.put(metaspaceMethod, log);
! }
! return log;
! }
}
@Override
public int intrinsicId() {
HotSpotVMConfig config = config();
! return UNSAFE.getChar(metaspaceMethod + config.methodIntrinsicIdOffset);
}
@Override
public boolean isIntrinsicCandidate() {
return (getFlags() & config().methodFlagsIntrinsicCandidate) != 0;
--- 689,718 ----
* @return virtual table index
*/
private int getVtableIndex() {
assert !holder.isInterface();
HotSpotVMConfig config = config();
! int result = UNSAFE.getInt(getMetaspaceMethod() + 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);
}
@Override
public SpeculationLog getSpeculationLog() {
! long address = compilerToVM().getFailedSpeculationsAddress(this);
! return new HotSpotSpeculationLog(address);
}
@Override
public int intrinsicId() {
HotSpotVMConfig config = config();
! return UNSAFE.getChar(getMetaspaceMethod() + config.methodIntrinsicIdOffset);
}
@Override
public boolean isIntrinsicCandidate() {
return (getFlags() & config().methodFlagsIntrinsicCandidate) != 0;
src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java
Index
Unified diffs
Context diffs
Sdiffs
Frames
Patch
New
Old
Previous File
Next File