Skip to content

8352690: [JVMCI] Add the set of caller saved registers to j.i.v.c.CallingConvention #24185

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 3 commits 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 @@ -24,12 +24,20 @@

import static jdk.vm.ci.code.ValueUtil.isAllocatableValue;
import static jdk.vm.ci.code.ValueUtil.isStackSlot;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.Value;

/**
* A calling convention describes the locations in which the arguments for a call are placed and the
* location in which the return value is placed if the call is not void.
* A calling convention describes how 2 functions interact with each other at the machine code
* level. It contains the locations in which the arguments for a call are placed, the location in
* which the return value is placed if the call is not void, and the locations that are killed by
* this call (a.k.a. the set of caller-saved registers).
*/
public class CallingConvention {

Expand All @@ -49,7 +57,13 @@ public interface Type {
/**
* The ordered locations in which the arguments are placed.
*/
private final AllocatableValue[] argumentLocations;
private final List<? extends AllocatableValue> argumentLocations;

/**
* The set of call-clobbered (caller-saved) registers. If a register is not in this set, it is a
* call-preserved (callee-saved) register.
*/
private final Set<? extends AllocatableValue> callerSavedLocations;

/**
* Creates a description of the registers and stack locations used by a call.
Expand All @@ -60,12 +74,13 @@ public interface Type {
* call
* @param argumentLocations the ordered locations in which the arguments are placed
*/
public CallingConvention(int stackSize, AllocatableValue returnLocation, AllocatableValue... argumentLocations) {
public CallingConvention(int stackSize, AllocatableValue returnLocation, List<? extends AllocatableValue> argumentLocations, Collection<? extends AllocatableValue> callerSavedLocations) {
Copy link
Member

Choose a reason for hiding this comment

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

This is a nice API improvement (array -> list for the type of argumentLocations) but will need Graal adaption.

Copy link
Contributor

Choose a reason for hiding this comment

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

The Graal adaption will likely fail the JDK21 compilation. Make sure to run a JDK21 gate

assert argumentLocations != null;
assert returnLocation != null;
this.argumentLocations = argumentLocations;
this.callerSavedLocations = Set.copyOf(callerSavedLocations);
this.argumentLocations = List.copyOf(argumentLocations);
this.returnLocation = Objects.requireNonNull(returnLocation);
this.stackSize = stackSize;
this.returnLocation = returnLocation;
assert verify();
}

Expand All @@ -80,7 +95,7 @@ public AllocatableValue getReturn() {
* Gets the location for the {@code index}'th argument.
*/
public AllocatableValue getArgument(int index) {
return argumentLocations[index];
return argumentLocations.get(index);
}

/**
Expand All @@ -94,18 +109,23 @@ public int getStackSize() {
* Gets the number of locations required for the arguments.
*/
public int getArgumentCount() {
return argumentLocations.length;
return argumentLocations.size();
}

/**
* Gets the locations required for the arguments.
* Gets the locations required for the arguments. The returned value is an immutable
* {@link List}.
*/
@SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "FB false positive")
public AllocatableValue[] getArguments() {
if (argumentLocations.length == 0) {
return argumentLocations;
}
return argumentLocations.clone();
public List<? extends AllocatableValue> getArguments() {
return argumentLocations;
}

/**
* Get the list of call-clobbered (caller-saved) registers. The returned value is an immutable
* {@link Set}.
*/
public Set<? extends AllocatableValue> getCallerSavedLocations() {
return callerSavedLocations;
}

@Override
Expand All @@ -125,8 +145,7 @@ public String toString() {
}

private boolean verify() {
for (int i = 0; i < argumentLocations.length; i++) {
Value location = argumentLocations[i];
for (Value location : argumentLocations) {
assert isStackSlot(location) || isAllocatableValue(location);
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ private CallingConvention callingConvention(RegisterArray generalParameterRegist

JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
return new CallingConvention(currentStackOffset, returnLocation, locations);
return new CallingConvention(currentStackOffset, returnLocation, List.of(locations), callerSaved.asList().stream().map(Register::asValue).toList());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ private CallingConvention callingConvention(RegisterArray generalParameterRegist

JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
return new CallingConvention(currentStackOffset, returnLocation, locations);
return new CallingConvention(currentStackOffset, returnLocation, List.of(locations), callerSaved.asList().stream().map(Register::asValue).toList());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ private CallingConvention callingConvention(RegisterArray generalParameterRegist

JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
return new CallingConvention(currentStackOffset, returnLocation, locations);
return new CallingConvention(currentStackOffset, returnLocation, List.of(locations), callerSaved.asList().stream().map(Register::asValue).toList());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2023, Arm Limited. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -367,9 +367,8 @@ public void emitEpilogue() {
@Override
public void emitCallPrologue(CallingConvention cc, Object... prim) {
growFrame(cc.getStackSize());
AllocatableValue[] args = cc.getArguments();
for (int i = 0; i < args.length; i++) {
emitLoad(args[i], prim[i]);
for (int i = 0; i < cc.getArgumentCount(); i++) {
emitLoad(cc.getArgument(i), prim[i]);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, 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
Expand Down Expand Up @@ -495,11 +495,10 @@ public void emitLoad(AllocatableValue av, Object prim) {
@Override
public void emitCallPrologue(CallingConvention cc, Object... prim) {
growFrame(cc.getStackSize());
AllocatableValue[] args = cc.getArguments();
// Do the emission in reverse, this avoids register collisons of xmm0 - which is used a
// scratch register when putting arguments on the stack.
for (int i = args.length - 1; i >= 0; i--) {
emitLoad(args[i], prim[i]);
for (int i = cc.getArgumentCount() - 1; i >= 0; i--) {
emitLoad(cc.getArgument(i), prim[i]);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2025, 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
Expand Down Expand Up @@ -227,9 +227,8 @@ public void emitEpilogue() {
@Override
public void emitCallPrologue(CallingConvention cc, Object... prim) {
growFrame(cc.getStackSize());
AllocatableValue[] args = cc.getArguments();
for (int i = 0; i < args.length; i++) {
emitLoad(args[i], prim[i]);
for (int i = 0; i < cc.getArgumentCount(); i++) {
emitLoad(cc.getArgument(i), prim[i]);
}
}

Expand Down