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