< 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 >