[pypy-commit] pypy fast-newarray: implement the case for string and unicode too
fijal
noreply at buildbot.pypy.org
Mon Apr 15 23:04:20 CEST 2013
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: fast-newarray
Changeset: r63392:fed361ad6aaa
Date: 2013-04-15 23:03 +0200
http://bitbucket.org/pypy/pypy/changeset/fed361ad6aaa/
Log: implement the case for string and unicode too
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
@@ -85,8 +85,20 @@
self._build_wb_slowpath(True, withfloats=True)
self._build_propagate_exception_path()
if gc_ll_descr.get_malloc_slowpath_addr is not None:
- self.malloc_slowpath = self._build_malloc_slowpath(varsize=False)
- self.malloc_slowpath_varsize = self._build_malloc_slowpath(varsize=True)
+ # generate few slowpaths for various cases
+ self.malloc_slowpath = self._build_malloc_slowpath(kind='fixed')
+ self.malloc_slowpath_varsize = self._build_malloc_slowpath(
+ kind='var')
+ if hasattr(gc_ll_descr, 'malloc_str'):
+ self.malloc_slowpath_str = self._build_malloc_slowpath(kind='str')
+ else:
+ self.malloc_slowpath_str = None
+ if hasattr(gc_ll_descr, 'malloc_unicode'):
+ self.malloc_slowpath_unicode = self._build_malloc_slowpath(
+ kind='unicode')
+ else:
+ self.malloc_slowpath_unicode = None
+
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
@@ -102,9 +102,11 @@
assert isinstance(descr, ArrayDescr)
self.handle_new_array(descr, op)
elif opnum == rop.NEWSTR:
- self.handle_new_array(self.gc_ll_descr.str_descr, op)
+ self.handle_new_array(self.gc_ll_descr.str_descr, op,
+ kind=FLAG_STR)
elif opnum == rop.NEWUNICODE:
- self.handle_new_array(self.gc_ll_descr.unicode_descr, op)
+ self.handle_new_array(self.gc_ll_descr.unicode_descr, op,
+ kind=FLAG_UNICODE)
else:
raise NotImplementedError(op.getopname())
@@ -116,7 +118,7 @@
else:
self.gen_malloc_fixedsize(size, descr.tid, op.result)
- def handle_new_array(self, arraydescr, op):
+ def handle_new_array(self, arraydescr, op, kind=FLAG_ARRAY):
v_length = op.getarg(0)
total_size = -1
if isinstance(v_length, ConstInt):
@@ -131,7 +133,7 @@
total_size = arraydescr.basesize
elif (self.gc_ll_descr.can_use_nursery_malloc(1) and
self.gen_malloc_nursery_varsize(arraydescr.itemsize,
- v_length, op.result, arraydescr)):
+ v_length, op.result, arraydescr, kind=kind)):
# note that we cannot initialize tid here, because the array
# might end up being allocated by malloc_external or some
# stuff that initializes GC header fields differently
@@ -300,28 +302,17 @@
self.gc_ll_descr.malloc_unicode_descr)
def gen_malloc_nursery_varsize(self, itemsize, v_length, v_result,
- arraydescr):
+ arraydescr, kind=FLAG_ARRAY):
""" itemsize is an int, v_length and v_result are boxes
"""
gc_descr = self.gc_ll_descr
- str_descr = gc_descr.str_descr
- unicode_descr = gc_descr.unicode_descr
- if (arraydescr.basesize == gc_descr.standard_array_basesize and
- arraydescr.lendescr.offset == gc_descr.standard_array_length_ofs):
- flag = FLAG_ARRAY # standard array
- elif (arraydescr.basesize == str_descr.basesize and
- arraydescr.lendescr.offset == str_descr.lendescr.offset):
- flag = FLAG_STR
- elif (arraydescr.basesize == unicode_descr.basesize and
- arraydescr.lendescr.offset == unicode_descr.lendescr.offset):
- # note that this might never be reached if we have the same
- # offsets, that does not quite matter though
- flag = FLAG_UNICODE
- else:
+ if (kind == FLAG_ARRAY and
+ (arraydescr.basesize != gc_descr.standard_array_basesize or
+ arraydescr.lendescr.offset != gc_descr.standard_array_length_ofs)):
return False
self.emitting_an_operation_that_can_collect()
op = ResOperation(rop.CALL_MALLOC_NURSERY_VARSIZE,
- [ConstInt(flag), ConstInt(itemsize), v_length],
+ [ConstInt(kind), ConstInt(itemsize), v_length],
v_result, descr=arraydescr)
self.newops.append(op)
self.recent_mallocs[v_result] = None
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
@@ -263,8 +263,8 @@
arraydescr.tid = 15
ops = '''
[i0, i1, i2]
- p0 = call_malloc_nursery_varsize(8, i0, descr=arraydescr)
- p1 = call_malloc_nursery_varsize(5, i1, descr=arraydescr)
+ p0 = call_malloc_nursery_varsize(0, 8, i0, descr=arraydescr)
+ p1 = call_malloc_nursery_varsize(0, 5, i1, descr=arraydescr)
guard_false(i0) [p0, p1]
'''
self.interpret(ops, [1, 2, 3],
@@ -286,10 +286,10 @@
self.cpu = self.getcpu(None)
ops = '''
[i0, i1, i2]
- p0 = call_malloc_nursery_varsize(8, i0, descr=arraydescr)
- p1 = call_malloc_nursery_varsize(5, i1, descr=arraydescr)
- p3 = call_malloc_nursery_varsize(5, i2, descr=arraydescr)
- p4 = call_malloc_nursery_varsize(5, i2, descr=arraydescr)
+ p0 = call_malloc_nursery_varsize(0, 8, i0, descr=arraydescr)
+ p1 = call_malloc_nursery_varsize(0, 5, i1, descr=arraydescr)
+ p3 = call_malloc_nursery_varsize(0, 5, i2, descr=arraydescr)
+ p4 = call_malloc_nursery_varsize(0, 5, i2, descr=arraydescr)
# overflow
guard_false(i0) [p0, p1, p3, p4]
'''
@@ -816,7 +816,7 @@
pdying = getarrayitem_gc(p0, 0, descr=arraydescr)
px = call_may_force(ConstClass(fptr), pf, pdying, i0, descr=calldescr)
guard_not_forced(descr=faildescr) [p1, p2, p3, px]
- finish(px, descr=finishdescr)
+ finish(px, descr=finaldescr)
""", namespace={'fptr': fptr, 'calldescr': calldescr,
'arraydescr': cpu.arraydescrof(A),
'faildescr': BasicFailDescr(1),
@@ -860,7 +860,7 @@
pdying = getarrayitem_gc(p0, 0, descr=arraydescr)
px = call(ConstClass(fptr), pf, pdying, i0, descr=calldescr)
guard_false(i0, descr=faildescr) [p1, p2, p3, px]
- finish(px, descr=finishdescr)
+ finish(px, descr=finaldescr)
""", namespace={'fptr': fptr, 'calldescr': calldescr,
'arraydescr': cpu.arraydescrof(A),
'faildescr': BasicFailDescr(1),
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
@@ -545,7 +545,7 @@
p1 = int_add(p0, %(strdescr.basesize + 16 * strdescr.itemsize)d)
setfield_gc(p1, %(unicodedescr.tid)d, descr=tiddescr)
setfield_gc(p1, 10, descr=unicodelendescr)
- p2 = call_malloc_nursery_varsize(1, 4, i2, \
+ p2 = call_malloc_nursery_varsize(2, 4, i2, \
descr=unicodedescr)
setfield_gc(p2, i2, descr=unicodelendescr)
p3 = call_malloc_nursery_varsize(1, 1, i2, \
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
@@ -1,7 +1,7 @@
import sys
import os
-from rpython.jit.backend.llsupport import symbolic, jitframe
+from rpython.jit.backend.llsupport import symbolic, jitframe, gc
from rpython.jit.backend.llsupport.assembler import (GuardToken, BaseAssembler,
DEBUG_COUNTER, debug_bridge)
from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
@@ -156,22 +156,27 @@
mc.RET()
self._frame_realloc_slowpath = mc.materialize(self.cpu.asmmemmgr, [])
- def _build_malloc_slowpath(self, varsize):
+ def _build_malloc_slowpath(self, kind):
""" While arriving on slowpath, we have a gcpattern on stack,
nursery_head in eax and the size in edi - eax
"""
+ assert kind in ['fixed', 'str', 'unicode', 'var']
mc = codebuf.MachineCodeBlockWrapper()
self._push_all_regs_to_frame(mc, [eax, edi], self.cpu.supports_floats)
ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
# store the gc pattern
mc.MOV_rs(ecx.value, WORD)
mc.MOV_br(ofs, ecx.value)
- if varsize:
+ if kind == 'fixed':
+ addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr()
+ elif kind == 'str':
+ addr = self.cpu.gc_ll_descr.get_malloc_fn_addr('malloc_str')
+ elif kind == 'unicode':
+ addr = self.cpu.gc_ll_descr.get_malloc_fn_addr('malloc_unicode')
+ else:
addr = self.cpu.gc_ll_descr.get_malloc_slowpath_array_addr()
- else:
- addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr()
mc.SUB_ri(esp.value, 16 - WORD)
- if not varsize:
+ if kind == 'fixed':
mc.SUB_rr(edi.value, eax.value) # compute the size we want
# the arg is already in edi
if IS_X86_32:
@@ -181,6 +186,11 @@
elif hasattr(self.cpu.gc_ll_descr, 'passes_frame'):
# for tests only
mc.MOV_rr(esi.value, ebp.value)
+ elif kind == 'str' or kind == 'unicode':
+ if IS_X86_32:
+ xxx
+ else:
+ mc.MOV_rs(edi.value, WORD * 3)
else:
if IS_X86_32:
xxx
@@ -2354,7 +2364,7 @@
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,
+ def malloc_cond_varsize(self, kind, nursery_free_adr, nursery_top_adr,
lengthloc, itemsize, maxlength, gcmap,
arraydescr):
from rpython.jit.backend.llsupport.descr import ArrayDescr
@@ -2376,9 +2386,12 @@
offset = self.mc.get_relative_pos() - jmp_adr0
assert 0 < offset <= 127
self.mc.overwrite(jmp_adr0-1, chr(offset))
- self.mc.MOV_si(WORD, itemsize)
- self.mc.MOV(RawEspLoc(WORD * 2, INT), lengthloc)
- self.mc.MOV_si(WORD * 3, arraydescr.tid)
+ if kind == 0:
+ self.mc.MOV_si(WORD, itemsize)
+ self.mc.MOV(RawEspLoc(WORD * 2, INT), lengthloc)
+ self.mc.MOV_si(WORD * 3, arraydescr.tid)
+ else:
+ self.mc.MOV(RawEspLoc(WORD, INT), lengthloc)
# save the gcmap
self.push_gcmap(self.mc, gcmap, mov=True)
self.mc.CALL(imm(self.malloc_slowpath_varsize))
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
@@ -871,7 +871,7 @@
sizeloc, gcmap)
def consider_call_malloc_nursery_varsize(self, op):
- length_box = op.getarg(1)
+ length_box = op.getarg(2)
arraydescr = op.getdescr()
assert isinstance(length_box, BoxInt) # we cannot have a const here!
# looking at the result
@@ -886,9 +886,10 @@
self.rm.possibly_free_var(tmp_box)
#
gc_ll_descr = self.assembler.cpu.gc_ll_descr
- itemsize = op.getarg(0).getint()
+ itemsize = op.getarg(1).getint()
maxlength = (gc_ll_descr.max_size_of_young_obj - WORD * 2) / itemsize
self.assembler.malloc_cond_varsize(
+ op.getarg(0).getint(),
gc_ll_descr.get_nursery_free_addr(),
gc_ll_descr.get_nursery_top_addr(),
lengthloc, itemsize, maxlength, gcmap, arraydescr)
More information about the pypy-commit
mailing list