[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