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