diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodeFrame.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodeFrame.java index c4d090a74c4b0..8c698b4ee3dc4 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodeFrame.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodeFrame.java @@ -387,4 +387,11 @@ public boolean equals(Object obj) { public String toString() { return CodeUtil.append(new StringBuilder(100), this).toString(); } + + /** + * Returns a copy of the array describing the Java kinds in {@link #values}. + */ + public JavaKind[] getSlotKinds() { + return (slotKinds == null) ? null : slotKinds.clone(); + } } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/VirtualObject.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/VirtualObject.java index d26b135a40556..1033fa559f82b 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/VirtualObject.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/VirtualObject.java @@ -289,17 +289,18 @@ public boolean equals(Object o) { if (o == this) { return true; } - if (o instanceof VirtualObject) { - VirtualObject l = (VirtualObject) o; - if (!l.type.equals(type) || l.values.length != values.length) { + if (o instanceof VirtualObject that) { + int thatValuesLength = (that.values == null) ? 0 : that.values.length; + int valuesLength = (values == null) ? 0 : values.length; + if (!that.type.equals(type) || thatValuesLength != valuesLength) { return false; } - for (int i = 0; i < values.length; i++) { + for (int i = 0; i < valuesLength; i++) { /* * Virtual objects can form cycles. Calling equals() could therefore lead to * infinite recursion. */ - if (!same(values[i], l.values[i])) { + if (!same(values[i], that.values[i])) { return false; } } @@ -311,4 +312,11 @@ public boolean equals(Object o) { private static boolean same(Object o1, Object o2) { return o1 == o2; } + + /** + * Returns a copy of the array containing the Java kinds of the values stored in this virtual object. + */ + public JavaKind[] getSlotKinds() { + return (slotKinds == null) ? null : slotKinds.clone(); + } } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Site.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Site.java index dbf76c58be05b..7d1239fea0e95 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Site.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/site/Site.java @@ -39,8 +39,8 @@ public Site(int pos) { } @Override - public final int hashCode() { - throw new UnsupportedOperationException("hashCode"); + public int hashCode() { + return 41 * pcOffset; } @Override diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledCode.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledCode.java index 6004db48423d2..6d1f16d5bd236 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledCode.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledCode.java @@ -188,4 +188,88 @@ public int getOffset(ResolvedJavaField field) { } }); } + + /** + * Returns a copy of the compiled machine code. + */ + public byte[] getTargetCode() { + return (targetCode == null) ? null : targetCode.clone(); + } + + /** + * Gets the size of the compiled machine code in bytes. + */ + public int getTargetCodeSize() { + return targetCodeSize; + } + + /** + * Returns a copy of the code annotations describing special sites in {@link #targetCode}. + */ + public Site[] getSites() { + return (sites == null) ? null : sites.clone(); + } + + /** + * Returns an array copy of the assumptions this code relies on. + */ + public Assumption[] getAssumptions() { + return (assumptions == null) ? null : assumptions.clone(); + } + + /** + * Returns an array copy of the methods whose bytecodes were used as input to the compilation. + */ + public ResolvedJavaMethod[] getMethods() { + return (methods == null) ? null : methods.clone(); + } + + /** + * Returns an array copy of the comments that are included in code dumps. + */ + public Comment[] getComments() { + return (comments == null) ? null : comments.clone(); + } + + /** + * Returns a copy of the data section containing serialized constants for the emitted machine code. + */ + public byte[] getDataSection() { + return (dataSection == null) ? null : dataSection.clone(); + } + + /** + * Gets the minimum alignment of the data section. + */ + public int getDataSectionAlignment() { + return dataSectionAlignment; + } + + /** + * Returns a copy of the {@link #dataSection} relocations. + */ + public DataPatch[] getDataSectionPatches() { + return (dataSectionPatches == null) ? null : dataSectionPatches.clone(); + } + + /** + * Checks if this compiled code is immutable and position independent. + */ + public boolean isImmutablePIC() { + return isImmutablePIC; + } + + /** + * Gets the total size of the stack frame of this compiled method. + */ + public int getTotalFrameSize() { + return totalFrameSize; + } + + /** + * Gets the deoptimization rescue slot associated with this compiled code. + */ + public StackSlot getDeoptRescueSlot() { + return deoptRescueSlot; + } } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java index b1be3dee25cd8..e0e93b0f8bce0 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java @@ -118,4 +118,44 @@ public boolean hasScopedAccess() { return false; } + /** + * Returns the method to which this compiled nmethod belongs. + */ + public HotSpotResolvedJavaMethod getMethod() { + return method; + } + + /** + * Returns the bytecode index (BCI) in the {@link #getMethod() method} that is the beginning of this compiled + * nmethod. -1 denotes the beginning of the method. + * + * @return the entry BCI of this nmethod or -1 if the entry is the method's beginning + */ + public int getEntryBCI() { + return entryBCI; + } + + /** + * Returns the identifier of the compilation request. + */ + public int getId() { + return id; + } + + /** + * Returns the address of a native {@code JVMCICompileState} object associated with this compiled nmethod. + * If no such object exists, it returns 0L. + * + * @return the address of the native {@code JVMCICompileState} object or 0L if it does not exist + */ + public long getCompileState() { + return compileState; + } + + /** + * Checks if this compiled nmethod has a memory access via the {@code Unsafe} class. + */ + public boolean hasUnsafeAccess() { + return hasUnsafeAccess; + } } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJavaType.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJavaType.java index ef8253596d8af..792c7bc00a276 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJavaType.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJavaType.java @@ -36,7 +36,7 @@ public HotSpotJavaType(String name) { } @Override - public final String getName() { + public String getName() { return name; } } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstant.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstant.java index 227fcb731a9f4..bed38f9198845 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstant.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstant.java @@ -22,14 +22,15 @@ */ package jdk.vm.ci.hotspot; -import java.lang.invoke.CallSite; -import java.util.Objects; - import jdk.vm.ci.meta.Assumptions; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.VMConstant; +import java.lang.invoke.CallSite; +import java.lang.invoke.ConstantCallSite; +import java.util.Objects; + /** * Represents a constant non-{@code null} object reference, within the compiler and across the * compiler/runtime interface. @@ -61,7 +62,26 @@ public interface HotSpotObjectConstant extends JavaConstant, HotSpotConstant, VM * change * @return {@code null} if this constant does not represent a {@link CallSite} object */ - JavaConstant getCallSiteTarget(Assumptions assumptions); + default JavaConstant getCallSiteTarget(Assumptions assumptions) { + Assumptions.AssumptionResult result = getCallSiteTarget(); + if (!result.canRecordTo(assumptions)) { + return null; + } + result.recordTo(assumptions); + return result.getResult(); + } + + /** + * Gets the result of {@link CallSite#getTarget()} for the {@link CallSite} object represented + * by this constant. The target is bound to an assumption if this is not a fully initialized + * {@link ConstantCallSite}. + * + * @return a call-site target (possibly bound to an assumption) or {@code null} if this constant + * does not represent a {@link CallSite} object + */ + default Assumptions.AssumptionResult getCallSiteTarget() { + throw new UnsupportedOperationException("getCallSiteTarget"); + } /** * Determines if this constant represents an {@linkplain String#intern() interned} string. diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java index cf3ac0f994a00..1dcc969b3e6a4 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java @@ -89,19 +89,15 @@ private HotSpotObjectConstantImpl readTarget() { } @Override - public JavaConstant getCallSiteTarget(Assumptions assumptions) { + public Assumptions.AssumptionResult getCallSiteTarget() { if (runtime().getCallSite().isInstance(this)) { // For ConstantCallSites, we need to read "isFrozen" before reading "target" // isFullyInitializedConstantCallSite() reads "isFrozen" if (isFullyInitializedConstantCallSite()) { - return readTarget(); - } - if (assumptions == null) { - return null; + return new Assumptions.AssumptionResult<>(readTarget()); } HotSpotObjectConstantImpl result = readTarget(); - assumptions.record(new Assumptions.CallSiteTargetValue(this, result)); - return result; + return new Assumptions.AssumptionResult<>(result, new Assumptions.CallSiteTargetValue(this, result)); } return null; } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java index 566a660d53117..ab634568a84f0 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java @@ -30,9 +30,9 @@ public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements ResolvedJavaType { - HotSpotResolvedObjectTypeImpl arrayOfType; + HotSpotResolvedObjectType arrayOfType; - HotSpotResolvedJavaType(String name) { + protected HotSpotResolvedJavaType(String name) { super(name); } @@ -40,16 +40,22 @@ public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements public abstract boolean equals(Object obj); @Override - public final int hashCode() { + public int hashCode() { return getName().hashCode(); } - abstract JavaConstant getJavaMirror(); + /** + * Gets the runtime representation of the {@link Class} object of this type. + */ + public abstract JavaConstant getJavaMirror(); - abstract HotSpotResolvedObjectTypeImpl getArrayType(); + /** + * Gets the array type of this type without caching the result. + */ + protected abstract HotSpotResolvedObjectType getArrayType(); @Override - public final HotSpotResolvedObjectType getArrayClass() { + public HotSpotResolvedObjectType getArrayClass() { if (arrayOfType == null) { arrayOfType = getArrayType(); } @@ -63,7 +69,7 @@ public final HotSpotResolvedObjectType getArrayClass() { * * @return {@code true} if this type is being initialized */ - abstract boolean isBeingInitialized(); + protected abstract boolean isBeingInitialized(); static void checkIsAnnotation(ResolvedJavaType type) { if (!type.isAnnotation()) { diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java index 0417a761fc47a..1fc5f1bfd6a0e 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java @@ -80,6 +80,13 @@ default JavaKind getJavaKind() { @Override AssumptionResult findUniqueConcreteMethod(ResolvedJavaMethod method); + /** + * Gets the runtime representation of the {@link Class} object of this type. + */ + default JavaConstant getJavaMirror() { + throw new UnsupportedOperationException("getJavaMirror"); + } + /** * Performs a fast-path check that this type is resolved in the context of a given accessing * class. A negative result does not mean this type is not resolved with respect to diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java index 63ab5aea0fe7e..46e53411deef7 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java @@ -672,12 +672,12 @@ public boolean equals(Object obj) { } @Override - JavaConstant getJavaMirror() { + public JavaConstant getJavaMirror() { return mirror; } @Override - HotSpotResolvedObjectTypeImpl getArrayType() { + protected HotSpotResolvedObjectTypeImpl getArrayType() { return runtime().compilerToVm.getArrayType((char) 0, this); } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java index d77ab1f08a1f8..e83c5c54532d6 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java @@ -61,7 +61,13 @@ private HotSpotResolvedPrimitiveType(JavaKind kind, HotSpotObjectConstantImpl mi this.kind = kind; } - static HotSpotResolvedPrimitiveType forKind(JavaKind kind) { + /** + * Returns a primitive type instance corresponding to the given {@link JavaKind}. + * + * @param kind the Java kind of the primitive type + * @return the primitive type instance for the given Java kind + */ + public static HotSpotResolvedPrimitiveType forKind(JavaKind kind) { HotSpotResolvedPrimitiveType primitive = primitives[kind.getBasicType()]; assert primitive != null : kind; return primitive; @@ -84,7 +90,7 @@ public int getModifiers() { } @Override - HotSpotResolvedObjectTypeImpl getArrayType() { + protected HotSpotResolvedObjectType getArrayType() { if (kind == JavaKind.Void) { return null; } @@ -321,7 +327,7 @@ public boolean equals(Object obj) { } @Override - JavaConstant getJavaMirror() { + public JavaConstant getJavaMirror() { return mirror; } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java index e3d812c2e83d6..4849750337c4c 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java @@ -28,6 +28,7 @@ import java.util.Arrays; import java.util.Formatter; import java.util.List; +import java.util.Objects; import jdk.vm.ci.code.BailoutException; import jdk.vm.ci.common.JVMCIError; @@ -130,7 +131,7 @@ public static final class HotSpotSpeculation extends Speculation { private final byte[] encoding; - HotSpotSpeculation(SpeculationReason reason, JavaConstant id, byte[] encoding) { + public HotSpotSpeculation(SpeculationReason reason, JavaConstant id, byte[] encoding) { super(reason); this.id = id; this.encoding = encoding; @@ -140,6 +141,13 @@ public JavaConstant getEncoding() { return id; } + /** + * Returns a copy of the speculation reason encoding. + */ + public byte[] getReasonEncoding() { + return (encoding == null) ? null : encoding.clone(); + } + @Override public String toString() { long indexAndLength = id.asLong(); @@ -147,6 +155,20 @@ public String toString() { int length = decodeLength(indexAndLength); return String.format("{0x%016x[index: %d, len: %d, hash: 0x%x]: %s}", indexAndLength, index, length, Arrays.hashCode(encoding), getReason()); } + + @Override + public boolean equals(Object object) { + if (object instanceof HotSpotSpeculation that) { + return getReason().equals(that.getReason()) && id.equals(that.id) && Arrays.equals(encoding, that.encoding); + } else { + return false; + } + } + + @Override + public int hashCode() { + return Objects.hash(getReason(), id, Arrays.hashCode(encoding)); + } } /** diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java index 9954c700ca7b3..15bd58a5a5d25 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java @@ -305,7 +305,7 @@ private T getFieldValue0(String name, Class type, T notPresent, String in * @return the field * @throws JVMCIError if the field is not present and {@code required == true} */ - private VMField getField(String name, String cppType, boolean required) { + public VMField getField(String name, String cppType, boolean required) { VMField entry = store.vmFields.get(name); if (entry == null) { if (!required) { diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMField.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMField.java index 3a294f5d9feef..21755445ca0ee 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMField.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMField.java @@ -66,7 +66,7 @@ public boolean isStatic() { * Creates a description of a non-static field. */ @VMEntryPoint - VMField(String name, String type, long offset, long address, Object value) { + public VMField(String name, String type, long offset, long address, Object value) { this.name = name; this.type = type; this.offset = offset; diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/EncodedSpeculationReason.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/EncodedSpeculationReason.java index 4df14bc672bb7..2e72896b31def 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/EncodedSpeculationReason.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/EncodedSpeculationReason.java @@ -113,4 +113,25 @@ public int hashCode() { public String toString() { return String.format("%s@%d%s", groupName, groupId, Arrays.toString(context)); } + + /** + * Returns the group ID of this speculation reason. + */ + public int getGroupId() { + return groupId; + } + + /** + * Returns the group name of this speculation reason. + */ + public String getGroupName() { + return groupName; + } + + /** + * Returns a copy of the array of context objects. + */ + public Object[] getContext() { + return (context == null) ? null : context.clone(); + } }