8156942: [JVMCI] replace LIRKind with abstract base class
authorrschatz
Wed, 18 May 2016 17:01:01 +0000
changeset 38692 54a84b7f3721
parent 38691 a2c52cff500d
child 38694 7be3816c7642
8156942: [JVMCI] replace LIRKind with abstract base class Reviewed-by: iveresov
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueKindFactory.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AllocatableValue.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LIRKind.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Value.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ValueKind.java
hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp
hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp
hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp
hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp
hotspot/test/compiler/jvmci/errors/TestInvalidDebugInfo.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestAssembler.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/amd64/AMD64TestAssembler.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/sparc/SPARCTestAssembler.java
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java	Wed May 18 17:01:01 2016 +0000
@@ -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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java	Wed May 18 17:01:01 2016 +0000
@@ -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 @@
      * @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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java	Wed May 18 17:01:01 2016 +0000
@@ -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
@@ -56,9 +57,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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java	Wed May 18 17:01:01 2016 +0000
@@ -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;
     }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java	Wed May 18 17:01:01 2016 +0000
@@ -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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java	Wed May 18 17:01:01 2016 +0000
@@ -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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueKindFactory.java	Wed May 18 17:01:01 2016 +0000
@@ -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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java	Wed May 18 17:01:01 2016 +0000
@@ -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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java	Wed May 18 17:01:01 2016 +0000
@@ -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();
@@ -200,14 +201,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
@@ -230,7 +231,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;
@@ -250,14 +252,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:
@@ -265,14 +267,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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java	Wed May 18 17:01:01 2016 +0000
@@ -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 @@
     }
 
     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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Wed May 18 17:01:01 2016 +0000
@@ -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
@@ -197,14 +198,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
@@ -227,7 +228,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;
@@ -247,14 +249,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:
@@ -262,14 +264,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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java	Wed May 18 17:01:01 2016 +0000
@@ -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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Wed May 18 17:01:01 2016 +0000
@@ -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);
         }
@@ -203,13 +204,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();
     }
@@ -234,7 +235,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;
@@ -254,7 +256,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:
@@ -265,13 +267,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:
@@ -279,18 +281,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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java	Wed May 18 17:01:01 2016 +0000
@@ -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 @@
 
 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 @@
 
     private final JavaKind javaKind;
 
-    public HotSpotSentinelConstant(LIRKind lirKind, JavaKind javaKind) {
-        super(lirKind);
+    public HotSpotSentinelConstant(ValueKind<?> valueKind, JavaKind javaKind) {
+        super(valueKind);
         this.javaKind = javaKind;
     }
 
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AllocatableValue.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AllocatableValue.java	Wed May 18 17:01:01 2016 +0000
@@ -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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LIRKind.java	Mon May 16 17:01:53 2016 +0300
+++ /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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Value.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Value.java	Wed May 18 17:01:01 2016 +0000
@@ -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/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ValueKind.java	Wed May 18 17:01:01 2016 +0000
@@ -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);
+}
--- a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Wed May 18 17:01:01 2016 +0000
@@ -219,9 +219,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/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp	Wed May 18 17:01:01 2016 +0000
@@ -230,12 +230,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/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp	Wed May 18 17:01:01 2016 +0000
@@ -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
 
--- a/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp	Wed May 18 17:01:01 2016 +0000
@@ -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")                   \
--- a/hotspot/test/compiler/jvmci/errors/TestInvalidDebugInfo.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/test/compiler/jvmci/errors/TestInvalidDebugInfo.java	Wed May 18 17:01:01 2016 +0000
@@ -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.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 @@
     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 @@
 
     @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);
     }
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java	Wed May 18 17:01:01 2016 +0000
@@ -82,7 +82,7 @@
     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 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 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 @@
         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);
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestAssembler.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestAssembler.java	Wed May 18 17:01:01 2016 +0000
@@ -48,9 +48,10 @@
 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 void emitTrap(DebugInfo info);
 
-    public final LIRKind narrowOopKind;
+    public final ValueKind<?> narrowOopKind;
 
     protected final Buffer code;
     protected final Buffer data;
@@ -191,8 +192,20 @@
 
     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 @@
         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 @@
             emitGrowStack(newFrameSize - frameSize);
             frameSize = newFrameSize;
         }
-        return StackSlot.get(kind, -curStackSlot, true);
+        return StackSlot.get(new TestValueKind(kind), -curStackSlot, true);
     }
 
     protected void setDeoptRescueSlot(StackSlot deoptRescue) {
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java	Wed May 18 17:01:01 2016 +0000
@@ -136,7 +136,7 @@
             } 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 @@
                     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;
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/amd64/AMD64TestAssembler.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/amd64/AMD64TestAssembler.java	Wed May 18 17:01:01 2016 +0000
@@ -37,7 +37,6 @@
 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 @@
         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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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;
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/sparc/SPARCTestAssembler.java	Mon May 16 17:01:53 2016 +0300
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/sparc/SPARCTestAssembler.java	Wed May 18 17:01:01 2016 +0000
@@ -37,7 +37,6 @@
 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 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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
 
     @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;