changeset 21733:27943aac2e3c

Merge
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Thu, 04 Jun 2015 11:08:12 -0700
parents bc2ec35a7189 (diff) 009842dce4f0 (current diff)
children c2e90b2b3fcc
files graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/BitOpsTest.java graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/IncrementDecrementMacroTest.java graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64AsmOptions.java graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCInstructionCounter.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java graal/com.oracle.graal.asm/overview.html graal/com.oracle.graal.asm/src/com/oracle/graal/asm/AsmOptions.java graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java graal/com.oracle.graal.asm/src/com/oracle/graal/asm/NumUtil.java graal/com.oracle.graal.bytecode/overview.html graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeLookupSwitch.java graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeStream.java graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeSwitch.java graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeTableSwitch.java graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/Bytecodes.java graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/Bytes.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/jvmci/AMD64HotSpotJVMCIBackendFactory.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/jvmci/SPARCHotSpotJVMCIBackendFactory.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetDescription.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/ConstantTest.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/FieldUniverse.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/MethodUniverse.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/NameAndSignature.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/ResolvedJavaTypeResolveConcreteMethodTest.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/ResolvedJavaTypeResolveMethodTest.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestConstantReflectionProvider.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestJavaField.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestJavaMethod.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestJavaType.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestMetaAccessProvider.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestResolvedJavaField.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestResolvedJavaMethod.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestResolvedJavaType.java graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TypeUniverse.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTest.java graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/DisassemblerProvider.java graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HexCodeFile.java graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotTargetDescription.java graal/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ExcludeFromIdentityComparisonVerification.java graal/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/Value.java graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/SourceTest.java
diffstat 18 files changed, 410 insertions(+), 739 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Thu Jun 04 17:04:21 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Thu Jun 04 11:08:12 2015 -0700
@@ -64,8 +64,6 @@
     public static final class LabelOp extends LIRInstruction {
         public static final LIRInstructionClass<LabelOp> TYPE = LIRInstructionClass.create(LabelOp.class);
 
-        private static final Value[] NO_VALUES = new Value[0];
-
         /**
          * In the LIR, every register and variable must be defined before it is used. For method
          * parameters that are passed in fixed registers, exception objects passed to the exception
@@ -83,7 +81,7 @@
             super(TYPE);
             this.label = label;
             this.align = align;
-            this.incomingValues = NO_VALUES;
+            this.incomingValues = Value.NO_VALUES;
         }
 
         public void setIncomingValues(Value[] values) {
@@ -101,7 +99,7 @@
         }
 
         public void clearIncomingValues() {
-            incomingValues = NO_VALUES;
+            incomingValues = Value.NO_VALUES;
         }
 
         @Override
@@ -130,8 +128,6 @@
     public static class JumpOp extends LIRInstruction implements BlockEndOp {
         public static final LIRInstructionClass<JumpOp> TYPE = LIRInstructionClass.create(JumpOp.class);
 
-        private static final Value[] NO_VALUES = new Value[0];
-
         @Alive({REG, STACK, CONST}) private Value[] outgoingValues;
 
         private final LabelRef destination;
@@ -143,7 +139,7 @@
         protected JumpOp(LIRInstructionClass<? extends JumpOp> c, LabelRef destination) {
             super(c);
             this.destination = destination;
-            this.outgoingValues = NO_VALUES;
+            this.outgoingValues = Value.NO_VALUES;
         }
 
         public void setOutgoingValues(Value[] values) {
@@ -161,7 +157,7 @@
         }
 
         public void clearOutgoingValues() {
-            outgoingValues = NO_VALUES;
+            outgoingValues = Value.NO_VALUES;
         }
 
         @Override
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java	Thu Jun 04 17:04:21 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java	Thu Jun 04 11:08:12 2015 -0700
@@ -25,6 +25,7 @@
 import static com.oracle.jvmci.code.ValueUtil.*;
 
 import java.util.*;
+import java.util.function.*;
 
 import com.oracle.graal.compiler.common.alloc.*;
 import com.oracle.graal.compiler.common.cfg.*;
@@ -104,51 +105,203 @@
         }
     }
 
-    private static final class LiveValueSet implements Iterable<Value> {
-        private static final Object MARKER = new Object();
+    private static final class ValueSet {
+        private Value[] values;
 
-        private final HashMap<Value, Object> map;
-
-        public LiveValueSet() {
-            map = new HashMap<>();
+        ValueSet() {
+            values = Value.NO_VALUES;
         }
 
-        public LiveValueSet(LiveValueSet s) {
-            map = new HashMap<>(s.map);
+        ValueSet(ValueSet other) {
+            int limit = other.values.length;
+            while (limit > 0) {
+                if (other.values[limit - 1] == null) {
+                    limit--;
+                    continue;
+                }
+                break;
+            }
+            values = new Value[limit];
+            System.arraycopy(other.values, 0, values, 0, values.length);
         }
 
-        public void put(Value v) {
-            map.put(v, MARKER);
+        void put(int index, Value value) {
+            if (value != null && value.getLIRKind().isValue()) {
+                return;
+            }
+            if (values.length <= index) {
+                if (value == null) {
+                    return;
+                }
+                Value[] newValues = new Value[index + 1];
+                System.arraycopy(values, 0, newValues, 0, values.length);
+                values = newValues;
+                values[index] = value;
+            } else {
+                values[index] = value;
+            }
         }
 
-        public void putAll(LiveValueSet v) {
-            map.putAll(v.map);
-        }
-
-        public void remove(Value v) {
-            map.remove(v);
-        }
-
-        public Iterator<Value> iterator() {
-            return map.keySet().iterator();
+        public void putAll(ValueSet stack) {
+            Value[] otherValues = stack.values;
+            int limit = otherValues.length;
+            if (limit > values.length) {
+                while (limit > 0) {
+                    if (otherValues[limit - 1] == null) {
+                        limit--;
+                        continue;
+                    }
+                    break;
+                }
+                if (limit > values.length) {
+                    Value[] newValues = new Value[limit];
+                    System.arraycopy(values, 0, newValues, 0, values.length);
+                    values = newValues;
+                }
+            }
+            for (int i = 0; i < limit; i++) {
+                Value value = otherValues[i];
+                if (value != null) {
+                    values[i] = value;
+                }
+            }
         }
 
         @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof LiveValueSet) {
-                return map.equals(((LiveValueSet) obj).map);
-            } else {
-                return false;
+        public boolean equals(Object other) {
+            if (other instanceof ValueSet) {
+                ValueSet that = (ValueSet) other;
+                int limit = Math.min(values.length, that.values.length);
+                for (int i = 0; i < limit; i++) {
+                    if (!Objects.equals(values[i], that.values[i])) {
+                        return false;
+                    }
+                }
+                for (int i = limit; i < values.length; i++) {
+                    if (values[i] != null) {
+                        return false;
+                    }
+                }
+                for (int i = limit; i < that.values.length; i++) {
+                    if (that.values[i] != null) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+            return false;
+        }
+
+        public void addLiveValues(ReferenceMap refMap) {
+            for (Value v : values) {
+                if (v != null) {
+                    refMap.addLiveValue(v);
+                }
             }
         }
 
         @Override
         public int hashCode() {
-            return map.hashCode();
+            throw new UnsupportedOperationException();
         }
     }
 
     private static final class Marker<T extends AbstractBlockBase<T>> {
+
+        private final class LiveValueSet implements Consumer<AbstractBlockBase<T>> {
+
+            public void accept(AbstractBlockBase<T> succ) {
+                putAll(liveInMap.get(succ));
+            }
+
+            private final ValueSet registers;
+            private final ValueSet stack;
+            private Set<Value> extraStack;
+
+            public LiveValueSet() {
+                registers = new ValueSet();
+                stack = new ValueSet();
+            }
+
+            public LiveValueSet(LiveValueSet s) {
+                registers = new ValueSet(s.registers);
+                stack = new ValueSet(s.stack);
+                if (s.extraStack != null) {
+                    extraStack = new HashSet<>(s.extraStack);
+                }
+            }
+
+            public void put(Value v) {
+                if (isRegister(v)) {
+                    int index = asRegister(v).getReferenceMapIndex();
+                    registers.put(index, v);
+                } else if (isStackSlot(v)) {
+                    int index = frameMap.offsetForStackSlot(asStackSlot(v));
+                    assert index >= 0;
+                    if (index % 4 == 0) {
+                        stack.put(index / 4, v);
+                    } else {
+                        if (extraStack == null) {
+                            extraStack = new HashSet<>();
+                        }
+                        extraStack.add(v);
+                    }
+                }
+            }
+
+            public void putAll(LiveValueSet v) {
+                registers.putAll(v.registers);
+                stack.putAll(v.stack);
+                if (v.extraStack != null) {
+                    if (extraStack == null) {
+                        extraStack = new HashSet<>();
+                    }
+                    extraStack.addAll(v.extraStack);
+                }
+            }
+
+            public void remove(Value v) {
+                if (isRegister(v)) {
+                    int index = asRegister(v).getReferenceMapIndex();
+                    registers.put(index, null);
+                } else if (isStackSlot(v)) {
+                    int index = frameMap.offsetForStackSlot(asStackSlot(v));
+                    assert index >= 0;
+                    if (index % 4 == 0) {
+                        stack.put(index / 4, null);
+                    } else {
+                        extraStack.remove(v);
+                    }
+                }
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override
+            public boolean equals(Object obj) {
+                if (obj instanceof Marker.LiveValueSet) {
+                    LiveValueSet other = (LiveValueSet) obj;
+                    return registers.equals(other.registers) && stack.equals(other.stack) && Objects.equals(extraStack, other.extraStack);
+                } else {
+                    return false;
+                }
+            }
+
+            @Override
+            public int hashCode() {
+                throw new UnsupportedOperationException();
+            }
+
+            public void addLiveValues(ReferenceMap refMap) {
+                registers.addLiveValues(refMap);
+                stack.addLiveValues(refMap);
+                if (extraStack != null) {
+                    for (Value v : extraStack) {
+                        refMap.addLiveValue(v);
+                    }
+                }
+            }
+        }
+
         private final LIR lir;
         private final FrameMap frameMap;
         private final RegisterAttributes[] registerAttributes;
@@ -181,9 +334,9 @@
         /**
          * Merge outSet with in-set of successors.
          */
-        private boolean updateOutBlock(AbstractBlockBase<?> block) {
+        private boolean updateOutBlock(AbstractBlockBase<T> block) {
             LiveValueSet union = new LiveValueSet();
-            block.getSuccessors().forEach(succ -> union.putAll(liveInMap.get(succ)));
+            block.getSuccessors().forEach(union);
             LiveValueSet outSet = liveOutMap.get(block);
             // check if changed
             if (outSet == null || !union.equals(outSet)) {
@@ -196,13 +349,14 @@
         private void processBlock(AbstractBlockBase<T> block, UniqueWorkList<T> worklist) {
             if (updateOutBlock(block)) {
                 try (Indent indent = Debug.logAndIndent("handle block %s", block)) {
-                    BlockClosure closure = new BlockClosure(new LiveValueSet(liveOutMap.get(block)));
+                    currentSet = new LiveValueSet(liveOutMap.get(block));
                     List<LIRInstruction> instructions = lir.getLIRforBlock(block);
                     for (int i = instructions.size() - 1; i >= 0; i--) {
                         LIRInstruction inst = instructions.get(i);
-                        closure.processInstructionBottomUp(inst);
+                        processInstructionBottomUp(inst);
                     }
-                    liveInMap.put(block, closure.getCurrentSet());
+                    liveInMap.put(block, currentSet);
+                    currentSet = null;
                     worklist.addAll(block.getPredecessors());
                 }
             }
@@ -211,78 +365,68 @@
         private static final EnumSet<OperandFlag> REGISTER_FLAG_SET = EnumSet.of(OperandFlag.REG);
         private static final LIRKind REFERENCE_KIND = LIRKind.reference(Kind.Object);
 
-        private final class BlockClosure {
-            private final LiveValueSet currentSet;
+        private LiveValueSet currentSet;
 
-            private BlockClosure(LiveValueSet set) {
-                currentSet = set;
-            }
+        /**
+         * Process all values of an instruction bottom-up, i.e. definitions before usages. Values
+         * that start or end at the current operation are not included.
+         */
+        private void processInstructionBottomUp(LIRInstruction op) {
+            try (Indent indent = Debug.logAndIndent("handle op %d, %s", op.id(), op)) {
+                // kills
 
-            private LiveValueSet getCurrentSet() {
-                return currentSet;
-            }
+                op.visitEachTemp(defConsumer);
+                op.visitEachOutput(defConsumer);
+                if (op.destroysCallerSavedRegisters()) {
+                    for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) {
+                        defConsumer.visitValue(reg.asValue(REFERENCE_KIND), OperandMode.TEMP, REGISTER_FLAG_SET);
+                    }
+                }
 
-            /**
-             * Process all values of an instruction bottom-up, i.e. definitions before usages.
-             * Values that start or end at the current operation are not included.
-             */
-            private void processInstructionBottomUp(LIRInstruction op) {
-                try (Indent indent = Debug.logAndIndent("handle op %d, %s", op.id(), op)) {
-                    // kills
+                // gen - values that are considered alive for this state
+                op.visitEachAlive(useConsumer);
+                op.visitEachState(useConsumer);
+                // mark locations
+                op.forEachState(stateConsumer);
+                // gen
+                op.visitEachInput(useConsumer);
+            }
+        }
 
-                    op.visitEachTemp(defConsumer);
-                    op.visitEachOutput(defConsumer);
-                    if (op.destroysCallerSavedRegisters()) {
-                        for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) {
-                            defConsumer.visitValue(reg.asValue(REFERENCE_KIND), OperandMode.TEMP, REGISTER_FLAG_SET);
-                        }
-                    }
+        InstructionStateProcedure stateConsumer = new InstructionStateProcedure() {
+            public void doState(LIRInstruction inst, LIRFrameState info) {
+                markLocation(inst, info, currentSet);
+            }
+        };
 
-                    // gen - values that are considered alive for this state
-                    op.visitEachAlive(useConsumer);
-                    op.visitEachState(useConsumer);
-                    // mark locations
-                    op.forEachState(stateConsumer);
-                    // gen
-                    op.visitEachInput(useConsumer);
+        ValueConsumer useConsumer = new ValueConsumer() {
+            public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                if (shouldProcessValue(operand)) {
+                    // no need to insert values and derived reference
+                    if (Debug.isLogEnabled()) {
+                        Debug.log("set operand: %s", operand);
+                    }
+                    currentSet.put(operand);
                 }
             }
-
-            InstructionStateProcedure stateConsumer = new InstructionStateProcedure() {
-                public void doState(LIRInstruction inst, LIRFrameState info) {
-                    markLocation(inst, info, getCurrentSet());
-                }
-            };
+        };
 
-            ValueConsumer useConsumer = new ValueConsumer() {
-                public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
-                    if (shouldProcessValue(operand)) {
-                        // no need to insert values and derived reference
-                        if (Debug.isLogEnabled()) {
-                            Debug.log("set operand: %s", operand);
-                        }
-                        currentSet.put(operand);
+        ValueConsumer defConsumer = new ValueConsumer() {
+            public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                if (shouldProcessValue(operand)) {
+                    if (Debug.isLogEnabled()) {
+                        Debug.log("clear operand: %s", operand);
                     }
+                    currentSet.remove(operand);
+                } else {
+                    assert isIllegal(operand) || operand.getPlatformKind() != Kind.Illegal || mode == OperandMode.TEMP : String.format("Illegal PlatformKind is only allowed for TEMP mode: %s, %s",
+                                    operand, mode);
                 }
-            };
+            }
+        };
 
-            ValueConsumer defConsumer = new ValueConsumer() {
-                public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
-                    if (shouldProcessValue(operand)) {
-                        if (Debug.isLogEnabled()) {
-                            Debug.log("clear operand: %s", operand);
-                        }
-                        currentSet.remove(operand);
-                    } else {
-                        assert isIllegal(operand) || operand.getPlatformKind() != Kind.Illegal || mode == OperandMode.TEMP : String.format(
-                                        "Illegal PlatformKind is only allowed for TEMP mode: %s, %s", operand, mode);
-                    }
-                }
-            };
-
-            protected boolean shouldProcessValue(Value operand) {
-                return (isRegister(operand) && attributes(asRegister(operand)).isAllocatable() || isStackSlot(operand)) && operand.getPlatformKind() != Kind.Illegal;
-            }
+        protected boolean shouldProcessValue(Value operand) {
+            return (isRegister(operand) && attributes(asRegister(operand)).isAllocatable() || isStackSlot(operand)) && operand.getPlatformKind() != Kind.Illegal;
         }
 
         /**
@@ -294,9 +438,10 @@
             }
 
             ReferenceMap refMap = info.debugInfo().getReferenceMap();
-            for (Value v : values) {
-                frameMap.setReference(v, refMap);
-            }
+            refMap.reset();
+            frameMap.addLiveValues(refMap);
+            values.addLiveValues(refMap);
+            refMap.finish();
         }
 
         /**
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java	Thu Jun 04 17:04:21 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java	Thu Jun 04 11:08:12 2015 -0700
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.lir.framemap;
 
-import static com.oracle.jvmci.code.ValueUtil.*;
-
 import java.util.*;
 
 import com.oracle.graal.asm.*;
@@ -103,6 +101,12 @@
         return target;
     }
 
+    public void addLiveValues(ReferenceMap refMap) {
+        for (Value value : objectStackSlots) {
+            refMap.addLiveValue(value);
+        }
+    }
+
     protected int returnAddressSize() {
         return getTarget().arch.getReturnAddressSize();
     }
@@ -322,29 +326,6 @@
 
     public ReferenceMap initReferenceMap(boolean hasRegisters) {
         ReferenceMap refMap = getTarget().createReferenceMap(hasRegisters, frameSize() / getTarget().wordSize);
-        for (StackSlot slot : objectStackSlots) {
-            setReference(slot, refMap);
-        }
         return refMap;
     }
-
-    /**
-     * Marks the specified location as a reference in the reference map of the debug information.
-     * The tracked location can be a {@link RegisterValue} or a {@link StackSlot}. Note that a
-     * {@link JavaConstant} is automatically tracked.
-     *
-     * @param location The location to be added to the reference map.
-     * @param refMap A reference map, as created by {@link #initReferenceMap(boolean)}.
-     */
-    public void setReference(Value location, ReferenceMap refMap) {
-        LIRKind kind = location.getLIRKind();
-        if (isRegister(location)) {
-            refMap.setRegister(asRegister(location).getReferenceMapIndex(), kind);
-        } else if (isStackSlot(location)) {
-            int offset = offsetForStackSlot(asStackSlot(location));
-            refMap.setStackSlot(offset, kind);
-        } else {
-            assert isConstant(location);
-        }
-    }
 }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Thu Jun 04 17:04:21 2015 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Thu Jun 04 11:08:12 2015 -0700
@@ -459,9 +459,9 @@
                 inst.forEachState(state -> {
                     if (state.hasDebugInfo()) {
                         DebugInfo di = state.debugInfo();
-                        stateString.append(debugInfoToString(di.getBytecodePosition(), di.getReferenceMap(), di.getCalleeSaveInfo(), target.arch));
+                        stateString.append(debugInfoToString(di.getBytecodePosition(), di.getReferenceMap(), di.getCalleeSaveInfo()));
                     } else {
-                        stateString.append(debugInfoToString(state.topFrame, null, null, target.arch));
+                        stateString.append(debugInfoToString(state.topFrame, null, null));
                     }
                 });
                 if (stateString.length() > 0) {
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java	Thu Jun 04 17:04:21 2015 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java	Thu Jun 04 11:08:12 2015 -0700
@@ -22,22 +22,12 @@
  */
 package com.oracle.graal.printer;
 
-import com.oracle.jvmci.code.Architecture;
-import com.oracle.jvmci.code.VirtualObject;
-import com.oracle.jvmci.code.BytecodePosition;
-import com.oracle.jvmci.code.BytecodeFrame;
-import com.oracle.jvmci.code.Register;
-import com.oracle.jvmci.code.CodeUtil;
-import com.oracle.jvmci.code.RegisterSaveLayout;
-import com.oracle.jvmci.code.ReferenceMap;
-import com.oracle.jvmci.meta.MetaUtil;
-import com.oracle.jvmci.meta.Value;
-import com.oracle.jvmci.meta.JavaMethod;
 import java.io.*;
 import java.util.*;
 
-import com.oracle.jvmci.code.CodeUtil.RefMapFormatter;
+import com.oracle.jvmci.code.*;
 import com.oracle.jvmci.debug.*;
+import com.oracle.jvmci.meta.*;
 
 /**
  * Utility for printing compilation related data structures at various compilation phases. The
@@ -122,19 +112,10 @@
     /**
      * Formats given debug info as a multi line string.
      */
-    protected String debugInfoToString(BytecodePosition codePos, ReferenceMap refMap, RegisterSaveLayout calleeSaveInfo, Architecture arch) {
+    protected String debugInfoToString(BytecodePosition codePos, ReferenceMap refMap, RegisterSaveLayout calleeSaveInfo) {
         StringBuilder sb = new StringBuilder();
-        RefMapFormatter formatter = new CodeUtil.NumberedRefMapFormatter();
-
-        if (refMap != null && refMap.hasRegisterRefMap()) {
-            sb.append("reg-ref-map:");
-            refMap.appendRegisterMap(sb, arch != null ? new CodeUtil.DefaultRegFormatter(arch) : formatter);
-            sb.append("\n");
-        }
-
-        if (refMap != null && refMap.hasFrameRefMap()) {
-            sb.append("frame-ref-map:");
-            refMap.appendFrameMap(sb, formatter);
+        if (refMap != null) {
+            sb.append(refMap.toString());
             sb.append("\n");
         }
 
--- a/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CodeUtil.java	Thu Jun 04 17:04:21 2015 +0200
+++ b/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CodeUtil.java	Thu Jun 04 11:08:12 2015 -0700
@@ -429,15 +429,8 @@
         }
         String nl = NEW_LINE;
         ReferenceMap refMap = info.getReferenceMap();
-        if (refMap != null && refMap.hasRegisterRefMap()) {
-            sb.append("  reg-ref-map:");
-            refMap.appendRegisterMap(sb, formatter);
-            sb.append(nl);
-        }
-        if (refMap != null && refMap.hasFrameRefMap()) {
-            sb.append("frame-ref-map:");
-            refMap.appendFrameMap(sb, formatter);
-            sb.append(nl);
+        if (refMap != null) {
+            sb.append(refMap.toString());
         }
         RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo();
         if (calleeSaveInfo != null) {
--- a/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CompilationResult.java	Thu Jun 04 17:04:21 2015 +0200
+++ b/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CompilationResult.java	Thu Jun 04 11:08:12 2015 -0700
@@ -27,7 +27,6 @@
 
 import java.util.*;
 
-import com.oracle.jvmci.code.CodeUtil.RefMapFormatter;
 import com.oracle.jvmci.meta.Assumptions.Assumption;
 import com.oracle.jvmci.meta.*;
 
@@ -858,17 +857,8 @@
         if (info != null) {
             ReferenceMap refMap = info.getReferenceMap();
             if (refMap != null) {
-                RefMapFormatter formatter = new CodeUtil.NumberedRefMapFormatter();
-                if (refMap.hasFrameRefMap()) {
-                    sb.append(" stackMap[");
-                    refMap.appendFrameMap(sb, formatter);
-                    sb.append(']');
-                }
-                if (refMap.hasRegisterRefMap()) {
-                    sb.append(" registerMap[");
-                    refMap.appendRegisterMap(sb, formatter);
-                    sb.append(']');
-                }
+                sb.append(refMap.toString());
+                sb.append(']');
             }
             RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo();
             if (calleeSaveInfo != null) {
--- a/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/ReferenceMap.java	Thu Jun 04 17:04:21 2015 +0200
+++ b/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/ReferenceMap.java	Thu Jun 04 11:08:12 2015 -0700
@@ -22,20 +22,24 @@
  */
 package com.oracle.jvmci.code;
 
-import com.oracle.jvmci.meta.LIRKind;
-import com.oracle.jvmci.code.CodeUtil.RefMapFormatter;
+import com.oracle.jvmci.meta.*;
+
+public abstract class ReferenceMap {
 
-public abstract class ReferenceMap implements Cloneable {
-
-    public abstract void setRegister(int idx, LIRKind kind);
-
-    public abstract void setStackSlot(int offset, LIRKind kind);
+    /**
+     * Empty out the reference map.
+     */
+    public abstract void reset();
 
-    public abstract boolean hasRegisterRefMap();
-
-    public abstract boolean hasFrameRefMap();
+    /**
+     * Add {@code value} to the current set of reference values.
+     *
+     * @param v
+     */
+    public abstract void addLiveValue(Value v);
 
-    public abstract void appendRegisterMap(StringBuilder sb, RefMapFormatter formatterArg);
-
-    public abstract void appendFrameMap(StringBuilder sb, RefMapFormatter formatterArg);
+    /**
+     * Perform any final encoding needed before use.
+     */
+    public abstract void finish();
 }
--- a/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotReferenceMap.java	Thu Jun 04 17:04:21 2015 +0200
+++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotReferenceMap.java	Thu Jun 04 11:08:12 2015 -0700
@@ -22,351 +22,60 @@
  */
 package com.oracle.jvmci.hotspot;
 
+import static com.oracle.jvmci.code.ValueUtil.*;
+
 import java.util.*;
 
-import com.oracle.jvmci.code.CodeUtil.RefMapFormatter;
 import com.oracle.jvmci.code.*;
-import com.oracle.jvmci.common.*;
 import com.oracle.jvmci.meta.*;
 
 public final class HotSpotReferenceMap extends ReferenceMap {
 
-    static final int OOP64 = 0b1010;
-    static final int OOP32 = 0b01;
-    static final int NARROW_LOW = OOP32;
-    static final int NARROW_HIGH = OOP32 << 2;
-    static final int NARROW_BOTH = NARROW_LOW | NARROW_HIGH;
+    private Value[] objects;
+    private int[] bytesPerElement;
+    private int maxRegisterSize;
+    private ArrayList<Value> objectValues;
 
-    private enum MapEntry {
-        NoReference(0),
-        WideOop(OOP64),
-        NarrowOopLowerHalf(NARROW_LOW),
-        NarrowOopUpperHalf(NARROW_HIGH),
-        TwoNarrowOops(NARROW_BOTH),
-        Illegal(-1);
+    private final TargetDescription target;
 
-        MapEntry(int pattern) {
-            this.pattern = pattern;
-        }
-
-        final int pattern;
+    public HotSpotReferenceMap(TargetDescription target) {
+        this.target = target;
+        this.objects = Value.NO_VALUES;
+    }
 
-        /**
-         * Create enum values from OopMap.
-         * <p>
-         * These bits can have the following values (MSB first):
-         *
-         * <pre>
-         * 0000 - contains no references
-         * 1010 - contains a wide oop
-         * 0001 - contains a narrow oop in the lower half
-         * 0101 - contains a narrow oop in the upper half
-         * 0101 - contains two narrow oops
-         * </pre>
-         *
-         * @see HotSpotReferenceMap#registerRefMap
-         * @see HotSpotReferenceMap#frameRefMap
-         */
-        static MapEntry getFromBits(int idx, HotSpotOopMap set) {
-            int n = set.get(idx);
-            switch (n) {
-                case 0:
-                    return NoReference;
-                case OOP64:
-                    return WideOop;
-                case NARROW_LOW:
-                    return NarrowOopLowerHalf;
-                case NARROW_HIGH:
-                    return NarrowOopUpperHalf;
-                case NARROW_BOTH:
-                    return TwoNarrowOops;
-                default:
-                    return Illegal;
+    @Override
+    public void reset() {
+        objectValues = new ArrayList<>();
+        objects = Value.NO_VALUES;
+        bytesPerElement = null;
+        maxRegisterSize = 0;
+    }
+
+    @Override
+    public void addLiveValue(Value v) {
+        if (isConstant(v)) {
+            return;
+        }
+        LIRKind lirKind = v.getLIRKind();
+        if (!lirKind.isValue()) {
+            objectValues.add(v);
+        }
+        if (isRegister(v)) {
+            int size = target.getSizeInBytes(lirKind.getPlatformKind());
+            if (size > maxRegisterSize) {
+                maxRegisterSize = size;
             }
         }
-
-        String toBitString() {
-            int bits = toBit(this);
-            if (bits == -1) {
-                return "---";
-            }
-            return String.format("%3s", Integer.toBinaryString(bits)).replace(' ', '0');
-        }
-
-        static int toBit(MapEntry type) {
-            return type.pattern;
-        }
     }
 
-    /**
-     * A specialized bit set that represents both wide and narrow oops in an efficient manner. The
-     * map consists of 4 bit entries that represent 8 bytes of memory.
-     *
-     */
-    class HotSpotOopMap implements Cloneable {
-
-        /**
-         * Each entry is 4 bits long and covers 8 bytes of memory.
-         */
-        private static final int BITS_PER_ENTRY = 4;
-        private static final int BITS_PER_ELEMENT = 64;
-
-        public HotSpotOopMap(int i) {
-            words = new long[(i * BITS_PER_ENTRY + BITS_PER_ELEMENT) / BITS_PER_ELEMENT];
-        }
-
-        public HotSpotOopMap(HotSpotOopMap other) {
-            words = other.words.clone();
-        }
-
-        private long[] words;
-
-        private int get(int i) {
-            return getEntry(i);
-        }
-
-        public void or(HotSpotOopMap src) {
-            if (words.length < src.words.length) {
-                long[] newWords = new long[src.words.length];
-                System.arraycopy(src.words, 0, newWords, 0, src.words.length);
-                for (int i = 0; i < words.length; i++) {
-                    newWords[i] |= words[i];
-                }
-                words = newWords;
-            } else {
-                for (int i = 0; i < src.words.length; i++) {
-                    words[i] |= src.words[i];
-                }
-            }
-        }
-
-        private void setOop(int regIdx) {
-            setEntry(regIdx, OOP64);
-        }
-
-        public int size() {
-            return words.length * BITS_PER_ELEMENT / BITS_PER_ENTRY;
-        }
-
-        @Override
-        public HotSpotOopMap clone() {
-            return new HotSpotOopMap(this);
-        }
-
-        private void setNarrowOop(int offset) {
-            setNarrowEntry(offset, OOP32);
-        }
-
-        private void setEntry(int regIdx, int value) {
-            assert regIdx % 2 == 0 : "must be alinged";
-            int bitIndex = (regIdx >> 1) * BITS_PER_ENTRY;
-            int wordIndex = bitIndex / BITS_PER_ELEMENT;
-            int shift = bitIndex - wordIndex * BITS_PER_ELEMENT;
-            if (wordIndex >= words.length) {
-                if (value == 0) {
-                    // Nothing to do since bits are clear
-                    return;
-                }
-                words = Arrays.copyOf(words, wordIndex + 1);
-            }
-            assert verifyUpdate(this, this);
-            long orig = words[wordIndex];
-            words[wordIndex] = (orig & (~(0b1111L << shift))) | ((long) value << shift);
-            assert get(regIdx / 2) == value;
-            assert verifyUpdate(this, this);
-        }
-
-        private void setNarrowEntry(int offset, int value) {
-            int regIdx = offset >> 1;
-            boolean low = offset % 2 == 0;
-            int bitIndex = regIdx * BITS_PER_ENTRY;
-            int wordIndex = bitIndex / BITS_PER_ELEMENT;
-            int shift = bitIndex - wordIndex * BITS_PER_ELEMENT;
-            if (wordIndex >= words.length) {
-                if (value == 0) {
-                    // Nothing to do since bits are clear
-                    return;
-                }
-                words = Arrays.copyOf(words, wordIndex + 1);
-            }
-            long originalValue = words[wordIndex];
-            int current = ((int) (originalValue >> shift)) & 0b1111;
-            if (current == OOP64) {
-                current = 0;
-            }
-            long newValue;
-            if (value != 0) {
-                newValue = current | (low ? value : (value << 2));
-            } else {
-                newValue = current & (low ? 0b1100 : 0b0011);
-            }
-            long masked = originalValue & (~(0b1111L << shift));
-            words[wordIndex] = masked | (newValue << shift);
-            assert verifyUpdate(this, this);
-        }
-
-        private int getEntry(int regIdx) {
-            int bitIndex = regIdx * BITS_PER_ENTRY;
-            int wordIndex = bitIndex / BITS_PER_ELEMENT;
-            int shift = bitIndex - wordIndex * BITS_PER_ELEMENT;
-            return ((int) (words[wordIndex] >>> shift)) & 0b1111;
+    @Override
+    public void finish() {
+        objects = objectValues.toArray(new Value[objectValues.size()]);
+        this.bytesPerElement = new int[objects.length];
+        for (int i = 0; i < objects.length; i++) {
+            bytesPerElement[i] = bytesPerElement(objects[i].getLIRKind());
         }
-
-        @Override
-        public boolean equals(Object other) {
-            if (this == other) {
-                return true;
-            }
-
-            if (other instanceof HotSpotOopMap) {
-                HotSpotOopMap otherMap = (HotSpotOopMap) other;
-                int limit = Math.min(words.length, otherMap.words.length);
-                for (int i = 0; i < limit; i++) {
-                    if (words[i] != otherMap.words[i]) {
-                        return false;
-                    }
-                }
-                for (int i = limit; i < words.length; i++) {
-                    if (words[i] != 0) {
-                        return false;
-                    }
-                }
-                for (int i = limit; i < otherMap.words.length; i++) {
-                    if (otherMap.words[i] != 0) {
-                        return false;
-                    }
-                }
-                return true;
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            long h = 1234;
-            for (int i = words.length; --i >= 0;) {
-                h ^= words[i] * (i + 1);
-            }
-            return (int) ((h >> 32) ^ h);
-        }
-
-        @Override
-        public String toString() {
-            int count = 0;
-            StringBuilder sb = new StringBuilder();
-            sb.append("[");
-            for (int idx = 0; idx < size(); idx++) {
-                MapEntry dstType = MapEntry.getFromBits(idx, this);
-                if (dstType == MapEntry.NoReference) {
-                    continue;
-                }
-                if (count > 0) {
-                    sb.append(", ");
-                }
-                if (dstType == MapEntry.Illegal) {
-                    int value = get(idx);
-                    sb.append("0x");
-                    sb.append(Integer.toHexString(value));
-                } else {
-                    sb.append(idx);
-                    sb.append(':');
-                    sb.append(dstType);
-                }
-                count++;
-            }
-            sb.append("]");
-            return sb.toString();
-        }
-    }
-
-    /**
-     * Contains 3 bits per scalar register, and n*3 bits per n-word vector register (e.g., on a
-     * 64-bit system, a 256-bit vector register requires 12 reference map bits).
-     * <p>
-     * These bits can have the following values (LSB first):
-     *
-     * <pre>
-     * 000 - contains no references
-     * 100 - contains a wide oop
-     * 110 - contains a narrow oop in the lower half
-     * 101 - contains a narrow oop in the upper half
-     * 111 - contains two narrow oops
-     * </pre>
-     */
-    private final HotSpotOopMap registerRefMap;
-
-    /**
-     * Contains 3 bits per stack word.
-     * <p>
-     * These bits can have the following values (LSB first):
-     *
-     * <pre>
-     * 000 - contains no references
-     * 100 - contains a wide oop
-     * 110 - contains a narrow oop in the lower half
-     * 101 - contains a narrow oop in the upper half
-     * 111 - contains two narrow oops
-     * </pre>
-     */
-    private final HotSpotOopMap frameRefMap;
-
-    private final TargetDescription target;
-
-    public HotSpotReferenceMap(int registerCount, int frameSlotCount, TargetDescription target) {
-        if (registerCount > 0) {
-            this.registerRefMap = new HotSpotOopMap(registerCount);
-        } else {
-            this.registerRefMap = null;
-        }
-        this.frameRefMap = new HotSpotOopMap(frameSlotCount);
-        this.target = target;
-    }
-
-    private HotSpotReferenceMap(HotSpotReferenceMap other) {
-        this.registerRefMap = other.registerRefMap.clone();
-        this.frameRefMap = other.frameRefMap.clone();
-        this.target = other.target;
-    }
-
-    @Override
-    public ReferenceMap clone() {
-        return new HotSpotReferenceMap(this);
-    }
-
-    // setters
-    @Override
-    public void setRegister(int idx, LIRKind kind) {
-        set(registerRefMap, idx * 2, kind);
-    }
-
-    @Override
-    public void setStackSlot(int offset, LIRKind kind) {
-        assert offset % bytesPerElement(kind) == 0 : "unaligned value in ReferenceMap";
-        set(frameRefMap, offset / 4, kind);
-    }
-
-    private void set(HotSpotOopMap refMap, int index, LIRKind kind) {
-        if (kind.isDerivedReference()) {
-            throw new JVMCIError("derived reference cannot be inserted in ReferenceMap");
-        }
-
-        int bytesPerElement = bytesPerElement(kind);
-        int length = kind.getPlatformKind().getVectorLength();
-        if (bytesPerElement == 8) {
-            for (int i = 0; i < length; i++) {
-                if (kind.isReference(i)) {
-                    refMap.setOop(index + i * 2);
-                }
-            }
-        } else if (bytesPerElement == 4) {
-            for (int i = 0; i < length; i++) {
-                if (kind.isReference(i)) {
-                    refMap.setNarrowOop(index + i);
-                }
-            }
-        } else {
-            assert kind.isValue() : "unknown reference kind " + kind;
-        }
+        objectValues = null;
     }
 
     private int bytesPerElement(LIRKind kind) {
@@ -374,74 +83,6 @@
         return target.getSizeInBytes(platformKind) / platformKind.getVectorLength();
     }
 
-    public HotSpotOopMap getFrameMap() {
-        return frameRefMap == null ? null : (HotSpotOopMap) frameRefMap.clone();
-    }
-
-    public HotSpotOopMap getRegisterMap() {
-        return registerRefMap == null ? null : (HotSpotOopMap) registerRefMap.clone();
-    }
-
-    static MapEntry[] entries(HotSpotOopMap fixedMap) {
-        MapEntry[] result = new MapEntry[fixedMap.size()];
-        for (int idx = 0; idx < fixedMap.size(); idx++) {
-            MapEntry dstType = MapEntry.getFromBits(idx, fixedMap);
-            result[idx] = dstType;
-        }
-        return result;
-    }
-
-    private static boolean verifyUpdate(HotSpotOopMap dst, HotSpotOopMap src) {
-        return verifyUpdate(dst, src, true);
-    }
-
-    private static boolean verifyUpdate(HotSpotOopMap dst, HotSpotOopMap src, boolean doAssert) {
-        for (int idx = 0; idx < Math.min(src.size(), dst.size()); idx++) {
-            if (!verifyUpdateEntry(idx, dst, src, doAssert)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private static boolean verifyUpdateEntry(int idx, HotSpotOopMap dst, HotSpotOopMap src, boolean doAssert) {
-        MapEntry dstType = MapEntry.getFromBits(idx, dst);
-        MapEntry srcType = MapEntry.getFromBits(idx, src);
-
-        if (dstType == MapEntry.Illegal || srcType == MapEntry.Illegal) {
-            assert !doAssert : String.format("Illegal RefMap bit pattern: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString());
-            return false;
-        }
-        switch (dstType) {
-            case NoReference:
-                return true;
-            case WideOop:
-                switch (srcType) {
-                    case NoReference:
-                    case WideOop:
-                        return true;
-                    default:
-                        assert false : String.format("Illegal RefMap combination: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString());
-                        return false;
-                }
-            case TwoNarrowOops:
-            case NarrowOopLowerHalf:
-            case NarrowOopUpperHalf:
-                switch (srcType) {
-                    case TwoNarrowOops:
-                    case NarrowOopLowerHalf:
-                    case NarrowOopUpperHalf:
-                    case NoReference:
-                        return true;
-                    default:
-                        assert false : String.format("Illegal RefMap combination: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString());
-                        return false;
-                }
-            default:
-                return false;
-        }
-    }
-
     @Override
     public int hashCode() {
         throw new UnsupportedOperationException();
@@ -454,7 +95,7 @@
         }
         if (obj instanceof HotSpotReferenceMap) {
             HotSpotReferenceMap that = (HotSpotReferenceMap) obj;
-            if (this.frameRefMap.equals(that.frameRefMap) && Objects.equals(this.registerRefMap, that.registerRefMap) && this.target.equals(that.target)) {
+            if (Arrays.equals(objects, that.objects) && this.target.equals(that.target)) {
                 return true;
             }
         }
@@ -462,49 +103,7 @@
     }
 
     @Override
-    public boolean hasRegisterRefMap() {
-        return registerRefMap != null && registerRefMap.size() > 0;
-    }
-
-    @Override
-    public boolean hasFrameRefMap() {
-        return frameRefMap != null && frameRefMap.size() > 0;
-    }
-
-    @Override
-    public void appendRegisterMap(StringBuilder sb, RefMapFormatter formatter) {
-        for (int idx = 0; idx < registerRefMap.size(); idx++) {
-            MapEntry dstType = MapEntry.getFromBits(idx, registerRefMap);
-            if (dstType != MapEntry.NoReference) {
-                sb.append(' ').append(formatter.formatRegister(idx)).append(':').append(dstType);
-            }
-        }
-    }
-
-    @Override
-    public void appendFrameMap(StringBuilder sb, RefMapFormatter formatter) {
-        for (int idx = 0; idx < frameRefMap.size(); idx++) {
-            MapEntry dstType = MapEntry.getFromBits(idx, frameRefMap);
-            if (dstType != MapEntry.NoReference) {
-                sb.append(' ').append(formatter.formatStackSlot(idx)).append(':').append(dstType);
-            }
-        }
-    }
-
-    @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder();
-        if (registerRefMap != null) {
-            sb.append("Registers = ");
-            sb.append(registerRefMap);
-        }
-        sb.append("Stack = ");
-        sb.append(frameRefMap);
-        return sb.toString();
-    }
-
-    public void verify() {
-        assert verifyUpdate(frameRefMap, frameRefMap);
-        assert registerRefMap == null || verifyUpdate(registerRefMap, registerRefMap);
+        return Arrays.toString(objects);
     }
 }
--- a/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotTargetDescription.java	Thu Jun 04 17:04:21 2015 +0200
+++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotTargetDescription.java	Thu Jun 04 11:08:12 2015 -0700
@@ -32,6 +32,6 @@
 
     @Override
     public ReferenceMap createReferenceMap(boolean hasRegisters, int stackSlotCount) {
-        return new HotSpotReferenceMap(hasRegisters ? arch.getRegisterReferenceMapSize() : 0, stackSlotCount, this);
+        return new HotSpotReferenceMap(this);
     }
 }
--- a/graal/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/Value.java	Thu Jun 04 17:04:21 2015 +0200
+++ b/graal/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/Value.java	Thu Jun 04 11:08:12 2015 -0700
@@ -28,7 +28,14 @@
  */
 public interface Value extends KindProvider, TrustedInterface {
 
-    AllocatableValue ILLEGAL = new AllocatableValue(LIRKind.Illegal) {
+    Value[] NO_VALUES = new Value[0];
+
+    AllocatableValue ILLEGAL = new IllegalValue();
+
+    public final class IllegalValue extends AllocatableValue {
+        private IllegalValue() {
+            super(LIRKind.Illegal);
+        }
 
         @Override
         public String toString() {
@@ -39,9 +46,9 @@
         public boolean equals(Object other) {
             // Due to de-serialization this object may exist multiple times. So we compare classes
             // instead of the individual objects. (This anonymous class has always the same meaning)
-            return other != null && this.getClass() == other.getClass();
+            return other instanceof IllegalValue;
         }
-    };
+    }
 
     LIRKind getLIRKind();
 
--- a/src/share/vm/classfile/systemDictionary.hpp	Thu Jun 04 17:04:21 2015 +0200
+++ b/src/share/vm/classfile/systemDictionary.hpp	Thu Jun 04 11:08:12 2015 -0700
@@ -205,7 +205,6 @@
   JVMCI_ONLY(do_klass(HotSpotCompiledNmethod_klass,          com_oracle_jvmci_hotspot_HotSpotCompiledNmethod,              Jvmci)) \
   JVMCI_ONLY(do_klass(HotSpotForeignCallTarget_klass,        com_oracle_jvmci_hotspot_HotSpotForeignCallTarget,            Jvmci)) \
   JVMCI_ONLY(do_klass(HotSpotReferenceMap_klass,             com_oracle_jvmci_hotspot_HotSpotReferenceMap,                 Jvmci)) \
-  JVMCI_ONLY(do_klass(HotSpotOopMap_klass,                   com_oracle_jvmci_hotspot_HotSpotReferenceMap_HotSpotOopMap,   Jvmci)) \
   JVMCI_ONLY(do_klass(HotSpotInstalledCode_klass,            com_oracle_jvmci_hotspot_HotSpotInstalledCode,                Jvmci)) \
   JVMCI_ONLY(do_klass(HotSpotNmethod_klass,                  com_oracle_jvmci_hotspot_HotSpotNmethod,                      Jvmci)) \
   JVMCI_ONLY(do_klass(HotSpotResolvedJavaMethodImpl_klass,   com_oracle_jvmci_hotspot_HotSpotResolvedJavaMethodImpl,       Jvmci)) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Thu Jun 04 17:04:21 2015 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Thu Jun 04 11:08:12 2015 -0700
@@ -306,7 +306,6 @@
   JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotCompiledNmethod,          "com/oracle/jvmci/hotspot/HotSpotCompiledNmethod"))               \
   JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotForeignCallTarget,        "com/oracle/jvmci/hotspot/HotSpotForeignCallTarget"))             \
   JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotReferenceMap,             "com/oracle/jvmci/hotspot/HotSpotReferenceMap"))                  \
-  JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotReferenceMap_HotSpotOopMap, "com/oracle/jvmci/hotspot/HotSpotReferenceMap$HotSpotOopMap"))  \
   JVMCI_ONLY(template(com_oracle_jvmci_hotspot_CompilerToVMImpl,                "com/oracle/jvmci/hotspot/CompilerToVMImpl"))                     \
   JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotInstalledCode,            "com/oracle/jvmci/hotspot/HotSpotInstalledCode"))                 \
   JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotNmethod,                  "com/oracle/jvmci/hotspot/HotSpotNmethod"))                       \
--- a/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Thu Jun 04 17:04:21 2015 +0200
+++ b/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Thu Jun 04 11:08:12 2015 -0700
@@ -69,83 +69,62 @@
   return asMethod(HotSpotResolvedJavaMethodImpl::metaspaceMethod(hotspot_method));
 }
 
-const int MapWordBits = 64;
-
-static int entry_value(typeArrayOop words, int i) {
-  jint words_idx = i / MapWordBits;
-  assert(words_idx >= 0 && words_idx < words->length(), "unexpected index");
-  jlong word = words->long_at(words_idx);
-  return (word >> (i % MapWordBits)) & 15LL;
-}
-
-static int fixedmap_size(oop bitset) {
-  typeArrayOop arr = HotSpotOopMap::words(bitset);
-  return arr->length() * MapWordBits;
-}
-
-static void set_vmreg_oops(OopMap* map, VMReg reg, typeArrayOop words, int idx) {
-  int value = entry_value(words, 4 * idx);
-  switch (value) {
-    case 10:
-      map->set_oop(reg);
-      break;
-    case 5:
-      map->set_narrowoop(reg);
-      map->set_narrowoop(reg->next());
-      break;
-    case 1:
-      map->set_narrowoop(reg);
-      break;
-    case 4:
-      map->set_narrowoop(reg->next());
-      break;
-    case 0:
-      break;
-    default:
-      assert(false, err_msg("unexpected bit pattern at %d = 0x%x", idx, value));
-      ShouldNotReachHere();
+// creates a HotSpot oop map out of the byte arrays provided by DebugInfo
+OopMap* CodeInstaller::create_oop_map(oop debug_info) {
+  oop reference_map = DebugInfo::referenceMap(debug_info);
+  if (HotSpotReferenceMap::maxRegisterSize(reference_map) > 16) {
+    _has_wide_vector = true;
   }
-}
-
-// creates a HotSpot oop map out of the byte arrays provided by DebugInfo
-static OopMap* create_oop_map(jint total_frame_size, jint parameter_count, oop debug_info) {
-  OopMap* map = new OopMap(total_frame_size, parameter_count);
-  oop reference_map = DebugInfo::referenceMap(debug_info);
-  oop register_map = HotSpotReferenceMap::registerRefMap(reference_map);
-  oop frame_map = HotSpotReferenceMap::frameRefMap(reference_map);
-  oop callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info);
-
-  if (register_map != NULL) {
-    typeArrayOop words = HotSpotOopMap::words(register_map);
-    int mapIdx = 0;
-    for (jint i = 0; i < RegisterImpl::number_of_registers; i++) {
-      set_vmreg_oops(map, as_Register(i)->as_VMReg(), words, mapIdx);
-      mapIdx++;
+  OopMap* map = new OopMap(_total_frame_size, _parameter_count);
+  objArrayOop objects = HotSpotReferenceMap::objects(reference_map);
+  typeArrayOop bytesPerArray = HotSpotReferenceMap::bytesPerElement(reference_map);
+  for (int i = 0; i < objects->length(); i++) {
+    oop value = objects->obj_at(i);
+    oop lirKind = AbstractValue::lirKind(value);
+    oop platformKind = LIRKind::platformKind(lirKind);
+    int bytesPerElement = bytesPerArray->int_at(i);
+    assert(bytesPerElement == 4 || bytesPerElement == 8, "wrong sizes");
+    jint referenceMask = LIRKind::referenceMask(lirKind);
+    assert(referenceMask != 0, "must be a reference type");
+    assert(referenceMask != -1, "must not be a derived reference type");
+    
+    VMReg vmReg;
+    if (value->is_a(RegisterValue::klass())) {
+      oop reg = RegisterValue::reg(value);
+      jint number = code_Register::number(reg);
+      vmReg = CodeInstaller::get_hotspot_reg(number);
+    } else if (value->is_a(StackSlot::klass())) {
+      jint offset = StackSlot::offset(value);
+#ifdef TARGET_ARCH_sparc
+      if(offset >= 0) {
+        offset += 128;
+      }
+#endif
+      if (StackSlot::addFrameSize(value)) {
+        offset += _total_frame_size;
+      }
+      assert(offset % 4 == 0, "must be aligned");
+      vmReg = VMRegImpl::stack2reg(offset / 4);
     }
-#ifdef TARGET_ARCH_x86
-    for (jint i = 0; i < XMMRegisterImpl::number_of_registers; i++) {
-      VMReg reg = as_XMMRegister(i)->as_VMReg();
-      for (jint j = 0; j < 4; j++) {
-        set_vmreg_oops(map, reg->next(2 * j), words, mapIdx++);
+      
+    int bit = 1;
+    while (referenceMask != 0) {
+      if (referenceMask & bit) {
+        if (bytesPerElement == 8) {
+          map->set_oop(vmReg);
+        } else {
+          map->set_narrowoop(vmReg);
+        }
+        referenceMask &= ~bit;
       }
+      vmReg = vmReg->next();
+      if (bytesPerElement == 8) {
+        vmReg = vmReg->next();
+      }
+      bit <<= 1;
     }
-#endif
-#ifdef TARGET_ARCH_sparc
-    for (jint i = 0; i < FloatRegisterImpl::number_of_registers; i++) {
-      VMReg reg = as_FloatRegister(i)->as_VMReg();
-      set_vmreg_oops(map, reg, words, mapIdx++);
-    }
-#endif
   }
-
-  typeArrayOop words = HotSpotOopMap::words(frame_map);
-  int size = fixedmap_size(frame_map) / 4;
-  for (jint i = 0; i < size; i++) {
-    // HotSpot stack slots are 4 bytes
-    VMReg reg = VMRegImpl::stack2reg(i * VMRegImpl::slots_per_word);
-    set_vmreg_oops(map, reg, words, i);
-  }
-
+  oop callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info);
   if (callee_save_info != NULL) {
     objArrayOop registers = RegisterSaveLayout::registers(callee_save_info);
     typeArrayOop slots = RegisterSaveLayout::slots(callee_save_info);
@@ -261,7 +240,17 @@
       return value;
     }
   } else if (value->is_a(StackSlot::klass())) {
-      Location::Type locationType;
+    jint offset = StackSlot::offset(value);
+#ifdef TARGET_ARCH_sparc
+    if(offset >= 0) {
+      offset += 128;
+    }
+#endif
+    if (StackSlot::addFrameSize(value)) {
+      offset += _total_frame_size;
+    }
+
+    Location::Type locationType;
     if (type == T_LONG) {
       locationType = reference ? Location::oop : Location::lng;
     } else if (type == T_INT) {
@@ -278,15 +267,6 @@
       assert(type == T_OBJECT && reference, "unexpected type in stack slot");
       locationType = Location::oop;
     }
-    jint offset = StackSlot::offset(value);
-#ifdef TARGET_ARCH_sparc
-    if(offset >= 0) {
-      offset += 128;
-    }
-#endif
-    if (StackSlot::addFrameSize(value)) {
-      offset += _total_frame_size;
-    }
     ScopeValue* value = new LocationValue(Location::new_stk_loc(locationType, offset));
     if (type == T_DOUBLE || (type == T_LONG && !reference)) {
       second = value;
@@ -470,8 +450,10 @@
       // Make sure a valid compile_id is associated with every compile
       id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci);
     }
-    result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
-        JVMCICompiler::instance(), _debug_recorder, _dependencies, env, id, false, installed_code, compiled_code, speculation_log);
+    result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer,
+                                       stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
+                                       JVMCICompiler::instance(), _debug_recorder, _dependencies, env, id,
+                                       false, _has_wide_vector, installed_code, compiled_code, speculation_log);
     cb = nm;
   }
 
@@ -513,6 +495,8 @@
 #endif
 
   _next_call_type = INVOKE_INVALID;
+
+  _has_wide_vector = false;
 }
 
 int CodeInstaller::estimate_stub_entries() {
@@ -856,7 +840,7 @@
 
   // address instruction = _instructions->start() + pc_offset;
   // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start();
-  _debug_recorder->add_safepoint(pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info));
+  _debug_recorder->add_safepoint(pc_offset, create_oop_map(debug_info));
   record_scope(pc_offset, debug_info);
   _debug_recorder->end_safepoint(pc_offset);
 }
@@ -891,7 +875,7 @@
   jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method);
 
   if (debug_info != NULL) {
-    _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info));
+    _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(debug_info));
     record_scope(next_pc_offset, debug_info);
   }
 
--- a/src/share/vm/jvmci/jvmciCodeInstaller.hpp	Thu Jun 04 17:04:21 2015 +0200
+++ b/src/share/vm/jvmci/jvmciCodeInstaller.hpp	Thu Jun 04 11:08:12 2015 -0700
@@ -70,6 +70,8 @@
   jobject       _comments_handle;
 #endif
 
+  bool          _has_wide_vector;
+
   MarkId        _next_call_type;
   address       _invoke_mark_pc;
 
@@ -139,6 +141,8 @@
   void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site);
   void site_Mark(CodeBuffer& buffer, jint pc_offset, oop site);
 
+  OopMap* create_oop_map(oop debug_info);
+
   void record_scope(jint pc_offset, oop debug_info);
   void record_scope(jint pc_offset, oop code_pos, GrowableArray<ScopeValue*>* objects);
   void record_object_value(ObjectValue* sv, oop value, GrowableArray<ScopeValue*>* objects);
--- a/src/share/vm/jvmci/jvmciEnv.cpp	Thu Jun 04 17:04:21 2015 +0200
+++ b/src/share/vm/jvmci/jvmciEnv.cpp	Thu Jun 04 11:08:12 2015 -0700
@@ -483,6 +483,7 @@
                                 JVMCIEnv* env,
                                 int compile_id,
                                 bool has_unsafe_access,
+                                bool has_wide_vector,
                                 Handle installed_code,
                                 Handle compiled_code,
                                 Handle speculation_log) {
@@ -546,12 +547,7 @@
         }
       } else {
         nm->set_has_unsafe_access(has_unsafe_access);
-#ifdef TARGET_ARCH_x86
-        // It might be preferable to set this only for methods which
-        // use vector instructions but we currently don't track this
-        // and it probably wouldn't make much difference.
-        nm->set_has_wide_vectors(MaxVectorSize > 16);
-#endif
+        nm->set_has_wide_vectors(has_wide_vector);
 
         // Record successful registration.
         // (Put nm into the task handle *before* publishing to the Java heap.)
--- a/src/share/vm/jvmci/jvmciEnv.hpp	Thu Jun 04 17:04:21 2015 +0200
+++ b/src/share/vm/jvmci/jvmciEnv.hpp	Thu Jun 04 11:08:12 2015 -0700
@@ -157,6 +157,7 @@
                        JVMCIEnv*                 env,
                        int                       compile_id,
                        bool                      has_unsafe_access,
+                       bool                      has_wide_vector,
                        Handle                    installed_code,
                        Handle                    compiled_code,
                        Handle                    speculation_log);
--- a/src/share/vm/jvmci/jvmciJavaAccess.hpp	Thu Jun 04 17:04:21 2015 +0200
+++ b/src/share/vm/jvmci/jvmciJavaAccess.hpp	Thu Jun 04 11:08:12 2015 -0700
@@ -157,16 +157,14 @@
     objArrayOop_field(DebugInfo, virtualObjectMapping, "[Lcom/oracle/jvmci/meta/Value;")                                                                       \
   end_class                                                                                                                                                    \
   start_class(HotSpotReferenceMap)                                                                                                                             \
-    oop_field(HotSpotReferenceMap, registerRefMap, "Lcom/oracle/jvmci/hotspot/HotSpotReferenceMap$HotSpotOopMap;")                                             \
-    oop_field(HotSpotReferenceMap, frameRefMap, "Lcom/oracle/jvmci/hotspot/HotSpotReferenceMap$HotSpotOopMap;")                                                \
+    objArrayOop_field(HotSpotReferenceMap, objects, "[Lcom/oracle/jvmci/meta/Value;")                                                                          \
+    typeArrayOop_field(HotSpotReferenceMap, bytesPerElement, "[I")                                                                                             \
+    int_field(HotSpotReferenceMap, maxRegisterSize)                                                                                                            \
   end_class                                                                                                                                                    \
   start_class(RegisterSaveLayout)                                                                                                                              \
     objArrayOop_field(RegisterSaveLayout, registers, "[Lcom/oracle/jvmci/code/Register;")                                                                      \
     typeArrayOop_field(RegisterSaveLayout, slots, "[I")                                                                                                        \
   end_class                                                                                                                                                    \
-  start_class(HotSpotOopMap)                                                                                                                                   \
-    typeArrayOop_field(HotSpotOopMap, words, "[J")                                                                                                             \
-  end_class                                                                                                                                                    \
   start_class(BytecodeFrame)                                                                                                                                   \
     objArrayOop_field(BytecodeFrame, values, "[Lcom/oracle/jvmci/meta/Value;")                                                                                 \
     int_field(BytecodeFrame, numLocals)                                                                                                                        \
@@ -223,15 +221,9 @@
   start_class(RegisterValue)                                                                                                                                   \
     oop_field(RegisterValue, reg, "Lcom/oracle/jvmci/code/Register;")                                                                                          \
   end_class                                                                                                                                                    \
-  start_class(RegisterCategory)                                                                                                                                \
-    oop_field(RegisterCategory, name, "Ljava/lang/String;")                                                                                                    \
-    int_field(RegisterCategory, referenceMapOffset)                                                                                                            \
-    int_field(RegisterCategory, referenceMapShift)                                                                                                             \
-  end_class                                                                                                                                                    \
   start_class(code_Register)                                                                                                                                   \
     int_field(code_Register, number)                                                                                                                           \
     int_field(code_Register, encoding)                                                                                                                         \
-    oop_field(code_Register, registerCategory, "Lcom/oracle/jvmci/code/Register$RegisterCategory;")                                                            \
   end_class                                                                                                                                                    \
   start_class(StackSlot)                                                                                                                                       \
     int_field(StackSlot, offset)                                                                                                                               \