changeset 7055:ec2e696fc3bc

Merge.
author Doug Simon <doug.simon@oracle.com>
date Tue, 27 Nov 2012 18:33:13 +0100
parents 5d4676ae84a4 (current diff) 6cbaae52bab9 (diff)
children 2841e28b5f41
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java
diffstat 21 files changed, 368 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Tue Nov 27 18:30:20 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Tue Nov 27 18:33:13 2012 +0100
@@ -242,4 +242,12 @@
      * Returns the {@link java.lang.Class} object representing this type.
      */
     Class< ? > toJava();
+
+    /**
+     * Returns the instance field of this class (or one of its super classes) at the given offset, or {@code null} if there is no such field.
+     *
+     * @param offset the offset of the field to look for
+     * @return the field with the given offset, or {@code null} if there is no such field.
+     */
+    ResolvedJavaField findFieldWithOffset(long offset);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Tue Nov 27 18:30:20 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Tue Nov 27 18:33:13 2012 +0100
@@ -45,8 +45,6 @@
 
     JavaMethod createUnresolvedJavaMethod(String name, String signature, JavaType holder);
 
-    Signature createSignature(String signature);
-
     JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags, boolean internal);
 
     ResolvedJavaMethod createResolvedJavaMethod(JavaType holder, long metaspaceMethod);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue Nov 27 18:30:20 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue Nov 27 18:33:13 2012 +0100
@@ -445,11 +445,6 @@
     }
 
     @Override
-    public Signature createSignature(String signature) {
-        return new HotSpotSignature(signature);
-    }
-
-    @Override
     public JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags, boolean internal) {
         if (offset != -1) {
             HotSpotResolvedJavaType resolved = (HotSpotResolvedJavaType) holder;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Tue Nov 27 18:30:20 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Tue Nov 27 18:33:13 2012 +0100
@@ -495,4 +495,15 @@
     public long prototypeMarkWord() {
         return HotSpotGraalRuntime.getInstance().getCompilerToVM().getPrototypeMarkWord(this);
     }
+
+    @Override
+    public ResolvedJavaField findFieldWithOffset(long offset) {
+        ResolvedJavaField[] declaredFields = getInstanceFields(true);
+        for (ResolvedJavaField field : declaredFields) {
+            if (((HotSpotResolvedJavaField) field).offset() == offset) {
+                return field;
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java	Tue Nov 27 18:30:20 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java	Tue Nov 27 18:33:13 2012 +0100
@@ -184,6 +184,11 @@
     }
 
     @Override
+    public ResolvedJavaField findFieldWithOffset(long offset) {
+        return null;
+    }
+
+    @Override
     public Class<?> mirror() {
         return javaMirror;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java	Tue Nov 27 18:30:20 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java	Tue Nov 27 18:33:13 2012 +0100
@@ -27,7 +27,6 @@
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.snippets.*;
 
@@ -35,7 +34,7 @@
  * Intrinsic for allocating an on-stack array of integers to hold the dimensions
  * of a multianewarray instruction.
  */
-public final class DimensionsNode extends FixedWithNextNode implements LIRGenLowerable, MonitorEnter {
+public final class DimensionsNode extends FixedWithNextNode implements LIRGenLowerable {
 
     private final int rank;
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Tue Nov 27 18:30:20 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Tue Nov 27 18:33:13 2012 +0100
@@ -26,12 +26,13 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.virtual.*;
 
 /**
  * Load of a value from a location specified as an offset relative to an object.
  * No null check is performed before the load.
  */
-public class UnsafeLoadNode extends FixedWithNextNode implements Lowerable {
+public class UnsafeLoadNode extends FixedWithNextNode implements Lowerable, Virtualizable {
 
     @Input private ValueNode object;
     @Input private ValueNode offset;
@@ -75,6 +76,26 @@
         tool.getRuntime().lower(this, tool);
     }
 
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        VirtualObjectNode virtual = tool.getVirtualState(object());
+        if (virtual != null) {
+            ValueNode indexValue = tool.getReplacedValue(offset());
+            if (indexValue.isConstant()) {
+                int fieldIndex = virtual.fieldIndexForOffset(indexValue.asConstant().asLong());
+                if (fieldIndex != -1) {
+                    ValueNode result = tool.getVirtualEntry(virtual, fieldIndex);
+                    VirtualObjectNode virtualResult = tool.getVirtualState(result);
+                    if (virtualResult != null) {
+                        tool.replaceWithVirtual(virtualResult);
+                    } else {
+                        tool.replaceWithValue(result);
+                    }
+                }
+            }
+        }
+    }
+
     @NodeIntrinsic
     public static native <T> T load(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind kind);
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Tue Nov 27 18:30:20 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Tue Nov 27 18:33:13 2012 +0100
@@ -26,12 +26,13 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.virtual.*;
 
 /**
  * Store of a value at a location specified as an offset relative to an object.
  * No null check is performed before the store.
  */
-public class UnsafeStoreNode extends FixedWithNextNode implements StateSplit, Lowerable {
+public class UnsafeStoreNode extends FixedWithNextNode implements StateSplit, Lowerable, Virtualizable {
 
     @Input private ValueNode object;
     @Input private ValueNode offset;
@@ -96,6 +97,21 @@
         tool.getRuntime().lower(this, tool);
     }
 
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        VirtualObjectNode virtual = tool.getVirtualState(object());
+        if (virtual != null) {
+            ValueNode indexValue = tool.getReplacedValue(offset());
+            if (indexValue.isConstant()) {
+                int fieldIndex = virtual.fieldIndexForOffset(indexValue.asConstant().asLong());
+                if (fieldIndex != -1) {
+                    tool.setVirtualEntry(virtual, fieldIndex, value());
+                    tool.delete();
+                }
+            }
+        }
+    }
+
     // specialized on value type until boxing/unboxing is sorted out in intrinsification
     @NodeIntrinsic
     public static native void store(Object object, @ConstantNodeParameter int displacement, long offset, Object value, @ConstantNodeParameter Kind kind);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java	Tue Nov 27 18:30:20 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java	Tue Nov 27 18:33:13 2012 +0100
@@ -58,4 +58,10 @@
         assert index == 0;
         return "value";
     }
+
+    @Override
+    public int fieldIndexForOffset(long constantOffset) {
+        // (lstadler) unsafe access to a newly created boxing object should only ever touch the value field
+        return 0;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java	Tue Nov 27 18:30:20 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java	Tue Nov 27 18:33:13 2012 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.nodes.virtual;
 
+import sun.misc.*;
+
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.spi.*;
@@ -70,4 +72,59 @@
     public String fieldName(int index) {
         return "[" + index + "]";
     }
+
+    @Override
+    public int fieldIndexForOffset(long constantOffset) {
+        int baseOffset;
+        int indexScale;
+        switch (componentType.getKind()) {
+            case Boolean:
+                baseOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
+                break;
+            case Byte:
+                baseOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_BYTE_INDEX_SCALE;
+                break;
+            case Short:
+                baseOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_SHORT_INDEX_SCALE;
+                break;
+            case Char:
+                baseOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_CHAR_INDEX_SCALE;
+                break;
+            case Int:
+                baseOffset = Unsafe.ARRAY_INT_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_INT_INDEX_SCALE;
+                break;
+            case Long:
+                baseOffset = Unsafe.ARRAY_LONG_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_LONG_INDEX_SCALE;
+                break;
+            case Float:
+                baseOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_FLOAT_INDEX_SCALE;
+                break;
+            case Double:
+                baseOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
+                break;
+            case Object:
+                baseOffset = Unsafe.ARRAY_OBJECT_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_OBJECT_INDEX_SCALE;
+                break;
+            default:
+                return -1;
+        }
+        long index = constantOffset - baseOffset;
+        if (index % indexScale != 0) {
+            return -1;
+        }
+        long elementIndex = index / indexScale;
+        if (elementIndex < 0 || elementIndex >= length) {
+            return -1;
+        }
+        return (int) elementIndex;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Tue Nov 27 18:30:20 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Tue Nov 27 18:33:13 2012 +0100
@@ -75,4 +75,9 @@
         Integer index = fieldMap.get(field);
         return index == null ? -1 : index;
     }
+
+    @Override
+    public int fieldIndexForOffset(long constantOffset) {
+        return fieldIndex(type.findFieldWithOffset(constantOffset));
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java	Tue Nov 27 18:30:20 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java	Tue Nov 27 18:33:13 2012 +0100
@@ -57,4 +57,6 @@
     public void materializeAt(@SuppressWarnings("unused") FixedNode fixed) {
         // nothing to do in here - this method allows subclasses to respond to materialization
     }
+
+    public abstract int fieldIndexForOffset(long constantOffset);
 }
--- a/src/share/vm/code/debugInfo.cpp	Tue Nov 27 18:30:20 2012 +0100
+++ b/src/share/vm/code/debugInfo.cpp	Tue Nov 27 18:33:13 2012 +0100
@@ -77,7 +77,11 @@
 
 enum { LOCATION_CODE = 0, CONSTANT_INT_CODE = 1,  CONSTANT_OOP_CODE = 2,
                           CONSTANT_LONG_CODE = 3, CONSTANT_DOUBLE_CODE = 4,
-                          OBJECT_CODE = 5,        OBJECT_ID_CODE = 6 };
+                          OBJECT_CODE = 5,        OBJECT_ID_CODE = 6,
+#ifdef GRAAL
+                          DEFERRED_READ_CODE = 7, DEFERRED_WRITE_CODE = 8
+#endif // GRAAL
+};
 
 ScopeValue* ScopeValue::read_from(DebugInfoReadStream* stream) {
   ScopeValue* result = NULL;
@@ -89,6 +93,10 @@
    case CONSTANT_DOUBLE_CODE: result = new ConstantDoubleValue(stream);  break;
    case OBJECT_CODE:          result = stream->read_object_value();      break;
    case OBJECT_ID_CODE:       result = stream->get_cached_object();      break;
+#ifdef GRAAL
+   case DEFERRED_READ_CODE:   result = new DeferredReadValue(stream);    break;
+   case DEFERRED_WRITE_CODE:  result = new DeferredWriteValue(stream);   break;
+#endif // GRAAL
    default: ShouldNotReachHere();
   }
   return result;
@@ -109,6 +117,63 @@
   location().print_on(st);
 }
 
+#ifdef GRAAL
+
+// DeferredLocationValue
+
+DeferredLocationValue::DeferredLocationValue(DebugInfoReadStream* stream) {
+  _base = read_from(stream);
+  _index = read_from(stream);
+  _scale = stream->read_int();
+  _disp = stream->read_long();
+}
+
+void DeferredLocationValue::write_on(DebugInfoWriteStream* stream) {
+  _base->write_on(stream);
+  _index->write_on(stream);
+  stream->write_int(_scale);
+  stream->write_long(_disp);
+}
+
+void DeferredLocationValue::print_on(outputStream* st) const {
+  _base->print_on(st);
+  _index->print_on(st);
+  st->print("%i %i", _scale, _disp);
+}
+
+// DeferredReadValue
+
+DeferredReadValue::DeferredReadValue(DebugInfoReadStream* stream)
+: DeferredLocationValue(stream) {
+}
+
+void DeferredReadValue::write_on(DebugInfoWriteStream* st) {
+  DeferredLocationValue::write_on(st);
+}
+
+void DeferredReadValue::print_on(outputStream* st) const {
+  DeferredLocationValue::print_on(st);
+}
+
+// DeferredWriteValue
+
+DeferredWriteValue::DeferredWriteValue(DebugInfoReadStream* stream)
+: DeferredLocationValue(stream) {
+  _value = read_from(stream);
+}
+
+void DeferredWriteValue::write_on(DebugInfoWriteStream* st) {
+  DeferredLocationValue::write_on(st);
+  _value->write_on(st);
+}
+
+void DeferredWriteValue::print_on(outputStream* st) const {
+  DeferredLocationValue::print_on(st);
+  _value->print_on(st);
+}
+
+#endif // GRAAL
+
 // ObjectValue
 
 void ObjectValue::read_object(DebugInfoReadStream* stream) {
--- a/src/share/vm/code/debugInfo.hpp	Tue Nov 27 18:30:20 2012 +0100
+++ b/src/share/vm/code/debugInfo.hpp	Tue Nov 27 18:33:13 2012 +0100
@@ -61,6 +61,11 @@
   // Serialization of debugging information
   virtual void write_on(DebugInfoWriteStream* stream) = 0;
   static ScopeValue* read_from(DebugInfoReadStream* stream);
+
+#ifdef GRAAL
+  // Printing
+  virtual void print_on(outputStream* st) const = 0;
+#endif // GRAAL
 };
 
 
@@ -83,6 +88,64 @@
   void print_on(outputStream* st) const;
 };
 
+#ifdef GRAAL
+
+class DeferredLocationValue: public ScopeValue {
+private:
+  ScopeValue* _base;
+  ScopeValue* _index;
+  jint _scale;
+  jlong _disp;
+public:
+  DeferredLocationValue(ScopeValue* base, ScopeValue* index, jint scale, jlong disp)
+  : _base(base), _index(index), _scale(scale), _disp(disp) { }
+
+  ScopeValue* base() { return _base; }
+  ScopeValue* index() { return _index; }
+  jint scale() { return _scale; }
+  jlong disp() { return _disp; }
+
+  // Serialization of debugging information
+  DeferredLocationValue(DebugInfoReadStream* stream);
+  void write_on(DebugInfoWriteStream* stream);
+
+  // Printing
+  void print_on(outputStream* st) const;
+};
+
+
+class DeferredReadValue: public DeferredLocationValue {
+public:
+  DeferredReadValue(ScopeValue* base, ScopeValue* index, jint scale, jint disp)
+  : DeferredLocationValue(base, index, scale, disp) { }
+
+  // Serialization of debugging information
+  DeferredReadValue(DebugInfoReadStream* stream);
+  void write_on(DebugInfoWriteStream* stream);
+
+  // Printing
+  void print_on(outputStream* st) const;
+};
+
+class DeferredWriteValue: public DeferredLocationValue {
+private:
+  ScopeValue* _value;
+public:
+  DeferredWriteValue(ScopeValue* base, ScopeValue* index, jint scale, jint disp, ScopeValue* value)
+  : DeferredLocationValue(base, index, scale, disp), _value(value) { }
+
+  ScopeValue* value() { return _value; }
+
+  // Serialization of debugging information
+  DeferredWriteValue(DebugInfoReadStream* stream);
+  void write_on(DebugInfoWriteStream* stream);
+
+  // Printing
+  void print_on(outputStream* st) const;
+};
+
+#endif // GRAAL
+
 
 // An ObjectValue describes an object eliminated by escape analysis.
 
--- a/src/share/vm/code/debugInfoRec.cpp	Tue Nov 27 18:30:20 2012 +0100
+++ b/src/share/vm/code/debugInfoRec.cpp	Tue Nov 27 18:33:13 2012 +0100
@@ -213,6 +213,29 @@
   return result;
 }
 
+#ifdef GRAAL
+
+int DebugInformationRecorder::serialize_deferred_writes(GrowableArray<DeferredWriteValue*>* deferred_writes) {
+  if (deferred_writes == NULL || deferred_writes->is_empty()) return DebugInformationRecorder::serialized_null;
+  assert(_recording_state == rs_safepoint, "must be recording a safepoint");
+  int result = stream()->position();
+  assert(result != serialized_null, "sanity");
+  stream()->write_int(deferred_writes->length());
+  for (int index = 0; index < deferred_writes->length(); index++) {
+    deferred_writes->at(index)->write_on(stream());
+  }
+
+  // (See comment below on DebugInformationRecorder::describe_scope.)
+  int shared_result = find_sharable_decode_offset(result);
+  if (shared_result != serialized_null) {
+    stream()->set_position(result);
+    result = shared_result;
+  }
+
+  return result;
+}
+
+#endif // GRAAL
 
 #ifndef PRODUCT
 // These variables are put into one block to reduce relocations
@@ -289,7 +312,11 @@
                                               bool        return_oop,
                                               DebugToken* locals,
                                               DebugToken* expressions,
-                                              DebugToken* monitors) {
+                                              DebugToken* monitors
+#ifdef GRAAL
+                                              , DebugToken* deferred_writes
+#endif // GRAAL
+                                              ) {
   assert(_recording_state != rs_null, "nesting of recording calls");
   PcDesc* last_pd = last_pc();
   assert(last_pd->pc_offset() == pc_offset, "must be last pc");
@@ -328,6 +355,9 @@
   stream()->write_int((intptr_t) locals);
   stream()->write_int((intptr_t) expressions);
   stream()->write_int((intptr_t) monitors);
+#ifdef GRAAL
+  stream()->write_int((intptr_t) deferred_writes);
+#endif // GRAAL
 
   // Here's a tricky bit.  We just wrote some bytes.
   // Wouldn't it be nice to find that we had already
@@ -409,6 +439,14 @@
   return (DebugToken*) (intptr_t) serialize_monitor_values(monitors);
 }
 
+#ifdef GRAAL
+
+DebugToken* DebugInformationRecorder::create_deferred_writes(GrowableArray<DeferredWriteValue*>* deferred_writes) {
+  assert(!recorders_frozen(), "not frozen yet");
+  return (DebugToken*) (intptr_t) serialize_deferred_writes(deferred_writes);
+}
+
+#endif // GRAAL
 
 int DebugInformationRecorder::data_size() {
   debug_only(mark_recorders_frozen());  // mark it "frozen" for asserts
--- a/src/share/vm/code/debugInfoRec.hpp	Tue Nov 27 18:30:20 2012 +0100
+++ b/src/share/vm/code/debugInfoRec.hpp	Tue Nov 27 18:33:13 2012 +0100
@@ -107,7 +107,11 @@
                       bool        return_oop = false,
                       DebugToken* locals      = NULL,
                       DebugToken* expressions = NULL,
-                      DebugToken* monitors    = NULL);
+                      DebugToken* monitors    = NULL
+#ifdef GRAAL
+                      , DebugToken* deferred_writes = NULL
+#endif // GRAAL
+                      );
 
 
   void dump_object_pool(GrowableArray<ScopeValue*>* objects);
@@ -120,6 +124,9 @@
   // helper fuctions for describe_scope to enable sharing
   DebugToken* create_scope_values(GrowableArray<ScopeValue*>* values);
   DebugToken* create_monitor_values(GrowableArray<MonitorValue*>* monitors);
+#ifdef GRAAL
+  DebugToken* create_deferred_writes(GrowableArray<DeferredWriteValue*>* deferred_writes);
+#endif // GRAAL
 
   // returns the size of the generated scopeDescs.
   int data_size();
@@ -194,6 +201,9 @@
 
   int  serialize_monitor_values(GrowableArray<MonitorValue*>* monitors);
   int  serialize_scope_values(GrowableArray<ScopeValue*>* values);
+#ifdef GRAAL
+  int serialize_deferred_writes(GrowableArray<DeferredWriteValue*>* deferred_writes);
+#endif // GRAAL
   int  find_sharable_decode_offset(int stream_offset);
 
 #ifndef PRODUCT
--- a/src/share/vm/code/scopeDesc.cpp	Tue Nov 27 18:30:20 2012 +0100
+++ b/src/share/vm/code/scopeDesc.cpp	Tue Nov 27 18:33:13 2012 +0100
@@ -73,6 +73,9 @@
     _locals_decode_offset = DebugInformationRecorder::serialized_null;
     _expressions_decode_offset = DebugInformationRecorder::serialized_null;
     _monitors_decode_offset = DebugInformationRecorder::serialized_null;
+#ifdef GRAAL
+    _deferred_writes_decode_offset = DebugInformationRecorder::serialized_null;
+#endif // GRAAL
   } else {
     // decode header
     DebugInfoReadStream* stream  = stream_at(decode_offset());
@@ -85,6 +88,9 @@
     _locals_decode_offset      = stream->read_int();
     _expressions_decode_offset = stream->read_int();
     _monitors_decode_offset    = stream->read_int();
+#ifdef GRAAL
+    _deferred_writes_decode_offset = stream->read_int();
+#endif // GRAAL
   }
 }
 
@@ -126,6 +132,25 @@
   return result;
 }
 
+#ifdef GRAAL
+
+GrowableArray<DeferredWriteValue*>* ScopeDesc::decode_deferred_writes(int decode_offset) {
+  if (decode_offset == DebugInformationRecorder::serialized_null) return NULL;
+  DebugInfoReadStream* stream  = stream_at(decode_offset);
+  int length = stream->read_int();
+  GrowableArray<DeferredWriteValue*>* result = new GrowableArray<DeferredWriteValue*> (length);
+  for (int index = 0; index < length; index++) {
+    result->push(new DeferredWriteValue(stream));
+  }
+  return result;
+}
+
+GrowableArray<DeferredWriteValue*>* ScopeDesc::deferred_writes() {
+  return decode_deferred_writes(_deferred_writes_decode_offset);
+}
+
+#endif // GRAAL
+
 DebugInfoReadStream* ScopeDesc::stream_at(int decode_offset) const {
   return new DebugInfoReadStream(_code, decode_offset, _objects);
 }
@@ -225,8 +250,8 @@
     }
   }
 
-#ifdef COMPILER2
-  if (DoEscapeAnalysis && is_top() && _objects != NULL) {
+#if defined(COMPILER2) || defined(GRAAL)
+  if (NOT_GRAAL(DoEscapeAnalysis &&) is_top() && _objects != NULL) {
     tty->print_cr("Objects");
     for (int i = 0; i < _objects->length(); i++) {
       ObjectValue* sv = (ObjectValue*) _objects->at(i);
@@ -235,7 +260,20 @@
       tty->cr();
     }
   }
-#endif // COMPILER2
+#endif // COMPILER2 || GRAAL
+#ifdef GRAAL
+  // deferred writes
+  { GrowableArray<DeferredWriteValue*>* l = ((ScopeDesc*) this)->deferred_writes();
+    if (l != NULL) {
+      st->print_cr("   Deferred writes");
+      for (int index = 0; index < l->length(); index++) {
+        st->print("    - @%d: ", index);
+        l->at(index)->print_on(st);
+        st->cr();
+      }
+    }
+  }
+#endif
 }
 
 #endif
--- a/src/share/vm/code/scopeDesc.hpp	Tue Nov 27 18:30:20 2012 +0100
+++ b/src/share/vm/code/scopeDesc.hpp	Tue Nov 27 18:33:13 2012 +0100
@@ -78,6 +78,9 @@
   GrowableArray<ScopeValue*>*   expressions();
   GrowableArray<MonitorValue*>* monitors();
   GrowableArray<ScopeValue*>*   objects();
+#ifdef GRAAL
+  GrowableArray<DeferredWriteValue*>* deferred_writes();
+#endif // GRAAL
 
   // Stack walking, returns NULL if this is the outer most scope.
   ScopeDesc* sender() const;
@@ -107,6 +110,9 @@
   int _locals_decode_offset;
   int _expressions_decode_offset;
   int _monitors_decode_offset;
+#ifdef GRAAL
+  int _deferred_writes_decode_offset;
+#endif // GRAAL
 
   // Object pool
   GrowableArray<ScopeValue*>* _objects;
@@ -119,6 +125,9 @@
   GrowableArray<ScopeValue*>* decode_scope_values(int decode_offset);
   GrowableArray<MonitorValue*>* decode_monitor_values(int decode_offset);
   GrowableArray<ScopeValue*>* decode_object_values(int decode_offset);
+#ifdef GRAAL
+  GrowableArray<DeferredWriteValue*>* decode_deferred_writes(int decode_offset);
+#endif // GRAAL
 
   DebugInfoReadStream* stream_at(int decode_offset) const;
 
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Tue Nov 27 18:30:20 2012 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Tue Nov 27 18:33:13 2012 +0100
@@ -530,9 +530,13 @@
   DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions);
   DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors);
 
+  GrowableArray<DeferredWriteValue*>* deferred_writes = new GrowableArray<DeferredWriteValue*> ();
+//  deferred_writes->append(new DeferredWriteValue(new LocationValue(Location::new_reg_loc(Location::lng, rax->as_VMReg())), new ConstantIntValue(0), 0, 100, new ConstantIntValue(123)));
+  DebugToken* deferred_writes_token = _debug_recorder->create_deferred_writes(deferred_writes);
+
   bool throw_exception = BytecodeFrame::rethrowException(frame) == JNI_TRUE;
 
-  _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, locals_token, expressions_token, monitors_token);
+  _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, locals_token, expressions_token, monitors_token, deferred_writes_token);
 }
 
 void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) {
--- a/src/share/vm/graal/graalVMToCompiler.cpp	Tue Nov 27 18:30:20 2012 +0100
+++ b/src/share/vm/graal/graalVMToCompiler.cpp	Tue Nov 27 18:33:13 2012 +0100
@@ -234,17 +234,6 @@
   return (oop) result.get_jobject();
 }
 
-oop VMToCompiler::createSignature(Handle name, TRAPS) {
-  assert(!name.is_null(), "just checking");
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_oop(name);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createSignature_name(), vmSymbols::createSignature_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createSignature");
-  return (oop) result.get_jobject();
-}
-
 oop VMToCompiler::createConstant(Handle kind, jlong value, TRAPS) {
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
--- a/src/share/vm/graal/graalVMToCompiler.hpp	Tue Nov 27 18:30:20 2012 +0100
+++ b/src/share/vm/graal/graalVMToCompiler.hpp	Tue Nov 27 18:33:13 2012 +0100
@@ -86,9 +86,6 @@
   // public abstract JavaType createPrimitiveJavaType(int basicType);
   static oop createPrimitiveJavaType(int basicType, TRAPS);
 
-  // public abstract Signature createSignature(String signature);
-  static oop createSignature(Handle name, TRAPS);
-
   // public abstract Constant createConstant(Kind kind, long value);
   static oop createConstant(Handle kind, jlong value, TRAPS);