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..093ec00400b69 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,14 @@ 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}. + * The returned array represents the kinds for the locals and the operand stack. + * + * @return a copy of the slot kinds array + */ + public JavaKind[] getSlotKinds() { + return (slotKinds == null) ? null : Arrays.copyOf(slotKinds, slotKinds.length); + } } 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..776e5382ff485 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 @@ -22,6 +22,7 @@ */ package jdk.vm.ci.code; +import java.util.Arrays; import java.util.Collections; import java.util.IdentityHashMap; import java.util.Set; @@ -291,10 +292,12 @@ public boolean equals(Object o) { } if (o instanceof VirtualObject) { VirtualObject l = (VirtualObject) o; - if (!l.type.equals(type) || l.values.length != values.length) { + int lValuesLength = (l.values == null) ? 0 : l.values.length; + int valuesLength = (values == null) ? 0 : values.length; + if (!l.type.equals(type) || lValuesLength != 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. @@ -311,4 +314,15 @@ 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. + * + * @return a copy of the array containing the Java kinds of the values or {@code null} if the + * values have not been initialized. + */ + public JavaKind[] getSlotKinds() { + return (slotKinds == null) ? null : Arrays.copyOf(slotKinds, slotKinds.length); + } } 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..50d5a69f65850 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 @@ -33,6 +33,8 @@ import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; +import java.util.Arrays; + /** * A {@link CompiledCode} with additional HotSpot-specific information required for installing the * code in HotSpot's code cache. @@ -188,4 +190,97 @@ public int getOffset(ResolvedJavaField field) { } }); } + + /** + * Returns a copy of the compiled machine code. + */ + public byte[] getTargetCode() { + return (targetCode == null) ? null : Arrays.copyOf(targetCode, targetCode.length); + } + + /** + * Gets the size of the compiled machine code in bytes. + */ + public int getTargetCodeSize() { + return targetCodeSize; + } + + /** + * Returns a copy of the array of {@link Site} objects associated with this compiled code. + */ + public Site[] getSites() { + return (sites == null) ? null : Arrays.copyOf(sites, sites.length); + } + + /** + * Returns a copy of the array of {@link Assumption} objects associated with this compiled code. + */ + public Assumption[] getAssumptions() { + return (assumptions == null) ? null : Arrays.copyOf(assumptions, assumptions.length); + } + + /** + * Returns a copy of the array of {@link ResolvedJavaMethod} objects representing the methods + * whose bytecodes were used as input to the compilation. If the compilation did not record + * method dependencies, this method returns {@code null}. Otherwise, the first element of the + * returned array is the root method of the compilation. + * + * @return a copy of the array of methods associated with this compiled code or {@code null} + * if no methods were recorded + */ + public ResolvedJavaMethod[] getMethods() { + return (methods == null) ? null : Arrays.copyOf(methods, methods.length); + } + + /** + * Returns a copy of the array of {@link Comment} objects associated with this compiled code. + */ + public Comment[] getComments() { + return Arrays.copyOf(comments, comments.length); + } + + /** + * Returns a copy of the data section containing serialized constants for the emitted machine code. + */ + public byte[] getDataSection() { + return (dataSection == null) ? null : Arrays.copyOf(dataSection, dataSection.length); + } + + /** + * Gets the minimum alignment of the data section. + */ + public int getDataSectionAlignment() { + return dataSectionAlignment; + } + + /** + * Returns a copy of the array of {@link DataPatch} objects representing the relocations in the + * {@linkplain #getDataSection() data section}. + * + * @return a copy of the array of data section patches or {@code null} if there are no patches + */ + public DataPatch[] getDataSectionPatches() { + return (dataSectionPatches == null) ? null : Arrays.copyOf(dataSectionPatches, dataSectionPatches.length); + } + + /** + * 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..3090c0b951b0a 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,42 @@ 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. + */ + 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/HotSpotMethod.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethod.java index c2145b298b622..98006237a5c71 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethod.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethod.java @@ -32,7 +32,7 @@ import jdk.vm.ci.meta.JavaMethod; import jdk.vm.ci.meta.ResolvedJavaMethod; -abstract class HotSpotMethod implements JavaMethod, Formattable { +public abstract class HotSpotMethod implements JavaMethod, Formattable { public static String applyFormattingFlagsAndWidth(String s, int flags, int width) { if (flags == 0 && width < 0) { 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 fbb5a3fc9b5c4..4d4e73761378e 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 @@ -27,9 +27,9 @@ public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements ResolvedJavaType { - HotSpotResolvedObjectTypeImpl arrayOfType; + HotSpotResolvedObjectType arrayOfType; - HotSpotResolvedJavaType(String name) { + protected HotSpotResolvedJavaType(String name) { super(name); } @@ -37,16 +37,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(); } @@ -60,5 +66,5 @@ public final HotSpotResolvedObjectType getArrayClass() { * * @return {@code true} if this type is being initialized */ - abstract boolean isBeingInitialized(); + protected abstract boolean isBeingInitialized(); } 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 8d3b9f48b4cd1..3917d2e7fa29e 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 4425ade0880a1..653fd7b9093eb 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; } @@ -316,7 +322,7 @@ public boolean equals(Object obj) { } @Override - JavaConstant getJavaMirror() { + public JavaConstant getJavaMirror() { return mirror; } @@ -329,5 +335,4 @@ public AnnotationData getAnnotationData(ResolvedJavaType type) { public List getAnnotationData(ResolvedJavaType type1, ResolvedJavaType type2, ResolvedJavaType... types) { return Collections.emptyList(); } - } 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..5c0557c87e225 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 : Arrays.copyOf(encoding, encoding.length); + } + @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..ec8beaceb6351 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 : Arrays.copyOf(context, context.length); + } }