[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