[pypy-commit] pypy reverse-debugger: Record the creation time of objects

arigo pypy.commits at gmail.com
Mon Jun 13 05:14:46 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: reverse-debugger
Changeset: r85119:55db2cb66764
Date: 2016-06-13 11:15 +0200
http://bitbucket.org/pypy/pypy/changeset/55db2cb66764/

Log:	Record the creation time of objects

diff --git a/rpython/memory/gctransform/boehm.py b/rpython/memory/gctransform/boehm.py
--- a/rpython/memory/gctransform/boehm.py
+++ b/rpython/memory/gctransform/boehm.py
@@ -10,7 +10,6 @@
 class BoehmGCTransformer(GCTransformer):
     malloc_zero_filled = True
     FINALIZER_PTR = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void))
-    HDR = lltype.Struct("header", ("hash", lltype.Signed))
 
     def __init__(self, translator, inline=False):
         super(BoehmGCTransformer, self).__init__(translator, inline=inline)
@@ -28,6 +27,10 @@
         ll_malloc_varsize_no_length = mh.ll_malloc_varsize_no_length
         ll_malloc_varsize = mh.ll_malloc_varsize
 
+        fields = [("hash", lltype.Signed)]
+        if translator.config.translation.reverse_debugger:
+            fields.append(("ctime", lltype.SignedLongLong))
+        self.HDR = lltype.Struct("header", *fields)
         HDRPTR = lltype.Ptr(self.HDR)
 
         if self.translator:
@@ -167,7 +170,7 @@
         hop.genop('int_invert', [v_int], resultvar=hop.spaceop.result)
 
     def gcheader_initdata(self, obj):
-        hdr = lltype.malloc(self.HDR, immortal=True)
+        hdr = lltype.malloc(self.HDR, immortal=True, zero=True)
         hdr.hash = lltype.identityhash_nocache(obj._as_ptr())
         return hdr._obj
 
diff --git a/rpython/rlib/revdb.py b/rpython/rlib/revdb.py
--- a/rpython/rlib/revdb.py
+++ b/rpython/rlib/revdb.py
@@ -43,6 +43,14 @@
     as the total number of stop-points)."""
     return llop.revdb_get_value(lltype.SignedLongLong, 't')
 
+ at specialize.argtype(0)
+def creation_time_of(x):
+    """Returns the time at which the object 'x' was created.
+    More precisely, returns t such that object 'x' was created when
+    current_time()==t; this means that the object exists from time t+1.
+    """
+    return llop.revdb_creation_time_of(lltype.SignedLongLong, x)
+
 @specialize.arg(1)
 def go_forward(time_delta, callback, arg_string):
     """For RPython debug commands: tells that after this function finishes,
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -571,6 +571,7 @@
     'revdb_get_value':      LLOp(sideeffects=False),
     'revdb_set_value':      LLOp(),
     'revdb_identityhash':   LLOp(),
+    'revdb_creation_time_of': LLOp(sideeffects=False),
 }
 # ***** Run test_lloperation after changes. *****
 
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -578,13 +578,22 @@
                                      self.expr(op.args[0]),
                                      self.expr(op.args[1]))
 
+    def _op_boehm_malloc(self, op, is_atomic):
+        expr_result = self.expr(op.result)
+        res = 'OP_BOEHM_ZERO_MALLOC(%s, %s, void*, %d, 0);' % (
+            self.expr(op.args[0]),
+            expr_result,
+            is_atomic)
+        if self.db.reverse_debugger:
+            from rpython.translator.revdb import revdb_genc
+            res += revdb_genc.record_malloc_ctime(expr_result)
+        return res
+
     def OP_BOEHM_MALLOC(self, op):
-        return 'OP_BOEHM_ZERO_MALLOC(%s, %s, void*, 0, 0);' % (self.expr(op.args[0]),
-                                                               self.expr(op.result))
+        return self._op_boehm_malloc(op, 0)
 
     def OP_BOEHM_MALLOC_ATOMIC(self, op):
-        return 'OP_BOEHM_ZERO_MALLOC(%s, %s, void*, 1, 0);' % (self.expr(op.args[0]),
-                                                               self.expr(op.result))
+        return self._op_boehm_malloc(op, 1)
 
     def OP_BOEHM_REGISTER_FINALIZER(self, op):
         return 'GC_REGISTER_FINALIZER(%s, (GC_finalization_proc)%s, NULL, NULL, NULL);' \
diff --git a/rpython/translator/revdb/revdb_genc.py b/rpython/translator/revdb/revdb_genc.py
--- a/rpython/translator/revdb/revdb_genc.py
+++ b/rpython/translator/revdb/revdb_genc.py
@@ -18,6 +18,9 @@
         return emit_void(normal_code)
     return 'RPY_REVDB_EMIT(%s, %s, %s);' % (normal_code, cdecl(tp, '_e'), value)
 
+def record_malloc_ctime(expr):
+    return ' RPY_REVDB_REC_CTIME(%s);' % (expr,)
+
 
 def prepare_database(db):
     FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Ptr(rstr.STR)], lltype.Void))
diff --git a/rpython/translator/revdb/src-revdb/revdb_include.h b/rpython/translator/revdb/src-revdb/revdb_include.h
--- a/rpython/translator/revdb/src-revdb/revdb_include.h
+++ b/rpython/translator/revdb/src-revdb/revdb_include.h
@@ -67,6 +67,11 @@
 #define RPY_REVDB_EMIT_VOID(normal_code)                                \
     if (!RPY_RDB_REPLAY) { normal_code } else { }
 
+#define RPY_REVDB_REC_CTIME(expr)                                       \
+    if (expr)                                                           \
+        ((struct pypy_header0 *)expr)->h_ctime = rpy_revdb.stop_point_seen
+
+
 #define OP_REVDB_STOP_POINT(r)                                          \
     if (++rpy_revdb.stop_point_seen == rpy_revdb.stop_point_break)      \
         rpy_reverse_db_stop_point()
@@ -83,6 +88,9 @@
 #define OP_REVDB_IDENTITYHASH(obj, r)                                   \
     r = rpy_reverse_db_identityhash((struct pypy_header0 *)(obj))
 
+#define OP_REVDB_CREATION_TIME_OF(x, r) \
+    r = ((struct pypy_header0 *)x)->h_ctime
+
 RPY_EXTERN void rpy_reverse_db_flush(void);
 RPY_EXTERN char *rpy_reverse_db_fetch(int expected_size,
                                       const char *file, int line);
diff --git a/rpython/translator/revdb/test/test_basic.py b/rpython/translator/revdb/test/test_basic.py
--- a/rpython/translator/revdb/test/test_basic.py
+++ b/rpython/translator/revdb/test/test_basic.py
@@ -191,12 +191,16 @@
 
     def setup_class(cls):
         def main(argv):
+            lst = [argv[0], 'prebuilt']
             for op in argv[1:]:
                 revdb.stop_point()
                 print op
+                lst.append(op + '??')   # create a new string here
+            for x in lst:
+                print revdb.creation_time_of(x)
             return 9
         compile(cls, main, [], backendopt=False)
-        assert run(cls, 'abc d ef') == 'abc\nd\nef\n'
+        assert run(cls, 'abc d ef') == 'abc\nd\nef\n0\n0\n1\n2\n3\n'
         rdb = fetch_rdb(cls, [cls.exename, 'abc', 'd', 'ef'])
         assert rdb.number_of_stop_points() == 3
 


More information about the pypy-commit mailing list