changeset 12617:bca33c3135de

PEA: support for unsafe stores of mismatching sizes, cleanup, documentation
author Lukas Stadler <lukas.stadler@jku.at>
date Mon, 28 Oct 2013 13:01:16 +0100
parents b292dd6d02ac
children 2925280e3f92
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostLoweringProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/GenericStamp.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java src/share/vm/runtime/deoptimization.cpp
diffstat 19 files changed, 389 insertions(+), 199 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java	Mon Oct 28 13:01:16 2013 +0100
@@ -138,12 +138,18 @@
         if (values != null) {
             if (!type.isArray()) {
                 ResolvedJavaField[] fields = type.getInstanceFields(true);
-                assert fields.length == values.length : type + ": fields=" + Arrays.toString(fields) + ", field values=" + Arrays.toString(values);
+                int fieldIndex = 0;
                 for (int i = 0; i < values.length; i++) {
-                    ResolvedJavaField field = fields[i];
+                    ResolvedJavaField field = fields[fieldIndex++];
                     Kind valKind = values[i].getKind().getStackKind();
-                    assert valKind == field.getKind().getStackKind() : field + ": " + valKind + " != " + field.getKind().getStackKind();
+                    if ((valKind == Kind.Double || valKind == Kind.Long) && field.getKind() == Kind.Int) {
+                        assert fields[fieldIndex].getKind() == Kind.Int;
+                        fieldIndex++;
+                    } else {
+                        assert valKind == field.getKind().getStackKind() : field + ": " + valKind + " != " + field.getKind().getStackKind();
+                    }
                 }
+                assert fields.length == fieldIndex : type + ": fields=" + Arrays.toString(fields) + ", field values=" + Arrays.toString(values);
             } else {
                 Kind componentKind = type.getComponentType().getKind().getStackKind();
                 for (int i = 0; i < values.length; i++) {
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Mon Oct 28 13:01:16 2013 +0100
@@ -112,11 +112,15 @@
 
     @Override
     public String toString() {
-        String annotationSuffix = "";
-        if (getKind() != Kind.Object && getPrimitiveAnnotation() != null) {
-            annotationSuffix = "{" + getPrimitiveAnnotation() + "}";
+        if (getKind() == Kind.Illegal) {
+            return "illegal";
+        } else {
+            String annotationSuffix = "";
+            if (getKind() != Kind.Object && getPrimitiveAnnotation() != null) {
+                annotationSuffix = "{" + getPrimitiveAnnotation() + "}";
+            }
+            return getKind().getJavaName() + "[" + getKind().format(asBoxedValue()) + (getKind() != Kind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]" + annotationSuffix;
         }
-        return getKind().getJavaName() + "[" + getKind().format(asBoxedValue()) + (getKind() != Kind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]" + annotationSuffix;
     }
 
     /**
@@ -144,6 +148,8 @@
                 return asDouble();
             case Object:
                 return object;
+            case Illegal:
+                return this;
         }
         throw new IllegalArgumentException();
     }
@@ -427,6 +433,10 @@
         }
     }
 
+    public static Constant forIllegal() {
+        return new Constant(Kind.Illegal, null, 0);
+    }
+
     /**
      * Returns a constant with the default value for the given kind.
      */
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Mon Oct 28 13:01:16 2013 +0100
@@ -87,8 +87,17 @@
                             changed = true;
                             VirtualObjectState currentField = (VirtualObjectState) objectStates.get(vobj);
                             assert currentField != null;
+                            int pos = 0;
                             for (int i = 0; i < vobj.entryCount(); i++) {
-                                values[i] = toValue(currentField.fieldValues().get(i));
+                                if (!currentField.fieldValues().get(i).isConstant() || currentField.fieldValues().get(i).asConstant().getKind() != Kind.Illegal) {
+                                    values[pos++] = toValue(currentField.fieldValues().get(i));
+                                } else {
+                                    assert currentField.fieldValues().get(i - 1).kind() == Kind.Double || currentField.fieldValues().get(i - 1).kind() == Kind.Long : vobj + " " + i + " " +
+                                                    currentField.fieldValues().get(i - 1);
+                                }
+                            }
+                            if (pos != vobj.entryCount()) {
+                                values = Arrays.copyOf(values, pos);
                             }
                         }
                         entry.getValue().setValues(values);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostLoweringProvider.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostLoweringProvider.java	Mon Oct 28 13:01:16 2013 +0100
@@ -317,10 +317,19 @@
                             if (value == null) {
                                 omittedValues.set(valuePos);
                             } else if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
+                                // Constant.illegal is always the defaultForKind, so it is skipped
                                 VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual;
-                                WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i), true),
-                                                (virtualInstance.field(i).getKind() == Kind.Object && !useDeferredInitBarriers()) ? BarrierType.IMPRECISE : BarrierType.NONE,
-                                                virtualInstance.field(i).getKind() == Kind.Object);
+                                Kind accessKind;
+                                HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) virtualInstance.field(i);
+                                if (value.kind().getStackKind() != field.getKind().getStackKind()) {
+                                    assert value.kind() == Kind.Long || value.kind() == Kind.Double;
+                                    accessKind = value.kind();
+                                } else {
+                                    accessKind = field.getKind();
+                                }
+                                ConstantLocationNode location = ConstantLocationNode.create(INIT_LOCATION, accessKind, field.offset(), graph);
+                                BarrierType barrierType = (virtualInstance.field(i).getKind() == Kind.Object && !useDeferredInitBarriers()) ? BarrierType.IMPRECISE : BarrierType.NONE;
+                                WriteNode write = new WriteNode(newObject, value, location, barrierType, virtualInstance.field(i).getKind() == Kind.Object);
                                 graph.addAfterFixed(newObject, graph.add(write));
                             }
                             valuePos++;
@@ -338,8 +347,20 @@
                             if (value == null) {
                                 omittedValues.set(valuePos);
                             } else if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
-                                WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph), true),
-                                                (value.kind() == Kind.Object && !useDeferredInitBarriers()) ? BarrierType.PRECISE : BarrierType.NONE, value.kind() == Kind.Object);
+                                // Constant.illegal is always the defaultForKind, so it is skipped
+                                Kind componentKind = element.getKind();
+                                Kind accessKind;
+                                if (value.kind().getStackKind() != componentKind.getStackKind()) {
+                                    assert value.kind() == Kind.Long || value.kind() == Kind.Double;
+                                    accessKind = value.kind();
+                                } else {
+                                    accessKind = componentKind;
+                                }
+
+                                int scale = getScalingFactor(componentKind);
+                                ConstantLocationNode location = ConstantLocationNode.create(INIT_LOCATION, accessKind, getArrayBaseOffset(componentKind) + i * scale, graph);
+                                BarrierType barrierType = (componentKind == Kind.Object && !useDeferredInitBarriers()) ? BarrierType.IMPRECISE : BarrierType.NONE;
+                                WriteNode write = new WriteNode(newObject, value, location, barrierType, componentKind == Kind.Object);
                                 graph.addAfterFixed(newObject, graph.add(write));
                             }
                             valuePos++;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Mon Oct 28 13:01:16 2013 +0100
@@ -187,7 +187,7 @@
                     return;
                 }
                 for (int i = 0; i < length; i++) {
-                    tool.setVirtualEntry(destState, destPos + i, srcState.getEntry(srcPos + i));
+                    tool.setVirtualEntry(destState, destPos + i, srcState.getEntry(srcPos + i), false);
                 }
                 tool.delete();
                 if (Debug.isLogEnabled()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Mon Oct 28 13:01:16 2013 +0100
@@ -77,10 +77,23 @@
                 long offset = indexValue.asConstant().asLong();
                 int entryIndex = state.getVirtualObject().entryIndexForOffset(offset);
                 if (entryIndex != -1) {
+                    Kind entryKind = state.getVirtualObject().entryKind(entryIndex);
                     ValueNode entry = state.getEntry(entryIndex);
-                    if (entry.kind() == value.kind() || state.getVirtualObject().entryKind(entryIndex) == accessKind()) {
-                        tool.setVirtualEntry(state, entryIndex, value());
+                    if (entry.kind() == value.kind() || entryKind == accessKind()) {
+                        tool.setVirtualEntry(state, entryIndex, value(), true);
                         tool.delete();
+                    } else {
+                        if ((accessKind() == Kind.Long || accessKind() == Kind.Double) && entryKind == Kind.Int) {
+                            int nextIndex = state.getVirtualObject().entryIndexForOffset(offset + 4);
+                            if (nextIndex != -1) {
+                                Kind nextKind = state.getVirtualObject().entryKind(nextIndex);
+                                if (nextKind == Kind.Int) {
+                                    tool.setVirtualEntry(state, entryIndex, value(), true);
+                                    tool.setVirtualEntry(state, nextIndex, ConstantNode.forConstant(Constant.forIllegal(), tool.getMetaAccessProvider(), graph()), true);
+                                    tool.delete();
+                                }
+                            }
+                        }
                     }
                 }
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Mon Oct 28 13:01:16 2013 +0100
@@ -98,7 +98,7 @@
                 VirtualObjectNode virtual = state.getVirtualObject();
                 int entryIndex = virtual.entryIndexForOffset(constantLocation.getDisplacement());
                 if (entryIndex != -1 && virtual.entryKind(entryIndex) == constantLocation.getValueKind()) {
-                    tool.setVirtualEntry(state, entryIndex, value());
+                    tool.setVirtualEntry(state, entryIndex, value(), false);
                     tool.delete();
                 }
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java	Mon Oct 28 13:01:16 2013 +0100
@@ -74,7 +74,7 @@
         if (state != null && state.getState() == EscapeState.Virtual) {
             int fieldIndex = ((VirtualInstanceNode) state.getVirtualObject()).fieldIndex(field());
             if (fieldIndex != -1) {
-                tool.setVirtualEntry(state, fieldIndex, value());
+                tool.setVirtualEntry(state, fieldIndex, value(), false);
                 tool.delete();
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Mon Oct 28 13:01:16 2013 +0100
@@ -76,7 +76,7 @@
                 ResolvedJavaType componentType = arrayState.getVirtualObject().type().getComponentType();
                 if (componentType.isPrimitive() || ObjectStamp.isObjectAlwaysNull(value) || componentType.getSuperclass() == null ||
                                 (ObjectStamp.typeOrNull(value) != null && componentType.isAssignableFrom(ObjectStamp.typeOrNull(value)))) {
-                    tool.setVirtualEntry(arrayState, index, value());
+                    tool.setVirtualEntry(arrayState, index, value(), false);
                     tool.delete();
                 }
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java	Mon Oct 28 13:01:16 2013 +0100
@@ -84,8 +84,9 @@
      * @param state the state.
      * @param index the index to be set.
      * @param value the new value for the given index.
+     * @param unsafe if true, then mismatching value {@link Kind}s will be accepted.
      */
-    void setVirtualEntry(State state, int index, ValueNode value);
+    void setVirtualEntry(State state, int index, ValueNode value, boolean unsafe);
 
     // scalar replacement
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/GenericStamp.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/GenericStamp.java	Mon Oct 28 13:01:16 2013 +0100
@@ -27,7 +27,7 @@
 public final class GenericStamp extends Stamp {
 
     public enum GenericStampType {
-        Dependency, Extension, Virtual, Condition, Void
+        Dependency, Extension, Condition, Void
     }
 
     private final GenericStampType type;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Mon Oct 28 13:01:16 2013 +0100
@@ -37,7 +37,6 @@
     private static final Stamp objectAlwaysNullStamp = new ObjectStamp(null, false, false, true);
     private static final Stamp dependencyStamp = new GenericStamp(GenericStampType.Dependency);
     private static final Stamp extensionStamp = new GenericStamp(GenericStampType.Extension);
-    private static final Stamp virtualStamp = new GenericStamp(GenericStampType.Virtual);
     private static final Stamp conditionStamp = new GenericStamp(GenericStampType.Condition);
     private static final Stamp voidStamp = new GenericStamp(GenericStampType.Void);
     private static final Stamp nodeIntrinsicStamp = new ObjectStamp(null, false, false, false);
@@ -94,10 +93,6 @@
         return extensionStamp;
     }
 
-    public static Stamp virtual() {
-        return virtualStamp;
-    }
-
     public static Stamp condition() {
         return conditionStamp;
     }
@@ -163,6 +158,8 @@
                 return forFloat(kind, value.asFloat(), value.asFloat(), !Float.isNaN(value.asFloat()));
             case Double:
                 return forFloat(kind, value.asDouble(), value.asDouble(), !Double.isNaN(value.asDouble()));
+            case Illegal:
+                return illegal(Kind.Illegal);
             default:
                 throw new GraalInternalError("unexpected kind: %s", kind);
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java	Mon Oct 28 13:01:16 2013 +0100
@@ -36,7 +36,7 @@
     private final int length;
 
     public VirtualArrayNode(ResolvedJavaType componentType, int length) {
-        super(true);
+        super(componentType.getArrayClass(), true);
         this.componentType = componentType;
         this.length = length;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Mon Oct 28 13:01:16 2013 +0100
@@ -37,7 +37,7 @@
     }
 
     public VirtualInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields, boolean hasIdentity) {
-        super(hasIdentity);
+        super(type, hasIdentity);
         this.type = type;
         this.fields = fields;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java	Mon Oct 28 13:01:16 2013 +0100
@@ -32,8 +32,8 @@
 
     private boolean hasIdentity;
 
-    public VirtualObjectNode(boolean hasIdentity) {
-        super(StampFactory.virtual());
+    public VirtualObjectNode(ResolvedJavaType type, boolean hasIdentity) {
+        super(StampFactory.exactNonNull(type));
         this.hasIdentity = hasIdentity;
     }
 
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java	Mon Oct 28 13:01:16 2013 +0100
@@ -132,13 +132,14 @@
     }
 
     /**
-     * Sets the phi node's input at the given index to the given value.
+     * Sets the phi node's input at the given index to the given value, adding new phi inputs as
+     * needed.
      * 
      * @param node The phi node whose input should be changed.
      * @param index The index of the phi input to be changed.
      * @param value The new value for the phi input.
      */
-    public void setPhiInput(final PhiNode node, final int index, final ValueNode value) {
+    public void initializePhiInput(final PhiNode node, final int index, final ValueNode value) {
         add(new Effect() {
 
             @Override
@@ -149,7 +150,7 @@
             @Override
             public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) {
                 assert node.isAlive() && value.isAlive() && index >= 0;
-                node.setValueAt(index, value);
+                node.initializeValueAt(index, value);
             }
         });
     }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Mon Oct 28 13:01:16 2013 +0100
@@ -208,20 +208,26 @@
         }
     }
 
-    private void ensureMaterialized(BlockT state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) {
+    /**
+     * @return true if materialization happened, false if not.
+     */
+    private boolean ensureMaterialized(BlockT state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) {
         assert obj != null;
         if (obj.getState() == EscapeState.Virtual) {
             metric.increment();
             state.materializeBefore(materializeBefore, obj.virtual, EscapeState.Materialized, effects);
+            assert !obj.isVirtual();
+            return true;
         } else {
             assert obj.getState() == EscapeState.Materialized;
+            return false;
         }
-        assert !obj.isVirtual();
     }
 
-    private void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, BlockT state, ObjectState obj, GraphEffectList effects, DebugMetric metric) {
-        ensureMaterialized(state, obj, materializeBefore, effects, metric);
+    private boolean replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, BlockT state, ObjectState obj, GraphEffectList effects, DebugMetric metric) {
+        boolean materialized = ensureMaterialized(state, obj, materializeBefore, effects, metric);
         effects.replaceFirstInput(usage, value, obj.getMaterializedValue());
+        return materialized;
     }
 
     @Override
@@ -275,8 +281,7 @@
     protected class MergeProcessor extends EffectsClosure<BlockT>.MergeProcessor {
 
         private final HashMap<Object, PhiNode> materializedPhis = new HashMap<>();
-        private final IdentityHashMap<VirtualObjectNode, PhiNode[]> valuePhis = new IdentityHashMap<>();
-        private final IdentityHashMap<PhiNode, PhiNode[]> valueObjectMergePhis = new IdentityHashMap<>();
+        private final IdentityHashMap<ValueNode, PhiNode[]> valuePhis = new IdentityHashMap<>();
         private final IdentityHashMap<PhiNode, VirtualObjectNode> valueObjectVirtuals = new IdentityHashMap<>();
 
         public MergeProcessor(Block mergeBlock) {
@@ -292,21 +297,13 @@
             return result;
         }
 
-        private PhiNode[] getValuePhis(VirtualObjectNode virtual) {
-            PhiNode[] result = valuePhis.get(virtual);
-            if (result == null) {
-                result = new PhiNode[virtual.entryCount()];
-                valuePhis.put(virtual, result);
-            }
-            return result;
-        }
-
-        private PhiNode[] getValueObjectMergePhis(PhiNode phi, int entryCount) {
-            PhiNode[] result = valueObjectMergePhis.get(phi);
+        private PhiNode[] getValuePhis(ValueNode key, int entryCount) {
+            PhiNode[] result = valuePhis.get(key);
             if (result == null) {
                 result = new PhiNode[entryCount];
-                valueObjectMergePhis.put(phi, result);
+                valuePhis.put(key, result);
             }
+            assert result.length == entryCount;
             return result;
         }
 
@@ -319,194 +316,299 @@
             return result;
         }
 
+        /**
+         * Merge all predecessor block states into one block state. This is an iterative process,
+         * because merging states can lead to materializations which make previous parts of the
+         * merging operation invalid. The merging process is executed until a stable state has been
+         * reached. This method needs to be careful to place the effects of the merging operation
+         * into the correct blocks.
+         * 
+         * @param states the predecessor block states of the merge
+         */
         @Override
         protected void merge(List<BlockT> states) {
             super.merge(states);
 
-            /*
-             * Iterative processing: Merging the materialized/virtual state of virtual objects can
-             * lead to new materializations, which can lead to new materializations because of phis,
-             * and so on.
-             */
-
+            // calculate the set of virtual objects that exist in all predecessors
             HashSet<VirtualObjectNode> virtualObjTemp = new HashSet<>(states.get(0).getVirtualObjects());
             for (int i = 1; i < states.size(); i++) {
                 virtualObjTemp.retainAll(states.get(i).getVirtualObjects());
             }
 
+            ObjectState[] objStates = new ObjectState[states.size()];
             boolean materialized;
             do {
                 mergeEffects.clear();
                 afterMergeEffects.clear();
                 materialized = false;
                 for (VirtualObjectNode object : virtualObjTemp) {
-                    ObjectState[] objStates = new ObjectState[states.size()];
-                    for (int i = 0; i < states.size(); i++) {
-                        objStates[i] = states.get(i).getObjectStateOptional(object);
-                        assert objStates[i] != null;
+                    for (int i = 0; i < objStates.length; i++) {
+                        objStates[i] = states.get(i).getObjectState(object);
                     }
+
+                    // determine if all inputs are virtual or the same materialized value
                     int virtual = 0;
                     ObjectState startObj = objStates[0];
                     boolean locksMatch = true;
-                    ValueNode singleValue = startObj.isVirtual() ? null : startObj.getMaterializedValue();
+                    ValueNode uniqueMaterializedValue = startObj.isVirtual() ? null : startObj.getMaterializedValue();
                     for (ObjectState obj : objStates) {
                         if (obj.isVirtual()) {
                             virtual++;
-                            singleValue = null;
-                        } else {
-                            if (obj.getMaterializedValue() != singleValue) {
-                                singleValue = null;
-                            }
+                            uniqueMaterializedValue = null;
+                            locksMatch &= obj.locksEqual(startObj);
+                        } else if (obj.getMaterializedValue() != uniqueMaterializedValue) {
+                            uniqueMaterializedValue = null;
                         }
-                        locksMatch &= obj.locksEqual(startObj);
                     }
 
-                    if (virtual < states.size() || !locksMatch) {
-                        if (singleValue == null) {
+                    if (virtual == objStates.length && locksMatch) {
+                        materialized |= mergeObjectStates(object, objStates, states);
+                    } else {
+                        if (uniqueMaterializedValue != null) {
+                            newState.addObject(object, new ObjectState(object, uniqueMaterializedValue, EscapeState.Materialized, null));
+                        } else {
                             PhiNode materializedValuePhi = getCachedPhi(object, Kind.Object);
                             mergeEffects.addFloatingNode(materializedValuePhi, "materializedPhi");
-                            for (int i = 0; i < states.size(); i++) {
-                                BlockT state = states.get(i);
+                            for (int i = 0; i < objStates.length; i++) {
                                 ObjectState obj = objStates[i];
-                                materialized |= obj.isVirtual();
                                 Block predecessor = mergeBlock.getPredecessors().get(i);
-                                ensureMaterialized(state, obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE);
+                                materialized |= ensureMaterialized(states.get(i), obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE);
                                 afterMergeEffects.addPhiInput(materializedValuePhi, obj.getMaterializedValue());
                             }
                             newState.addObject(object, new ObjectState(object, materializedValuePhi, EscapeState.Materialized, null));
-                        } else {
-                            newState.addObject(object, new ObjectState(object, singleValue, EscapeState.Materialized, null));
                         }
-                    } else {
-                        assert virtual == states.size();
-                        ValueNode[] values = startObj.getEntries().clone();
-                        PhiNode[] phis = getValuePhis(object);
-                        for (int index = 0; index < values.length; index++) {
-                            for (int i = 1; i < states.size(); i++) {
-                                ValueNode[] fields = objStates[i].getEntries();
-                                if (phis[index] == null && values[index] != fields[index]) {
-                                    Kind kind = values[index].kind();
-                                    if (kind == Kind.Illegal) {
-                                        // Can happen if one of the values is virtual and is only
-                                        // materialized in the following loop.
-                                        kind = Kind.Object;
-                                    }
-                                    phis[index] = new PhiNode(kind, merge);
-                                }
-                            }
-                        }
-                        outer: for (int index = 0; index < values.length; index++) {
-                            if (phis[index] != null) {
-                                mergeEffects.addFloatingNode(phis[index], "virtualMergePhi");
-                                for (int i = 0; i < states.size(); i++) {
-                                    if (!objStates[i].isVirtual()) {
-                                        break outer;
-                                    }
-                                    ValueNode[] fields = objStates[i].getEntries();
-                                    if (fields[index] instanceof VirtualObjectNode) {
-                                        ObjectState obj = states.get(i).getObjectState((VirtualObjectNode) fields[index]);
-                                        materialized |= obj.isVirtual();
-                                        Block predecessor = mergeBlock.getPredecessors().get(i);
-                                        ensureMaterialized(states.get(i), obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE);
-                                        fields[index] = obj.getMaterializedValue();
-                                    }
-                                    afterMergeEffects.addPhiInput(phis[index], fields[index]);
-                                }
-                                values[index] = phis[index];
-                            }
-                        }
-                        newState.addObject(object, new ObjectState(object, values, EscapeState.Virtual, startObj.getLocks()));
                     }
                 }
 
                 for (PhiNode phi : merge.phis()) {
                     if (usages.isMarked(phi) && phi.type() == PhiType.Value) {
-                        materialized |= processPhi(phi, states);
+                        materialized |= processPhi(phi, states, virtualObjTemp);
                     }
                 }
             } while (materialized);
         }
 
-        private boolean processPhi(PhiNode phi, List<BlockT> states) {
-            aliases.set(phi, null);
-            assert states.size() == phi.valueCount();
-            int virtualInputs = 0;
-            boolean materialized = false;
-            VirtualObjectNode sameObject = null;
-            ResolvedJavaType sameType = null;
-            int sameEntryCount = -1;
-            boolean hasIdentity = false;
-            for (int i = 0; i < phi.valueCount(); i++) {
-                ValueNode value = phi.valueAt(i);
-                ObjectState obj = getObjectState(states.get(i), value);
-                if (obj != null) {
-                    if (obj.isVirtual()) {
-                        virtualInputs++;
-                        if (i == 0) {
-                            sameObject = obj.virtual;
-                            sameType = obj.virtual.type();
-                            sameEntryCount = obj.virtual.entryCount();
-                        } else {
-                            if (sameObject != obj.virtual) {
-                                sameObject = null;
+        /**
+         * Try to merge multiple virtual object states into a single object state. If the incoming
+         * object states are compatible, then this method will create PhiNodes for the object's
+         * entries where needed. If they are incompatible, then all incoming virtual objects will be
+         * materialized, and a PhiNode for the materialized values will be created. Object states
+         * can be incompatible if they contain {@code long} or {@code double} values occupying two
+         * {@code int} slots in such a way that that their values cannot be merged using PhiNodes.
+         * 
+         * @param object the virtual object that should be associated with the merged object state
+         * @param objStates the incoming object states (all of which need to be virtual)
+         * @param blockStates the predecessor block states of the merge
+         * @return true if materialization happened during the merge, false otherwise
+         */
+        private boolean mergeObjectStates(VirtualObjectNode object, ObjectState[] objStates, List<BlockT> blockStates) {
+            boolean compatible = true;
+            ValueNode[] values = objStates[0].getEntries().clone();
+
+            // determine all entries that have a two-slot value
+            Kind[] twoSlotKinds = null;
+            outer: for (int i = 0; i < objStates.length; i++) {
+                ValueNode[] entries = objStates[i].getEntries();
+                int valueIndex = 0;
+                while (valueIndex < values.length) {
+                    Kind otherKind = entries[valueIndex].kind();
+                    Kind entryKind = object.entryKind(valueIndex);
+                    if (entryKind == Kind.Int && (otherKind == Kind.Long || otherKind == Kind.Double)) {
+                        if (twoSlotKinds == null) {
+                            twoSlotKinds = new Kind[values.length];
+                        }
+                        if (twoSlotKinds[valueIndex] != null && twoSlotKinds[valueIndex] != otherKind) {
+                            compatible = false;
+                            break outer;
+                        }
+                        twoSlotKinds[valueIndex] = otherKind;
+                        // skip the next entry
+                        valueIndex++;
+                    } else {
+                        assert entryKind.getStackKind() == otherKind.getStackKind() : entryKind + " vs " + otherKind;
+                    }
+                    valueIndex++;
+                }
+            }
+            if (compatible && twoSlotKinds != null) {
+                // if there are two-slot values then make sure the incoming states can be merged
+                outer: for (int valueIndex = 0; valueIndex < values.length; valueIndex++) {
+                    if (twoSlotKinds[valueIndex] != null) {
+                        assert valueIndex < object.entryCount() - 1 && object.entryKind(valueIndex) == Kind.Int && object.entryKind(valueIndex + 1) == Kind.Int;
+                        for (int i = 0; i < objStates.length; i++) {
+                            ValueNode value = objStates[i].getEntry(valueIndex);
+                            Kind valueKind = value.kind();
+                            if (valueKind != twoSlotKinds[valueIndex]) {
+                                ValueNode nextValue = objStates[i].getEntry(valueIndex + 1);
+                                if (value.isConstant() && value.asConstant().equals(Constant.INT_0) && nextValue.isConstant() && nextValue.asConstant().equals(Constant.INT_0)) {
+                                    // rewrite to a zero constant of the larger kind
+                                    objStates[i].setEntry(valueIndex, ConstantNode.defaultForKind(twoSlotKinds[valueIndex], merge.graph()));
+                                    objStates[i].setEntry(valueIndex + 1, ConstantNode.forConstant(Constant.forIllegal(), tool.getMetaAccessProvider(), merge.graph()));
+                                } else {
+                                    compatible = false;
+                                    break outer;
+                                }
                             }
-                            if (sameType != obj.virtual.type()) {
-                                sameType = null;
-                            }
-                            if (sameEntryCount != obj.virtual.entryCount()) {
-                                sameEntryCount = -1;
-                            }
-                            hasIdentity |= obj.virtual.hasIdentity();
                         }
-                    } else {
-                        afterMergeEffects.setPhiInput(phi, i, obj.getMaterializedValue());
                     }
                 }
             }
-            boolean materialize = false;
-            if (virtualInputs == 0) {
-                // nothing to do...
-            } else if (virtualInputs == phi.valueCount()) {
-                if (sameObject != null) {
-                    addAndMarkAlias(sameObject, phi);
-                } else if (sameType != null && sameEntryCount != -1) {
-                    if (!hasIdentity) {
-                        VirtualObjectNode virtual = getValueObjectVirtual(phi, getObjectState(states.get(0), phi.valueAt(0)).virtual);
+
+            if (compatible) {
+                // virtual objects are compatible: create phis for all entries that need them
+                PhiNode[] phis = getValuePhis(object, object.entryCount());
+                int valueIndex = 0;
+                while (valueIndex < values.length) {
+                    for (int i = 1; i < objStates.length; i++) {
+                        ValueNode[] fields = objStates[i].getEntries();
+                        if (phis[valueIndex] == null && values[valueIndex] != fields[valueIndex]) {
+                            phis[valueIndex] = new PhiNode(values[valueIndex].kind(), merge);
+                        }
+                    }
+                    if (twoSlotKinds != null && twoSlotKinds[valueIndex] != null) {
+                        // skip an entry after a long/double value that occupies two int slots
+                        valueIndex++;
+                        phis[valueIndex] = null;
+                        values[valueIndex] = ConstantNode.forConstant(Constant.forIllegal(), tool.getMetaAccessProvider(), merge.graph());
+                    }
+                    valueIndex++;
+                }
+
+                boolean materialized = false;
+                for (int i = 0; i < values.length; i++) {
+                    PhiNode phi = phis[i];
+                    if (phi != null) {
+                        mergeEffects.addFloatingNode(phi, "virtualMergePhi");
+                        if (object.entryKind(i) == Kind.Object) {
+                            materialized |= mergeObjectEntry(objStates, blockStates, phi, i);
+                        } else {
+                            mergePrimitiveEntry(objStates, phi, i);
+                        }
+                        values[i] = phi;
+                    }
+                }
+                newState.addObject(object, new ObjectState(object, values, EscapeState.Virtual, objStates[0].getLocks()));
+                return materialized;
+            } else {
+                // not compatible: materialize in all predecessors
+                PhiNode materializedValuePhi = getCachedPhi(object, Kind.Object);
+                for (int i = 0; i < blockStates.size(); i++) {
+                    ObjectState obj = objStates[i];
+                    Block predecessor = mergeBlock.getPredecessors().get(i);
+                    ensureMaterialized(blockStates.get(i), obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE);
+                    afterMergeEffects.addPhiInput(materializedValuePhi, obj.getMaterializedValue());
+                }
+                newState.addObject(object, new ObjectState(object, materializedValuePhi, EscapeState.Materialized, null));
+                return true;
+            }
+        }
 
-                        PhiNode[] phis = getValueObjectMergePhis(phi, virtual.entryCount());
-                        for (int i = 0; i < virtual.entryCount(); i++) {
-                            assert virtual.entryKind(i) != Kind.Object;
-                            if (phis[i] == null) {
-                                phis[i] = new PhiNode(virtual.entryKind(i), merge);
-                            }
-                            mergeEffects.addFloatingNode(phis[i], "valueObjectPhi");
-                            for (int i2 = 0; i2 < phi.valueCount(); i2++) {
-                                afterMergeEffects.addPhiInput(phis[i], getObjectState(states.get(i2), phi.valueAt(i2)).getEntry(i));
-                            }
+        /**
+         * Fill the inputs of the PhiNode corresponding to one {@link Kind#Object} entry in the
+         * virtual object.
+         * 
+         * @return true if materialization happened during the merge, false otherwise
+         */
+        private boolean mergeObjectEntry(ObjectState[] objStates, List<BlockT> blockStates, PhiNode phi, int entryIndex) {
+            boolean materialized = false;
+            for (int i = 0; i < objStates.length; i++) {
+                if (!objStates[i].isVirtual()) {
+                    break;
+                }
+                ValueNode[] entries = objStates[i].getEntries();
+                if (entries[entryIndex] instanceof VirtualObjectNode) {
+                    ObjectState obj = blockStates.get(i).getObjectState((VirtualObjectNode) entries[entryIndex]);
+                    Block predecessor = mergeBlock.getPredecessors().get(i);
+                    materialized |= ensureMaterialized(blockStates.get(i), obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE);
+                    entries[entryIndex] = obj.getMaterializedValue();
+                }
+                afterMergeEffects.addPhiInput(phi, entries[entryIndex]);
+            }
+            return materialized;
+        }
+
+        /**
+         * Fill the inputs of the PhiNode corresponding to one primitive entry in the virtual
+         * object.
+         */
+        private void mergePrimitiveEntry(ObjectState[] objStates, PhiNode phi, int entryIndex) {
+            for (ObjectState state : objStates) {
+                if (!state.isVirtual()) {
+                    break;
+                }
+                afterMergeEffects.addPhiInput(phi, state.getEntries()[entryIndex]);
+            }
+        }
+
+        /**
+         * Examine a PhiNode and try to replace it with merging of virtual objects if all its inputs
+         * refer to virtual object states. In order for the merging to happen, all incoming object
+         * states need to be compatible and without object identity (meaning that their object
+         * identity if not used later on).
+         * 
+         * @param phi the PhiNode that should be processed
+         * @param states the predecessor block states of the merge
+         * @param mergedVirtualObjects the set of virtual objects that exist in all incoming states,
+         *            and therefore also exist in the merged state
+         * @return true if materialization happened during the merge, false otherwise
+         */
+        private boolean processPhi(PhiNode phi, List<BlockT> states, Set<VirtualObjectNode> mergedVirtualObjects) {
+            aliases.set(phi, null);
+            assert states.size() == phi.valueCount();
+
+            // determine how many inputs are virtual and if they're all the same virtual object
+            int virtualInputs = 0;
+            ObjectState[] objStates = new ObjectState[states.size()];
+            boolean uniqueVirtualObject = true;
+            for (int i = 0; i < objStates.length; i++) {
+                ObjectState obj = objStates[i] = getObjectState(states.get(i), phi.valueAt(i));
+                if (obj != null) {
+                    if (obj.isVirtual()) {
+                        if (objStates[0] == null || objStates[0].virtual != obj.virtual) {
+                            uniqueVirtualObject = false;
                         }
+                        virtualInputs++;
+                    }
+                }
+            }
+            if (virtualInputs == objStates.length) {
+                if (uniqueVirtualObject) {
+                    // all inputs refer to the same object: just make the phi node an alias
+                    addAndMarkAlias(objStates[0].virtual, phi);
+                    return false;
+                } else {
+                    // all inputs are virtual: check if they're compatible and without identity
+                    boolean compatible = true;
+                    ObjectState firstObj = objStates[0];
+                    for (int i = 0; i < objStates.length; i++) {
+                        ObjectState obj = objStates[i];
+                        boolean hasIdentity = obj.virtual.hasIdentity() && mergedVirtualObjects.contains(obj.virtual);
+                        if (hasIdentity || firstObj.virtual.type() != obj.virtual.type() || firstObj.virtual.entryCount() != obj.virtual.entryCount() || !firstObj.locksEqual(obj)) {
+                            compatible = false;
+                            break;
+                        }
+                    }
+
+                    if (compatible) {
+                        VirtualObjectNode virtual = getValueObjectVirtual(phi, getObjectState(states.get(0), phi.valueAt(0)).virtual);
                         mergeEffects.addFloatingNode(virtual, "valueObjectNode");
-                        newState.addObject(virtual, new ObjectState(virtual, Arrays.copyOf(phis, phis.length, ValueNode[].class), EscapeState.Virtual, null));
+
+                        boolean materialized = mergeObjectStates(virtual, objStates, states);
                         addAndMarkAlias(virtual, virtual);
                         addAndMarkAlias(virtual, phi);
-                    } else {
-                        materialize = true;
+                        return materialized;
                     }
-                } else {
-                    materialize = true;
                 }
-            } else {
-                materialize = true;
             }
 
-            if (materialize) {
-                for (int i = 0; i < phi.valueCount(); i++) {
-                    ValueNode value = phi.valueAt(i);
-                    ObjectState obj = getObjectState(states.get(i), value);
-                    if (obj != null) {
-                        materialized |= obj.isVirtual();
-                        Block predecessor = mergeBlock.getPredecessors().get(i);
-                        replaceWithMaterialized(value, phi, predecessor.getEndNode(), states.get(i), obj, blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_PHI);
-                    }
+            // otherwise: materialize all phi inputs
+            boolean materialized = false;
+            for (int i = 0; i < objStates.length; i++) {
+                ObjectState obj = objStates[i];
+                if (obj != null) {
+                    Block predecessor = mergeBlock.getPredecessors().get(i);
+                    materialized |= ensureMaterialized(states.get(i), obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_PHI);
+                    afterMergeEffects.initializePhiInput(phi, i, obj.getMaterializedValue());
                 }
             }
             return materialized;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Mon Oct 28 13:10:10 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Mon Oct 28 13:01:16 2013 +0100
@@ -80,22 +80,26 @@
     }
 
     @Override
-    public void setVirtualEntry(State objectState, int index, ValueNode value) {
+    public void setVirtualEntry(State objectState, int index, ValueNode value, boolean unsafe) {
         ObjectState obj = (ObjectState) objectState;
         assert obj != null && obj.isVirtual() : "not virtual: " + obj;
-        ObjectState valueState = closure.getObjectState(state, value);
         ValueNode newValue;
-        if (valueState == null) {
-            newValue = getReplacedValue(value);
-            assert obj.getEntry(index) == null || obj.getEntry(index).kind() == newValue.kind() || (isObjectEntry(obj.getEntry(index)) && isObjectEntry(newValue));
+        if (value == null) {
+            newValue = null;
         } else {
-            if (valueState.getState() != EscapeState.Virtual) {
-                newValue = valueState.getMaterializedValue();
-                assert newValue.kind() == Kind.Object;
+            ObjectState valueState = closure.getObjectState(state, value);
+            if (valueState == null) {
+                newValue = getReplacedValue(value);
+                assert unsafe || obj.getEntry(index) == null || obj.getEntry(index).kind() == newValue.kind() || (isObjectEntry(obj.getEntry(index)) && isObjectEntry(newValue));
             } else {
-                newValue = valueState.getVirtualObject();
+                if (valueState.getState() != EscapeState.Virtual) {
+                    newValue = valueState.getMaterializedValue();
+                    assert newValue.kind() == Kind.Object;
+                } else {
+                    newValue = valueState.getVirtualObject();
+                }
+                assert obj.getEntry(index) == null || isObjectEntry(obj.getEntry(index));
             }
-            assert obj.getEntry(index) == null || isObjectEntry(obj.getEntry(index));
         }
         obj.setEntry(index, newValue);
     }
--- a/src/share/vm/runtime/deoptimization.cpp	Mon Oct 28 13:10:10 2013 +0200
+++ b/src/share/vm/runtime/deoptimization.cpp	Mon Oct 28 13:01:16 2013 +0100
@@ -914,7 +914,8 @@
   fields->sort(compare);
   for (int i = 0; i < fields->length(); i++) {
     intptr_t val;
-    StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(svIndex));
+    ScopeValue* scope_field = sv->field_at(svIndex);
+    StackValue* value = StackValue::create_stack_value(fr, reg_map, scope_field);
     int offset = fields->at(i)._offset;
     BasicType type = fields->at(i)._type;
     switch (type) {
@@ -923,6 +924,37 @@
         obj->obj_field_put(offset, value->get_obj()());
         break;
 
+      // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem.
+      case T_INT: case T_FLOAT: { // 4 bytes.
+        assert(value->type() == T_INT, "Agreement.");
+        bool big_value = false;
+        if (i+1 < fields->length() && fields->at(i+1)._type == T_INT) {
+          if (scope_field->is_location()) {
+            Location::Type type = ((LocationValue*) scope_field)->location().type();
+            if (type == Location::dbl || type == Location::lng) {
+              big_value = true;
+            }
+          }
+          if (scope_field->is_constant_int()) {
+            ScopeValue* next_scope_field = sv->field_at(svIndex + 1);
+            if (next_scope_field->is_constant_long() || next_scope_field->is_constant_double()) {
+              big_value = true;
+            }
+          }
+        }
+
+        if (big_value) {
+          i++;
+          assert(i < fields->length(), "second T_INT field needed");
+          assert(fields->at(i)._type == T_INT, "T_INT field needed");
+        } else {
+          val = value->get_int();
+          obj->int_field_put(offset, (jint)*((jint*)&val));
+          break;
+        }
+      }
+        /* no break */
+
       case T_LONG: case T_DOUBLE: {
         assert(value->type() == T_INT, "Agreement.");
         StackValue* low = StackValue::create_stack_value(fr, reg_map, sv->field_at(++svIndex));
@@ -939,12 +971,6 @@
         obj->long_field_put(offset, res);
         break;
       }
-      // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem.
-      case T_INT: case T_FLOAT: // 4 bytes.
-        assert(value->type() == T_INT, "Agreement.");
-        val = value->get_int();
-        obj->int_field_put(offset, (jint)*((jint*)&val));
-        break;
 
       case T_SHORT: case T_CHAR: // 2 bytes
         assert(value->type() == T_INT, "Agreement.");