[pypy-commit] pypy virtual-raw-mallocs: dump RawBuffer logs when something goes wrong

antocuni noreply at buildbot.pypy.org
Sat Dec 22 11:45:34 CET 2012


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: virtual-raw-mallocs
Changeset: r59533:d520708b53ea
Date: 2012-12-22 11:45 +0100
http://bitbucket.org/pypy/pypy/changeset/d520708b53ea/

Log:	dump RawBuffer logs when something goes wrong

diff --git a/pypy/jit/metainterp/optimizeopt/rawbuffer.py b/pypy/jit/metainterp/optimizeopt/rawbuffer.py
--- a/pypy/jit/metainterp/optimizeopt/rawbuffer.py
+++ b/pypy/jit/metainterp/optimizeopt/rawbuffer.py
@@ -1,3 +1,6 @@
+from pypy.rlib.debug import debug_start, debug_stop, debug_print
+from pypy.rlib.objectmodel import compute_unique_id, we_are_translated
+
 class InvalidRawOperation(Exception):
     pass
 
@@ -8,7 +11,7 @@
     pass
 
 class RawBuffer(object):
-    def __init__(self, cpu):
+    def __init__(self, cpu, logops=None):
         # the following lists represents the writes in the buffer: values[i]
         # is the value of length lengths[i] stored at offset[i].
         #
@@ -16,6 +19,7 @@
         # offset[i]+length[i] <= offset[i+1], i.e. that the writes never
         # overlaps
         self.cpu = cpu
+        self.logops = logops
         self.offsets = []
         self.lengths = []
         self.descrs = []
@@ -28,6 +32,54 @@
         """
         return zip(self.offsets, self.lengths, self.descrs, self.values)
 
+    def _repr_of_descr(self, descr):
+        if self.logops:
+            s = self.logops.repr_of_descr(descr)
+        else:
+            s = str(descr)
+        s += " at %d" % compute_unique_id(descr)
+        return s
+
+    def _repr_of_value(self, value):
+        if not we_are_translated() and isinstance(value, str):
+            return value # for tests
+        if self.logops:
+            s = self.logops.repr_of_arg(value.box)
+        else:
+            s = str(value.box)
+        s += " at %d" % compute_unique_id(value.box)
+        return s
+
+    def _dump_to_log(self):
+        debug_print("RawBuffer state")
+        debug_print("offset, length, descr, box")
+        debug_print("(box == None means that the value is still virtual)")
+        for i in range(len(self.offsets)):
+            descr = self._repr_of_descr(self.descrs[i])
+            box = self._repr_of_value(self.values[i])
+            debug_print("%d, %d, %s, %s" % (self.offsets[i], self.lengths[i], descr, box))
+
+    def _invalid_write(self, message, offset, length, descr, value):
+        debug_start('jit-log-rawbuffer')
+        debug_print('Invalid write: %s' % message)
+        debug_print("  offset: %d" % offset)
+        debug_print("  length: %d" % length)
+        debug_print("  descr:  %s" % self._repr_of_descr(descr))
+        debug_print("  value:  %s" % self._repr_of_value(value))
+        self._dump_to_log()
+        debug_stop('jit-log-rawbuffer')
+        raise InvalidRawWrite
+
+    def _invalid_read(self, message, offset, length, descr):
+        debug_start('jit-log-rawbuffer')
+        debug_print('Invalid read: %s' % message)
+        debug_print("  offset: %d" % offset)
+        debug_print("  length: %d" % length)
+        debug_print("  descr:  %s" % self._repr_of_descr(descr))
+        self._dump_to_log()
+        debug_stop('jit-log-rawbuffer')
+        raise InvalidRawRead
+
     def _descrs_are_compatible(self, d1, d2):
         # two arraydescrs are compatible if they have the same basesize,
         # itemsize and sign, even if they are not identical
@@ -44,7 +96,8 @@
                     # in theory we could add support for the cases in which
                     # the length or descr is different, but I don't think we
                     # need it in practice
-                    raise InvalidRawWrite
+                    self._invalid_write('length or descr not compatible',
+                                        offset, length, descr, value)
                 # update the value at this offset
                 self.values[i] = value
                 return
@@ -53,9 +106,11 @@
             i += 1
         #
         if i < len(self.offsets) and offset+length > self.offsets[i]:
-            raise InvalidRawWrite
+            self._invalid_write("overlap with next bytes",
+                                offset, length, descr, value)
         if i > 0 and self.offsets[i-1]+self.lengths[i-1] > offset:
-            raise InvalidRawWrite
+            self._invalid_write("overlap with previous bytes",
+                                offset, length, descr, value)
         # insert a new value at offset
         self.offsets.insert(i, offset)
         self.lengths.insert(i, length)
@@ -69,9 +124,11 @@
             if self.offsets[i] == offset:
                 if (length != self.lengths[i] or
                     not self._descrs_are_compatible(descr, self.descrs[i])):
-                    raise InvalidRawRead
+                    self._invalid_read('length or descr not compatible',
+                                       offset, length, descr)
                 return self.values[i]
             i += 1
         # memory location not found: this means we are reading from
         # uninitialized memory, give up the optimization
-        raise InvalidRawRead
+        self._invalid_read('uninitialized memory',
+                           offset, length, descr)
diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py
--- a/pypy/jit/metainterp/optimizeopt/virtualize.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualize.py
@@ -388,14 +388,14 @@
 
 class VRawBufferValue(AbstractVArrayValue):
 
-    def __init__(self, cpu, size, keybox, source_op):
+    def __init__(self, cpu, logops, size, keybox, source_op):
         AbstractVirtualValue.__init__(self, keybox, source_op)
         # note that size is unused, because we assume that the buffer is big
         # enough to write/read everything we need. If it's not, it's undefined
         # behavior anyway, although in theory we could probably detect such
         # cases here
         self.size = size
-        self.buffer = RawBuffer(cpu)
+        self.buffer = RawBuffer(cpu, logops)
 
     def getlength(self):
         return len(self.buffer.values)
@@ -491,7 +491,8 @@
         return vvalue
 
     def make_virtual_raw_memory(self, size, box, source_op):
-        vvalue = VRawBufferValue(self.optimizer.cpu, size, box, source_op)
+        logops = self.optimizer.loop.logops
+        vvalue = VRawBufferValue(self.optimizer.cpu, logops, size, box, source_op)
         self.make_equal_to(box, vvalue)
         return vvalue
 


More information about the pypy-commit mailing list