[pypy-svn] r68617 - in pypy/trunk/pypy/jit/backend/x86: . test

fijal at codespeak.net fijal at codespeak.net
Mon Oct 19 11:01:54 CEST 2009


Author: fijal
Date: Mon Oct 19 11:01:53 2009
New Revision: 68617

Added:
   pypy/trunk/pypy/jit/backend/x86/support.py   (contents, props changed)
   pypy/trunk/pypy/jit/backend/x86/test/test_support.py   (contents, props changed)
Modified:
   pypy/trunk/pypy/jit/backend/x86/assembler.py
   pypy/trunk/pypy/jit/backend/x86/runner.py
   pypy/trunk/pypy/jit/backend/x86/test/test_regalloc.py
Log:
Fix issue471
Don't have a hard limit on number of fail boxes, but grow them as needed


Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/assembler.py	Mon Oct 19 11:01:53 2009
@@ -13,15 +13,15 @@
 from pypy.jit.backend.x86 import codebuf
 from pypy.jit.backend.x86.ri386 import *
 from pypy.jit.metainterp.resoperation import rop
-
-
+from pypy.jit.backend.x86.support import NonmovableGrowableArrayFloat,\
+     NonmovableGrowableArraySigned, NonmovableGrowableArrayGCREF,\
+     CHUNK_SIZE
 
 # our calling convention - we pass first 6 args in registers
 # and the rest stays on the stack
 
 RET_BP = 5 # ret ip + bp + bx + esi + edi = 5 words
 
-MAX_FAIL_BOXES = 1000
 if sys.platform == 'darwin':
     # darwin requires the stack to be 16 bytes aligned on calls
     CALL_ALIGN = 4
@@ -76,30 +76,18 @@
         self.malloc_array_func_addr = 0
         self.malloc_str_func_addr = 0
         self.malloc_unicode_func_addr = 0
-        self.fail_boxes_int = lltype.malloc(lltype.GcArray(lltype.Signed),
-                                            MAX_FAIL_BOXES, zero=True)
-        self.fail_boxes_ptr = lltype.malloc(lltype.GcArray(llmemory.GCREF),
-                                            MAX_FAIL_BOXES, zero=True)
-        self.fail_boxes_float = lltype.malloc(lltype.GcArray(lltype.Float),
-                                              MAX_FAIL_BOXES, zero=True)
+        self.fail_boxes_int = NonmovableGrowableArraySigned()
+        self.fail_boxes_ptr = NonmovableGrowableArrayGCREF()
+        self.fail_boxes_float = NonmovableGrowableArrayFloat()
 
     def leave_jitted_hook(self):
         fail_boxes_ptr = self.fail_boxes_ptr
-        llop.gc_assume_young_pointers(lltype.Void,
-                                      llmemory.cast_ptr_to_adr(fail_boxes_ptr))
+        for chunk in fail_boxes_ptr.chunks:
+            llop.gc_assume_young_pointers(lltype.Void,
+                                      llmemory.cast_ptr_to_adr(chunk))
 
     def make_sure_mc_exists(self):
         if self.mc is None:
-            rffi.cast(lltype.Signed, self.fail_boxes_int)   # workaround
-            rffi.cast(lltype.Signed, self.fail_boxes_ptr)   # workaround
-            rffi.cast(lltype.Signed, self.fail_boxes_float) # workaround
-            self.fail_box_int_addr = rffi.cast(lltype.Signed,
-                lltype.direct_arrayitems(self.fail_boxes_int))
-            self.fail_box_ptr_addr = rffi.cast(lltype.Signed,
-                lltype.direct_arrayitems(self.fail_boxes_ptr))
-            self.fail_box_float_addr = rffi.cast(lltype.Signed,
-                lltype.direct_arrayitems(self.fail_boxes_float))
-
             # the address of the function called by 'new'
             gc_ll_descr = self.cpu.gc_ll_descr
             gc_ll_descr.initialize()
@@ -213,23 +201,22 @@
                 # This uses XCHG to put zeroes in fail_boxes_ptr after
                 # reading them
                 self.mc.XOR(target, target)
-                self.mc.XCHG(target, addr_add(imm(self.fail_box_ptr_addr),
-                                              imm(i*WORD)))
+                adr = self.fail_boxes_ptr.get_addr_for_num(i)
+                self.mc.XCHG(target, heap(adr))
             else:
-                self.mc.MOV(target, addr_add(imm(self.fail_box_int_addr),
-                                             imm(i*WORD)))
+                adr = self.fail_boxes_int.get_addr_for_num(i)
+                self.mc.MOV(target, heap(adr))
             if target is not loc:
                 self.mc.MOV(loc, target)
         for i in range(len(floatlocs)):
             loc = floatlocs[i]
             if loc is None:
                 continue
+            adr = self.fail_boxes_float.get_addr_for_num(i)
             if isinstance(loc, REG):
-                self.mc.MOVSD(loc, addr64_add(imm(self.fail_box_float_addr),
-                                              imm(i*WORD*2)))
+                self.mc.MOVSD(loc, heap64(adr))
             else:
-                self.mc.MOVSD(xmmtmp, addr64_add(imm(self.fail_box_float_addr),
-                                               imm(i*WORD*2)))
+                self.mc.MOVSD(xmmtmp, heap64(adr))
                 self.mc.MOVSD(loc, xmmtmp)
         return adr_stackadjust
 
@@ -741,41 +728,38 @@
         return addr
 
     def generate_failure(self, mc, faildescr, failargs, locs, exc):
-        assert len(failargs) < MAX_FAIL_BOXES
         pos = mc.tell()
         for i in range(len(failargs)):
             arg = failargs[i]
             loc = locs[i]
             if isinstance(loc, REG):
                 if arg.type == FLOAT:
-                    mc.MOVSD(addr64_add(imm(self.fail_box_float_addr),
-                                        imm(i*WORD*2)), loc)
+                    adr = self.fail_boxes_float.get_addr_for_num(i)
+                    mc.MOVSD(heap64(adr), loc)
                 else:
                     if arg.type == REF:
-                        base = self.fail_box_ptr_addr
+                        adr = self.fail_boxes_ptr.get_addr_for_num(i)
                     else:
-                        base = self.fail_box_int_addr
-                    mc.MOV(addr_add(imm(base), imm(i*WORD)), loc)
+                        adr = self.fail_boxes_int.get_addr_for_num(i)
+                    mc.MOV(heap(adr), loc)
         for i in range(len(failargs)):
             arg = failargs[i]
             loc = locs[i]
             if not isinstance(loc, REG):
                 if arg.type == FLOAT:
                     mc.MOVSD(xmm0, loc)
-                    mc.MOVSD(addr64_add(imm(self.fail_box_float_addr),
-                                        imm(i*WORD*2)), xmm0)
+                    adr = self.fail_boxes_float.get_addr_for_num(i)
+                    mc.MOVSD(heap64(adr), xmm0)
                 else:
                     if arg.type == REF:
-                        base = self.fail_box_ptr_addr
+                        adr = self.fail_boxes_ptr.get_addr_for_num(i)
                     else:
-                        base = self.fail_box_int_addr
+                        adr = self.fail_boxes_int.get_addr_for_num(i)
                     mc.MOV(eax, loc)
-                    mc.MOV(addr_add(imm(base), imm(i*WORD)), eax)
+                    mc.MOV(heap(adr), eax)
         if self.debug_markers:
             mc.MOV(eax, imm(pos))
-            mc.MOV(addr_add(imm(self.fail_box_int_addr),
-                                 imm(len(locs) * WORD)),
-                                 eax)
+            mc.MOV(heap(self.fail_boxes_int.get_addr_for_num(len(locs))), eax)
 
         # we call a provided function that will
         # - call our on_leave_jitted_hook which will mark

Modified: pypy/trunk/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/runner.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/runner.py	Mon Oct 19 11:01:53 2009
@@ -5,7 +5,7 @@
 from pypy.rpython.llinterp import LLInterpreter
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.jit.metainterp import history
-from pypy.jit.backend.x86.assembler import Assembler386, MAX_FAIL_BOXES
+from pypy.jit.backend.x86.assembler import Assembler386
 from pypy.jit.backend.llsupport.llmodel import AbstractLLCPU
 
 
@@ -38,28 +38,25 @@
         self.assembler.assemble_bridge(faildescr, inputargs, operations)
 
     def set_future_value_int(self, index, intvalue):
-        assert index < MAX_FAIL_BOXES, "overflow!"
-        self.assembler.fail_boxes_int[index] = intvalue
+        self.assembler.fail_boxes_int.setitem(index, intvalue)
 
     def set_future_value_float(self, index, floatvalue):
-        assert index < MAX_FAIL_BOXES, "overflow!"
-        self.assembler.fail_boxes_float[index] = floatvalue
+        self.assembler.fail_boxes_float.setitem(index, floatvalue)
 
     def set_future_value_ref(self, index, ptrvalue):
-        assert index < MAX_FAIL_BOXES, "overflow!"
-        self.assembler.fail_boxes_ptr[index] = ptrvalue
+        self.assembler.fail_boxes_ptr.setitem(index, ptrvalue)
 
     def get_latest_value_int(self, index):
-        return self.assembler.fail_boxes_int[index]
+        return self.assembler.fail_boxes_int.getitem(index)
 
     def get_latest_value_float(self, index):
-        return self.assembler.fail_boxes_float[index]
+        return self.assembler.fail_boxes_float.getitem(index)
 
     def get_latest_value_ref(self, index):
-        ptrvalue = self.assembler.fail_boxes_ptr[index]
+        ptrvalue = self.assembler.fail_boxes_ptr.getitem(index)
         # clear after reading
-        self.assembler.fail_boxes_ptr[index] = lltype.nullptr(
-            llmemory.GCREF.TO)
+        self.assembler.fail_boxes_ptr.setitem(index, lltype.nullptr(
+            llmemory.GCREF.TO))
         return ptrvalue
 
     def execute_token(self, executable_token):

Added: pypy/trunk/pypy/jit/backend/x86/support.py
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/jit/backend/x86/support.py	Mon Oct 19 11:01:53 2009
@@ -0,0 +1,42 @@
+
+from pypy.rpython.lltypesystem import lltype, rffi, llmemory
+
+CHUNK_SIZE = 1000
+
+def new_nonmovable_growable_array(TP):
+    ATP = lltype.GcArray(TP)
+    
+    class NonmovableGrowableArray(object):
+        def __init__(self):
+            self.chunks = []
+            self._grow()
+
+        def _grow(self):
+            self.chunks.append(lltype.malloc(ATP, CHUNK_SIZE,
+                                             zero=True))
+
+        def get_addr_for_num(self, i):
+            chunk_no, ofs = self._no_of(i)
+            chunk = self.chunks[chunk_no]
+            rffi.cast(lltype.Signed, chunk)
+            return rffi.cast(lltype.Signed, lltype.direct_ptradd(
+                lltype.direct_arrayitems(chunk), ofs))
+
+        def _no_of(self, i):
+            while i > len(self.chunks) * CHUNK_SIZE:
+                self._grow()
+            return i / CHUNK_SIZE, i % CHUNK_SIZE
+
+        def setitem(self, i, v):
+            chunk_no, ofs = self._no_of(i)
+            self.chunks[chunk_no][ofs] = v
+
+        def getitem(self, i):
+            chunk_no, ofs = self._no_of(i)
+            return self.chunks[chunk_no][ofs]
+
+    return NonmovableGrowableArray
+
+NonmovableGrowableArrayFloat = new_nonmovable_growable_array(lltype.Float)
+NonmovableGrowableArraySigned = new_nonmovable_growable_array(lltype.Signed)
+NonmovableGrowableArrayGCREF = new_nonmovable_growable_array(llmemory.GCREF)

Modified: pypy/trunk/pypy/jit/backend/x86/test/test_regalloc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/test/test_regalloc.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_regalloc.py	Mon Oct 19 11:01:53 2009
@@ -198,8 +198,8 @@
         ptr = lltype.malloc(S)
         self.interpret(ops, [0, ptr])
         assert self.getptr(0, lltype.Ptr(S)) == ptr
-        assert not self.cpu.assembler.fail_boxes_ptr[0]
-        assert not self.cpu.assembler.fail_boxes_ptr[1]
+        assert not self.cpu.assembler.fail_boxes_ptr.getitem(0)
+        assert not self.cpu.assembler.fail_boxes_ptr.getitem(1)
 
     def test_exception_bridge_no_exception(self):
         ops = '''

Added: pypy/trunk/pypy/jit/backend/x86/test/test_support.py
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_support.py	Mon Oct 19 11:01:53 2009
@@ -0,0 +1,26 @@
+
+from pypy.jit.backend.x86.support import NonmovableGrowableArraySigned, CHUNK_SIZE
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
+
+def test_nonmovable_growable_array():
+    ar = NonmovableGrowableArraySigned()
+    adr = ar.get_addr_for_num(10)
+    rffi.cast(rffi.CArrayPtr(lltype.Signed), adr)[0] = 42
+    assert ar.getitem(10) == 42
+    ar.setitem(42, 38)
+    adr = ar.get_addr_for_num(42)
+    assert rffi.cast(rffi.CArrayPtr(lltype.Signed), adr)[0] == 38
+    adr = ar.get_addr_for_num(CHUNK_SIZE + 10)
+    rffi.cast(rffi.CArrayPtr(lltype.Signed), adr)[0] = 42
+    assert ar.getitem(CHUNK_SIZE + 10) == 42
+    ar.setitem(CHUNK_SIZE + 42, 38)
+    adr = ar.get_addr_for_num(CHUNK_SIZE + 42)
+    assert rffi.cast(rffi.CArrayPtr(lltype.Signed), adr)[0] == 38
+    adr = ar.get_addr_for_num(3 * CHUNK_SIZE + 10)
+    rffi.cast(rffi.CArrayPtr(lltype.Signed), adr)[0] = 42
+    assert ar.getitem(3 * CHUNK_SIZE + 10) == 42
+    ar.setitem(3 * CHUNK_SIZE + 42, 38)
+    adr = ar.get_addr_for_num(3 * CHUNK_SIZE + 42)
+    assert rffi.cast(rffi.CArrayPtr(lltype.Signed), adr)[0] == 38
+
+    



More information about the Pypy-commit mailing list