[pypy-commit] pypy fast-newarray: (fijal, wlav) in-progress malloc_varsize

wlav noreply at buildbot.pypy.org
Mon Mar 18 22:25:44 CET 2013


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: fast-newarray
Changeset: r62408:4b24eca3babc
Date: 2013-03-18 13:40 -0700
http://bitbucket.org/pypy/pypy/changeset/4b24eca3babc/

Log:	(fijal, wlav) in-progress malloc_varsize

diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py
--- a/rpython/jit/backend/llsupport/test/test_gc_integration.py
+++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py
@@ -145,6 +145,7 @@
     gcrootmap = None
     passes_frame = True
     write_barrier_descr = None
+    max_size_of_young_obj = 50
 
     def __init__(self, callback):
         GcLLDescription.__init__(self, None)
@@ -244,6 +245,29 @@
         # slowpath never called
         assert gc_ll_descr.calls == []
 
+    def test_malloc_nursery_varsize(self):
+        self.cpu = self.getcpu(None)
+        ops = '''
+        [i0, i1, i2]
+        p0 = call_malloc_nursery_varsize(8, i0)
+        p1 = call_malloc_nursery_varsize(5, i1)
+        p2 = call_malloc_nursery_varsize(7, i2)
+        guard_true(i0) [p0, p1, p2]
+        '''
+        self.interpret(ops, [1, 2, 3])
+        # check the returned pointers
+        gc_ll_descr = self.cpu.gc_ll_descr
+        nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery)
+        ref = lambda n: self.cpu.get_ref_value(self.deadframe, n)
+        assert rffi.cast(lltype.Signed, ref(0)) == nurs_adr + 0
+        assert rffi.cast(lltype.Signed, ref(1)) == nurs_adr + 2*WORD + 8*1
+        assert rffi.cast(lltype.Signed, ref(2)) == nurs_adr + 2*WORD + 8*1 + 2*WORD + 5*2
+        # check the nursery content and state
+        gc_ll_descr.check_nothing_in_nursery()
+        assert gc_ll_descr.addrs[0] == nurs_adr + 64
+        # slowpath never called
+        assert gc_ll_descr.calls == []
+
     def test_malloc_slowpath(self):
         def check(frame):
             expected_size = 1
@@ -664,9 +688,6 @@
         assert cpu.gc_ll_descr.nursery_ptrs[0] == thing + sizeof.size
         assert rffi.cast(JITFRAMEPTR, cpu.gc_ll_descr.write_barrier_on_frame_called) == frame
 
-    def test_malloc_nursery_varsize(self):
-        xxx
-
     def test_call_release_gil(self):
         # note that we can't test floats here because when untranslated
         # people actually wreck xmm registers
diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -2460,6 +2460,31 @@
         self.mc.overwrite(jmp_adr-1, chr(offset))
         self.mc.MOV(heap(nursery_free_adr), edi)
 
+    def malloc_cond_varsize(self, nursery_free_adr, nursery_top_adr,
+                            lengthloc, itemsize, maxlength, gcmap):
+        self.mc.CMP(lengthloc, imm(maxlength))
+        self.mc.J_il8(rx86.Conditions['L'], 0) # patched later
+        jmp_adr0 = self.mc.get_relative_pos()
+        self.mc.MOV(edi, heap(nursery_free_adr))
+        self.mc.MOV(eax, edi)
+        self.mc.MOV(edi, lengthloc)
+        self.mc.IMUL(edi, imm(itemsize))
+        self.mc.ADD(edi, eax)
+        self.mc.ADD(edi, imm(WORD * 2))
+        self.mc.CMP(edi, heap(nursery_top_adr))
+        self.mc.J_il8(rx86.Conditions['NA'], 0) # patched later
+        jmp_adr1 = self.mc.get_relative_pos()
+        offset = self.mc.get_relative_pos() - jmp_adr0
+        assert 0 < offset <= 127
+        self.mc.overwrite(jmp_adr0-1, chr(offset))
+        # save the gcmap
+        self.push_gcmap(self.mc, gcmap, mov=True)
+        self.mc.CALL(imm(0))
+        offset = self.mc.get_relative_pos() - jmp_adr1
+        assert 0 < offset <= 127
+        self.mc.overwrite(jmp_adr1-1, chr(offset))
+        self.mc.MOV(heap(nursery_free_adr), edi)
+
     def force_token(self, reg):
         # XXX kill me
         assert isinstance(reg, RegLoc)
diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -870,6 +870,28 @@
             gc_ll_descr.get_nursery_top_addr(),
             sizeloc, gcmap)
 
+    def consider_call_malloc_nursery_varsize(self, op):
+        length_box = op.getarg(1)
+        assert isinstance(length_box, BoxInt) # we cannot have a const here!
+        # looking at the result
+        self.rm.force_allocate_reg(op.result, selected_reg=eax)
+        #
+        # We need edx as a temporary, but otherwise don't save any more
+        # register.  See comments in _build_malloc_slowpath().
+        tmp_box = TempBox()
+        self.rm.force_allocate_reg(tmp_box, selected_reg=edi)
+        lengthloc = self.rm.make_sure_var_in_reg(length_box, [op.result, tmp_box])
+        gcmap = self.get_gcmap([eax, edi]) # allocate the gcmap *before*
+        self.rm.possibly_free_var(tmp_box)
+        #
+        gc_ll_descr = self.assembler.cpu.gc_ll_descr
+        itemsize = op.getarg(0).getint()
+        maxlength = (gc_ll_descr.max_size_of_young_obj - WORD * 2) / itemsize
+        self.assembler.malloc_cond_varsize(
+            gc_ll_descr.get_nursery_free_addr(),
+            gc_ll_descr.get_nursery_top_addr(),
+            lengthloc, itemsize, maxlength, gcmap)
+
     def get_gcmap(self, forbidden_regs=[], noregs=False):
         frame_depth = self.fm.get_frame_depth()
         gcmap = allocate_gcmap(self.assembler, frame_depth, JITFRAME_FIXED_SIZE)


More information about the pypy-commit mailing list