Author: Maciej Fijalkowski <[email protected]>
Branch: jitframe-on-heap
Changeset: r60539:537d5ac910a9
Date: 2013-01-27 21:45 +0200
http://bitbucket.org/pypy/pypy/changeset/537d5ac910a9/

Log:    implement malloc_cond_varsize_small for the JIT, not used so far

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
@@ -2486,6 +2486,22 @@
         self.mc.overwrite(jmp_adr-1, chr(offset))
         self.mc.MOV(heap(nursery_free_adr), edi)
 
+    def malloc_cond_varsize_small(self, nursery_free_adr, nursery_top_adr,
+                                  sizeloc, gcmap):
+        self.mc.MOV(edi, heap(nursery_free_adr))
+        self.mc.MOV(eax, edi)
+        self.mc.ADD(edi, sizeloc)
+        self.mc.CMP(edi, heap(nursery_top_adr))
+        self.mc.J_il8(rx86.Conditions['NA'], 0) # patched later
+        jmp_adr = self.mc.get_relative_pos()
+        # save the gcmap
+        self.push_gcmap(self.mc, gcmap, mov=True)
+        self.mc.CALL(imm(self.malloc_slowpath))
+        offset = self.mc.get_relative_pos() - jmp_adr
+        assert 0 < offset <= 127
+        self.mc.overwrite(jmp_adr-1, chr(offset))
+        self.mc.MOV(heap(nursery_free_adr), edi)
+
     def force_token(self, reg):
         base_ofs = self.cpu.get_baseofs_of_frame_field()
         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
@@ -4,7 +4,7 @@
 
 import os
 from rpython.jit.metainterp.history import (Box, Const, ConstInt, ConstPtr,
-                                            BoxPtr, ConstFloat,
+                                            BoxPtr, ConstFloat, BoxInt,
                                             BoxFloat, INT, REF, FLOAT,
                                             TargetToken, JitCellToken)
 from rpython.jit.backend.x86.regloc import *
@@ -874,6 +874,26 @@
             gc_ll_descr.get_nursery_top_addr(),
             size, gcmap)
 
+    def consider_call_malloc_nursery_varsize_small(self, op):
+        size_box = op.getarg(0)
+        assert isinstance(size_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)
+        sizeloc = self.rm.make_sure_var_in_reg(size_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
+        self.assembler.malloc_cond_varsize_small(
+            gc_ll_descr.get_nursery_free_addr(),
+            gc_ll_descr.get_nursery_top_addr(),
+            sizeloc, gcmap)
+
     def get_gcmap(self, forbidden_regs=[]):
         frame_depth = self.fm.get_frame_depth()
         size = frame_depth + JITFRAME_FIXED_SIZE
diff --git a/rpython/jit/backend/x86/test/test_gc_integration.py 
b/rpython/jit/backend/x86/test/test_gc_integration.py
--- a/rpython/jit/backend/x86/test/test_gc_integration.py
+++ b/rpython/jit/backend/x86/test/test_gc_integration.py
@@ -202,6 +202,29 @@
         # slowpath never called
         assert gc_ll_descr.calls == []
 
+    def test_malloc_nursery_varsize_small(self):
+        self.cpu = self.getcpu(None)
+        ops = '''
+        [i0, i1, i2]
+        p0 = call_malloc_nursery_varsize_small(i0)
+        p1 = call_malloc_nursery_varsize_small(i1)
+        p2 = call_malloc_nursery_varsize_small(i2)
+        guard_true(i0) [p0, p1, p2]
+        ''' 
+        self.interpret(ops, [16, 32, 16])
+        # 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 + 16
+        assert rffi.cast(lltype.Signed, ref(2)) == nurs_adr + 48
+        # 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):
             assert len(frame.jf_gcmap) == 1
diff --git a/rpython/jit/metainterp/resoperation.py 
b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -529,6 +529,10 @@
     'CALL_PURE/*d',             # removed before it's passed to the backend
     'CALL_MALLOC_GC/*d',      # like CALL, but NULL => propagate MemoryError
     'CALL_MALLOC_NURSERY/1',  # nursery malloc, const number of bytes, zeroed
+    'CALL_MALLOC_NURSERY_VARSIZE_SMALL/1',
+    # nursery malloc, non-const number of bytes, zeroed
+    # note that the number of bytes must be well known to be small enough
+    # to fulfill allocating in the nursery rules (and no card markings)
     '_CALL_LAST',
     '_CANRAISE_LAST', # ----- end of can_raise operations -----
 
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to