8156942: [JVMCI] replace LIRKind with abstract base class
Reviewed-by: iveresov
This commit is contained in:
parent
fd3645227b
commit
5686cc1784
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 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
|
||||
@ -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) {
|
||||
public static CallingConvention getCallingConvention(CodeCacheProvider codeCache, CallingConvention.Type type, ResolvedJavaMethod method, ValueKindFactory<?> valueKindFactory) {
|
||||
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());
|
||||
return registerConfig.getCallingConvention(type, retType, argTypes, valueKindFactory);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 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
|
||||
@ -22,8 +22,7 @@
|
||||
*/
|
||||
package jdk.vm.ci.code;
|
||||
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.LIRKind;
|
||||
import jdk.vm.ci.meta.ValueKind;
|
||||
|
||||
/**
|
||||
* Represents a target machine register.
|
||||
@ -144,17 +143,17 @@ public final class Register implements Comparable<Register> {
|
||||
* @param kind the specified kind
|
||||
* @return the {@link RegisterValue}
|
||||
*/
|
||||
public RegisterValue asValue(LIRKind kind) {
|
||||
public RegisterValue asValue(ValueKind<?> kind) {
|
||||
return new RegisterValue(kind, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this register as a {@linkplain RegisterValue value} with no particular kind.
|
||||
*
|
||||
* @return a {@link RegisterValue} with {@link JavaKind#Illegal} kind.
|
||||
* @return a {@link RegisterValue} with {@link ValueKind#Illegal} kind.
|
||||
*/
|
||||
public RegisterValue asValue() {
|
||||
return asValue(LIRKind.Illegal);
|
||||
return asValue(ValueKind.Illegal);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 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
|
||||
@ -26,6 +26,7 @@ import jdk.vm.ci.code.CallingConvention.Type;
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.JavaType;
|
||||
import jdk.vm.ci.meta.PlatformKind;
|
||||
import jdk.vm.ci.meta.ValueKind;
|
||||
|
||||
/**
|
||||
* A register configuration binds roles and {@linkplain RegisterAttributes attributes} to physical
|
||||
@ -56,9 +57,9 @@ public interface RegisterConfig {
|
||||
* @param type the type of calling convention being requested
|
||||
* @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 valueKindFactory the factory to create custom {@link ValueKind ValueKinds}
|
||||
*/
|
||||
CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target);
|
||||
CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory);
|
||||
|
||||
/**
|
||||
* Gets the ordered set of registers that are can be used to pass parameters according to a
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 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
|
||||
@ -23,23 +23,16 @@
|
||||
package jdk.vm.ci.code;
|
||||
|
||||
import jdk.vm.ci.meta.AllocatableValue;
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.LIRKind;
|
||||
import jdk.vm.ci.meta.ValueKind;
|
||||
|
||||
/**
|
||||
* Denotes a register that stores a value of a fixed kind. There is exactly one (canonical) instance
|
||||
* of {@link RegisterValue} for each ({@link Register}, {@link JavaKind}) pair. Use
|
||||
* {@link Register#asValue(LIRKind)} to retrieve the canonical {@link RegisterValue} instance for a
|
||||
* given (register,kind) pair.
|
||||
* Denotes a register that stores a value of a fixed kind.
|
||||
*/
|
||||
public final class RegisterValue extends AllocatableValue {
|
||||
|
||||
private final Register reg;
|
||||
|
||||
/**
|
||||
* Should only be called from {@link Register#Register} to ensure canonicalization.
|
||||
*/
|
||||
protected RegisterValue(LIRKind kind, Register register) {
|
||||
protected RegisterValue(ValueKind<?> kind, Register register) {
|
||||
super(kind);
|
||||
this.reg = register;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 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
|
||||
@ -23,7 +23,7 @@
|
||||
package jdk.vm.ci.code;
|
||||
|
||||
import jdk.vm.ci.meta.AllocatableValue;
|
||||
import jdk.vm.ci.meta.LIRKind;
|
||||
import jdk.vm.ci.meta.ValueKind;
|
||||
|
||||
/**
|
||||
* Represents a compiler spill slot or an outgoing stack-based argument in a method's frame or an
|
||||
@ -43,16 +43,16 @@ public final class StackSlot extends AllocatableValue {
|
||||
* @param addFrameSize Specifies if the offset is relative to the stack pointer, or the
|
||||
* beginning of the frame (stack pointer + total frame size).
|
||||
*/
|
||||
public static StackSlot get(LIRKind kind, int offset, boolean addFrameSize) {
|
||||
public static StackSlot get(ValueKind<?> kind, int offset, boolean addFrameSize) {
|
||||
assert addFrameSize || offset >= 0;
|
||||
return new StackSlot(kind, offset, addFrameSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor to enforce use of {@link #get(LIRKind, int, boolean)} so that a cache can
|
||||
* be used.
|
||||
* Private constructor to enforce use of {@link #get(ValueKind, int, boolean)} so that a cache
|
||||
* can be used.
|
||||
*/
|
||||
private StackSlot(LIRKind kind, int offset, boolean addFrameSize) {
|
||||
private StackSlot(ValueKind<?> kind, int offset, boolean addFrameSize) {
|
||||
super(kind);
|
||||
this.offset = offset;
|
||||
this.addFrameSize = addFrameSize;
|
||||
@ -99,7 +99,7 @@ public final class StackSlot extends AllocatableValue {
|
||||
public StackSlot asOutArg() {
|
||||
assert offset >= 0;
|
||||
if (addFrameSize) {
|
||||
return get(getLIRKind(), offset, false);
|
||||
return get(getValueKind(), offset, false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -110,7 +110,7 @@ public final class StackSlot extends AllocatableValue {
|
||||
public StackSlot asInArg() {
|
||||
assert offset >= 0;
|
||||
if (!addFrameSize) {
|
||||
return get(getLIRKind(), offset, true);
|
||||
return get(getValueKind(), offset, true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 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
|
||||
@ -23,9 +23,8 @@
|
||||
package jdk.vm.ci.code;
|
||||
|
||||
import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString;
|
||||
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.LIRKind;
|
||||
import jdk.vm.ci.meta.PlatformKind;
|
||||
|
||||
/**
|
||||
* Represents the target machine for a compiler, including the CPU architecture, the size of
|
||||
@ -118,13 +117,4 @@ public class TargetDescription {
|
||||
public String toString() {
|
||||
return identityHashCodeString(this);
|
||||
}
|
||||
|
||||
public LIRKind getLIRKind(JavaKind javaKind) {
|
||||
PlatformKind platformKind = arch.getPlatformKind(javaKind);
|
||||
if (javaKind.isObject()) {
|
||||
return LIRKind.reference(platformKind);
|
||||
} else {
|
||||
return LIRKind.value(platformKind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 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.code;
|
||||
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.ValueKind;
|
||||
|
||||
/**
|
||||
* Can be implemented by compilers to create custom {@link ValueKind} subclasses.
|
||||
*/
|
||||
public interface ValueKindFactory<K extends ValueKind<K>> {
|
||||
|
||||
K getValueKind(JavaKind javaKind);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
@ -68,7 +68,7 @@ public class AArch64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac
|
||||
}
|
||||
|
||||
protected RegisterConfig createRegisterConfig(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target) {
|
||||
return new AArch64HotSpotRegisterConfig(target.arch, runtime.getConfig());
|
||||
return new AArch64HotSpotRegisterConfig(target, runtime.getConfig());
|
||||
}
|
||||
|
||||
protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
@ -64,19 +64,20 @@ import jdk.vm.ci.code.RegisterAttributes;
|
||||
import jdk.vm.ci.code.RegisterConfig;
|
||||
import jdk.vm.ci.code.StackSlot;
|
||||
import jdk.vm.ci.code.TargetDescription;
|
||||
import jdk.vm.ci.code.ValueKindFactory;
|
||||
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;
|
||||
import jdk.vm.ci.meta.JavaType;
|
||||
import jdk.vm.ci.meta.LIRKind;
|
||||
import jdk.vm.ci.meta.PlatformKind;
|
||||
import jdk.vm.ci.meta.Value;
|
||||
import jdk.vm.ci.meta.ValueKind;
|
||||
|
||||
public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
||||
|
||||
private final Architecture architecture;
|
||||
private final TargetDescription target;
|
||||
|
||||
private final Register[] allocatable;
|
||||
|
||||
@ -104,7 +105,7 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
||||
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
|
||||
ArrayList<Register> list = new ArrayList<>();
|
||||
for (Register reg : registers) {
|
||||
if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
|
||||
if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
|
||||
list.add(reg);
|
||||
}
|
||||
}
|
||||
@ -159,13 +160,13 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
||||
return registers;
|
||||
}
|
||||
|
||||
public AArch64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) {
|
||||
this(architecture, config, initAllocatable(architecture, config.useCompressedOops));
|
||||
public AArch64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
|
||||
this(target, config, initAllocatable(target.arch, config.useCompressedOops));
|
||||
assert callerSaved.length >= allocatable.length;
|
||||
}
|
||||
|
||||
public AArch64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, Register[] allocatable) {
|
||||
this.architecture = architecture;
|
||||
public AArch64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config, Register[] allocatable) {
|
||||
this.target = target;
|
||||
this.maxFrameSize = config.maxFrameSize;
|
||||
|
||||
this.allocatable = allocatable.clone();
|
||||
@ -200,14 +201,14 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
|
||||
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
|
||||
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
|
||||
if (type == HotSpotCallingConventionType.NativeCall) {
|
||||
return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
|
||||
return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
|
||||
}
|
||||
// On x64, parameter locations are the same whether viewed
|
||||
// from the caller or callee perspective
|
||||
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
|
||||
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -230,7 +231,8 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
||||
}
|
||||
}
|
||||
|
||||
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
|
||||
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
|
||||
ValueKindFactory<?> valueKindFactory) {
|
||||
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
|
||||
|
||||
int currentGeneral = 0;
|
||||
@ -250,14 +252,14 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
||||
case Object:
|
||||
if (currentGeneral < generalParameterRegisters.length) {
|
||||
Register register = generalParameterRegisters[currentGeneral++];
|
||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
||||
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||
}
|
||||
break;
|
||||
case Float:
|
||||
case Double:
|
||||
if (currentSIMD < simdParameterRegisters.length) {
|
||||
Register register = simdParameterRegisters[currentSIMD++];
|
||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
||||
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -265,14 +267,14 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
||||
}
|
||||
|
||||
if (locations[i] == null) {
|
||||
LIRKind lirKind = target.getLIRKind(kind);
|
||||
locations[i] = StackSlot.get(lirKind, currentStackOffset, !type.out);
|
||||
currentStackOffset += Math.max(lirKind.getPlatformKind().getSizeInBytes(), target.wordSize);
|
||||
ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
|
||||
locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.out);
|
||||
currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize);
|
||||
}
|
||||
}
|
||||
|
||||
JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
|
||||
AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(target.getLIRKind(returnKind.getStackKind()));
|
||||
AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
|
||||
return new CallingConvention(currentStackOffset, returnLocation, locations);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -152,7 +152,7 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
|
||||
}
|
||||
|
||||
protected RegisterConfig createRegisterConfig(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target) {
|
||||
return new AMD64HotSpotRegisterConfig(target.arch, runtime.getConfig());
|
||||
return new AMD64HotSpotRegisterConfig(target, runtime.getConfig());
|
||||
}
|
||||
|
||||
protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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
|
||||
@ -56,19 +56,20 @@ import jdk.vm.ci.code.RegisterAttributes;
|
||||
import jdk.vm.ci.code.RegisterConfig;
|
||||
import jdk.vm.ci.code.StackSlot;
|
||||
import jdk.vm.ci.code.TargetDescription;
|
||||
import jdk.vm.ci.code.ValueKindFactory;
|
||||
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;
|
||||
import jdk.vm.ci.meta.JavaType;
|
||||
import jdk.vm.ci.meta.LIRKind;
|
||||
import jdk.vm.ci.meta.PlatformKind;
|
||||
import jdk.vm.ci.meta.Value;
|
||||
import jdk.vm.ci.meta.ValueKind;
|
||||
|
||||
public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
||||
|
||||
private final Architecture architecture;
|
||||
private final TargetDescription target;
|
||||
|
||||
private final Register[] allocatable;
|
||||
|
||||
@ -96,7 +97,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
||||
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
|
||||
ArrayList<Register> list = new ArrayList<>();
|
||||
for (Register reg : registers) {
|
||||
if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
|
||||
if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
|
||||
list.add(reg);
|
||||
}
|
||||
}
|
||||
@ -145,13 +146,13 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
||||
return registers;
|
||||
}
|
||||
|
||||
public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) {
|
||||
this(architecture, config, initAllocatable(architecture, config.useCompressedOops));
|
||||
public AMD64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
|
||||
this(target, config, initAllocatable(target.arch, config.useCompressedOops));
|
||||
assert callerSaved.length >= allocatable.length;
|
||||
}
|
||||
|
||||
public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, Register[] allocatable) {
|
||||
this.architecture = architecture;
|
||||
public AMD64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config, Register[] allocatable) {
|
||||
this.target = target;
|
||||
this.maxFrameSize = config.maxFrameSize;
|
||||
|
||||
if (config.windowsOs) {
|
||||
@ -173,7 +174,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
||||
callerSaved = callerSaveSet.toArray(new Register[callerSaveSet.size()]);
|
||||
|
||||
allAllocatableAreCallerSaved = true;
|
||||
attributesMap = RegisterAttributes.createMap(this, architecture.getRegisters());
|
||||
attributesMap = RegisterAttributes.createMap(this, target.arch.getRegisters());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -197,14 +198,14 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
|
||||
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
|
||||
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
|
||||
if (type == HotSpotCallingConventionType.NativeCall) {
|
||||
return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
|
||||
return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
|
||||
}
|
||||
// On x64, parameter locations are the same whether viewed
|
||||
// from the caller or callee perspective
|
||||
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
|
||||
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -227,7 +228,8 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
||||
}
|
||||
}
|
||||
|
||||
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
|
||||
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
|
||||
ValueKindFactory<?> valueKindFactory) {
|
||||
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
|
||||
|
||||
int currentGeneral = 0;
|
||||
@ -247,14 +249,14 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
||||
case Object:
|
||||
if (currentGeneral < generalParameterRegisters.length) {
|
||||
Register register = generalParameterRegisters[currentGeneral++];
|
||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
||||
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||
}
|
||||
break;
|
||||
case Float:
|
||||
case Double:
|
||||
if (currentXMM < xmmParameterRegisters.length) {
|
||||
Register register = xmmParameterRegisters[currentXMM++];
|
||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
||||
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -262,14 +264,14 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
||||
}
|
||||
|
||||
if (locations[i] == null) {
|
||||
LIRKind lirKind = target.getLIRKind(kind);
|
||||
locations[i] = StackSlot.get(lirKind, currentStackOffset, !type.out);
|
||||
currentStackOffset += Math.max(lirKind.getPlatformKind().getSizeInBytes(), target.wordSize);
|
||||
ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
|
||||
locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.out);
|
||||
currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize);
|
||||
}
|
||||
}
|
||||
|
||||
JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
|
||||
AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(target.getLIRKind(returnKind.getStackKind()));
|
||||
AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
|
||||
return new CallingConvention(currentStackOffset, returnLocation, locations);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -146,7 +146,7 @@ public class SPARCHotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
|
||||
TargetDescription target = createTarget(runtime.getConfig());
|
||||
|
||||
HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(runtime);
|
||||
RegisterConfig regConfig = new SPARCHotSpotRegisterConfig(target.arch, runtime.getConfig());
|
||||
RegisterConfig regConfig = new SPARCHotSpotRegisterConfig(target, runtime.getConfig());
|
||||
HotSpotCodeCacheProvider codeCache = createCodeCache(runtime, target, regConfig);
|
||||
HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(runtime);
|
||||
StackIntrospection stackIntrospection = new HotSpotStackIntrospection(runtime);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 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
|
||||
@ -78,19 +78,20 @@ import jdk.vm.ci.code.RegisterAttributes;
|
||||
import jdk.vm.ci.code.RegisterConfig;
|
||||
import jdk.vm.ci.code.StackSlot;
|
||||
import jdk.vm.ci.code.TargetDescription;
|
||||
import jdk.vm.ci.code.ValueKindFactory;
|
||||
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;
|
||||
import jdk.vm.ci.meta.JavaType;
|
||||
import jdk.vm.ci.meta.LIRKind;
|
||||
import jdk.vm.ci.meta.PlatformKind;
|
||||
import jdk.vm.ci.meta.ValueKind;
|
||||
import jdk.vm.ci.sparc.SPARC;
|
||||
|
||||
public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
||||
|
||||
private final Architecture architecture;
|
||||
private final TargetDescription target;
|
||||
|
||||
private final Register[] allocatable;
|
||||
|
||||
@ -110,7 +111,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
||||
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
|
||||
ArrayList<Register> list = new ArrayList<>();
|
||||
for (Register reg : registers) {
|
||||
if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
|
||||
if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
|
||||
list.add(reg);
|
||||
}
|
||||
}
|
||||
@ -166,16 +167,16 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
||||
return registers;
|
||||
}
|
||||
|
||||
public SPARCHotSpotRegisterConfig(Architecture arch, HotSpotVMConfig config) {
|
||||
this(arch, initAllocatable(arch, config.useCompressedOops), config);
|
||||
public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
|
||||
this(target, initAllocatable(target.arch, config.useCompressedOops), config);
|
||||
}
|
||||
|
||||
public SPARCHotSpotRegisterConfig(Architecture arch, Register[] allocatable, HotSpotVMConfig config) {
|
||||
this.architecture = arch;
|
||||
public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable, HotSpotVMConfig config) {
|
||||
this.target = target;
|
||||
this.allocatable = allocatable.clone();
|
||||
this.addNativeRegisterArgumentSlots = config.linuxOs;
|
||||
HashSet<Register> callerSaveSet = new HashSet<>();
|
||||
Collections.addAll(callerSaveSet, arch.getAvailableValueRegisters());
|
||||
Collections.addAll(callerSaveSet, target.arch.getAvailableValueRegisters());
|
||||
for (Register cs : calleeSaveRegisters) {
|
||||
callerSaveSet.remove(cs);
|
||||
}
|
||||
@ -203,13 +204,13 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
|
||||
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
|
||||
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
|
||||
if (type == HotSpotCallingConventionType.JavaCall || type == HotSpotCallingConventionType.NativeCall) {
|
||||
return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, hotspotType, target);
|
||||
return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
|
||||
}
|
||||
if (type == HotSpotCallingConventionType.JavaCallee) {
|
||||
return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, hotspotType, target);
|
||||
return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
|
||||
}
|
||||
throw JVMCIError.shouldNotReachHere();
|
||||
}
|
||||
@ -234,7 +235,8 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
||||
}
|
||||
}
|
||||
|
||||
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
|
||||
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
|
||||
ValueKindFactory<?> valueKindFactory) {
|
||||
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
|
||||
|
||||
int currentGeneral = 0;
|
||||
@ -254,7 +256,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
||||
case Object:
|
||||
if (currentGeneral < generalParameterRegisters.length) {
|
||||
Register register = generalParameterRegisters[currentGeneral++];
|
||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
||||
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||
}
|
||||
break;
|
||||
case Double:
|
||||
@ -265,13 +267,13 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
||||
}
|
||||
Register register = fpuDoubleParameterRegisters[currentFloating];
|
||||
currentFloating += 2; // Only every second is a double register
|
||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
||||
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||
}
|
||||
break;
|
||||
case Float:
|
||||
if (currentFloating < fpuFloatParameterRegisters.length) {
|
||||
Register register = fpuFloatParameterRegisters[currentFloating++];
|
||||
locations[i] = register.asValue(target.getLIRKind(kind));
|
||||
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -279,18 +281,18 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
||||
}
|
||||
|
||||
if (locations[i] == null) {
|
||||
LIRKind lirKind = target.getLIRKind(kind);
|
||||
ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
|
||||
// Stack slot is always aligned to its size in bytes but minimum wordsize
|
||||
int typeSize = lirKind.getPlatformKind().getSizeInBytes();
|
||||
int typeSize = valueKind.getPlatformKind().getSizeInBytes();
|
||||
currentStackOffset = roundUp(currentStackOffset, typeSize);
|
||||
int slotOffset = currentStackOffset + REGISTER_SAFE_AREA_SIZE;
|
||||
locations[i] = StackSlot.get(lirKind, slotOffset, !type.out);
|
||||
locations[i] = StackSlot.get(valueKind, slotOffset, !type.out);
|
||||
currentStackOffset += typeSize;
|
||||
}
|
||||
}
|
||||
|
||||
JavaKind returnKind = returnType == null ? Void : returnType.getJavaKind();
|
||||
AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind()));
|
||||
AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
|
||||
|
||||
int outArgSpillArea;
|
||||
if (type == HotSpotCallingConventionType.NativeCall && addNativeRegisterArgumentSlots) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 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
|
||||
@ -24,7 +24,7 @@ package jdk.vm.ci.hotspot;
|
||||
|
||||
import jdk.vm.ci.meta.JavaConstant;
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.LIRKind;
|
||||
import jdk.vm.ci.meta.ValueKind;
|
||||
import jdk.vm.ci.meta.VMConstant;
|
||||
import jdk.vm.ci.meta.Value;
|
||||
|
||||
@ -32,8 +32,8 @@ public final class HotSpotSentinelConstant extends Value implements JavaConstant
|
||||
|
||||
private final JavaKind javaKind;
|
||||
|
||||
public HotSpotSentinelConstant(LIRKind lirKind, JavaKind javaKind) {
|
||||
super(lirKind);
|
||||
public HotSpotSentinelConstant(ValueKind<?> valueKind, JavaKind javaKind) {
|
||||
super(valueKind);
|
||||
this.javaKind = javaKind;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 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
|
||||
@ -30,7 +30,7 @@ public abstract class AllocatableValue extends Value implements JavaValue {
|
||||
|
||||
public static final AllocatableValue[] NONE = {};
|
||||
|
||||
public AllocatableValue(LIRKind lirKind) {
|
||||
super(lirKind);
|
||||
public AllocatableValue(ValueKind<?> kind) {
|
||||
super(kind);
|
||||
}
|
||||
}
|
||||
|
@ -1,460 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2015, 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.meta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Represents the type of values in the LIR. It is composed of a {@link PlatformKind} that gives the
|
||||
* low level representation of the value, and a {@link #referenceMask} that describes the location
|
||||
* of object references in the value, and optionally a {@link #derivedReferenceBase}.
|
||||
*
|
||||
* <h2>Constructing {@link LIRKind} instances</h2>
|
||||
*
|
||||
* During LIR generation, every new {@link Value} should get a {@link LIRKind} of the correct
|
||||
* {@link PlatformKind} that also contains the correct reference information. {@linkplain LIRKind
|
||||
* LIRKinds} should be created as follows:
|
||||
*
|
||||
* <p>
|
||||
* If the result value is created from one or more input values, the {@link LIRKind} should be
|
||||
* created with {@link LIRKind#combine}(inputs). If the result has a different {@link PlatformKind}
|
||||
* than the inputs, {@link LIRKind#combine}(inputs).{@link #changeType}(resultKind) should be used.
|
||||
* <p>
|
||||
* If the result is an exact copy of one of the inputs, {@link Value#getLIRKind()} can be used. Note
|
||||
* that this is only correct for move-like operations, like conditional move or compare-and-swap.
|
||||
* For convert operations, {@link LIRKind#combine} should be used.
|
||||
* <p>
|
||||
* If it is known that the result will be a reference (e.g. pointer arithmetic where the end result
|
||||
* is a valid oop), {@link LIRKind#reference} should be used.
|
||||
* <p>
|
||||
* If it is known that the result will neither be a reference nor be derived from a reference,
|
||||
* {@link LIRKind#value} can be used. If the operation producing this value has inputs, this is very
|
||||
* likely wrong, and {@link LIRKind#combine} should be used instead.
|
||||
* <p>
|
||||
* If it is known that the result is derived from a reference in a way that the garbage collector
|
||||
* can not track, {@link LIRKind#unknownReference} can be used. In most cases,
|
||||
* {@link LIRKind#combine} should be used instead, since it is able to detect this automatically.
|
||||
*/
|
||||
public final class LIRKind {
|
||||
|
||||
private enum IllegalKind implements PlatformKind {
|
||||
ILLEGAL;
|
||||
|
||||
private final EnumKey<IllegalKind> key = new EnumKey<>(this);
|
||||
|
||||
public Key getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public int getSizeInBytes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getVectorLength() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public char getTypeChar() {
|
||||
return '-';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The non-type. This uses {@link #unknownReference}, so it can never be part of an oop map.
|
||||
*/
|
||||
public static final LIRKind Illegal = unknownReference(IllegalKind.ILLEGAL);
|
||||
|
||||
private final PlatformKind platformKind;
|
||||
private final int referenceMask;
|
||||
|
||||
private AllocatableValue derivedReferenceBase;
|
||||
|
||||
private static final int UNKNOWN_REFERENCE = -1;
|
||||
|
||||
private LIRKind(PlatformKind platformKind, int referenceMask, AllocatableValue derivedReferenceBase) {
|
||||
this.platformKind = platformKind;
|
||||
this.referenceMask = referenceMask;
|
||||
this.derivedReferenceBase = derivedReferenceBase;
|
||||
|
||||
assert derivedReferenceBase == null || !derivedReferenceBase.getLIRKind().isDerivedReference() : "derived reference can't have another derived reference as base";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link LIRKind} of type {@code platformKind} that contains a primitive value. Should
|
||||
* be only used when it's guaranteed that the value is not even indirectly derived from a
|
||||
* reference. Otherwise, {@link #combine(Value...)} should be used instead.
|
||||
*/
|
||||
public static LIRKind value(PlatformKind platformKind) {
|
||||
return new LIRKind(platformKind, 0, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link LIRKind} of type {@code platformKind} that contains a single tracked oop
|
||||
* reference.
|
||||
*/
|
||||
public static LIRKind reference(PlatformKind platformKind) {
|
||||
return derivedReference(platformKind, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link LIRKind} of type {@code platformKind} that contains a derived reference.
|
||||
*/
|
||||
public static LIRKind derivedReference(PlatformKind platformKind, AllocatableValue base) {
|
||||
int length = platformKind.getVectorLength();
|
||||
assert 0 < length && length < 32 : "vector of " + length + " references not supported";
|
||||
return new LIRKind(platformKind, (1 << length) - 1, base);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link LIRKind} of type {@code platformKind} that contains a value that is derived
|
||||
* from a reference in a non-linear way. Values of this {@link LIRKind} can not be live at
|
||||
* safepoints. In most cases, this should not be called directly. {@link #combine} should be
|
||||
* used instead to automatically propagate this information.
|
||||
*/
|
||||
public static LIRKind unknownReference(PlatformKind platformKind) {
|
||||
return new LIRKind(platformKind, UNKNOWN_REFERENCE, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a derived reference.
|
||||
*
|
||||
* @param base An {@link AllocatableValue} containing the base pointer of the derived reference.
|
||||
*/
|
||||
public LIRKind makeDerivedReference(AllocatableValue base) {
|
||||
assert !isUnknownReference() && derivedReferenceBase == null;
|
||||
if (Value.ILLEGAL.equals(base)) {
|
||||
return makeUnknownReference();
|
||||
} else {
|
||||
if (isValue()) {
|
||||
return derivedReference(platformKind, base);
|
||||
} else {
|
||||
return new LIRKind(platformKind, referenceMask, base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive a new type from inputs. The result will have the {@link PlatformKind} of one of the
|
||||
* inputs. If all inputs are values, the result is a value. Otherwise, the result is an unknown
|
||||
* reference.
|
||||
*
|
||||
* This method should be used to construct the result {@link LIRKind} of any operation that
|
||||
* modifies values (e.g. arithmetics).
|
||||
*/
|
||||
public static LIRKind combine(Value... inputs) {
|
||||
assert inputs.length > 0;
|
||||
for (Value input : inputs) {
|
||||
LIRKind kind = input.getLIRKind();
|
||||
if (kind.isUnknownReference()) {
|
||||
return kind;
|
||||
} else if (!kind.isValue()) {
|
||||
return kind.makeUnknownReference();
|
||||
}
|
||||
}
|
||||
|
||||
// all inputs are values, just return one of them
|
||||
return inputs[0].getLIRKind();
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the types of the inputs. The result will have the {@link PlatformKind} of one of the
|
||||
* inputs. If all inputs are values (references), the result is a value (reference). Otherwise,
|
||||
* the result is an unknown reference.
|
||||
*
|
||||
* This method should be used to construct the result {@link LIRKind} of merge operation that
|
||||
* does not modify values (e.g. phis).
|
||||
*/
|
||||
public static LIRKind merge(Value... inputs) {
|
||||
assert inputs.length > 0;
|
||||
ArrayList<LIRKind> kinds = new ArrayList<>(inputs.length);
|
||||
for (int i = 0; i < inputs.length; i++) {
|
||||
kinds.add(inputs[i].getLIRKind());
|
||||
}
|
||||
return merge(kinds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to construct derived reference kinds. Returns the base value of a reference or
|
||||
* derived reference. For values it returns {@code null}, and for unknown references it returns
|
||||
* {@link Value#ILLEGAL}.
|
||||
*/
|
||||
public static AllocatableValue derivedBaseFromValue(AllocatableValue value) {
|
||||
LIRKind kind = value.getLIRKind();
|
||||
if (kind.isValue()) {
|
||||
return null;
|
||||
} else if (kind.isDerivedReference()) {
|
||||
return kind.getDerivedReferenceBase();
|
||||
} else if (kind.isUnknownReference()) {
|
||||
return Value.ILLEGAL;
|
||||
} else {
|
||||
// kind is a reference
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to construct derived reference kinds. If one of {@code base1} or {@code base2}
|
||||
* are set, it creates a derived reference using it as the base. If both are set, the result is
|
||||
* an unknown reference.
|
||||
*/
|
||||
public static LIRKind combineDerived(LIRKind kind, AllocatableValue base1, AllocatableValue base2) {
|
||||
if (base1 == null && base2 == null) {
|
||||
return kind;
|
||||
} else if (base1 == null) {
|
||||
return kind.makeDerivedReference(base2);
|
||||
} else if (base2 == null) {
|
||||
return kind.makeDerivedReference(base1);
|
||||
} else {
|
||||
return kind.makeUnknownReference();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #merge(Value...)
|
||||
*/
|
||||
public static LIRKind merge(Iterable<LIRKind> kinds) {
|
||||
LIRKind mergeKind = null;
|
||||
|
||||
for (LIRKind kind : kinds) {
|
||||
|
||||
if (kind.isUnknownReference()) {
|
||||
/**
|
||||
* Kind is an unknown reference, therefore the result can only be also an unknown
|
||||
* reference.
|
||||
*/
|
||||
mergeKind = kind;
|
||||
break;
|
||||
}
|
||||
if (mergeKind == null) {
|
||||
mergeKind = kind;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kind.isValue()) {
|
||||
/* Kind is a value. */
|
||||
if (mergeKind.referenceMask != 0) {
|
||||
/*
|
||||
* Inputs consists of values and references. Make the result an unknown
|
||||
* reference.
|
||||
*/
|
||||
mergeKind = mergeKind.makeUnknownReference();
|
||||
break;
|
||||
}
|
||||
/* Check that other inputs are also values. */
|
||||
} else {
|
||||
/* Kind is a reference. */
|
||||
if (mergeKind.referenceMask != kind.referenceMask) {
|
||||
/*
|
||||
* Reference maps do not match so the result can only be an unknown reference.
|
||||
*/
|
||||
mergeKind = mergeKind.makeUnknownReference();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
assert mergeKind != null && verifyMerge(mergeKind, kinds);
|
||||
|
||||
// all inputs are values or references, just return one of them
|
||||
return mergeKind;
|
||||
}
|
||||
|
||||
private static boolean verifyMerge(LIRKind mergeKind, Iterable<LIRKind> kinds) {
|
||||
for (LIRKind kind : kinds) {
|
||||
assert mergeKind == null || verifyMoveKinds(mergeKind, kind) : String.format("Input kinds do not match %s vs. %s", mergeKind, kind);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link LIRKind} with the same reference information and a new
|
||||
* {@linkplain #getPlatformKind platform kind}. If the new kind is a longer vector than this,
|
||||
* the new elements are marked as untracked values.
|
||||
*/
|
||||
public LIRKind changeType(PlatformKind newPlatformKind) {
|
||||
if (newPlatformKind == platformKind) {
|
||||
return this;
|
||||
} else if (isUnknownReference()) {
|
||||
return unknownReference(newPlatformKind);
|
||||
} else if (referenceMask == 0) {
|
||||
// value type
|
||||
return LIRKind.value(newPlatformKind);
|
||||
} else {
|
||||
// reference type
|
||||
int newLength = Math.min(32, newPlatformKind.getVectorLength());
|
||||
int newReferenceMask = referenceMask & (0xFFFFFFFF >>> (32 - newLength));
|
||||
assert newReferenceMask != UNKNOWN_REFERENCE;
|
||||
return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link LIRKind} with a new {@linkplain #getPlatformKind platform kind}. If the
|
||||
* new kind is longer than this, the reference positions are repeated to fill the vector.
|
||||
*/
|
||||
public LIRKind repeat(PlatformKind newPlatformKind) {
|
||||
if (isUnknownReference()) {
|
||||
return unknownReference(newPlatformKind);
|
||||
} else if (referenceMask == 0) {
|
||||
// value type
|
||||
return LIRKind.value(newPlatformKind);
|
||||
} else {
|
||||
// reference type
|
||||
int oldLength = platformKind.getVectorLength();
|
||||
int newLength = newPlatformKind.getVectorLength();
|
||||
assert oldLength <= newLength && newLength < 32 && (newLength % oldLength) == 0;
|
||||
|
||||
// repeat reference mask to fill new kind
|
||||
int newReferenceMask = 0;
|
||||
for (int i = 0; i < newLength; i += platformKind.getVectorLength()) {
|
||||
newReferenceMask |= referenceMask << i;
|
||||
}
|
||||
|
||||
assert newReferenceMask != UNKNOWN_REFERENCE;
|
||||
return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link LIRKind} with the same type, but marked as containing an
|
||||
* {@link LIRKind#unknownReference}.
|
||||
*/
|
||||
public LIRKind makeUnknownReference() {
|
||||
return new LIRKind(platformKind, UNKNOWN_REFERENCE, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the low level type that is used in code generation.
|
||||
*/
|
||||
public PlatformKind getPlatformKind() {
|
||||
return platformKind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this value is a derived reference.
|
||||
*/
|
||||
public boolean isDerivedReference() {
|
||||
return getDerivedReferenceBase() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base value of a derived reference.
|
||||
*/
|
||||
public AllocatableValue getDerivedReferenceBase() {
|
||||
return derivedReferenceBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the base value of a derived reference. This must be called on derived references only.
|
||||
*/
|
||||
public void setDerivedReferenceBase(AllocatableValue derivedReferenceBase) {
|
||||
assert isDerivedReference();
|
||||
this.derivedReferenceBase = derivedReferenceBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this value is derived from a reference in a non-linear way. If this returns
|
||||
* {@code true}, this value must not be live at safepoints.
|
||||
*/
|
||||
public boolean isUnknownReference() {
|
||||
return referenceMask == UNKNOWN_REFERENCE;
|
||||
}
|
||||
|
||||
public int getReferenceCount() {
|
||||
assert !isUnknownReference();
|
||||
return Integer.bitCount(referenceMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the {@code idx}th part of this value is a reference that must be tracked at
|
||||
* safepoints.
|
||||
*
|
||||
* @param idx The index into the vector if this is a vector kind. Must be 0 if this is a scalar
|
||||
* kind.
|
||||
*/
|
||||
public boolean isReference(int idx) {
|
||||
assert 0 <= idx && idx < platformKind.getVectorLength() : "invalid index " + idx + " in " + this;
|
||||
return !isUnknownReference() && (referenceMask & 1 << idx) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this kind is a value type that doesn't need to be tracked at safepoints.
|
||||
*/
|
||||
public boolean isValue() {
|
||||
return referenceMask == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (isValue()) {
|
||||
return platformKind.name();
|
||||
} else if (isUnknownReference()) {
|
||||
return platformKind.name() + "[*]";
|
||||
} else {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
ret.append(platformKind.name());
|
||||
ret.append('[');
|
||||
for (int i = 0; i < platformKind.getVectorLength(); i++) {
|
||||
if (isReference(i)) {
|
||||
ret.append('.');
|
||||
} else {
|
||||
ret.append(' ');
|
||||
}
|
||||
}
|
||||
ret.append(']');
|
||||
return ret.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((platformKind == null) ? 0 : platformKind.hashCode());
|
||||
result = prime * result + referenceMask;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof LIRKind)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LIRKind other = (LIRKind) obj;
|
||||
return platformKind == other.platformKind && referenceMask == other.referenceMask;
|
||||
}
|
||||
|
||||
public static boolean verifyMoveKinds(LIRKind dst, LIRKind src) {
|
||||
if (src.equals(dst)) {
|
||||
return true;
|
||||
}
|
||||
if (src.getPlatformKind().equals(dst.getPlatformKind())) {
|
||||
return !src.isUnknownReference() || dst.isUnknownReference();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 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
|
||||
@ -33,7 +33,7 @@ public abstract class Value {
|
||||
|
||||
private static final class IllegalValue extends AllocatableValue {
|
||||
private IllegalValue() {
|
||||
super(LIRKind.Illegal);
|
||||
super(ValueKind.Illegal);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -49,15 +49,15 @@ public abstract class Value {
|
||||
}
|
||||
}
|
||||
|
||||
private final LIRKind lirKind;
|
||||
private final ValueKind<?> valueKind;
|
||||
|
||||
/**
|
||||
* Initializes a new value of the specified kind.
|
||||
*
|
||||
* @param lirKind the kind
|
||||
* @param valueKind the kind
|
||||
*/
|
||||
protected Value(LIRKind lirKind) {
|
||||
this.lirKind = lirKind;
|
||||
protected Value(ValueKind<?> valueKind) {
|
||||
this.valueKind = valueKind;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,27 +68,31 @@ public abstract class Value {
|
||||
return "|" + getPlatformKind().getTypeChar();
|
||||
}
|
||||
|
||||
public final LIRKind getLIRKind() {
|
||||
return lirKind;
|
||||
public final ValueKind<?> getValueKind() {
|
||||
return valueKind;
|
||||
}
|
||||
|
||||
public final <K extends ValueKind<K>> K getValueKind(Class<K> cls) {
|
||||
return cls.cast(valueKind);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the platform specific kind used to store this value.
|
||||
*/
|
||||
public final PlatformKind getPlatformKind() {
|
||||
return lirKind.getPlatformKind();
|
||||
return valueKind.getPlatformKind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 41 + lirKind.hashCode();
|
||||
return 41 + valueKind.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Value) {
|
||||
Value that = (Value) obj;
|
||||
return lirKind.equals(that.lirKind);
|
||||
return valueKind.equals(that.valueKind);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 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.meta;
|
||||
|
||||
/**
|
||||
* Represents the type of {@link Value values}. This class can be extended by compilers to track
|
||||
* additional information about values.
|
||||
*/
|
||||
public abstract class ValueKind<K extends ValueKind<K>> {
|
||||
|
||||
private enum IllegalKind implements PlatformKind {
|
||||
ILLEGAL;
|
||||
|
||||
private final EnumKey<IllegalKind> key = new EnumKey<>(this);
|
||||
|
||||
public Key getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public int getSizeInBytes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getVectorLength() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public char getTypeChar() {
|
||||
return '-';
|
||||
}
|
||||
}
|
||||
|
||||
private static class IllegalValueKind extends ValueKind<IllegalValueKind> {
|
||||
|
||||
IllegalValueKind() {
|
||||
super(IllegalKind.ILLEGAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IllegalValueKind changeType(PlatformKind newPlatformKind) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The non-type.
|
||||
*/
|
||||
public static final ValueKind<?> Illegal = new IllegalValueKind();
|
||||
|
||||
private final PlatformKind platformKind;
|
||||
|
||||
public ValueKind(PlatformKind platformKind) {
|
||||
this.platformKind = platformKind;
|
||||
}
|
||||
|
||||
public final PlatformKind getPlatformKind() {
|
||||
return platformKind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link ValueKind} with a different {@link PlatformKind}. Subclasses must
|
||||
* override this to preserve the additional information added by the compiler.
|
||||
*/
|
||||
public abstract K changeType(PlatformKind newPlatformKind);
|
||||
}
|
@ -219,9 +219,8 @@ narrowKlass CodeInstaller::record_narrow_metadata_reference(Handle constant, TRA
|
||||
#endif
|
||||
|
||||
Location::Type CodeInstaller::get_oop_type(Handle value) {
|
||||
Handle lirKind = Value::lirKind(value);
|
||||
Handle platformKind = LIRKind::platformKind(lirKind);
|
||||
assert(LIRKind::referenceMask(lirKind) == 1, "unexpected referenceMask");
|
||||
Handle valueKind = Value::valueKind(value);
|
||||
Handle platformKind = ValueKind::platformKind(valueKind);
|
||||
|
||||
if (platformKind == word_kind()) {
|
||||
return Location::oop;
|
||||
|
@ -230,12 +230,11 @@ class JVMCIJavaClasses : AllStatic {
|
||||
static_oop_field(JavaKind, Int, "Ljdk/vm/ci/meta/JavaKind;"); \
|
||||
static_oop_field(JavaKind, Long, "Ljdk/vm/ci/meta/JavaKind;"); \
|
||||
end_class \
|
||||
start_class(LIRKind) \
|
||||
oop_field(LIRKind, platformKind, "Ljdk/vm/ci/meta/PlatformKind;") \
|
||||
int_field(LIRKind, referenceMask) \
|
||||
start_class(ValueKind) \
|
||||
oop_field(ValueKind, platformKind, "Ljdk/vm/ci/meta/PlatformKind;") \
|
||||
end_class \
|
||||
start_class(Value) \
|
||||
oop_field(Value, lirKind, "Ljdk/vm/ci/meta/LIRKind;") \
|
||||
oop_field(Value, valueKind, "Ljdk/vm/ci/meta/ValueKind;") \
|
||||
static_oop_field(Value, ILLEGAL, "Ljdk/vm/ci/meta/AllocatableValue;"); \
|
||||
end_class \
|
||||
start_class(RegisterValue) \
|
||||
|
@ -83,7 +83,7 @@
|
||||
do_klass(NullConstant_klass, jdk_vm_ci_meta_NullConstant, Jvmci) \
|
||||
do_klass(ExceptionHandler_klass, jdk_vm_ci_meta_ExceptionHandler, Jvmci) \
|
||||
do_klass(JavaKind_klass, jdk_vm_ci_meta_JavaKind, Jvmci) \
|
||||
do_klass(LIRKind_klass, jdk_vm_ci_meta_LIRKind, Jvmci) \
|
||||
do_klass(ValueKind_klass, jdk_vm_ci_meta_ValueKind, Jvmci) \
|
||||
do_klass(Value_klass, jdk_vm_ci_meta_Value, Jvmci)
|
||||
#endif
|
||||
|
||||
|
@ -56,7 +56,7 @@
|
||||
template(jdk_vm_ci_meta_NullConstant, "jdk/vm/ci/meta/NullConstant") \
|
||||
template(jdk_vm_ci_meta_ExceptionHandler, "jdk/vm/ci/meta/ExceptionHandler") \
|
||||
template(jdk_vm_ci_meta_JavaKind, "jdk/vm/ci/meta/JavaKind") \
|
||||
template(jdk_vm_ci_meta_LIRKind, "jdk/vm/ci/meta/LIRKind") \
|
||||
template(jdk_vm_ci_meta_ValueKind, "jdk/vm/ci/meta/ValueKind") \
|
||||
template(jdk_vm_ci_meta_Value, "jdk/vm/ci/meta/Value") \
|
||||
template(jdk_vm_ci_meta_Assumptions_ConcreteSubtype, "jdk/vm/ci/meta/Assumptions$ConcreteSubtype") \
|
||||
template(jdk_vm_ci_meta_Assumptions_LeafType, "jdk/vm/ci/meta/Assumptions$LeafType") \
|
||||
|
@ -36,6 +36,7 @@
|
||||
|
||||
package compiler.jvmci.errors;
|
||||
|
||||
import jdk.vm.ci.code.Architecture;
|
||||
import jdk.vm.ci.code.BytecodeFrame;
|
||||
import jdk.vm.ci.code.DebugInfo;
|
||||
import jdk.vm.ci.code.Location;
|
||||
@ -53,9 +54,10 @@ import jdk.vm.ci.meta.Assumptions.Assumption;
|
||||
import jdk.vm.ci.meta.JavaConstant;
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.JavaValue;
|
||||
import jdk.vm.ci.meta.LIRKind;
|
||||
import jdk.vm.ci.meta.PlatformKind;
|
||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
import jdk.vm.ci.meta.Value;
|
||||
import jdk.vm.ci.meta.ValueKind;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
@ -67,6 +69,22 @@ public class TestInvalidDebugInfo extends CodeInstallerTest {
|
||||
private static class UnknownJavaValue implements JavaValue {
|
||||
}
|
||||
|
||||
private static class TestValueKind extends ValueKind<TestValueKind> {
|
||||
|
||||
TestValueKind(Architecture arch, JavaKind kind) {
|
||||
this(arch.getPlatformKind(kind));
|
||||
}
|
||||
|
||||
TestValueKind(PlatformKind kind) {
|
||||
super(kind);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestValueKind changeType(PlatformKind kind) {
|
||||
return new TestValueKind(kind);
|
||||
}
|
||||
}
|
||||
|
||||
private void test(JavaValue[] values, JavaKind[] slotKinds, int locals, int stack, int locks) {
|
||||
test(null, values, slotKinds, locals, stack, locks);
|
||||
}
|
||||
@ -146,7 +164,7 @@ public class TestInvalidDebugInfo extends CodeInstallerTest {
|
||||
|
||||
@Test(expected = JVMCIError.class)
|
||||
public void testUnexpectedTypeOnStack() {
|
||||
LIRKind kind = codeCache.getTarget().getLIRKind(JavaKind.Int);
|
||||
ValueKind<?> kind = new TestValueKind(codeCache.getTarget().arch, JavaKind.Int);
|
||||
StackSlot value = StackSlot.get(kind, 8, false);
|
||||
test(new JavaValue[]{value}, new JavaKind[]{JavaKind.Illegal}, 1, 0, 0);
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ public class SimpleDebugInfoTest extends DebugInfoTest {
|
||||
public void testRegInt() {
|
||||
DebugInfoCompiler compiler = (asm, values) -> {
|
||||
Register reg = asm.emitLoadInt(42);
|
||||
values[0] = reg.asValue(target.getLIRKind(JavaKind.Int));
|
||||
values[0] = reg.asValue(asm.getValueKind(JavaKind.Int));
|
||||
return null;
|
||||
};
|
||||
testIntOnStack(compiler);
|
||||
@ -131,7 +131,7 @@ public class SimpleDebugInfoTest extends DebugInfoTest {
|
||||
public void testRegFloat() {
|
||||
DebugInfoCompiler compiler = (asm, values) -> {
|
||||
Register reg = asm.emitLoadFloat(42.0f);
|
||||
values[0] = reg.asValue(target.getLIRKind(JavaKind.Float));
|
||||
values[0] = reg.asValue(asm.getValueKind(JavaKind.Float));
|
||||
return null;
|
||||
};
|
||||
testFloatOnStack(compiler);
|
||||
@ -181,7 +181,7 @@ public class SimpleDebugInfoTest extends DebugInfoTest {
|
||||
public void testRegLong() {
|
||||
DebugInfoCompiler compiler = (asm, values) -> {
|
||||
Register reg = asm.emitLoadLong(42);
|
||||
values[0] = reg.asValue(target.getLIRKind(JavaKind.Long));
|
||||
values[0] = reg.asValue(asm.getValueKind(JavaKind.Long));
|
||||
values[1] = Value.ILLEGAL;
|
||||
return null;
|
||||
};
|
||||
@ -234,7 +234,7 @@ public class SimpleDebugInfoTest extends DebugInfoTest {
|
||||
ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack());
|
||||
DebugInfoCompiler compiler = (asm, values) -> {
|
||||
Register reg = asm.emitLoadPointer((HotSpotConstant) constantReflection.asJavaClass(type));
|
||||
values[0] = reg.asValue(target.getLIRKind(JavaKind.Object));
|
||||
values[0] = reg.asValue(asm.getValueKind(JavaKind.Object));
|
||||
return null;
|
||||
};
|
||||
testObjectOnStack(compiler);
|
||||
|
@ -48,9 +48,10 @@ import jdk.vm.ci.hotspot.HotSpotConstant;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
||||
import jdk.vm.ci.meta.Assumptions.Assumption;
|
||||
import jdk.vm.ci.meta.InvokeTarget;
|
||||
import jdk.vm.ci.meta.LIRKind;
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.PlatformKind;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
import jdk.vm.ci.meta.ValueKind;
|
||||
import jdk.vm.ci.meta.VMConstant;
|
||||
|
||||
/**
|
||||
@ -173,7 +174,7 @@ public abstract class TestAssembler {
|
||||
*/
|
||||
public abstract void emitTrap(DebugInfo info);
|
||||
|
||||
public final LIRKind narrowOopKind;
|
||||
public final ValueKind<?> narrowOopKind;
|
||||
|
||||
protected final Buffer code;
|
||||
protected final Buffer data;
|
||||
@ -191,8 +192,20 @@ public abstract class TestAssembler {
|
||||
|
||||
private StackSlot deoptRescue;
|
||||
|
||||
private static class TestValueKind extends ValueKind<TestValueKind> {
|
||||
|
||||
TestValueKind(PlatformKind kind) {
|
||||
super(kind);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestValueKind changeType(PlatformKind kind) {
|
||||
return new TestValueKind(kind);
|
||||
}
|
||||
}
|
||||
|
||||
protected TestAssembler(CodeCacheProvider codeCache, int initialFrameSize, int stackAlignment, PlatformKind narrowOopKind, Register... registers) {
|
||||
this.narrowOopKind = LIRKind.reference(narrowOopKind);
|
||||
this.narrowOopKind = new TestValueKind(narrowOopKind);
|
||||
|
||||
this.code = new Buffer();
|
||||
this.data = new Buffer();
|
||||
@ -209,12 +222,16 @@ public abstract class TestAssembler {
|
||||
this.curStackSlot = initialFrameSize;
|
||||
}
|
||||
|
||||
public ValueKind<?> getValueKind(JavaKind kind) {
|
||||
return new TestValueKind(codeCache.getTarget().arch.getPlatformKind(kind));
|
||||
}
|
||||
|
||||
protected Register newRegister() {
|
||||
return registers[nextRegister++];
|
||||
}
|
||||
|
||||
protected StackSlot newStackSlot(LIRKind kind) {
|
||||
curStackSlot += kind.getPlatformKind().getSizeInBytes();
|
||||
protected StackSlot newStackSlot(PlatformKind kind) {
|
||||
curStackSlot += kind.getSizeInBytes();
|
||||
if (curStackSlot > frameSize) {
|
||||
int newFrameSize = curStackSlot;
|
||||
if (newFrameSize % stackAlignment != 0) {
|
||||
@ -223,7 +240,7 @@ public abstract class TestAssembler {
|
||||
emitGrowStack(newFrameSize - frameSize);
|
||||
frameSize = newFrameSize;
|
||||
}
|
||||
return StackSlot.get(kind, -curStackSlot, true);
|
||||
return StackSlot.get(new TestValueKind(kind), -curStackSlot, true);
|
||||
}
|
||||
|
||||
protected void setDeoptRescueSlot(StackSlot deoptRescue) {
|
||||
|
@ -136,7 +136,7 @@ public class VirtualObjectDebugInfoTest extends DebugInfoTest {
|
||||
} else if (template.arrayField[i] instanceof String) {
|
||||
String value = (String) template.arrayField[i];
|
||||
Register reg = asm.emitLoadPointer((HotSpotConstant) constantReflection.forString(value));
|
||||
arrayContent[i] = reg.asValue(target.getLIRKind(JavaKind.Object));
|
||||
arrayContent[i] = reg.asValue(asm.getValueKind(JavaKind.Object));
|
||||
} else {
|
||||
Assert.fail("unexpected value");
|
||||
}
|
||||
@ -159,7 +159,7 @@ public class VirtualObjectDebugInfoTest extends DebugInfoTest {
|
||||
break;
|
||||
case Float: // template.floatField
|
||||
Register fReg = asm.emitLoadFloat(template.floatField);
|
||||
retContent[i] = fReg.asValue(target.getLIRKind(JavaKind.Float));
|
||||
retContent[i] = fReg.asValue(asm.getValueKind(JavaKind.Float));
|
||||
break;
|
||||
case Object: // template.arrayField
|
||||
retContent[i] = array;
|
||||
|
@ -37,7 +37,6 @@ import jdk.vm.ci.hotspot.HotSpotConstant;
|
||||
import jdk.vm.ci.hotspot.HotSpotForeignCallTarget;
|
||||
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.LIRKind;
|
||||
import jdk.vm.ci.meta.VMConstant;
|
||||
|
||||
public class AMD64TestAssembler extends TestAssembler {
|
||||
@ -64,7 +63,7 @@ public class AMD64TestAssembler extends TestAssembler {
|
||||
emitFatNop();
|
||||
code.emitByte(0x50 | AMD64.rbp.encoding); // PUSH rbp
|
||||
emitMove(true, AMD64.rbp, AMD64.rsp); // MOV rbp, rsp
|
||||
setDeoptRescueSlot(newStackSlot(LIRKind.value(AMD64Kind.QWORD)));
|
||||
setDeoptRescueSlot(newStackSlot(AMD64Kind.QWORD));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -193,7 +192,7 @@ public class AMD64TestAssembler extends TestAssembler {
|
||||
|
||||
@Override
|
||||
public StackSlot emitIntToStack(Register a) {
|
||||
StackSlot ret = newStackSlot(LIRKind.value(AMD64Kind.DWORD));
|
||||
StackSlot ret = newStackSlot(AMD64Kind.DWORD);
|
||||
// MOV r/m32,r32
|
||||
emitModRMMemory(false, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
|
||||
return ret;
|
||||
@ -201,7 +200,7 @@ public class AMD64TestAssembler extends TestAssembler {
|
||||
|
||||
@Override
|
||||
public StackSlot emitLongToStack(Register a) {
|
||||
StackSlot ret = newStackSlot(LIRKind.value(AMD64Kind.QWORD));
|
||||
StackSlot ret = newStackSlot(AMD64Kind.QWORD);
|
||||
// MOV r/m64,r64
|
||||
emitModRMMemory(true, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
|
||||
return ret;
|
||||
@ -209,7 +208,7 @@ public class AMD64TestAssembler extends TestAssembler {
|
||||
|
||||
@Override
|
||||
public StackSlot emitFloatToStack(Register a) {
|
||||
StackSlot ret = newStackSlot(LIRKind.value(AMD64Kind.SINGLE));
|
||||
StackSlot ret = newStackSlot(AMD64Kind.SINGLE);
|
||||
emitREX(false, a.encoding, 0, 0);
|
||||
code.emitByte(0xF3);
|
||||
code.emitByte(0x0F);
|
||||
@ -221,7 +220,7 @@ public class AMD64TestAssembler extends TestAssembler {
|
||||
|
||||
@Override
|
||||
public StackSlot emitPointerToStack(Register a) {
|
||||
StackSlot ret = newStackSlot(LIRKind.reference(AMD64Kind.QWORD));
|
||||
StackSlot ret = newStackSlot(AMD64Kind.QWORD);
|
||||
// MOV r/m64,r64
|
||||
emitModRMMemory(true, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
|
||||
return ret;
|
||||
@ -229,7 +228,7 @@ public class AMD64TestAssembler extends TestAssembler {
|
||||
|
||||
@Override
|
||||
public StackSlot emitNarrowPointerToStack(Register a) {
|
||||
StackSlot ret = newStackSlot(LIRKind.reference(AMD64Kind.DWORD));
|
||||
StackSlot ret = newStackSlot(AMD64Kind.DWORD);
|
||||
// MOV r/m32,r32
|
||||
emitModRMMemory(false, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
|
||||
return ret;
|
||||
|
@ -37,7 +37,6 @@ import jdk.vm.ci.hotspot.HotSpotForeignCallTarget;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
||||
import jdk.vm.ci.hotspot.HotSpotVMConfig;
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.LIRKind;
|
||||
import jdk.vm.ci.meta.VMConstant;
|
||||
import jdk.vm.ci.sparc.SPARC;
|
||||
import jdk.vm.ci.sparc.SPARCKind;
|
||||
@ -70,7 +69,7 @@ public class SPARCTestAssembler extends TestAssembler {
|
||||
public void emitPrologue() {
|
||||
// SAVE sp, -128, sp
|
||||
emitOp3(0b10, SPARC.sp, 0b111100, SPARC.sp, -SPARC.REGISTER_SAFE_AREA_SIZE);
|
||||
setDeoptRescueSlot(newStackSlot(LIRKind.value(SPARCKind.XWORD)));
|
||||
setDeoptRescueSlot(newStackSlot(SPARCKind.XWORD));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -194,7 +193,7 @@ public class SPARCTestAssembler extends TestAssembler {
|
||||
|
||||
@Override
|
||||
public StackSlot emitIntToStack(Register a) {
|
||||
StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.WORD));
|
||||
StackSlot ret = newStackSlot(SPARCKind.WORD);
|
||||
// STW a, [fp+offset]
|
||||
emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
|
||||
return ret;
|
||||
@ -202,7 +201,7 @@ public class SPARCTestAssembler extends TestAssembler {
|
||||
|
||||
@Override
|
||||
public StackSlot emitLongToStack(Register a) {
|
||||
StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.XWORD));
|
||||
StackSlot ret = newStackSlot(SPARCKind.XWORD);
|
||||
// STX a, [fp+offset]
|
||||
emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
|
||||
return ret;
|
||||
@ -210,7 +209,7 @@ public class SPARCTestAssembler extends TestAssembler {
|
||||
|
||||
@Override
|
||||
public StackSlot emitFloatToStack(Register a) {
|
||||
StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.SINGLE));
|
||||
StackSlot ret = newStackSlot(SPARCKind.SINGLE);
|
||||
// STF a, [fp+offset]
|
||||
emitOp3(0b11, a, 0b100100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
|
||||
return ret;
|
||||
@ -218,7 +217,7 @@ public class SPARCTestAssembler extends TestAssembler {
|
||||
|
||||
@Override
|
||||
public StackSlot emitPointerToStack(Register a) {
|
||||
StackSlot ret = newStackSlot(LIRKind.reference(SPARCKind.XWORD));
|
||||
StackSlot ret = newStackSlot(SPARCKind.XWORD);
|
||||
// STX a, [fp+offset]
|
||||
emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
|
||||
return ret;
|
||||
@ -226,7 +225,7 @@ public class SPARCTestAssembler extends TestAssembler {
|
||||
|
||||
@Override
|
||||
public StackSlot emitNarrowPointerToStack(Register a) {
|
||||
StackSlot ret = newStackSlot(LIRKind.reference(SPARCKind.WORD));
|
||||
StackSlot ret = newStackSlot(SPARCKind.WORD);
|
||||
// STW a, [fp+offset]
|
||||
emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user