Commits

Maciej Fijalkowski committed bb9e3d5

rewrite call_assembler into allocating frame. not ideal so far sincei t's a call

Comments (0)

Files changed (2)

pypy/jit/backend/llsupport/rewrite.py

 from pypy.jit.backend.llsupport.symbolic import WORD
 from pypy.jit.backend.llsupport.descr import SizeDescr, ArrayDescr
 from pypy.jit.backend.llsupport import jitframe
+from pypy.rpython.lltypesystem import lltype, llmemory
 
 
 class GcRewriterAssembler(object):
                 if op.getopnum() == rop.SETARRAYITEM_GC:
                     self.handle_write_barrier_setarrayitem(op)
                     continue
-            # ----------
+            # ---------- call assembler -----------
+            if op.getopnum() == rop.CALL_ASSEMBLER:
+                self.handle_call_assembler(op)
+                continue
+            #
             self.newops.append(op)
         return self.newops
 
             else:
                 raise NotImplementedError(op.getopname())
 
+    def handle_call_assembler(self, op):
+        descrs = self.gc_ll_descr.getframedescrs(self.cpu)
+        loop_token = op.getdescr()
+        assert isinstance(loop_token, history.JitCellToken)
+        lgt_box = history.BoxInt()
+        frame = history.BoxPtr()
+        jfi = loop_token.compiled_loop_token.frame_info
+        llref = lltype.cast_opaque_ptr(llmemory.GCREF, jfi)
+        op0 = ResOperation(rop.GETFIELD_GC, [history.ConstPtr(llref)], lgt_box,
+                           descr=descrs.jfi_frame_depth)
+        self.newops.append(op0)
+        op1 = ResOperation(rop.NEW_ARRAY, [lgt_box], frame,
+                           descr=descrs.arraydescr)
+        self.handle_new_array(descrs.arraydescr, op1)
+        op2 = ResOperation(rop.SETFIELD_GC, [frame, history.ConstPtr(llref)],
+                           None, descr=descrs.jf_frame_info)
+        self.newops.append(op2)
+        lst = op.getarglist()
+        self.newops.append(ResOperation(rop.CALL_ASSEMBLER, [frame] + lst,
+                                        op.result, op.getdescr()))
+
     # ----------
 
     def emitting_an_operation_that_can_collect(self):

pypy/jit/backend/llsupport/test/test_rewrite.py

 from pypy.jit.backend.llsupport.descr import *
 from pypy.jit.backend.llsupport.gc import *
+from pypy.jit.backend.llsupport import jitframe
 from pypy.jit.metainterp.gc import get_description
 from pypy.jit.tool.oparser import parse
 from pypy.jit.metainterp.optimizeopt.util import equaloplists
 from pypy.jit.codewriter.heaptracker import register_known_gctype
+from pypy.jit.metainterp.history import JitCellToken
 
 
 class Evaluator(object):
         return eval(key, self.scope)
 
 
+class FakeLoopToken(object):
+    pass
+
 class RewriteTests(object):
     def check_rewrite(self, frm_operations, to_operations, **namespace):
         S = lltype.GcStruct('S', ('x', lltype.Signed),
         unicodedescr = self.gc_ll_descr.unicode_descr
         strlendescr     = strdescr.lendescr
         unicodelendescr = unicodedescr.lendescr
+
+        casmdescr = JitCellToken()
+        clt = FakeLoopToken()
+        frame_info = lltype.malloc(jitframe.JITFRAMEINFO)
+        ll_frame_info = lltype.cast_opaque_ptr(llmemory.GCREF, frame_info)
+        clt.frame_info = frame_info
+        frame_info.jfi_frame_depth = 13
+        framedescrs = self.gc_ll_descr.getframedescrs(self.cpu)
+        jfi_frame_depth = framedescrs.jfi_frame_depth
+        jf_frame_info = framedescrs.jf_frame_info
+        casmdescr.compiled_loop_token = clt
         #
         namespace.update(locals())
         #
                                                         [])
         equaloplists(operations, expected.operations)
 
+class BaseFakeCPU(object):
+    def __init__(self):
+        self._cache = {}
+    
+    def arraydescrof(self, ARRAY):
+        try:
+            return self._cache[ARRAY]
+        except KeyError:
+            r = ArrayDescr(1, 2, FieldDescr('len', 0, 0, 0), 0)
+            self._cache[ARRAY] = r
+            return r
+    def fielddescrof(self, STRUCT, fname):
+        key = (STRUCT, fname)
+        try:
+            return self._cache[key]
+        except KeyError:
+            r = FieldDescr(fname, 1, 1, 1)
+            self._cache[key] = r
+            return r
 
 class TestBoehm(RewriteTests):
     def setup_method(self, meth):
-        class FakeCPU(object):
+        class FakeCPU(BaseFakeCPU):
             def sizeof(self, STRUCT):
                 return SizeDescrWithVTable(102)
         self.cpu = FakeCPU()
         self.gc_ll_descr.write_barrier_descr.has_write_barrier_from_array = (
             lambda cpu: True)
         #
-        class FakeCPU(object):
+        class FakeCPU(BaseFakeCPU):
             def sizeof(self, STRUCT):
                 descr = SizeDescrWithVTable(104)
                 descr.tid = 9315
             setfield_raw(p0, p1, descr=tzdescr)
             jump()
         """)
+
+    def test_rewrite_call_assembler(self):
+        self.check_rewrite("""
+        [i0]
+        i1 = call_assembler(i0, descr=casmdescr)
+        """, """
+        [i0]
+        i1 = getfield_gc(ConstPtr(ll_frame_info), descr=jfi_frame_depth)
+        p1 = call_malloc_gc(ConstClass(malloc_array_nonstandard), 1, 2, 0, 0, i1, descr=malloc_array_nonstandard_descr)
+        setfield_gc(p1, ConstPtr(ll_frame_info), descr=jf_frame_info)
+        i2 = call_assembler(p1, i0, descr=casmdescr)
+        """)
+        # XXX we want call_malloc_nursery actually, but let's not care
+        # for now, the array is a bit non-standard