8148101: [JVMCI] Make CallingConvention.Type extensible

Reviewed-by: twisti
This commit is contained in:
Tom Rodriguez 2016-01-25 09:12:58 -08:00
parent 4e99638d69
commit a3351a8233
9 changed files with 113 additions and 72 deletions

View File

@ -34,35 +34,9 @@ import jdk.vm.ci.meta.Value;
public class CallingConvention {
/**
* Constants denoting the type of a call for which a calling convention is requested.
* Marker interface denoting the type of a call for which a calling convention is requested.
*/
public enum Type {
/**
* A request for the outgoing argument locations at a call site to Java code.
*/
JavaCall(true),
/**
* A request for the incoming argument locations.
*/
JavaCallee(false),
/**
* A request for the outgoing argument locations at a call site to external native code that
* complies with the platform ABI.
*/
NativeCall(true);
/**
* Determines if this is a request for the outgoing argument locations at a call site.
*/
public final boolean out;
public static final Type[] VALUES = values();
private Type(boolean out) {
this.out = out;
}
public interface Type {
}
/**

View File

@ -417,7 +417,7 @@ public class CodeUtil {
/**
* Create a calling convention from a {@link ResolvedJavaMethod}.
*/
public static CallingConvention getCallingConvention(CodeCacheProvider codeCache, CallingConvention.Type type, ResolvedJavaMethod method, boolean stackOnly) {
public static CallingConvention getCallingConvention(CodeCacheProvider codeCache, CallingConvention.Type type, ResolvedJavaMethod method) {
Signature sig = method.getSignature();
JavaType retType = sig.getReturnType(null);
int sigCount = sig.getParameterCount(false);
@ -434,6 +434,6 @@ public class CodeUtil {
}
RegisterConfig registerConfig = codeCache.getRegisterConfig();
return registerConfig.getCallingConvention(type, retType, argTypes, codeCache.getTarget(), stackOnly);
return registerConfig.getCallingConvention(type, retType, argTypes, codeCache.getTarget());
}
}

View File

@ -57,9 +57,8 @@ public interface RegisterConfig {
* @param returnType the return type (can be null for methods returning {@code void})
* @param parameterTypes the types of the arguments of the call
* @param target the target platform
* @param stackOnly ignore registers
*/
CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly);
CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target);
/**
* Gets the ordered set of registers that are can be used to pass parameters according to a

View File

@ -62,6 +62,7 @@ import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaKind;
@ -96,6 +97,7 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
return allocatable.clone();
}
@Override
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
ArrayList<Register> list = new ArrayList<>();
for (Register reg : registers) {
@ -191,16 +193,19 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
}
@Override
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) {
if (type == Type.NativeCall) {
return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
if (type == HotSpotCallingConventionType.NativeCall) {
return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
}
// On x64, parameter locations are the same whether viewed
// from the caller or callee perspective
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
}
@Override
public Register[] getCallingConventionRegisters(Type type, JavaKind kind) {
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
switch (kind) {
case Boolean:
case Byte:
@ -209,7 +214,7 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
case Int:
case Long:
case Object:
return type == Type.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters;
return hotspotType == HotSpotCallingConventionType.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters;
case Float:
case Double:
return simdParameterRegisters;
@ -218,7 +223,7 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
}
}
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) {
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
int currentGeneral = 0;
@ -236,14 +241,14 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
case Int:
case Long:
case Object:
if (!stackOnly && currentGeneral < generalParameterRegisters.length) {
if (currentGeneral < generalParameterRegisters.length) {
Register register = generalParameterRegisters[currentGeneral++];
locations[i] = register.asValue(target.getLIRKind(kind));
}
break;
case Float:
case Double:
if (!stackOnly && currentSIMD < simdParameterRegisters.length) {
if (currentSIMD < simdParameterRegisters.length) {
Register register = simdParameterRegisters[currentSIMD++];
locations[i] = register.asValue(target.getLIRKind(kind));
}

View File

@ -56,6 +56,7 @@ import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaKind;
@ -90,6 +91,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
return allocatable.clone();
}
@Override
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
ArrayList<Register> list = new ArrayList<>();
for (Register reg : registers) {
@ -175,6 +177,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
return callerSaved;
}
@Override
public Register[] getCalleeSaveRegisters() {
return null;
}
@ -190,16 +193,19 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
}
@Override
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) {
if (type == Type.NativeCall) {
return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
if (type == HotSpotCallingConventionType.NativeCall) {
return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
}
// On x64, parameter locations are the same whether viewed
// from the caller or callee perspective
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
}
@Override
public Register[] getCallingConventionRegisters(Type type, JavaKind kind) {
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
switch (kind) {
case Boolean:
case Byte:
@ -208,7 +214,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
case Int:
case Long:
case Object:
return type == Type.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters;
return hotspotType == HotSpotCallingConventionType.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters;
case Float:
case Double:
return xmmParameterRegisters;
@ -217,12 +223,12 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
}
}
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) {
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
int currentGeneral = 0;
int currentXMM = 0;
int currentStackOffset = type == Type.NativeCall && needsNativeStackHomeSpace ? generalParameterRegisters.length * target.wordSize : 0;
int currentStackOffset = type == HotSpotCallingConventionType.NativeCall && needsNativeStackHomeSpace ? generalParameterRegisters.length * target.wordSize : 0;
for (int i = 0; i < parameterTypes.length; i++) {
final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind();
@ -235,14 +241,14 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
case Int:
case Long:
case Object:
if (!stackOnly && currentGeneral < generalParameterRegisters.length) {
if (currentGeneral < generalParameterRegisters.length) {
Register register = generalParameterRegisters[currentGeneral++];
locations[i] = register.asValue(target.getLIRKind(kind));
}
break;
case Float:
case Double:
if (!stackOnly && currentXMM < xmmParameterRegisters.length) {
if (currentXMM < xmmParameterRegisters.length) {
Register register = xmmParameterRegisters[currentXMM++];
locations[i] = register.asValue(target.getLIRKind(kind));
}

View File

@ -22,9 +22,6 @@
*/
package jdk.vm.ci.hotspot.sparc;
import static jdk.vm.ci.code.CallingConvention.Type.JavaCall;
import static jdk.vm.ci.code.CallingConvention.Type.JavaCallee;
import static jdk.vm.ci.code.CallingConvention.Type.NativeCall;
import static jdk.vm.ci.meta.JavaKind.Void;
import static jdk.vm.ci.meta.Value.ILLEGAL;
import static jdk.vm.ci.sparc.SPARC.REGISTER_SAFE_AREA_SIZE;
@ -81,6 +78,7 @@ import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaKind;
@ -107,6 +105,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
return allocatable.clone();
}
@Override
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
ArrayList<Register> list = new ArrayList<>();
for (Register reg : registers) {
@ -200,17 +199,20 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
}
@Override
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) {
if (type == JavaCall || type == NativeCall) {
return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
if (type == HotSpotCallingConventionType.JavaCall || type == HotSpotCallingConventionType.NativeCall) {
return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, hotspotType, target);
}
if (type == JavaCallee) {
return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
if (type == HotSpotCallingConventionType.JavaCallee) {
return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, hotspotType, target);
}
throw JVMCIError.shouldNotReachHere();
}
@Override
public Register[] getCallingConventionRegisters(Type type, JavaKind kind) {
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
switch (kind) {
case Boolean:
case Byte:
@ -219,7 +221,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
case Int:
case Long:
case Object:
return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
return hotspotType == HotSpotCallingConventionType.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
case Double:
case Float:
return fpuFloatParameterRegisters;
@ -228,7 +230,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
}
}
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) {
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
int currentGeneral = 0;
@ -246,13 +248,13 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
case Int:
case Long:
case Object:
if (!stackOnly && currentGeneral < generalParameterRegisters.length) {
if (currentGeneral < generalParameterRegisters.length) {
Register register = generalParameterRegisters[currentGeneral++];
locations[i] = register.asValue(target.getLIRKind(kind));
}
break;
case Double:
if (!stackOnly && currentFloating < fpuFloatParameterRegisters.length) {
if (currentFloating < fpuFloatParameterRegisters.length) {
if (currentFloating % 2 != 0) {
// Make register number even to be a double reg
currentFloating++;
@ -263,7 +265,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
}
break;
case Float:
if (!stackOnly && currentFloating < fpuFloatParameterRegisters.length) {
if (currentFloating < fpuFloatParameterRegisters.length) {
Register register = fpuFloatParameterRegisters[currentFloating++];
locations[i] = register.asValue(target.getLIRKind(kind));
}
@ -287,7 +289,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind()));
int outArgSpillArea;
if (type == NativeCall && addNativeRegisterArgumentSlots) {
if (type == HotSpotCallingConventionType.NativeCall && addNativeRegisterArgumentSlots) {
// Space for native callee which may spill our outgoing arguments
outArgSpillArea = Math.min(locations.length, generalParameterRegisters.length) * target.wordSize;
} else {
@ -302,10 +304,10 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
@Override
public Register getReturnRegister(JavaKind kind) {
return getReturnRegister(kind, JavaCallee);
return getReturnRegister(kind, HotSpotCallingConventionType.JavaCallee);
}
private static Register getReturnRegister(JavaKind kind, Type type) {
private static Register getReturnRegister(JavaKind kind, HotSpotCallingConventionType type) {
switch (kind) {
case Boolean:
case Byte:
@ -314,7 +316,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
case Int:
case Long:
case Object:
return type == JavaCallee ? i0 : o0;
return type == HotSpotCallingConventionType.JavaCallee ? i0 : o0;
case Float:
return f0;
case Double:

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2016, 2016, 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.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.CallingConvention.Type;
public enum HotSpotCallingConventionType implements CallingConvention.Type {
/**
* A request for the outgoing argument locations at a call site to Java code.
*/
JavaCall(true),
/**
* A request for the incoming argument locations.
*/
JavaCallee(false),
/**
* A request for the outgoing argument locations at a call site to external native code that
* complies with the platform ABI.
*/
NativeCall(true);
/**
* Determines if this is a request for the outgoing argument locations at a call site.
*/
public final boolean out;
public static final Type[] VALUES = values();
private HotSpotCallingConventionType(boolean out) {
this.out = out;
}
}

View File

@ -25,13 +25,13 @@ package compiler.jvmci.code.amd64;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64Kind;
import jdk.vm.ci.code.CallingConvention.Type;
import jdk.vm.ci.code.CodeCacheProvider;
import jdk.vm.ci.code.DebugInfo;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.ConstantReference;
import jdk.vm.ci.code.site.DataSectionReference;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.LIRKind;
@ -76,12 +76,12 @@ public class AMD64TestAssembler extends TestAssembler {
@Override
public Register emitIntArg0() {
return codeCache.getRegisterConfig().getCallingConventionRegisters(Type.JavaCall, JavaKind.Int)[0];
return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCall, JavaKind.Int)[0];
}
@Override
public Register emitIntArg1() {
return codeCache.getRegisterConfig().getCallingConventionRegisters(Type.JavaCall, JavaKind.Int)[1];
return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCall, JavaKind.Int)[1];
}
private void emitREX(boolean w, int r, int x, int b) {

View File

@ -23,13 +23,13 @@
package compiler.jvmci.code.sparc;
import jdk.vm.ci.code.CallingConvention.Type;
import jdk.vm.ci.code.CodeCacheProvider;
import jdk.vm.ci.code.DebugInfo;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.ConstantReference;
import jdk.vm.ci.code.site.DataSectionReference;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
import jdk.vm.ci.hotspot.HotSpotConstant;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
@ -83,12 +83,12 @@ public class SPARCTestAssembler extends TestAssembler {
@Override
public Register emitIntArg0() {
return codeCache.getRegisterConfig().getCallingConventionRegisters(Type.JavaCallee, JavaKind.Int)[0];
return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[0];
}
@Override
public Register emitIntArg1() {
return codeCache.getRegisterConfig().getCallingConventionRegisters(Type.JavaCallee, JavaKind.Int)[1];
return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[1];
}
@Override