Skip to content

8357689: Refactor JVMCI to enable replay compilation in Graal #25433

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep in mind that slotKinds is being converted to a List. In that context, can we return the list without making a copy? Or is the caller expected to be able to mutate the return value?

return (slotKinds == null) ? null : Arrays.copyOf(slotKinds, slotKinds.length);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -291,10 +292,12 @@ public boolean equals(Object o) {
}
if (o instanceof VirtualObject) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename l to that and use pattern instanceof:

Suggested change
if (o instanceof VirtualObject) {
if (o instanceof VirtualObject that) {

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.
Expand All @@ -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() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments as for BytecodeFrame.getSlotKinds. This applies to all other non-primitive array return values added by this PR.

return (slotKinds == null) ? null : Arrays.copyOf(slotKinds, slotKinds.length);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ public Site(int pos) {
}

@Override
public final int hashCode() {
throw new UnsupportedOperationException("hashCode");
public int hashCode() {
return 41 * pcOffset;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null -> empty list?

* 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public HotSpotJavaType(String name) {
}

@Override
public final String getName() {
public String getName() {
return name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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<JavaConstant> 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<JavaConstant> getCallSiteTarget() {
throw new UnsupportedOperationException("getCallSiteTarget");
}

/**
* Determines if this constant represents an {@linkplain String#intern() interned} string.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,15 @@ private HotSpotObjectConstantImpl readTarget() {
}

@Override
public JavaConstant getCallSiteTarget(Assumptions assumptions) {
public Assumptions.AssumptionResult<JavaConstant> 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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,32 @@

public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements ResolvedJavaType {

HotSpotResolvedObjectTypeImpl arrayOfType;
HotSpotResolvedObjectType arrayOfType;

HotSpotResolvedJavaType(String name) {
protected HotSpotResolvedJavaType(String name) {
super(name);
}

@Override
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();
}
Expand All @@ -60,5 +66,5 @@ public final HotSpotResolvedObjectType getArrayClass() {
*
* @return {@code true} if this type is being initialized
*/
abstract boolean isBeingInitialized();
protected abstract boolean isBeingInitialized();
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ default JavaKind getJavaKind() {
@Override
AssumptionResult<ResolvedJavaMethod> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Loading