changeset 23396:9ed5b586018b

Replace LIRKind with abstract base class (JDK-8156942).
author Roland Schatz <roland.schatz@oracle.com>
date Fri, 13 May 2016 14:33:19 +0200
parents 19432ed40848
children a7b12c1ab514
files jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueKindFactory.java jvmci/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java jvmci/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java jvmci/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java jvmci/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java jvmci/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java jvmci/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AllocatableValue.java jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LIRKind.java jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Value.java jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ValueKind.java src/share/vm/jvmci/jvmciCodeInstaller.cpp src/share/vm/jvmci/jvmciJavaClasses.hpp src/share/vm/jvmci/systemDictionary_jvmci.hpp src/share/vm/jvmci/vmSymbols_jvmci.hpp
diffstat 21 files changed, 240 insertions(+), 583 deletions(-) [+]
line wrap: on
line diff
--- a/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java	Fri May 13 14:33:19 2016 +0200
@@ -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 @@
     /**
      * 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 @@
         }
 
         RegisterConfig registerConfig = codeCache.getRegisterConfig();
-        return registerConfig.getCallingConvention(type, retType, argTypes, codeCache.getTarget());
+        return registerConfig.getCallingConvention(type, retType, argTypes, valueKindFactory);
     }
 }
--- a/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java	Fri May 13 14:33:19 2016 +0200
@@ -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.
@@ -136,17 +135,17 @@
      * @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);
     }
 
     /**
--- a/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java	Fri May 13 14:33:19 2016 +0200
@@ -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.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
@@ -57,9 +58,9 @@
      * @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
--- a/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java	Fri May 13 14:33:19 2016 +0200
@@ -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
@@ -24,13 +24,13 @@
 
 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.
+ * {@link Register#asValue(ValueKind)} to retrieve the canonical {@link RegisterValue} instance for
+ * a given (register,kind) pair.
  */
 public final class RegisterValue extends AllocatableValue {
 
@@ -39,7 +39,7 @@
     /**
      * 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;
     }
--- a/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java	Fri May 13 14:33:19 2016 +0200
@@ -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 @@
      * @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 StackSlot asOutArg() {
         assert offset >= 0;
         if (addFrameSize) {
-            return get(getLIRKind(), offset, false);
+            return get(getValueKind(), offset, false);
         }
         return this;
     }
@@ -110,7 +110,7 @@
     public StackSlot asInArg() {
         assert offset >= 0;
         if (!addFrameSize) {
-            return get(getLIRKind(), offset, true);
+            return get(getValueKind(), offset, true);
         }
         return this;
     }
--- a/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java	Fri May 13 14:33:19 2016 +0200
@@ -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 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);
-        }
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueKindFactory.java	Fri May 13 14:33:19 2016 +0200
@@ -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);
+}
--- a/jvmci/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java	Fri May 13 14:33:19 2016 +0200
@@ -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 @@
     }
 
     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) {
--- a/jvmci/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java	Fri May 13 14:33:19 2016 +0200
@@ -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.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 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 @@
         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();
@@ -195,14 +196,14 @@
     }
 
     @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
@@ -225,7 +226,8 @@
         }
     }
 
-    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;
@@ -245,14 +247,14 @@
                 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:
@@ -260,14 +262,14 @@
             }
 
             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);
     }
 
--- a/jvmci/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java	Fri May 13 14:33:19 2016 +0200
@@ -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
@@ -119,7 +119,7 @@
     }
 
     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) {
--- a/jvmci/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Fri May 13 14:33:19 2016 +0200
@@ -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.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 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 @@
         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 @@
         callerSaved = callerSaveSet.toArray(new Register[callerSaveSet.size()]);
 
         allAllocatableAreCallerSaved = true;
-        attributesMap = RegisterAttributes.createMap(this, architecture.getRegisters());
+        attributesMap = RegisterAttributes.createMap(this, target.arch.getRegisters());
     }
 
     @Override
@@ -192,14 +193,14 @@
     }
 
     @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
@@ -222,7 +223,8 @@
         }
     }
 
-    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;
@@ -242,14 +244,14 @@
                 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:
@@ -257,14 +259,14 @@
             }
 
             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);
     }
 
--- a/jvmci/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java	Fri May 13 14:33:19 2016 +0200
@@ -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 @@
         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);
--- a/jvmci/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Fri May 13 14:33:19 2016 +0200
@@ -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.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 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 @@
         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);
         }
@@ -198,13 +199,13 @@
     }
 
     @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();
     }
@@ -229,7 +230,8 @@
         }
     }
 
-    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;
@@ -249,7 +251,7 @@
                 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:
@@ -260,13 +262,13 @@
                         }
                         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:
@@ -274,18 +276,18 @@
             }
 
             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) {
--- a/jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AllocatableValue.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AllocatableValue.java	Fri May 13 14:33:19 2016 +0200
@@ -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 static final AllocatableValue[] NONE = {};
 
-    public AllocatableValue(LIRKind lirKind) {
-        super(lirKind);
+    public AllocatableValue(ValueKind<?> kind) {
+        super(kind);
     }
 }
--- a/jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LIRKind.java	Fri May 13 11:49:57 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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;
-    }
-}
--- a/jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Value.java	Fri May 13 11:49:57 2016 +0200
+++ b/jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Value.java	Fri May 13 14:33:19 2016 +0200
@@ -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 @@
 
     private static final class IllegalValue extends AllocatableValue {
         private IllegalValue() {
-            super(LIRKind.Illegal);
+            super(ValueKind.Illegal);
         }
 
         @Override
@@ -49,15 +49,15 @@
         }
     }
 
-    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 @@
         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;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ValueKind.java	Fri May 13 14:33:19 2016 +0200
@@ -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 should
+     * override this to preserve the additional information added by the compiler.
+     */
+    public abstract K changeType(PlatformKind newPlatformKind);
+}
--- a/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Fri May 13 11:49:57 2016 +0200
+++ b/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Fri May 13 14:33:19 2016 +0200
@@ -201,9 +201,8 @@
 #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;
--- a/src/share/vm/jvmci/jvmciJavaClasses.hpp	Fri May 13 11:49:57 2016 +0200
+++ b/src/share/vm/jvmci/jvmciJavaClasses.hpp	Fri May 13 14:33:19 2016 +0200
@@ -226,12 +226,11 @@
     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)                                                                                                                                   \
--- a/src/share/vm/jvmci/systemDictionary_jvmci.hpp	Fri May 13 11:49:57 2016 +0200
+++ b/src/share/vm/jvmci/systemDictionary_jvmci.hpp	Fri May 13 14:33:19 2016 +0200
@@ -80,7 +80,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
 
--- a/src/share/vm/jvmci/vmSymbols_jvmci.hpp	Fri May 13 11:49:57 2016 +0200
+++ b/src/share/vm/jvmci/vmSymbols_jvmci.hpp	Fri May 13 14:33:19 2016 +0200
@@ -54,7 +54,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")                                  \