Author: Maciej Fijalkowski <[email protected]>
Branch: fast-newarray
Changeset: r62512:8dc4f4ba085c
Date: 2013-03-19 16:25 -0700
http://bitbucket.org/pypy/pypy/changeset/8dc4f4ba085c/
Log: random progress
diff --git a/rpython/jit/backend/llsupport/assembler.py
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -72,7 +72,8 @@
self._build_wb_slowpath(True, withfloats=True)
self._build_propagate_exception_path()
if gc_ll_descr.get_malloc_slowpath_addr is not None:
- self._build_malloc_slowpath()
+ self.malloc_slowpath = self._build_malloc_slowpath(varsize=False)
+ self.malloc_slowpath_varsize =
self._build_malloc_slowpath(varsize=True)
self._build_stack_check_slowpath()
if gc_ll_descr.gcrootmap:
self._build_release_gil(gc_ll_descr.gcrootmap)
diff --git a/rpython/jit/backend/llsupport/rewrite.py
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -128,7 +128,6 @@
elif (self.gc_ll_descr.can_use_nursery_malloc(1) and
self.gen_malloc_nursery_varsize(arraydescr.itemsize,
v_length, op.result, arraydescr)):
- self.gen_initialize_tid(op.result, arraydescr.tid)
self.gen_initialize_len(op.result, v_length, arraydescr.lendescr)
return
if (total_size >= 0 and
@@ -304,9 +303,8 @@
self.emitting_an_operation_that_can_collect()
op = ResOperation(rop.CALL_MALLOC_NURSERY_VARSIZE,
[ConstInt(itemsize), v_length],
- v_result)
+ v_result, descr=arraydescr)
self.newops.append(op)
- self.recent_mallocs[v_result] = None
return True
def gen_malloc_nursery_varsize_small(self, sizebox, v_result):
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
@@ -247,24 +247,48 @@
def test_malloc_nursery_varsize(self):
self.cpu = self.getcpu(None)
+ A = lltype.GcArray(lltype.Signed)
+ arraydescr = self.cpu.arraydescrof(A)
+ arraydescr.tid = 15
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]
+ p0 = call_malloc_nursery_varsize(8, i0, descr=arraydescr)
+ p1 = call_malloc_nursery_varsize(5, i1, descr=arraydescr)
+ guard_true(i0) [p0, p1]
'''
- self.interpret(ops, [1, 2, 3])
+ self.interpret(ops, [1, 2, 3],
+ namespace={'arraydescr': arraydescr})
# 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
+ assert gc_ll_descr.nursery[0] == 15
+ assert gc_ll_descr.nursery[2 + 8 / WORD] == 15
+ assert gc_ll_descr.addrs[0] == nurs_adr + 4 * WORD + 8*1 + 5*2
+ # slowpath never called
+ assert gc_ll_descr.calls == []
+
+ def test_malloc_nursery_varsize_slowpath(self):
+ self.cpu = self.getcpu(None)
+ ops = '''
+ [i0, i1, i2]
+ p0 = call_malloc_nursery_varsize(8, i0)
+ p1 = call_malloc_nursery_varsize(5, i1)
+ guard_true(i0) [p0, p1]
+ '''
+ self.interpret(ops, [10, 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
# check the nursery content and state
gc_ll_descr.check_nothing_in_nursery()
- assert gc_ll_descr.addrs[0] == nurs_adr + 64
+ assert gc_ll_descr.addrs[0] == nurs_adr + 4 * WORD + 8*1 + 5*2
# slowpath never called
assert gc_ll_descr.calls == []
diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
@@ -93,8 +93,8 @@
type_system=self.type_system,
boxkinds=boxkinds)
- def interpret(self, ops, args, run=True):
- loop = self.parse(ops)
+ def interpret(self, ops, args, run=True, namespace=None):
+ loop = self.parse(ops, namespace=namespace)
self.loop = loop
looptoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py
b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -408,8 +408,7 @@
jump(i0)
""", """
[i0]
- p0 = call_malloc_nursery_varsize(1, i0)
- setfield_gc(p0, %(bdescr.tid)d, descr=tiddescr)
+ p0 = call_malloc_nursery_varsize(1, i0, descr=bdescr)
setfield_gc(p0, i0, descr=blendescr)
jump(i0)
""")
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
@@ -60,6 +60,7 @@
self.float_const_neg_addr = 0
self.float_const_abs_addr = 0
self.malloc_slowpath = 0
+ self.malloc_slowpath_varsize = 0
self.wb_slowpath = [0, 0, 0, 0, 0]
self.setup_failure_recovery()
self._debug = False
@@ -176,7 +177,7 @@
mc.RET()
self._frame_realloc_slowpath = mc.materialize(self.cpu.asmmemmgr, [])
- def _build_malloc_slowpath(self):
+ def _build_malloc_slowpath(self, varsize):
""" While arriving on slowpath, we have a gcpattern on stack,
nursery_head in eax and the size in edi - eax
"""
@@ -190,13 +191,16 @@
mc.SUB_rr(edi.value, eax.value) # compute the size we want
# the arg is already in edi
mc.SUB_ri(esp.value, 16 - WORD)
- if IS_X86_32:
- mc.MOV_sr(0, edi.value)
- if hasattr(self.cpu.gc_ll_descr, 'passes_frame'):
- mc.MOV_sr(WORD, ebp.value)
- elif hasattr(self.cpu.gc_ll_descr, 'passes_frame'):
- # for tests only
- mc.MOV_rr(esi.value, ebp.value)
+ if not varsize:
+ if IS_X86_32:
+ mc.MOV_sr(0, edi.value)
+ if hasattr(self.cpu.gc_ll_descr, 'passes_frame'):
+ mc.MOV_sr(WORD, ebp.value)
+ elif hasattr(self.cpu.gc_ll_descr, 'passes_frame'):
+ # for tests only
+ mc.MOV_rr(esi.value, ebp.value)
+ else:
+ return 0
extra_ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth')
mc.MOV_bi(extra_ofs, 16)
mc.CALL(imm(addr))
@@ -224,7 +228,7 @@
mc.JMP(imm(self.propagate_exception_path))
#
rawstart = mc.materialize(self.cpu.asmmemmgr, [])
- self.malloc_slowpath = rawstart
+ return rawstart
def _build_propagate_exception_path(self):
if not self.cpu.propagate_exception_descr:
@@ -651,7 +655,7 @@
if expected_size == -1:
mc.MOV_si(WORD, 0xffffff)
else:
- mc.MOV_si(WORD, expected_size)
+ mc.MOV_si(WORD, expected_size)
ofs2 = mc.get_relative_pos() - 4
self.push_gcmap(mc, gcmap, mov=True)
mc.CALL(imm(self._frame_realloc_slowpath))
@@ -689,7 +693,7 @@
mc = codebuf.MachineCodeBlockWrapper()
mc.writeimm32(allocated_depth)
mc.copy_to_raw_memory(adr)
-
+
def get_asmmemmgr_blocks(self, looptoken):
clt = looptoken.compiled_loop_token
if clt.asmmemmgr_blocks is None:
@@ -718,7 +722,7 @@
struct.number = compute_unique_id(token)
self.loop_run_counters.append(struct)
return struct
-
+
def patch_jump_for_descr(self, faildescr, adr_new_target):
adr_jump_offset = faildescr._x86_adr_jump_offset
assert adr_jump_offset != 0
@@ -946,7 +950,7 @@
else:
assert isinstance(to_loc, RawEspLoc)
self.mc.MOV32_si(to_loc.value, low_part)
- self.mc.MOV32_si(to_loc.value + 4, high_part)
+ self.mc.MOV32_si(to_loc.value + 4, high_part)
def regalloc_perform(self, op, arglocs, resloc):
genop_list[op.getopnum()](self, op, arglocs, resloc)
@@ -1792,7 +1796,7 @@
if exctploc is not None:
assert exctploc.is_reg()
mc.MOV(exctploc, heap(self.cpu.pos_exception()))
-
+
mc.MOV(heap(self.cpu.pos_exception()), imm0)
mc.MOV(heap(self.cpu.pos_exc_value()), imm0)
@@ -2461,15 +2465,16 @@
self.mc.MOV(heap(nursery_free_adr), edi)
def malloc_cond_varsize(self, nursery_free_adr, nursery_top_adr,
- lengthloc, itemsize, maxlength, gcmap):
+ lengthloc, itemsize, maxlength, gcmap,
+ arraydescr):
self.mc.CMP(lengthloc, imm(maxlength))
- self.mc.J_il8(rx86.Conditions['L'], 0) # patched later
+ self.mc.J_il8(rx86.Conditions['G'], 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, heap(nursery_free_adr))
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
@@ -2479,7 +2484,7 @@
self.mc.overwrite(jmp_adr0-1, chr(offset))
# save the gcmap
self.push_gcmap(self.mc, gcmap, mov=True)
- self.mc.CALL(imm(0))
+ self.mc.CALL(imm(self.malloc_slowpath_varsize))
offset = self.mc.get_relative_pos() - jmp_adr1
assert 0 < offset <= 127
self.mc.overwrite(jmp_adr1-1, chr(offset))
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
@@ -54,7 +54,7 @@
class X86_64_RegisterManager(X86RegisterManager):
# r11 omitted because it's used as scratch
all_regs = [ecx, eax, edx, ebx, esi, edi, r8, r9, r10, r12, r13, r14, r15]
-
+
no_lower_byte_regs = []
save_around_call_regs = [eax, ecx, edx, esi, edi, r8, r9, r10]
@@ -103,7 +103,7 @@
def __init__(self, base_ofs):
FrameManager.__init__(self)
self.base_ofs = base_ofs
-
+
def frame_pos(self, i, box_type):
return FrameLoc(i, get_ebp_ofs(self.base_ofs, i), box_type)
@@ -872,6 +872,7 @@
def consider_call_malloc_nursery_varsize(self, op):
length_box = op.getarg(1)
+ arraydescr = op.getdescr()
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)
@@ -890,7 +891,7 @@
self.assembler.malloc_cond_varsize(
gc_ll_descr.get_nursery_free_addr(),
gc_ll_descr.get_nursery_top_addr(),
- lengthloc, itemsize, maxlength, gcmap)
+ lengthloc, itemsize, maxlength, gcmap, arraydescr)
def get_gcmap(self, forbidden_regs=[], noregs=False):
frame_depth = self.fm.get_frame_depth()
@@ -1335,7 +1336,7 @@
#jump_op = self.final_jump_op
#if jump_op is not None and jump_op.getdescr() is descr:
# self._compute_hint_frame_locations_from_descr(descr)
-
+
def consider_keepalive(self, op):
pass
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,7 +529,7 @@
'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/2',
+ 'CALL_MALLOC_NURSERY_VARSIZE/2d',
'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
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit