[pypy-svn] r46087 - in pypy/branch/pypy-more-rtti-inprogress/rpython: . test
fijal at codespeak.net
fijal at codespeak.net
Tue Aug 28 12:55:49 CEST 2007
Author: fijal
Date: Tue Aug 28 12:55:48 2007
New Revision: 46087
Modified:
pypy/branch/pypy-more-rtti-inprogress/rpython/llinterp.py
pypy/branch/pypy-more-rtti-inprogress/rpython/test/test_llinterp.py
Log:
Add malloc checking feature to llinterpreter, only works for malloc='raw',
not sure if debugging info stored there makes sense, but well...
we'll see.
Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/llinterp.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/llinterp.py (original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/llinterp.py Tue Aug 28 12:55:48 2007
@@ -42,7 +42,8 @@
class LLInterpreter(object):
""" low level interpreter working with concrete values. """
- def __init__(self, typer, heap=llheap, tracing=True, exc_data_ptr=None):
+ def __init__(self, typer, heap=llheap, tracing=True, exc_data_ptr=None,
+ malloc_check=True):
self.bindings = {}
self.typer = typer
self.heap = heap #module that provides malloc, etc for lltypes
@@ -52,7 +53,9 @@
# prepare_graphs_and_create_gc might already use the llinterpreter!
self.gc = None
self.tracer = None
+ self.malloc_check = malloc_check
self.frame_class = LLFrame
+ self.mallocs = {}
if hasattr(heap, "prepare_graphs_and_create_gc"):
flowgraphs = typer.annotator.translator.graphs
self.gc = heap.prepare_graphs_and_create_gc(self, flowgraphs)
@@ -158,6 +161,12 @@
return self.exc_data_ptr
return None
+ def remember_malloc(self, ptr, llframe):
+ # err....
+ self.mallocs[ptr._obj] = llframe
+
+ def remember_free(self, ptr):
+ del self.mallocs[ptr._obj]
def checkptr(ptr):
assert isinstance(lltype.typeOf(ptr), lltype.Ptr)
@@ -633,8 +642,11 @@
return result
else:
raise ValueError("cannot allocate variable-sized things on the stack")
-
- return self.heap.malloc(obj, zero=zero, flavor=flavor)
+
+ ptr = self.heap.malloc(obj, zero=zero, flavor=flavor)
+ if flavor == 'raw' and self.llinterpreter.malloc_check:
+ self.llinterpreter.remember_malloc(ptr, self)
+ return ptr
# only after gc transform
def op_cpy_malloc(self, obj, cpytype): # xxx
@@ -654,12 +666,17 @@
return self.llinterpreter.gc.adjust_result_malloc(result, obj, size)
assert flavor in ('gc', 'raw')
try:
- return self.heap.malloc(obj, size, zero=zero, flavor=flavor)
+ ptr = self.heap.malloc(obj, size, zero=zero, flavor=flavor)
+ if flavor == 'raw' and self.llinterpreter.malloc_check:
+ self.llinterpreter.remember_malloc(ptr, self)
+ return ptr
except MemoryError:
self.make_llexception()
def op_free(self, obj, flavor):
assert isinstance(flavor, str)
+ if flavor == 'raw' and self.llinterpreter.malloc_check:
+ self.llinterpreter.remember_free(obj)
self.heap.free(obj, flavor=flavor)
def op_zero_gc_pointers_inside(self, obj):
Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/test/test_llinterp.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/test/test_llinterp.py (original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/test/test_llinterp.py Tue Aug 28 12:55:48 2007
@@ -1,6 +1,7 @@
import py
import sys
-from pypy.rpython.lltypesystem.lltype import typeOf, pyobjectptr, Ptr, PyObject, Void
+from pypy.rpython.lltypesystem.lltype import typeOf, pyobjectptr, Ptr,\
+ PyObject, Void, malloc, free
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.llinterp import LLInterpreter, LLException, log
from pypy.rpython.rmodel import inputconst
@@ -14,6 +15,9 @@
# switch on logging of interp to show more info on failing tests
+class MallocMismatch(Exception):
+ pass
+
def setup_module(mod):
mod.logstate = py.log._getstate()
py.log.setconsumer("llinterp", py.log.STDOUT)
@@ -62,7 +66,8 @@
_tcache.clear()
def get_interpreter(func, values, view='auto', viewbefore='auto', policy=None,
- someobjects=False, type_system="lltype", backendopt=False, config=None):
+ someobjects=False, type_system="lltype", backendopt=False,
+ config=None, malloc_check=True):
key = (func,) + tuple([typeOf(x) for x in values])+ (someobjects,
backendopt)
try:
@@ -85,7 +90,7 @@
t, typer, graph = gengraph(func, [annotation(x) for x in values],
viewbefore, policy, type_system=type_system,
backendopt=backendopt, config=config)
- interp = LLInterpreter(typer)
+ interp = LLInterpreter(typer, malloc_check=malloc_check)
_tcache[key] = (t, interp, graph)
# keep the cache small
_lastinterpreted.append(key)
@@ -98,11 +103,16 @@
return interp, graph
def interpret(func, values, view='auto', viewbefore='auto', policy=None,
- someobjects=False, type_system="lltype", backendopt=False, config=None):
+ someobjects=False, type_system="lltype", backendopt=False,
+ config=None, malloc_check=True):
interp, graph = get_interpreter(func, values, view, viewbefore, policy,
someobjects, type_system=type_system,
- backendopt=backendopt, config=config)
- return interp.eval_graph(graph, values)
+ backendopt=backendopt, config=config,
+ malloc_check=malloc_check)
+ result = interp.eval_graph(graph, values)
+ if malloc_check and interp.mallocs:
+ raise MallocMismatch(interp.mallocs)
+ return result
def interpret_raises(exc, func, values, view='auto', viewbefore='auto',
policy=None, someobjects=False, type_system="lltype",
@@ -581,3 +591,21 @@
assert res == -63
res = interp.eval_graph(graph, [1, sys.maxint])
assert res == -42
+
+def test_malloc_checker():
+ T = lltype.Struct('x')
+ def f(x):
+ t = malloc(T, flavor='raw')
+ if x:
+ free(t, flavor='raw')
+ interpret(f, [1])
+ py.test.raises(MallocMismatch, "interpret(f, [0])")
+
+ def f():
+ t1 = malloc(T, flavor='raw')
+ t2 = malloc(T, flavor='raw')
+ free(t1, flavor='raw')
+ free(t2, flavor='raw')
+
+ interpret(f, [])
+
More information about the Pypy-commit
mailing list