[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