changeset 7046:b6a8f2d23057

VM support for deferred reads and writes: ScopeDesc, DebugInfo, DebugInfoRecorder
author Lukas Stadler <lukas.stadler@jku.at>
date Tue, 27 Nov 2012 13:43:04 +0100
parents adf5c101bc4b
children 3269254a9b25
files src/share/vm/code/debugInfo.cpp src/share/vm/code/debugInfo.hpp src/share/vm/code/debugInfoRec.cpp src/share/vm/code/debugInfoRec.hpp src/share/vm/code/scopeDesc.cpp src/share/vm/code/scopeDesc.hpp src/share/vm/graal/graalCodeInstaller.cpp
diffstat 7 files changed, 234 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/code/debugInfo.cpp	Tue Nov 27 12:10:41 2012 +0100
+++ b/src/share/vm/code/debugInfo.cpp	Tue Nov 27 13:43:04 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 12:10:41 2012 +0100
+++ b/src/share/vm/code/debugInfo.hpp	Tue Nov 27 13:43:04 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 12:10:41 2012 +0100
+++ b/src/share/vm/code/debugInfoRec.cpp	Tue Nov 27 13:43:04 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 12:10:41 2012 +0100
+++ b/src/share/vm/code/debugInfoRec.hpp	Tue Nov 27 13:43:04 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 12:10:41 2012 +0100
+++ b/src/share/vm/code/scopeDesc.cpp	Tue Nov 27 13:43:04 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 12:10:41 2012 +0100
+++ b/src/share/vm/code/scopeDesc.hpp	Tue Nov 27 13:43:04 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 12:10:41 2012 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Tue Nov 27 13:43:04 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) {